-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LWMAC: A simple duty cycling 802.15.4 MAC protocol (2nd try). #6554
Conversation
ac772c2
to
8f13480
Compare
So if I understand correctly this example is with:
|
Yes, I haven't changed the defualt setting of the original Lw-MAC in PR-3730. And, the wake interval is set currently to 100ms. Of cause, this parameter can be adjusted according to users.
Generally correct. I would say, for a trial period of 210ms (this can be larger, for example, 1 second), repeating every 7ms a preamble on the sender side, until the receiver replies a preamble-ACK to tell the sender it is now in the reception period for receiving data.
The wake up period (listening phase) is set to twice the size of preamble invterval, to guarantee the reception of a preamble packet:
In this case, the listening phase will be 2*7ms = 14ms. |
In short, given a listening phase of 2*7ms = 14ms, the larger the |
Tested on samr21 could send/receive packets |
would be useful to display on the sender side the number of preambles sent + delay from the time where data is available to send, and the time where the packet is actually sent. |
would also be useful to have an example with UDP |
Will work on those suggestions soon. |
@zhuoshuguo just for clarification: is this PR based on the old code in #3730? If so, where are the original commit by @daniel-k, would be nice then to keep his commits to honor is work. |
further, we should close #3730. |
We (@daniel-k, @zhuoshuguo and I) changed a lot to RIOT's API to include it, so the make-up of it might now be a little different, so I could understand, why @zhuoshuguo decided to make all-new commits. @daniel-k's work is also honored by the |
+ I'm getting more and more the feeling that commit authorship is more about blaming, not honoring other people ^^" |
@smlng Good suggestion! Yes, this PR is based on the old codes in #3730. But, since the author of #3730 didn't have time to push it forward in #3730, so, as a simple solution for this situation, I took it over and built a new PR for continuing pushing it. Also, actually, I really don't know how to include the old commits in such a case, maybe there is a method for it in git but I am not aware of it. :-/ |
@miri64 Thanks for the clarification. :-) |
Hey guys! First of all thanks to @zhuoshuguo for taking over the "mess" I've left behind 🙂 I wish I would have (had) more time to push this forward myself, but unfortunately I don't. Concerning the attribution aspect, I'm okay with staying in |
Added UDP transmission example, which is based on |
Till now, have cleaned up the codes again and tackled all the remaining coding-style and comment-style issues I could find. Also, personally, I believe that the functionality of Lw-MAC is complete now. So, ping~ Any comments for Lw-MAC for pushing it towards getting merged (I think it is close now) ? :-) |
Through tests, found that, especially in multi-hop networks, Lw-MAC is still prone to link breakdown and packet drops, mainly due to WR (preamble) collisions among multi senders. Have thought of a way to fix it. Will update soon. |
How does your test case look like? To be honest, I didn't consider multi-hop too much if I remember correctly. Guess there's still potential for improvement :) |
I have tested Lw-MAC on a linear 5-hops (6 nodes) test-bed, and tried 5-hops transmissions, (e.g., from the left-end node to the right-end node.) And, different WRs from different senders will interrupt with each other and result in link breakdown for almost all senders (when there are more senders). The backoff scheme of WR doesn't work well. And, yes, there are indeed some room for improvement! :-) And I have already done some (will reflect on this PR soon). |
Yes, I imagine that this doesn't work well. I mainly considered a 1-hop network during design.
This sounds like a really sensible (and easy) optimization! 🙂 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check coding style and adapt as needed, specifically look for:
- placement of parentheses
- indention
check other comments, and address as you see fit - some are personal opinions so no need to adapt everything 😉
Otherwise nice work!
sys/include/net/gnrc/lwmac/lwmac.h
Outdated
* latency and throughput! | ||
*/ | ||
#ifndef LWMAC_WAKEUP_INTERVAL_US | ||
#define LWMAC_WAKEUP_INTERVAL_US (100U * 1000) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use conversion macros US_PER_MS
, here and below
sys/include/net/gnrc/lwmac/lwmac.h
Outdated
* @brief The Maximum WR duration time. | ||
*/ | ||
#ifndef LWMAC_PREAMBLE_DURATION_US | ||
#define LWMAC_PREAMBLE_DURATION_US ((12*LWMAC_WAKEUP_INTERVAL_US)/10) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I admit I'm not into any details on this, but why times 12 and divide by 10, here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To my knowledge, multiplying by 1.2
would result in an implicit cast to float
which should be avoided. Integer division is enough.
#define A 15
#define B ((A*12)/10)
#define C (1.2 * A)
printf("A = %i, B = %i, C = %i\n", A, B, C);
results in A = 15, B = 18, C = 2147483640
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, that's however fixable by explicitly casting back to int like so:
#define D ((int)(1.2 * A))
I just check with my host compiler and it is equivalent to B, so B == D
. This is even more readable I guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I didn't mean to suggest using * 1.2
here, I just wondered where this numbers to multiply and divide by come from. What's the rational to use these and not 42
and 13
? Empirical results, random choice by dice, or logic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Empirical results, random choice by dice, or logic?
A bit all of them and poorly (i.e. not) documented. The idea was to send preambles/WRs for a slightly longer period than LWMAC_WAKEUP_INTERVAL_US
in order to make sure that I will really be received by the destination. However, in retrospective I doubt this make much sense ... 😝
sys/include/net/gnrc/lwmac/lwmac.h
Outdated
* dispatched to the driver. | ||
*/ | ||
#ifndef LWMAC_WR_PREPARATION_US | ||
#define LWMAC_WR_PREPARATION_US (7000U + LWMAC_WR_BEFORE_PHASE_US) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
above you #define LWMAC_TIME_BETWEEN_WR_US (7000U)
, so should/could(?) this actually be:
#define LWMAC_WR_PREPARATION_US (LWMAC_TIME_BETWEEN_WR_US + LWMAC_WR_BEFORE_PHASE_US)
Two further comments,
- whats
WR
again? And, - you might think about consistent naming here, i.e.
LWMAC_WR_<something>_US
orLWMAC_<something>_WR_US
, currently its a bit mixed up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WR is actually preamble, but is called "Wakeup Request, WR" in Lw-MAC.
sys/include/net/gnrc/lwmac/lwmac.h
Outdated
* received at least one packet. | ||
*/ | ||
#ifndef LWMAC_BROADCAST_DURATION_US | ||
#define LWMAC_BROADCAST_DURATION_US ((LWMAC_WAKEUP_INTERVAL_US * 1100) / 1000) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again why 1100 and 1000? And can be reduced to *11
and / 10
.
sys/include/net/gnrc/lwmac/lwmac.h
Outdated
|
||
/** | ||
* @brief CSMA retries for BROADCAST packet, too many may lead to running out of | ||
* destinations wakup period. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/wakup/wakeup/
#define LOG_DEBUG(...) LOG(LOG_DEBUG, "[lwmac-rx] " __VA_ARGS__) | ||
|
||
/* Break out of switch and mark the need for rescheduling */ | ||
#define GOTO_RX_STATE(rx_state, do_resched) gnrc_netdev2->rx.state = rx_state; \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather have this inline, so I don't have to look it up every time to know whats happening
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what I see problematic here is, that it hides the break;
statement which makes a difference to have or not in loops and switches. If you really want to use this I'd rename this to SET_RX_STATE_AND_BREAK
to make it clear
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I acknowledge that hiding the break
is bad, especially for the case where you might accidentally use it inside a loop.
I'd rather have this inline, so I don't have to look it up every time to know whats happening
Well, this is actually why you abstract stuff away into functions (or defines for that matter), so you need not know whats happening behind the scenes. In this case I'd see this as an implementation detail of the state machine implementation, so I don't like SET_RX_STATE_AND_BREAK
too much.
Maybe we have a valid case for using a goto
here, like so:
#define GOTO_RX_STATE(rx_state, do_resched) \
gnrc_netdev2->rx.state = rx_state; \
if(do_resched) goto rx_state_machine_begin; \
else goto rx_state_machine_end
rx_state_machine_begin:
switch(rx.state)
{
// [...]
}
rx_state_machine_end:
What do you think? I don't like using goto
too much either, but I've seen such an implementation sometimes. Probably the labels and switch
statement should then also be wrapped inside macros.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mhm, I dislike goto
even more, so maybe leave as is for now. Maybe someone else has an opinion on this, too.
*/ | ||
|
||
/* Send WA */ | ||
int res = gnrc_netdev2->send(gnrc_netdev2, pkt); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
res
not used afterwards, rewrite to:
if (gnrc_netdev2->send(...) < 0) {
lwmac_packet_info_t info; | ||
int ret = _parse_packet(pkt, &info); | ||
|
||
if (ret != 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ret
only used for debugging, could be omitted.
|
||
/* Sender maybe didn't get the WA */ | ||
if (info.header->type == FRAMETYPE_WR) { | ||
LOG_INFO("Found a WR while waiting for DATA\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why LOG_INFO
not LOG_DEBUG
? or if problematic better use LOG_WARNING
{ | ||
if(gnrc_netdev2->lwmac.timeouts[i].type == TIMEOUT_DISABLED) | ||
{ | ||
gnrc_netdev2->lwmac.timeouts[i].type = type; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
coding style above and below, indention here
@smlng Thanks for the comments, and sorry for the mess! 😄 Will adapt soon! |
I don't see the point of having a complete (?) copy of |
That's a good point~ What do you think? @emmanuelsearch @miri64 @kaspar030 . I do agree that there is some functionality overlap between |
I'd rather do the opposite and remove the example. Because, I see the larger overlap between |
@zhuoshuguo @smlng I would rather remove the example, if any. Regarding integrating |
@miri64 you're right: no need to bloat Still I don't see the benefits of having a close copy of that example to show case lwmac - the test should do, and if currently does not: extend that, but remove the example. |
The origin goal for doing is to show that lwmac can support all the upper layers |
So, we remove |
Is this something special for lwMAC or something that all MAC protocols should be expected to deliver due to the proper abstraction ;-)? |
Em, for a MAC that is designed for specific purpose/usage (e.g., in WSN or IoT), it is not required to provide general support for upper layers. But, for (especially, duty-cycled) MAC protocols that aim to provide general support (the case of LWMAC), they should be able (expected) to deliver such capabilities. |
If having So, now, we only keep |
Ping?~ |
I will not block this, just because of the example - my objections are noted here, I think 😉 So please proceed as you see fit, we may cleanup up the examples/tests situation later on. |
Yap!~ Thanks for the suggestion. :-)~ I will do that with all the other following updates of LWMAC and So, we proceed? @miri64 @emmanuelsearch @kaspar030 @gebart ? :-) |
@smlng I would prefer if you hit the merge button ;-). |
Ping~ @smlng Let's go for merge? :-) |
OK, fingers crossed 🤞 😉 |
Congratulations!~ @daniel-k 😃 LWMAC finally gets merged. And, @smlng @miri64 @kaspar030 @gebart Thanks a lot for all your hard work and time on this!~ 😄 |
Congrats @zhuoshuguo and other people involved in this PR! |
Congrats @zhuoshuguo @daniel-k ! |
Thank you all guys, especially @zhuoshuguo! 🎆 I'm really glad it got merged now. Sorry again for all the hard work testing and fixing stuff that I couldn't do anymore. If one day we meet in person, beer's on me 🍻 |
Hello! |
Hi @benemorius, @zhuoshuguo and @miri64, |
@areejeliyan use the See mac.c. |
Hi @benemorius, I did and this is what I got. basically I can't see the duty cycle.. Another question: I am trying to build a protocol between 2 openmote-b that send and receive packet in lwmac.. is adding the USEMODULE += gnrc_lwmac module will guarantee that I am sending and receiving packets in lwmac. ) |
This is a second trial of LWMAC, which is an enhanced version of X-MAC (with phase-lock scheme), and is originally designed and implemented by @daniel-k .
In short, I have adapted and rebased the original LWMAC onto the
gnrc_mac
module.However, this LWMAC here in this PR still contains its (origin) own timeout module (it suppose to use
gnrc_mac
's timeout module which is based on evtimer ). As soon as theevtimer
will be merged, I will remove LWMAC's timeout module and usegnrc_mac
's timeout module instead.Notably, the current implementation of LWMAC uses RTT as the underlying timer source. So, currently, the protocol cannot run on nodes that don't have RTT. But, as a long-term plan, we will replace RTT by a general timer API (like evtimer) as the underlying timer to make LWMAC suitable for a larger scale of devices, when the related implementations are ready.
More tests and review are welcome. I will continue to update it according to your feedbacks. Let's get LWMAC merged this time. :-)
The basic scheme of LWMAC:
LWMAC adopts the radio duty-cycle scheme. Namely, in each cycle period (frame), a node device wakes up for a short period of time (called listen period or wake period) for receiving possible incoming packets from other devices. Outside the listen period, the node device turns off its radio to conserve power.
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 phase. This is also called phase-lock. After phase-locking, the sender node will (likely) spend less preamble packets (also called WR packets in LWMAC) for initiating a hand-shaking procedure for transmitting a data packet, compared to the first time it talks to the receiver. The phase-lock scheme is also shown in the above figure.
Besides, @daniel-k (just to let you know), I have also made some revisions to LWMAC:
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 embedded in the MAC header for instruction of this situation, and buffered packets will be transmitted in a continuous sequence, back to back, to the receiver in one shot. To this end, a sender can send more packets to the receiver in one cycle duration.
LWMAC adopts wakeup auto 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 wakeup timeout to extend its wakeup 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.
LWMAC adopts simple retransmission scheme to enhace link reliability. The origin LWMAC will drop the data packet if it didn't receive a reply (WA/preamble-ACK) from the receiver after one single full
LWMAC_PREAMBLE_DURATION_US
period. While in multi-senders scenarios or multi-hop scenarios in which several senders may try to transmit WRs at the same time and it is quite easy for senders to loose WA from the receiver due to interferences, leading to (frequent) packet drops. To this end, I simply added aretransmission counter
, that data packet will only be dropped in case theretransmission counter
gets larger thanLWMAC_DATA_TX_RETRIES
LWMAC adopts a 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 wakeup 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, while C sends to B), a link of either will be definitely interfered, leading to collisions and link throughput reductions. 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 backoff scheme to randomly reselect a new wakeup phase for itself.A typical transmission procedure you will oberve on sniffer:
1) first handshake and data transmission:
When a sender first sends data to a phase-unkown receiver, normally it spends longer preamble procedure for finding the receiver's wake-up phase. As shown in the above figure, the former four packets are all repeated preamble packets. The fifth packet is the preamble-ACK packet replied from the receiver. And then, comes the data packet and ACK.
After the first handshake, the sender will record the receiver's phase. So, the next time when the sender wants to send data packet to the same receiver, it wakes up just a little bit in advance to the receiver's listen period and then starts the preamble. It is expected that, after phase-locking, the preamble of the sender will be much quicker replied by the preamble-ACK of the receiver. As shown in the below figure.
2) second handshake and data transmission (the same for the following ones, before phase-lock failure due to timer drift):
This time, after phase-locking, the first preamble is quickly replied by the preamble-ACK of the receiver. In this manner, power consumption on the sender side will be redueced.
In case of phase-lock failure due to timer drift (let's say the first preamble didn't get immediately replied by the preamble-ACK), the sender simply continue its preamble procedure until it gets the preamble-ACK again, like the first time it talks to the receiver. And then, the phase of the receiver gets updated again on the sender.
Print out the achieved duty-cyle of LWMAC:
You can print out the achieved radio duty-cyle (currently a roughly one) of LWMAC by setting the
LWMAC_ENABLE_DUTYCYLE_RECORD
flag insys/include/net/gnrc/lwmac/types.h
to "1".By doing so, each time when a device sends or receives a packet, it will print out its achieved duty-cycle (start from power-up or reboot).
Also, by further enabling the debug flag in
sys/net/gnrc/link_layer/lwmac/tx_state_machine.c
you will get the printout of how many preamble (WR) and time (sending delay) cost for sending this packet in the TX procedure of LWMAC.For instance:
sender side:
receiver side:
The above figure shows the radio duty-cycle of LWMAC (in idle listening state), as a function of the wake-up frequency (or, can be also called channel check rate), measured on the samr21 board.
It can be expected that the radio duty-cycle of LwMAC is proportional to the wake-up frequency, as it has a linear relation with the wake-up frequency.
How to test:
Currently, it seems that you can only use the
samr21-xpro
board to test this MAC, since some certain features of the protocol are only available on that platform (see LWMAC).But, I don't know this (i.e., you can only use the
samr21-xpro
) still holds or not. Due to more drivers available now, maybe it also works on other boards as well. So, you are welcome to give it a try on other boards!!Test by using the
default
example:I have simply copied the
default
example fromRIOT/examples
to build a text example inRIOT/tests/lw_mac
for testing this duty-cycle protocol.Manually send packet from one board to the other via interactive shell:
you can also broadcast a packet by typing:
Try UDP transmissions with LWMAC:
For trying UDP transmissions by using LWMAC as your MAC layer, you can switch to
RIOT/examples/gnrc_networking/
example (in this branch), and flash your boards:Then, as instructed in
gnrc_networking/README
file, you can first start a UDP server on your node-A:use
ifconfig
command to get node-A's IP address:On your node-B, try to send message to node-A using UDP:
Some evaluation results:
Here are some evaluation results (on SAMR21 test-bed) to share, which are from a simple, star-topology, one receiver and multi-senders experimental scenario.
Handle contention
This simple test evaluates the impacet of sender number on LWMAC's performance, in terms of packet delay, packet reception ratio, sender duty-cycle and receiver duty-cycle.
Test settings:
Each sender adopts a data rate of 2 packets per second through the test, and each data packet contains a raw payload of 80 bytes.
the cycle duration ofLWMAC in this evalution experiment is enlarged to 500ms.
Each test scenario lasts for 300 seconds.
All the other parameters of LWMAC are the same as in this branch
Note that, by setting the data-rate the same as the channel-check-rate, i.e., both to 2Hz, this means that, averagely, all the sender will attend the competition for transmissions in each cycle of the receiver. This critical data rate setting (i.e., equals the channel-check-rate,) intends to evaluate LWMAC's reliability on handling transmission competitions/collisions and maintaining link quality.
![lwmac](https://cloud.githubusercontent.com/assets/9894607/24085522/237d9b98-0cfe-11e7-83ae-256761f7f939.png)
Stability evaluation 1
This test intends to evaluate the stability of LWMAC for running over a long time.
Setting: one receiver, three senders all sending to the same receiver.
Cycle duration of LWMAC: 100ms;
Data rate: 1 packet / 1 second per node;
Test duration: larger than 48 hours.
Results:
Packet reception ratio: 528988 /528990 = ( > 99.99%), only two packets lost out of 528988.
PS: during one shot of long time test, one node experienced a
FAILED ASSERTION
halted:arm-none-eabi-addr2line
infers thisFAILED ASSERTION
halted to at86rf2xx_netdev.c:558, that may have something to do with issue 5486.Stability evaluation 2
Settings:
![2094878 1300000001](https://cloud.githubusercontent.com/assets/9894607/26027830/7992e230-3815-11e7-99fd-3611441e9784.png)
Topology: see below, a multi-hop test-bed of SAMR21-xpro with at most 3 hops transmission. All the nodes were deployed in my office room environment (all nodes are in each other's radio/interference range).
Application: based on the default application in RIOT/examples/default
Cycle duration of LWMAC for all nodes: 100ms;
data rate: 1 packet / 10 seconds per node.
Maximum link layer packet retransmission: 3 times.
Experiment duration: 50 hours (> two days)
results:
None packet drop. Packet deliver ratio: 90341/90341 = 100%.
Stability evaluation 3
Run a third time experiment for evaluating LWMAC's stability:
![image](https://cloud.githubusercontent.com/assets/9894607/26502429/1d2e80d0-423d-11e7-9105-20d7d21167db.png)
settings:
This experiment is based on the
examples/gnrc_networking
which includes UDP and RPL.There are one sink and 5 senders.
The sink initiates the RPL network and sets itself as the root. All the senders send packets to sink using UDP.
In the experiment, there are simultaneously two types of traffics:
1, upward traffic generated by son noders (senders) heading to the sink,
2, downward traffic generated by the sink heading to all senders.
For upward traffic, all senders use UDP to send packets to the link local address of the sink (bypass RPL, since I found that configured IPv6 address for RPL will expire (time out and disappear) on the son nodes (senders) after a certain period of time);
For downward traffic, the sink uses UDP to send packets to the configured ipv6 addresses of all the senders which are informed to the sink through RPL networking, i.e., downward traffic is based on RPL routing.
Other key MAC settings:
Cycle duration of LWMAC for all nodes: 100ms;
Maximum link layer packet retransmission: 3 times.
Data rate:
The experiment lasted about 48 hours (two days).
Results:
For upward traffic: 443461 (received) / 443481 (generated) = 99.9955%
For downward traffic : 35435 (received) / 35443 (generated) = 99.977%
Stability evaluation 4
Finished a 4th long-time experiment (the final one) for evaluating LWMAC's stability:
![image](https://cloud.githubusercontent.com/assets/9894607/26718338/f726122e-4780-11e7-94e4-7bbe94211ac1.png)
Settings:
Topology: one sink (receiver) and 5 senders:
This experiment is based on
examples/default
5 senders adopt an intensive data rate for continuing generating data packets and sending to the sink;
Data rate for each sender: 5packets/1second;
MAC cycle duration for all nodes: 100ms;
MAC Tx-Queue size for each node: 10 packets;
Experiment duration: 61 hours;
Notably, the taffic of the network (taffic loads from all the senders) is beyong the offered throughput of LWMAC. And by applying such an overwhelming taffic, the goal of this experiment is to check that:
Results: