IEEE802.15.4 over LoRa

Yes, you will get 6LowPAN there because the network interface is declared as 6LowPAN compatible (IEEE 802.15.4).

Thanks, @jia200x
I’ll configure timeout and give you a feedback.

If I use 6LowPAN already, how should I understand it? :slight_smile: gnrc_networking and gnrc_border_router works as in examples in readme’s. As I know, 6LowPAN can compress header which makes a packet less, can communicate by short addresses. All is not clear for me.

I’m sorry if I trouble you.

Hi @HoCoK

If you enable debug on sys/net/gnrc/network_layer/sixlowpan/gnrc_sixlowpan.c, you should be able to see 6LowPAN debug messages. That indicates that 6LowPAN is running. 6LowPAN defines header compression and packet fragmentation, so it allows transmitting full IPv6 frames with low MTU link-layers (e.g IEEE 802.15.4). In GNRC this is transparent to the upper layer (IPv6, UDP, CoAP), therefore you don’t need to configure anything actively (of course there are tweaks you can do, but they are not required to run 6LowPAN out of the box).

Communication using short addresses it’s not related to 6LowPAN, as this is a IEEE 802.15.4 feature. I’m not sure though, if the GNRC network interface maps 6LowPAN frames to the short address. That could be addressed if it’s not the case.

You can try to ping with a packet size larger than the IEEE 802.15.4 MTU (104 bytes payload). E.g try this:

ping <IP address> -i 10000 -s 300

That would confirm 6LowPAN is running.

Cheers.

Ok, @jia200x

I think I got it.

Ping
[17:38:13:597] > ping fe80::a4de:1264:dac5:a42b -i 10000 -s 300␍␊

[17:38:47:192] 308 bytes from fe80::a4de:1264:dac5:a42b%7: icmp_seq=0 ttl=64 rssi=60 dBm time=6380.098 ms␊

[17:38:57:177] 308 bytes from fe80::a4de:1264:dac5:a42b%7: icmp_seq=1 ttl=64 rssi=60 dBm time=6364.780 ms␊

[17:39:07:188] 308 bytes from fe80::a4de:1264:dac5:a42b%7: icmp_seq=2 ttl=64 rssi=60 dBm time=6371.498 ms␊

[17:39:07:188] ␊

[17:39:07:188] --- fe80::a4de:1264:dac5:a42b PING statistics ---␊

[17:39:07:210] 3 packets transmitted, 3 packets received, 0% packet loss␊

[17:39:07:210] round-trip min/avg/max = 6364.780/6372.125/6380.098 ms␊

Thank you for your support! When I get some extra boards, I’ll try to create a cluster-tree network.

Hi, @jia200x

While I’m waiting extra boards, I found some issues with CSMA-CA and frame retransmissions in my implementation:

  1. ACK_TIMEOUT doesn’t changes a quality of transmission. Packets are duplicate about 4 times, “ping” has a huge latency. Only -ack_req helps.

  2. CSMA-CA doesn’t work. As I think, CSMA-CA should call a CCA before transmission. If CCA says that link is clear, module waits a bit and transmission begins. But I have not seen, where submac runs a CCA function (ieee802154_radio_cca), except ieee802154_hal test.

gnrc_netif_ieee802154.c
...
#ifdef MODULE_GNRC_MAC
    if (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_CSMA_ENABLED) {
        res = csma_sender_csma_ca_send(dev, &iolist_header, &netif->mac.csma_conf);
    }

This function is never reached from submac…

I will be glad to see your suggestions.

Hi @HoCoK

ACK_TIMEOUT doesn’t changes a quality of transmission. Packets are duplicate about 4 times, “ping” has a huge latency. Only -ack_req helps.

This occurs when the MAC does not receive an ACK frame. In such case, the SubMAC will perform retransmission. By default, the SubMAC will try to send up to 4 times if it doesn’t receive ACKs. That’s why you see 4 packets.

Did you implement the ACK reply in the driver? The Radio HAL documentation states:

The transceiver or driver MUST handle the ACK reply if the Ack Request bit is set in the received frame and promiscuous mode is disabled.

This means, the driver has to reply with an ACK frame if the ACK Request bit is set. See e.g RIOT/cpu/nrf52/radio/nrf802154/nrf802154_radio.c at master · RIOT-OS/RIOT · GitHub to see how this is implemented in the NRF52840.

  1. It is a bit misleading, but MODULE_GNRC_MAC has nothing to do with the SubMAC. This is just a 6 years old module the enable other MAC protocols in GNRC (namely lwmac and gomach). When you use the SubMAC with GNRC Netif, the dependency tree looks like:
gnrc_netif_ieee802154 => netdev_ieee802154_submac =>ieee802154_submac => ieee802154_hal_t

In words, GNRC Netif only “speaks” netdev (which will eventually change after the migration phase). Therefore, we developed a netdev_ieee802154_submac module that implements the netdev interface on top of the SubMAC.

Regarding CCA, the current SubMAC implementation assumes the radio always performs CCA if CSMA/CA retries are not disabled:

/**

  • @brief Set the CSMA-CA parameters.
  • @pre the device is on
  • @param[in] dev IEEE802.15.4 device descriptor
  • @param[in] bd parameters of the exponential backoff. If NULL, the
  •           parameters are not altered.
    
  • @param[in] retries number of CSMA-CA retries. If @p retries < 0,
  •                retransmissions with CSMA-CA MUST be disabled.
    
  •                If @p retries == 0, the @ref
    
  •                ieee802154_radio_request_transmit function is
    
  •                equivalent to CCA send.
    
  • @return 0 on success
  • @return -EINVAL if the settings are not supported.
  • @return negative errno on error */ int (*set_csma_params)(ieee802154_dev_t *dev, const ieee802154_csma_be_t *bd, int8_t retries);

Therefore, you have to implement it in the driver. You can check the NRF52840 implementation too. Note that there’s no real way to do CCA in LoRa as RSSI cannot detect frames below the noise floor. But you could use CAD to try to detect a frame.

Hello @jia200x

I continue to make an implementation radio hal for lora and again met with some issues.

Now I try to implement ACK reply. I run ieee802154_hal test and what I receive:

Transmiter
[16:22:32:810] main(): This is RIOT! (Version: 28a8b)␊
[16:22:32:810] Trying to register sx126x.␊
[16:22:32:810] Success␊
[16:22:32:827] Initialization successful - starting the shell now␊
[16:22:32:827] > txtsnd DE:EE:68:50:08:4E:84:05 10 ackreq␍␊
[16:22:40:742] Transmission succeeded␊
[16:22:40:742] ␊
[16:22:40:742] ␊
[16:22:40:742] > Size = 3␊
[16:22:40:752] Received valid ACK with sqn 0␊
[16:22:40:763] 00000000  02  00  00                                                      ...␊
[16:22:40:763] LQI: 255, RSSI: 208␊
[16:22:40:763] ␊
[16:22:42:957] txtsnd DE:EE:68:50:08:4E:84:05 10 ackreq␍␊
[16:22:42:979] Transmission succeeded␊
[16:22:42:979] ␊
[16:22:42:979] ␊
[16:22:42:979] > Size = 3␊
[16:22:42:989] Received valid ACK with sqn 1␊
[16:22:43:020] 00000000  02  00  01                                                      ...␊
[16:22:43:020] LQI: 255, RSSI: 208␊
[16:22:43:020] ␊
[16:25:19:684] test_states␍␊
[16:25:19:694] Testing TX<->RX transition time: 153 us (PASS)␊
[16:25:19:694] Testing RX<->TX transition time81 us (PASS)␊
[16:25:19:694] >
Receiver
[16:22:30:697] main(): This is RIOT! (Version: 28a8b)␊
[16:22:30:697] Trying to register sx126x.␊
[16:22:30:697] Success␊
[16:22:30:713] Initialization successful - starting the shell now␊
[16:22:30:713] > Size = 31␊
[16:22:40:751] Frame received:␊
[16:22:40:759] 00000000  61  DC  00  23  00  05  84  4E  08  50  68  EE  DE  2B  B4  C5  a..#...N.Ph..+..␊
[16:22:40:768] 00000010  DA  64  12  DE  A6  4C  6F  72  65  6D  20  69  70  73  75      .d...Lorem ipsu␊
[16:22:40:768] LQI: 255, RSSI: 208␊
[16:22:40:768] ␊
[16:22:42:987] Size = 31␊
[16:22:42:987] Frame received:␊
[16:22:42:995] 00000000  61  DC  01  23  00  05  84  4E  08  50  68  EE  DE  2B  B4  C5  a..#...N.Ph..+..␊
[16:22:43:005] 00000010  DA  64  12  DE  A6  4C  6F  72  65  6D  20  69  70  73  75      .d...Lorem ipsu␊
[16:22:43:005] LQI: 255, RSSI: 208␊
[16:22:43:005] ␊

As I understand it, all works fine. I transmit a frame with ack_req bit and I get back an ack frame.

But I cannot see an ack_frame in ieee802154_submac test. The rx_done handler doesn’t fire after ack reception:

submac transmiter
[16:51:09:120] > txtsnd DE:EE:68:50:08:4E:84:05 80␍␊

[16:51:11:362] [sx126x] netdev: set STATE_STANDBY␊

[16:51:11:362] [sx126x] netdev: send: wrote data to payload buffer.␊

[16:51:11:372] [sx126x] netdev: send: wrote data to payload buffer.␊

[16:51:11:372] [sx126x] writing (size: 101).␊

[16:51:11:372] > [sx126x] netdev: set STATE_TX␊

[16:51:11:428] [sx126x] netdev: SX126X_IRQ_TX_DONE␊

[16:51:11:428] [sx126x] netdev: set STATE_STANDBY␊

[16:51:11:428] [sx126x] netdev: set STATE_RX␊

[16:51:11:428] [sx126x] netdev: SX126X_IRQ_NONE␊

[16:51:11:432] [sx126x] netdev: SX126X_IRQ_PREAMBLE_DETECTED␊

[16:51:11:436] [sx126x] netdev: SX126X_IRQ_HEADER_VALID␊

[16:51:11:439] [sx126x] netdev: SX126X_IRQ_RX_DONE␊

[16:51:11:443] [sx126x] Received ACK.␊

[16:51:11:443] [sx126x] netdev: set STATE_STANDBY␊

[16:51:11:448] [sx126x] netdev: read received data.␊

[16:51:11:451] [sx126x] netdev: SX126X_IRQ_NONE␊

[16:51:11:456] [sx126x] netdev: set STATE_TX␊

[16:51:11:509] [sx126x] netdev: SX126X_IRQ_TX_DONE␊

[16:51:11:509] [sx126x] netdev: set STATE_STANDBY␊

[16:51:11:509] [sx126x] netdev: set STATE_RX␊

[16:51:11:514] [sx126x] netdev: SX126X_IRQ_NONE␊

[16:51:11:528] [sx126x] netdev: set STATE_STANDBY␊

[16:51:11:530] [sx126x] netdev: set STATE_TX␊

[16:51:11:581] [sx126x] netdev: SX126X_IRQ_TX_DONE␊

[16:51:11:581] [sx126x] netdev: set STATE_STANDBY␊

[16:51:11:581] [sx126x] netdev: set STATE_RX␊

[16:51:11:586] [sx126x] netdev: SX126X_IRQ_NONE␊

[16:51:11:598] [sx126x] netdev: set STATE_STANDBY␊

[16:51:11:602] [sx126x] netdev: set STATE_TX␊

[16:51:11:655] [sx126x] netdev: SX126X_IRQ_TX_DONE␊

[16:51:11:655] [sx126x] netdev: set STATE_STANDBY␊

[16:51:11:655] [sx126x] netdev: set STATE_RX␊

[16:51:11:658] [sx126x] netdev: SX126X_IRQ_NONE␊

[16:51:11:672] [sx126x] netdev: set STATE_STANDBY␊

[16:51:11:680] [sx126x] netdev: set STATE_TX␊

[16:51:11:733] [sx126x] netdev: SX126X_IRQ_TX_DONE␊

[16:51:11:733] [sx126x] netdev: set STATE_STANDBY␊

[16:51:11:733] [sx126x] netdev: set STATE_RX␊

[16:51:11:736] [sx126x] netdev: SX126X_IRQ_NONE␊

[16:51:11:749] [sx126x] netdev: set STATE_STANDBY␊

[16:51:11:753] No ACK␊
submac receiver
[16:50:59:925] > [sx126x] netdev: SX126X_IRQ_PREAMBLE_DETECTED␊
[16:51:11:381] [sx126x] netdev: SX126X_IRQ_NONE␊
[16:51:11:385] [sx126x] netdev: SX126X_IRQ_HEADER_VALID␊
[16:51:11:389] [sx126x] netdev: SX126X_IRQ_NONE␊
[16:51:11:418] [sx126x] netdev: SX126X_IRQ_RX_DONE␊
[16:51:11:424] [sx[sx126x] netdev: set STATE_STANDBY␊
[16:51:11:429] [sx126x] netdev: set STATE_TX␊
[16:51:11:429] 126x] netdev: set STATE_TX␊
[16:51:11:429] NDB[sx126x] netdev: SX126X_IRQ_TX_DONE␊
[16:51:11:441] [nrf52840] TX ACK done.[sx126x] netdev: set STATE_STANDBY␊
[16:51:11:445] ␊
[16:51:11:445] [sx126x] netdev: read received data.␊
[16:51:11:445] DATA␊
[16:51:11:450] Dest. PAN: 0x0023, Dest. addr.: de:ee:68:50:08:4e:84:05␊
[16:51:11:455] Src. PAN: 0x0023, Src. addr.: a6:de:12:64:da:c5:b4:2b␊
[16:51:11:455] Security: 0, Frame pend.: 0, ACK req.: 1, PAN comp.: 1␊
[16:51:11:461] Version: 1, Seq.: 0␊
[16:51:11:468] 00000000  4C  6F  72  65  6D  20  69  70  73  75  6D  20  64  6F  6C  6F␊
[16:51:11:475] 00000010  72  20  73  69  74  20  61  6D  65  74  2C  20  63  6F  6E  73␊
[16:51:11:481] 00000020  65  63  74  65  74  75  72  20  61  64  69  70  69  73  63  69␊
[16:51:11:488] 00000030  6E  67  20  65  6C  69  74  2E  20  45  74  69  61  6D  20  6F␊
[16:51:11:494] 00000040  72  6E  61  72  65  6C  61  63  69  6E  69  61  20  6D  69  20␊
[16:51:11:505] txt (80 chars): Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam ornarelacini␊
[16:51:11:505]      a mi ␊
[16:51:11:505] RSSI: 205, LQI: 255␊
[16:51:11:505] ␊
[16:51:11:510] [sx126x] netdev: SX126X_IRQ_NONE␊
[16:51:11:510] [sx126x] netdev: set STATE_RX␊
[16:51:11:534] [sx126x] netdev: SX126X_IRQ_PREAMBLE_DETECTED␊
[16:51:11:536] [sx126x] netdev: SX126X_IRQ_NONE␊
[16:51:11:540] [sx126x] netdev: SX126X_IRQ_HEADER_VALID␊
[16:51:11:543] [sx126x] netdev: SX126X_IRQ_NONE␊
[16:51:11:576] [sx126x] netdev: SX126X_IRQ_RX_DONE␊
[16:51:11:583] [sx126x] Addr filter failed or ACK filter on.␊
[16:51:11:583] [sx126x] netdev: set STATE_RX␊
[16:51:11:589] [sx126x] netdev: set STATE_STANDBY␊
[16:51:11:594] [sx126x] netdev: read received data.␊
[16:51:11:594] [sx126x] netdev: set STATE_RX␊
[16:51:11:600] [sx126x] netdev: SX126X_IRQ_NONE␊
[16:51:11:608] [sx126x] netdev: SX126X_IRQ_PREAMBLE_DETECTED␊
[16:51:11:612] [sx126x] netdev: SX126X_IRQ_NONE␊
[16:51:11:616] [sx126x] netdev: SX126X_IRQ_HEADER_VALID␊
[16:51:11:619] [sx126x] netdev: SX126X_IRQ_NONE␊
[16:51:11:650] [sx126x] netdev: SX126X_IRQ_RX_DONE␊
[16:51:11:657] [sx126x] Addr filter failed or ACK filter on.␊
[16:51:11:657] [sx126x] netdev: set STATE_RX␊
[16:51:11:660] [sx126x] netdev: set STATE_STANDBY␊
[16:51:11:666] [sx126x] netdev: read received data.␊
[16:51:11:666] [sx126x] netdev: set STATE_RX␊
[16:51:11:669] [sx126x] netdev: SX126X_IRQ_NONE␊
[16:51:11:685] [sx126x] netdev: SX126X_IRQ_PREAMBLE_DETECTED␊
[16:51:11:688] [sx126x] netdev: SX126X_IRQ_NONE␊
[16:51:11:692] [sx126x] netdev: SX126X_IRQ_HEADER_VALID␊
[16:51:11:695] [sx126x] netdev: SX126X_IRQ_NONE␊
[16:51:11:727] [sx126x] netdev: SX126X_IRQ_RX_DONE␊
[16:51:11:734] [sx126x] Addr filter failed or ACK filter on.␊
[16:51:11:734] [sx126x] netdev: set STATE_RX␊
[16:51:11:738] [sx126x] netdev: set STATE_STANDBY␊
[16:51:11:743] [sx126x] netdev: read received data.␊
[16:51:11:743] [sx126x] netdev: set STATE_RX␊

sx126x_radio_hal.c

ACK_TIMEOUT_US in submac.c sets in 13824 (SF7, BW500)

Hi @HoCoK

I’m interested in this. Do you think you could create a draft PR? Then I could test, with the lora-e5 board, and maybe help.

Thanks, David

Hi, @jdavid

I’ve created a draft pull request: github

If you’ll run it successfully, let me know, please :slight_smile:

1 Like

This is very interesting!

With PR #19172, I’ve successfully run the ieee802154_hal test using a LoRa-E5 Dev Board and a LoRa-E5 mini. However, I found that CAD was not working correctly when performing a stress test by letting both devices send 10 packets, starting roughly simultaneously. As you can see on the left, packets are colliding: IEEE802154_hal_LoRa

Then I found that the device is actually not waiting for SX126X_IRQ_CAD_DONE, but immediately goes to the transmit state. After I made some changes in the state machine, I get either “Medium busy”, or they start to transmit at exactly the same time (see the picture above on the right). I believe the latter is expected, because there is no CSMA/CA yet.

@HoCoK I see the PR is still in a draft version. Are you still working on this?

Hello @GUVWAF

Thanks for your message! I’m completely forgot about this PR because I had changed a job. But if it is interesting for someone, i’ll try to complete this.

That would be nice, but don’t feel obligated :slight_smile:

I just opened a PR to your Fork with the changes I applied.

1 Like