netdev.h
6.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
/*
* Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup net_gnrc_netdev Adaption layer for GNRC on top of Netdev
* @ingroup net_gnrc
* @brief Provides the glue code for @ref net_gnrc on top of @ref drivers_netdev_api
* @{
*
* @file
* @brief netdev-GNRC glue code interface
*
* This interface is supposed to provide common adaption code between the
* low-level network device interface "netdev" and the GNRC network stack.
*
* GNRC sends around "gnrc_pktsnip_t" structures, but netdev can only handle
* "struct iovec" structures when sending, or a flat buffer when receiving.
*
* The purpose of gnrc_netdev is to bring these two interfaces together.
*
* @author Kaspar Schleiser <kaspar@schleiser.de>
*/
#ifndef NET_GNRC_NETDEV_H
#define NET_GNRC_NETDEV_H
#include <assert.h>
#include <stdint.h>
#include "kernel_types.h"
#include "net/netdev.h"
#include "net/gnrc.h"
#include "net/gnrc/mac/types.h"
#include "net/ieee802154.h"
#include "net/gnrc/mac/mac.h"
#ifdef MODULE_GNRC_MAC
#include "net/csma_sender.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Default priority for adaption layer's threads
*/
#ifndef GNRC_NETDEV_MAC_PRIO
#define GNRC_NETDEV_MAC_PRIO (THREAD_PRIORITY_MAIN - 5)
#endif
/**
* @brief Type for @ref msg_t if device fired an event
*/
#define NETDEV_MSG_TYPE_EVENT 0x1234
/**
* @brief Mask for @ref gnrc_mac_tx_feedback_t
*/
#define GNRC_NETDEV_MAC_INFO_TX_FEEDBACK_MASK (0x0003U)
/**
* @brief Flag to track if a transmission might have corrupted a received
* packet
*/
#define GNRC_NETDEV_MAC_INFO_RX_STARTED (0x0004U)
/**
* @brief Flag to track if a device has enabled CSMA for transmissions
*
* If `gnrc_mac` is used, the user should be noticed that the `send()`
* function of gnrc_netdev will be affected with the state of this flag, since
* `gnrc_mac` accordingly adapts the `send()` function. If the device doesn't
* support on-chip CSMA and this flag is set for requiring CSMA transmission,
* then, the device will run software CSMA using `csma_sender` APIs.
*/
#define GNRC_NETDEV_MAC_INFO_CSMA_ENABLED (0x0100U)
/**
* @brief Structure holding GNRC netdev adapter state
*
* This structure is supposed to hold any state parameters needed
* to use a netdev device from GNRC.
*
* It can be extended
*/
typedef struct gnrc_netdev {
/**
* @brief Send a pktsnip using this device
*
* This function should convert the pktsnip into a format
* the underlying device understands and send it.
*/
int (*send)(struct gnrc_netdev *dev, gnrc_pktsnip_t *snip);
/**
* @brief Receive a pktsnip from this device
*
* This function should receive a raw frame from the underlying
* device and convert it into a pktsnip while adding a netif header
* and possibly marking out higher-layer headers.
*/
gnrc_pktsnip_t * (*recv)(struct gnrc_netdev *dev);
/**
* @brief netdev handle this adapter is working with
*/
netdev_t *dev;
/**
* @brief PID of this adapter for netapi messages
*/
kernel_pid_t pid;
#ifdef MODULE_GNRC_MAC
/**
* @brief general information for the MAC protocol
*/
uint16_t mac_info;
/**
* @brief device's l2 address
*/
uint8_t l2_addr[IEEE802154_LONG_ADDRESS_LEN];
/**
* @brief device's l2 address length
*/
uint8_t l2_addr_len;
/**
* @brief device's software CSMA configuration
*/
csma_sender_conf_t csma_conf;
#if ((GNRC_MAC_RX_QUEUE_SIZE != 0) || (GNRC_MAC_DISPATCH_BUFFER_SIZE != 0)) || defined(DOXYGEN)
/**
* @brief MAC internal object which stores reception parameters, queues, and
* state machines.
*/
gnrc_mac_rx_t rx;
#endif /* ((GNRC_MAC_RX_QUEUE_SIZE != 0) || (GNRC_MAC_DISPATCH_BUFFER_SIZE != 0)) || defined(DOXYGEN) */
#if ((GNRC_MAC_TX_QUEUE_SIZE != 0) || (GNRC_MAC_NEIGHBOR_COUNT != 0)) || defined(DOXYGEN)
/**
* @brief MAC internal object which stores transmission parameters, queues, and
* state machines.
*/
gnrc_mac_tx_t tx;
#endif /* ((GNRC_MAC_TX_QUEUE_SIZE != 0) || (GNRC_MAC_NEIGHBOR_COUNT == 0)) || defined(DOXYGEN) */
#ifdef MODULE_GNRC_LWMAC
/**
* @brief LWMAC specific structure object for storing LWMAC internal states.
*/
gnrc_lwmac_t lwmac;
#endif
#endif /* MODULE_GNRC_MAC */
} gnrc_netdev_t;
#ifdef MODULE_GNRC_MAC
/**
* @brief get the 'rx_started' state of the device
*
* This function checks whether the device has started receiving a packet.
*
* @param[in] dev ptr to netdev device
*
* @return the rx_started state
*/
static inline bool gnrc_netdev_get_rx_started(gnrc_netdev_t *dev)
{
return (dev->mac_info & GNRC_NETDEV_MAC_INFO_RX_STARTED);
}
/**
* @brief set the rx_started state of the device
*
* This function is intended to be called only in netdev_t::event_callback().
*
* @param[in] dev ptr to netdev device
*
*/
static inline void gnrc_netdev_set_rx_started(gnrc_netdev_t *dev, bool rx_started)
{
if (rx_started) {
dev->mac_info |= GNRC_NETDEV_MAC_INFO_RX_STARTED;
}
else {
dev->mac_info &= ~GNRC_NETDEV_MAC_INFO_RX_STARTED;
}
}
/**
* @brief get the transmission feedback of the device
*
* @param[in] dev ptr to netdev device
*
* @return the transmission feedback
*/
static inline gnrc_mac_tx_feedback_t gnrc_netdev_get_tx_feedback(gnrc_netdev_t *dev)
{
return (gnrc_mac_tx_feedback_t)(dev->mac_info &
GNRC_NETDEV_MAC_INFO_TX_FEEDBACK_MASK);
}
/**
* @brief set the transmission feedback of the device
*
* This function is intended to be called only in netdev_t::event_callback().
*
* @param[in] dev ptr to netdev device
*
*/
static inline void gnrc_netdev_set_tx_feedback(gnrc_netdev_t *dev,
gnrc_mac_tx_feedback_t txf)
{
/* check if gnrc_mac_tx_feedback does not collide with
* GNRC_NETDEV_MAC_INFO_RX_STARTED */
assert(!(txf & GNRC_NETDEV_MAC_INFO_RX_STARTED));
/* unset previous value */
dev->mac_info &= ~GNRC_NETDEV_MAC_INFO_TX_FEEDBACK_MASK;
dev->mac_info |= (uint16_t)(txf & GNRC_NETDEV_MAC_INFO_TX_FEEDBACK_MASK);
}
#endif
/**
* @brief Initialize GNRC netdev handler thread
*
* @param[in] stack ptr to preallocated stack buffer
* @param[in] stacksize size of stack buffer
* @param[in] priority priority of thread
* @param[in] name name of thread
* @param[in] gnrc_netdev ptr to netdev device to handle in created thread
*
* @return pid of created thread
* @return KERNEL_PID_UNDEF on error
*/
kernel_pid_t gnrc_netdev_init(char *stack, int stacksize, char priority,
const char *name, gnrc_netdev_t *gnrc_netdev);
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_NETDEV_H */
/** @} */