Blame view

RIOT/sys/include/net/gnrc/lwmac/lwmac.h 15.1 KB
a752c7ab   elopes   add first test an...
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
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
  /*
   * Copyright (C) 2015 Daniel Krebs
   *               2016 INRIA
   *
   * 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_lwmac Simplest possible MAC layer
   * @ingroup     net_gnrc
   * @brief       Lightweight MAC protocol that allows for duty cycling to save
   *              energy.
   *
   * ## LWMAC implementation
   *
   * ## Radio duty cycling
   * LWMAC adopts the radio duty-cycle scheme to conserve power. Namely, in each
   * cycle period (MAC superframe), a node device wakes up for a short period of
   * time (called listen period or wake-up period) for receiving possible incoming
   * packets from other devices. Outside the listen period, the node device turns
   * off its radio to conserve power.
   *
   * ## Phase-lock scheme
   * LWMAC adopts the phase-lock scheme to further reduce power consumption. Each
   * node device in LWMAC will try to record/track its Tx-neighbor's wake-up phase.
   * This is called phase-lock. After phase-locking, the sender node will (likely)
   * spend less preamble packets (also called WR packet, i.e., wake-up-request, in
   * LWMAC) for initiating a hand-shaking procedure for transmitting a data packet,
   * compared to the first time it talks to the receiver.
   *
   * ## Burst transmission
   * LWMAC adopts pending-bit technique to enhance its throughput. Namely, in case
   * of having multi packets for the receiver, a sender uses the pending-bit flag
   * embedded in the MAC header to instruct this situation, and the buffered packets
   * will be transmitted in a continuous sequence, back to back, to the receiver in
   * one shot.
   *
   * ## Auto wake-up extension
   * LWMAC adopts auto wake-up extension scheme based on timeout (like T-MAC). In short,
   * when a packet is successfully received at the receiver side, the receiver will
   * reset the wake-up timeout to extend its wake-up period for receiving more potential
   * incoming packets. This is to be compatible with the pending-bit technique to allow
   * the receiver to absorb more packets when needed, thus boosts the throughput.
   *
   * ## Simple retransmission scheme
   * LWMAC adopts a simple retransmission scheme to enhance link reliability. The data
   * packet will only be dropped in case the retransmission counter gets larger than
   * @ref GNRC_LWMAC_MAX_DATA_TX_RETRIES.
   *
   * ## Automatic phase backoff scheme
   * LWMAC adopts an automatic phase backoff scheme to reduce WR (preamble) collision
   * probability. In multi-hop scenarios, let's say, nodes A <---B <----C (which is
   * common in multi-hop data collection networks), in which B has packets for A, and
   * C has packets for B. In case A and B's wake-up phases are too close (overlapping).
   * Then, especially in high traffic conditions, B and C may initiate transmissions
   * at the same time (B sends to A, and C sends to B), a link of either will be
   * definitely interfered, leading to collisions and link throughput reduction. To
   * this end, by using the automatic phase backoff scheme, if a sender finds its
   * receiver's phase is too close to its own phase, it will run a backoff scheme to
   * randomly reselect a new wake-up phase for itself.
   *
   * @{
   *
   * @file
   * @brief       Interface definition for the LWMAC protocol
   *
   * @author      Daniel Krebs <github@daniel-krebs.net>
   * @author      Shuguo Zhuo  <shuguo.zhuo@inria.fr>
   */
  
  #ifndef NET_GNRC_LWMAC_LWMAC_H
  #define NET_GNRC_LWMAC_LWMAC_H
  
  #include "kernel_types.h"
  #include "net/gnrc/netdev.h"
  
  #ifdef __cplusplus
  extern "C" {
  #endif
  
  /**
   * @brief Time between consecutive wake-ups.
   *
   * This macro governs power consumption, latency and throughput!
   * In LWMAC, devices adopt duty-cycle scheme to conserve power. That is,
   * time is divided into repeated cycles (or, superframes), and in each
   * cycle, a node only wakes up for a period of time for receiving potential
   * incoming packets for itself. This macro defines the wake-up interval, or,
   * in other words, defines the cycle duration used in LWMAC. If the wake-up interval
   * is short, nodes will wake up more frequently, which also increases
   * the chances for receiving packets from neighbors (i.e., leads to higher
   * throughput), but also results in higher power consumption.
   * In LWMAC, by default, we regard the wake-up period as the beginning of a cycle.
   */
  #ifndef GNRC_LWMAC_WAKEUP_INTERVAL_US
  #define GNRC_LWMAC_WAKEUP_INTERVAL_US        (100LU * US_PER_MS)
  #endif
  
  /**
   * @brief The Maximum WR (preamble packet @ref gnrc_lwmac_frame_wr_t) duration time.
   *
   * Since LWMAC adopts duty-cycle scheme, a node only wakes up for a short
   * period in each cycle. Thus, to probe where is the wake-up period of the
   * receiver, a sender sends WR (preamble) packets to notice the receiver for
   * communication. To ensure that the receiver will catch at least one WR
   * packet in one cycle, the sender repeatedly broadcasts a stream of WR packets
   * with the broadcast duration (preamble duration) slightly longer period than
   * @ref GNRC_LWMAC_WAKEUP_INTERVAL_US.
   */
  #ifndef GNRC_LWMAC_PREAMBLE_DURATION_US
  #define GNRC_LWMAC_PREAMBLE_DURATION_US      ((13LU * GNRC_LWMAC_WAKEUP_INTERVAL_US) / 10)
  #endif
  
  /**
   * @brief Timeout to send the next WR in case no WA has been received during that
   *        time.
   *
   * In LWMAC, when a sender initiates a transmission to a receiver, it starts with
   * sending a stream of repeated WR packets with @ref GNRC_LWMAC_TIME_BETWEEN_WR_US interval
   * between two consecutive WRs. After sending one WR (preamble) packet, the sender turns
   * to the listen mode to receive the potential incoming WA (preamble-ACK) packet with
   * a timeout of @ref GNRC_LWMAC_TIME_BETWEEN_WR_US. If no WA is received during
   * @ref GNRC_LWMAC_TIME_BETWEEN_WR_US, the sender starts sending the next WR.
   * It is referenced to the beginning of both WRs, but due to internal
   * overhead, the exact spacing is slightly higher.
   * The minimum possible value depends on the time it takes to completely
   * send a WR with the given hardware (including processor) and data rate.
   */
  #ifndef GNRC_LWMAC_TIME_BETWEEN_WR_US
  #define GNRC_LWMAC_TIME_BETWEEN_WR_US        (5U * US_PER_MS)
  #endif
  
  /**
   * @brief How long a node in LWMAC should keep awake and listen on the channel in one cycle.
   *
   * LWMAC adopts the duty-cycle scheme that a node only wakes up for a short
   * period of @ref GNRC_LWMAC_WAKEUP_DURATION_US in each cycle. In the rest of the cycle, the node
   * turns off the radio to conserve power. @ref GNRC_LWMAC_WAKEUP_DURATION_US is set to twice the
   * duration of @ref GNRC_LWMAC_TIME_BETWEEN_WR_US, to guarantee that the wake-up period is long
   * enough that receiver will not miss the WR (preamble) packet.
   * Receiver needs to support @ref NETDEV_EVENT_RX_STARTED event in order to use time-between-WR
   * as a sensible default here. Otherwise the duration of WRs as well as longest
   * possible data broadcasts need to be taken into account.
   */
  #ifndef GNRC_LWMAC_WAKEUP_DURATION_US
  #define GNRC_LWMAC_WAKEUP_DURATION_US        (GNRC_LWMAC_TIME_BETWEEN_WR_US * 2)
  #endif
  
  /**
   * @brief How long broadcast packets @ref gnrc_lwmac_frame_broadcast_t will be sent to make sure
   *        every participant has received at least one copy.
   *
   * Since LWMAC adopts duty-cycle scheme, a node only wakes up for a short period in
   * each cycle. Thus, when a node wants to broadcast a packet, it repeatedly broadcasts the
   * packet for one @ref GNRC_LWMAC_BROADCAST_DURATION_US duration which is slightly longer
   * than @ref GNRC_LWMAC_WAKEUP_INTERVAL_US. This is to ensure that all neighbors will not miss
   * the broadcast procedure of the sender and catch at least one copy of the broadcast packet.
   */
  #ifndef GNRC_LWMAC_BROADCAST_DURATION_US
  #define GNRC_LWMAC_BROADCAST_DURATION_US     ((GNRC_LWMAC_WAKEUP_INTERVAL_US * 11) / 10)
  #endif
  
  /**
   * @brief Time to idle between two successive broadcast packets, referenced to the
   *        start of the packet.
   *
   * The same limitation as for @ref GNRC_LWMAC_TIME_BETWEEN_WR_US apply here.
   * In LWMAC, when a sender initiates a broadcast, it starts with sending a stream of
   * repeated broadcast packets with @ref GNRC_LWMAC_TIME_BETWEEN_BROADCAST_US interval
   * between two consecutive broadcast packets. After sending one broadcast packet, the sender
   * turns to the listen mode with a timeout of @ref GNRC_LWMAC_TIME_BETWEEN_BROADCAST_US. When this
   * timeout expires, the sender sends the next broadcast packet until reaching the maximum
   * broadcast duration of @ref GNRC_LWMAC_BROADCAST_DURATION_US.
   */
  #ifndef GNRC_LWMAC_TIME_BETWEEN_BROADCAST_US
  #define GNRC_LWMAC_TIME_BETWEEN_BROADCAST_US (GNRC_LWMAC_TIME_BETWEEN_WR_US)
  #endif
  
  /**
   * @brief WR preparation overhead before it can be sent (higher with debugging output).
   *
   * In LWMAC, when a sender wants to send a data packet to the receiver, it starts
   * sending the WR stream a little bit earlier (advance) to the beginning edge
   * of destination's wake-up phase over time. The idea is not to miss the wake-up
   * period of the receiver, otherwise will lead to a long WR procedure.
   */
  #ifndef GNRC_LWMAC_WR_PREPARATION_US
  #define GNRC_LWMAC_WR_PREPARATION_US         ((3U * US_PER_MS))
  #endif
  
  /**
   * @brief How long to wait after a WA for data to come in.
   *
   * When a node in LWMAC gets a WR during its wake-up period, it immediately
   * replies a WA packet to the sender for acknowledging the sender's transmission
   * request. After sending the WA, the receiver waits for the data packet from the
   * sender, with a timeout of @ref GNRC_LWMAC_DATA_DELAY_US duration. In case no data will be
   * received in this period, the receiver regards reception failed and go back to
   * normal listen mode. However, in case the receiver receives other unintended packets,
   * like WR/WA packets from other neighbor communication pairs, the receiver resets
   * this timeout and continues to wait for the data packet, with the consideration that
   * the sender's data transmission might be delayed due to other ongoing transmissions
   * (the data packet is transmitted with CSMA/CA).
   * This data timeout is long enough to catch the beginning of the packet if the transceiver
   * supports @ref NETDEV_EVENT_RX_STARTED event (this can be important for big packets).
   */
  #ifndef GNRC_LWMAC_DATA_DELAY_US
  #define GNRC_LWMAC_DATA_DELAY_US             (10U * US_PER_MS)
  #endif
  
  /**
   * @brief CSMA retries for DATA packet after WR->WA was successful.
   *
   * After receiving the WA packet @ref gnrc_lwmac_frame_wa_t from the receiver, the sender
   * starts sending the data packet using CSMA/CA. This macro defines how many CSMA retries
   * a sender will be allowed to execute for sending its data, before the data is successfully
   * sent (gets data ACK from the receiver).
   */
  #ifndef GNRC_LWMAC_DATA_CSMA_RETRIES
  #define GNRC_LWMAC_DATA_CSMA_RETRIES         (3U)
  #endif
  
  /**
   * @brief Maximum TX transmission retries for DATA packet in case of no response from the receiver.
   *
   * When a data packet is scheduled for transmission, i.e., pushed into TX for sending,
   * LWMAC defines a maximum of @ref GNRC_LWMAC_MAX_DATA_TX_RETRIES retries for transmission of the
   * packet. That is, in case of transmission failure in TX due to no WA from the receiver,
   * the sender will not drop the packet, but keeps it and retries to send the data packet
   * in the following cycles, until the sender reaches the maximum retries limit defined here.
   * Then, the packet will be dropped.
   */
  #ifndef GNRC_LWMAC_MAX_DATA_TX_RETRIES
  #define GNRC_LWMAC_MAX_DATA_TX_RETRIES       (3U)
  #endif
  
  /**
   * @brief MAX burst transmission packet number in one shot.
   *
   * LWMAC supports burst transmission based on the pending-bit technique, and this macro
   * here defines the largest number of packets allowed to be sent in one consecutive
   * sequence. In case a sender has multi packets for one receiver,the burst transmission
   * procedure is as follow:
   * 1. The sender first uses WR stream to locate the receiver's wake-up period (if the
   * sender has already phase-locked the receiver's phase, normally the sender only cost
   * one WR to get the first WA from the receiver) and then sends its first data.
   * 2. After the transmission of the first data, the sender immediately sends a WR to
   * the receiver for starting the second round of transmission of the second data. The
   * receiver should also immediately reply WA for continue receiving data packets. In
   * case the sender doesn't receive WA during @ref GNRC_LWMAC_TIME_BETWEEN_WR_US, it regards the
   * consecutive (burst) transmission failed and quits TX procedure (the data will be queued
   * back to the transmission queue for normal transmission attempt in following cycles).
   * 3. In case the second transmission succeeds, the sender repeats step (2) to send all the
   * following pending packets.
   * In short, in burst transmission mode, the sender doesn't tolerate no-WA event. ALl the
   * pending data packets should be sent with only one WR cost for leading the transmission.
   */
  #ifndef GNRC_LWMAC_MAX_TX_BURST_PKT_NUM
  #define GNRC_LWMAC_MAX_TX_BURST_PKT_NUM      (GNRC_LWMAC_WAKEUP_INTERVAL_US / GNRC_LWMAC_WAKEUP_DURATION_US)
  #endif
  
  /**
   * @brief MAX bad Listen period extensions a node can tolerate.
   *
   * In LWMAC, to allow burst transmissions, when in the wake-up period and by default, a node
   * will extend its wake-up period to another @ref GNRC_LWMAC_WAKEUP_DURATION_US after each packet
   * reception (except for broadcast packet). However, in some cases, a receiver may
   * overhear other unintended packets, e.g., WR or WA packets for other nodes, these are
   * called bad extensions for the receiver. If a receiver reaches the maximum bad listen
   * extension limit defined here, it goes to sleep mode with the consideration that the
   * channel is currently unavailable/busy.
   */
  #ifndef GNRC_LWMAC_MAX_RX_EXTENSION_NUM
  #define GNRC_LWMAC_MAX_RX_EXTENSION_NUM      (3U)
  #endif
  
  /**
   * @brief CSMA retries for broadcast packet.
   *
   * Currently, each broadcast packet is sent with CSMA/CA for collision avoidance.
   * Too many CSMA retries may lead to running out of destinations wake-up period.
   */
  #ifndef GNRC_LWMAC_BROADCAST_CSMA_RETRIES
  #define GNRC_LWMAC_BROADCAST_CSMA_RETRIES    (3U)
  #endif
  
  /**
   * @brief Default message queue size to use for the LWMAC thread.
   *
   * The value of this macro should be enough for supporting the manipulation of
   * LWMAC.
   *
   */
  #ifndef GNRC_LWMAC_IPC_MSG_QUEUE_SIZE
  #define GNRC_LWMAC_IPC_MSG_QUEUE_SIZE        (8U)
  #endif
  
  /**
   * @brief Initialize an instance of the LWMAC layer
   *
   * The initialization starts a new thread that connects to the given netdev
   * device and starts a link layer event loop.
   *
   * @param[in] stack         stack for the control thread
   * @param[in] stacksize     size of *stack*
   * @param[in] priority      priority for the thread housing the LWMAC instance
   * @param[in] name          name of the thread housing the LWMAC instance
   * @param[in] dev           netdev device, needs to be already initialized
   *
   * @return                  PID of LWMAC thread on success
   * @return                  -EINVAL if creation of thread fails
   * @return                  -ENODEV if *dev* is invalid
   */
  kernel_pid_t gnrc_lwmac_init(char *stack, int stacksize, char priority,
                               const char *name, gnrc_netdev_t *dev);
  
  #ifdef __cplusplus
  }
  #endif
  
  #endif /* NET_GNRC_LWMAC_LWMAC_H */
  /** @} */