gnrc.h
11.1 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
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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 Generic (GNRC) network stack
* @ingroup net
* @brief RIOT's modular default IP network stack.
* @see [Martine Lenders' master thesis](http://doc.riot-os.org/mlenders_msc.pdf)
* about GNRC's design and evaluation and the slide set of
* [its defense](http://doc.riot-os.org/mlenders_msc_def.pdf).
*
* About
* =====
*
* This module is currently the default network stack for RIOT and includes
* many components ranging from a @ref net_gnrc_netdev through a fully-featured
* @ref net_gnrc_ipv6 implementation with @ref net_gnrc_sixlowpan "6LowPAN"
* extensions to an @ref net_gnrc_udp "UDP" implementation and
* @ref net_gnrc_rpl.
*
* A list of all features contained in the @ref net_gnrc is available in the
* `Modules` section above.
*
* Integration into RIOT
* =====================
*
* From the application layer the @ref net_gnrc can be accessed through the
* @ref net_sock, while the interface to the @ref drivers_netdev_api is
* defined by the @ref net_gnrc_netdev.
*
* Architecture
* ============
*
* ![GNRC Network Stack](riot-gnrc.svg)
*
* Each layer of the network stack runs in its own thread and each lower layer
* thread has a higher priority than any upper layer thread. In this regard,
* the thread of the MAC layer implementation has the highest priority and
* threads on the application layer have the lowest priority. The communication
* between threads is handled by the kernel's @ref core_msg functionality and
* by the @ref net_gnrc_netapi. Most of the times IPC will take place between
* threads of neighboring layers for packets that traverse the network stack up
* or down.
*
* Due to the design of @ref net_gnrc "GNRC" and the nature of inter-process
* communication, it is crucial for a new module that introduces a new thread
* to follow a certain programming construct if it desires to interact with
* other threads without blocking the system: Utilizing an `event loop`.
*
* Hence, a thread for @ref net_gnrc "GNRC" will usually consist of four basic
* steps.
*
* 1. Initialize a message queue (note that its size **must** be a power of two,
* see @ref msg_init_queue())
* 2. register for a @ref net_gnrc_nettype
* 3. wait for a message
* 4. react appropriately to a message and return to 3.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
* void *_event_loop(void *arg)
* {
* static msg_t _msg_q[Q_SZ];
* (void)arg;
* msg_init_queue(_msg_q, Q_SZ);
* gnrc_netreg_entry me_reg = GNRC_NETREG_ENTRY_INIT_PID(
* GNRC_NETREG_DEMUX_CTX_ALL,
* sched_active_pid);
* gnrc_netreg_register(GNRC_NETTYPE_IPV6, &me_reg);
* while (1) {
* msg_receive(&msg);
* switch (msg.type) {
* case TYPE1:
* callback1();
* break;
* ...
* }
* }
*
* return NULL;
* }
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* @note As an example have a look at the event loops of @ref net_gnrc_ipv6 and
* @ref net_gnrc_rpl
*
* Receiving / Transmitting Packets
* ================================
*
* Packets can be received or transmitted by interacting with the @ref
* net_gnrc_netapi.
*
* Receiving Packets
* -----------------
*
* The reception of a @ref net_gnrc_pkt from another thread is handled by the
* @ref net_gnrc_netapi module. In order to receive a @ref net_gnrc_pkt of a
* specific type, it is necessary to register for the appropriate @ref
* net_gnrc_nettype first. Your thread will then be able to receive certain
* commands defined in the @ref net_gnrc_netapi module (e.g. @ref
* net_gnrc_netapi::GNRC_NETAPI_MSG_TYPE_RCV) for all @ref net_gnrc_pkt
* "Packets" that your thread registered for.
*
* The following example will sketch how to receive incoming and outgoing UDP
* traffic on port 80.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
* void *_event_loop(void *arg)
* {
* static msg_t _msg_q[Q_SZ];
* msg_t msg, reply;
* reply.type = GNRC_NETAPI_MSG_TYPE_ACK;
* reply.content.value = -ENOTSUP;
* msg_init_queue(_msg_q, Q_SZ);
* gnrc_pktsnip_t *pkt = NULL;
* gnrc_netreg_entry me_reg = { .demux_ctx = 80, .pid = thread_getpid() };
* gnrc_netreg_register(GNRC_NETTYPE_UDP, &me_reg);
*
* while (1) {
* msg_receive(&msg);
* switch (msg.type) {
* case GNRC_NETAPI_MSG_TYPE_RCV:
* pkt = msg.content.ptr;
* _handle_incoming_pkt(pkt);
* break;
* case GNRC_NETAPI_MSG_TYPE_SND:
* pkt = msg.content.ptr;
* _handle_outgoing_pkt(pkt);
* break;
* case GNRC_NETAPI_MSG_TYPE_SET:
* case GNRC_NETAPI_MSG_TYPE_GET:
* msg_reply(&msg, &reply);
* break;
* default:
* break;
* }
* }
*
* return NULL;
* }
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* @note When receiving a message of type @ref GNRC_NETAPI_MSG_TYPE_SET or
* @ref GNRC_NETAPI_MSG_TYPE_GET, it is necessary to acknowledge it by
* calling @ref msg_reply() with a message of type
* @ref GNRC_NETAPI_MSG_TYPE_ACK which contains the actual size of the
* GET message's content on success or an error code otherwise.
*
* @note Do not forget to unregister with @ref gnrc_netreg_unregister() if you
* leave the function
* context
*
* Transmitting Packets
* --------------------
*
* A packet is transmitted by relaying it to threads interested in handling (and
* dispatching) packets of its type. To do this, the @ref net_gnrc_netapi
* offers dispatch helper functions called @ref gnrc_netapi_dispatch_send()
* and gnrc_netapi_dispatch_receive().
*
* The following example sketches the usage and assumes a valid @ref
* net_gnrc_pkt named `pkt`.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
* gnrc_pktsnip_t *pkt;
*
* pkt = gnrc_pktbuf_add(NULL, data, size, GNRC_NETTYPE_UNDEF);
* if (pkt == NULL) {
* puts("Error: unable to copy data to packet buffer\n");
* return;
* }
* if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_UDP, 80, pkt)) {
* puts("Error: no thread is interested");
* gnrc_pktbuf_release(pkt);
* return;
* }
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* First, the data to be sent is added to the @ref net_gnrc_pktbuf "packet buffer".
* This ensures its intactness during the sending process. After the data to be
* sent has been added to the packet buffer, its parent data structure can safely
* be freed or re-used.
*
* Then, the @ref net_gnrc_pkt "pkt" will be sent to all threads that registered
* for @ref GNRC_NETTYPE_UDP and the demux context `80`. Every registered thread
* will receive a @ref GNRC_NETAPI_MSG_TYPE_SND command and can access the @ref
* net_gnrc_pkt. Note that at this point, the threads receiving pkt act as its
* owners, so please don't modify pkt after calling any dispatch function.
*
* If @ref gnrc_netapi_dispatch_send() is replaced by @ref
* gnrc_netapi_dispatch_receive() then threads will receive the @ref
* GNRC_NETAPI_MSG_TYPE_RCV command instead, again with access to the @ref
* net_gnrc_pkt.
*
* @note If the data to be sent requires extra headers to be added for successful
* transmission (in the example, this would be IP and UDP headers), these
* have to be built manually before calling @ref gnrc_netapi_dispatch_send().
* In the interest of conciseness, this is omitted in this tutorial;
* please refer to @ref gnrc_udp_hdr_build(), @ref gnrc_ipv6_hdr_build()
* etc. for more information.
*
* How To Use
* ==========
* @ref net_gnrc is highly modular and can be adjusted to include only the
* desired features. In the following several of the available modules will be
* stated that you can include in your application's Makefile.
*
* - To include the default network device(s) on your board:
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
* USEMODULE += gnrc_netdev_default
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* - To auto-initialize these network devices as GNRC network interfaces
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
* USEMODULE += auto_init_gnrc_netif
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* - You may choose to build either as an IPv6 Node
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
* USEMODULE += gnrc_ipv6_default
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* or as an IPv6 Router
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
* USEMODULE += gnrc_ipv6_router_default
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* An IPv6 Router can forward packets, while an IPv6 Node will simply drop
* packets not targeted to it. If an IEEE 802.15.4 network device is present
* @ref net_gnrc_sixlowpan (with @ref net_gnrc_sixlowpan_frag and @ref
* net_gnrc_sixlowpan_iphc) will be included automatically.
* - For basic IPv6 (and 6LoWPAN) functionalities choose instead
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
* USEMODULE += gnrc_ipv6
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* or
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
* USEMODULE += gnrc_ipv6_router
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* respectively. Those modules provide the bare minimum of IPv6
* functionalities (no @ref net_gnrc_icmpv6, no @ref net_gnrc_ndp). Because
* of that, the @ref net_gnrc_ipv6_nc needs to be configured manually. If an
* IEEE 802.15.4 device is present @ref net_gnrc_sixlowpan will be included
* automatically, but no fragmentation or header compression support will be
* provided.
*
* - For @ref net_gnrc_icmpv6_echo "ICMPv6 echo request/reply (ping)"
* functionality:
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
* USEMODULE += gnrc_icmpv6_echo
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* - For @ref net_gnrc_udp support include
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
* USEMODULE += gnrc_udp
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* - To use @ref net_sock_udp with GNRC include
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
* USEMODULE += gnrc_sock_udp
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* - To include the @ref net_gnrc_rpl module
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
* USEMODULE += gnrc_rpl
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This will include the @ref net_gnrc_rpl module. To provide forwarding
* capabilities it is necessary to build the application with
* `gnrc_ipv6_router_default` (or `gnrc_ipv6_router`), not
* `gnrc_ipv6_default` (or `gnrc_ipv6`).
*
* @{
*
* @file
* @brief Includes all essential GNRC network stack base modules
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef NET_GNRC_H
#define NET_GNRC_H
#include "net/netopt.h"
#include "net/gnrc/netapi.h"
#include "net/gnrc/netreg.h"
#include "net/gnrc/nettype.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/netif/hdr.h"
#include "net/gnrc/pktbuf.h"
#include "net/gnrc/pkt.h"
#ifdef __cplusplus
extern "C" {
#endif
/* this file does not provide anything on it's own */
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_H */
/** @} */