This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Directly modify Link Layer packet

Hello, 

I am very new to BLE and NRF and trying to understand what the best way would be to send data from one device to another

From the documentation and messing around with ble_app_blinky on my nrf52833 DK as I understand it there is a Link Layer that is responsible for advertising and establishing connection. Once the connection is established the one device sends 27-byte data payload packet and gets a response from the other at an established interval. 

With the nrf sdk how to I directly modify the 27 byte payload?

All the examples in the SDK seem to set up a GATT as a data model but I would like to simply access the 27 byte payload on one nrf52833 DK, put my own 27 bytes into it and receive it on another nrf52833 DK. As I understand this would allow for the highest throughput and eliminate any overhead from the higher layers.

Parents
  • You can find various throughput numbers here depending on configuration:
    https://infocenter.nordicsemi.com/topic/sds_s140/SDS/s1xx/ble_data_throughput/ble_data_throughput.html 

    As you can see you may get slightly higher throughput (e.g. 771.1 kbps -> 803 kbps). However, whether it is worth the additional development time to get it right (firmware and application), and the drawback of likely not being compatible with many phone vendors I will let be up for discussion.

    If you need multiple links please check out:
    https://infocenter.nordicsemi.com/topic/sds_s140/SDS/s1xx/multilink_scheduling/suggested_intervals_windows_s132.html 

    Best regards,
    Kenneth

  • Hi Kenneth, thanks a lot, I think I am getting closer to understanding the possible throughput for my case and BLE in general.

    Looking at the throughput tables I think I can correctly calculate theoretical maximum for some of the table. Here is my thinking:

    Connection interval is time between two data transfer events, event length is how long the data transfer event is. Minimal event length is 2.5ms during which 2 Link Layer packets get transferred. 

    This lines up with the throughput numbers you provided for some rows of the table, for example with a connection interval of 7.5ms

    Protocol ATT MTU size Event length Method Maximum data throughput (LE 1M PHY) Maximum data throughput (LE 2M PHY)
    GATT SERVER 23 2.5ms Send Notification 42.6kbps

    To calculate the 42.6kbps we have 1000/7.5 =133.333 connections per second. Each connection has one event of 2.5ms. During each event 2 Link Layer packets are transferred. Each packet has 23-3 bytes payload. 

    So we will have 1000/7.5*2 packets transfered, since each packet has (23-3) bytes of payload we can calculate the throughput in bps as 1000/7.5*2*(23-3)*8 = 42.6kbps. 

    However I must be missing something since this does not work for other rows of the table when we have event length larger than 2.5ms. For example: 

    GATT Client 23 7.5 ms Receive Notification 192.0 kbps 256.0 kbps

    I was thinking now since event length is 7.5 instead of 2.5 we will send 3 times as many Link Layer packets however

    1000/7.5*2*(23-3)*8*3 = 128.0kbps and not 192.

    Also as I understand BLE is 1MBPS using LE 1M PHY, at 1MBPS each bit takes a microsecond. so 2500 bits can be send in a 2.5ms interval. For ATT MTU size of 158 as in the table does this mean only 1 Link Layer packet is sent every 2.5ms since the number of bits in two packets 158*2*8 is just a little larger than 2500? How is the row with 158 ATT_MTU computed?

    GATT Server 158 7.5 ms Send Notification 248.0 kbps 330.6 kbps

    Following last table it seems that for 12 devices at a connection interval of 40ms, event length of 2.5, and ATT_MTU 158 assuming only 1 Link Layer packet gets sent per event I can get a theoretical throughput of 1000/40*(158-3) = 3875 bytes per second. Since the events would not overlap.

  • Hi,

    The event length specify the maximum time width of the "timeslot" the active link will allow to exchange data during an BLE event, the actual timing and number of packet that can fit into the "timeslot" follow the BLE spec and also depend on the length of packets, type of transfer and direction of packets. In specific the LL payload size have a dramatic impact on the throughput, since a 155byte ATT MTU payload will be split into multiple LL packets over the air if using the default size of 27bytes, actually 6 LL packets will be required to send 155bytes, at the same time the 7.5ms event length allow for 9 LL packets, so will be able to send 1.5 ATT MTU in each window:

    155 / 0.0075 * 1.5 * 8 = 248 kbps.

    Best regards,
    Kenneth

  • Thank Kenneth, I was confusing data length with ATT MTU. 

    I will get a second 52840DK and go ahead try to test the throughput under different settings. As I am understanding so far to reduce overhead I can avoid GATT all together and establish an L2CAP channel for each device. Looking at the l2cap channel setup message sequence once a connection is established I can initiate a channel from one device to another. Then the packets sent and their length in octets will be as follows:

    [Preamble 1][Access Address 4][Link Layer header 2][L2CAP header 4][DATA(Data Length - 4)][MIC 4][CRC 3]

    Where I can put anything into DATA i want using sd_ble_l2cap_tx()

    Looking at BLE spec the raw radio is 1MBPS but there is a mandatory 150us delay between packets (Antenna cooling to avoid frequency shift?). Each packet is acknowledged with 80bits. 

    So for a 27 Data Length we have a total of 41bytes or 328bits. The timing will be as follows.

    Side A sends 328bits = 328us -> Wait 150us -> Side B Acknowledges 80bits (empty packet) = 80us -> Wait 150us. Total time to send 1 packet of 27 Data Length  = (328+150+80+150)us or 0.708ms. Thus with event length of 7.5ms we can ideally send 10.59 packets. This is close to the 9LL packets you mention. 

    So if I set Data Length to maximum of 251bytes the packet would be 265bytes or 2120bits long. The timing would work as: Side A sends 2120bits = 2120us -> Wait 150us -> Side B Acknowledges 80bits (empty packet) = 80us -> Wait 150us. Which means I can have an event length of (2120+150+80+150)us or 2.5ms. Is this why event length is multiples of 2.5ms?

    With this set up I would be sending 247 DATA bytes that I can fill up using sd_ble_l2cap_tx()  in 2.5ms. So for say 12 devices I can set the event length to 2.5ms and connection interval to 50ms meaning each device will send 247 bytes of data 20 times a second leading to an ideal throughput of 4.9Kbytes. Switching to LE 2 PHY (as I understand it this is just 2 bits instead of 1 GFSK) I can get up to 9.6Kbytes.

    Excited to try this, hopefully I can get my hands on another 52840DK soon.

     

         

  • Your calculation is not taking into account pre- and post processing is part of the BLE event. Also, I don't think you can rely on peer is always sending empty packets. The minimum 2.5ms is choisen because in BLE everything is in 1.25ms resolution (e.g. connection interval = n * 1.25ms), and when taking into account the pre- and post processing it just isn't enough time to also include any radio activity if the BLE event is shorter than 2.5ms period. Realistically if you need to support long packets, I expect you will need to set BLE event to 3.75ms, but that should still work with 12 device, since 3.75ms * 12 < 50ms.

    Best regards,
    Kenneth

  • Thank Kenneth, 

    I am getting a little bit closer to the setup mentioned above. I think now I am having trouble understanding the SDK. I have a 52833DK trying to set up an L2CAP channel with 52840 Dongle which is running the peripheral blinky app. I am simply using the blinky app since I can try to set up an L2CAP channel after connection is established. I also have a 52840DK acting as a sniffer.

    My code works as follows, the 52833 scans for device named "BLINKY" and connects to it. This part works.

    When BLE_GAP_EVT_CONNECTED is triggered on the 52833 I call sd_ble_l2cap_ch_setup with same params as the OTS example. At this point I can see in wireshark that everything is as I expect. 

    No.	Time	Source	PHY	Protocol	Length	Delta time (µs end to start)	SN	NESN	More Data	Event counter	Info
    834	20.674	c4:03:29:65:50:fe	LE 1M	LE LL	21	498				0	ADV_IND
    835	20.675	c4:03:29:65:50:fe	LE 1M	LE LL	21	1050				0	ADV_IND
    836	21.677	c4:03:29:65:50:fe	LE 1M	LE LL	21	1000658				0	ADV_IND
    837	21.678	f7:51:61:6c:70:ca	LE 1M	LE LL	34	151				0	CONNECT_REQ
    838	21.679	Master_0xb2a7e1bf	LE 1M	L2CAP	18	1253	0	0	False	0	LE Credit Based Connection Request (CID: 0040, Initial Credits: 0)
    839	21.679	Slave_0xb2a7e1bf	LE 1M	LE LL	0	150	0	1	False	0	Empty PDU
    840	21.707	Master_0xb2a7e1bf	LE 1M	LE LL	0	29545	1	1	False	1	Empty PDU
    841	21.708	Slave_0xb2a7e1bf	LE 1M	L2CAP	18	151	1	0	False	1	LE Credit Based Connection Response (CID: 0000, Initial Credits: 0)
    842	21.737	Master_0xb2a7e1bf	LE 1M	LE LL	0	29546	0	0	False	2	Empty PDU
    843	21.738	Slave_0xb2a7e1bf	LE 1M	LE LL	0	150	0	1	False	2	Empty PDU
    844	21.767	Master_0xb2a7e1bf	LE 1M	LE LL	0	29692	1	1	False	3	Empty PDU
    845	21.768	Slave_0xb2a7e1bf	LE 1M	LE LL	0	150	1	0	False	3	Empty PDU
    

    Since the 52840 Dongle is not set up for L2CAP it refuses the connection. In wireshark I can see LE Result: Connection Refused - No Resources Available (0x0004)

    Frame 841: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface wireshark_extcap2808, id 0
    Nordic BLE Sniffer
    Bluetooth Low Energy Link Layer
    Bluetooth L2CAP Protocol
        Length: 14
        CID: Low Energy L2CAP Signaling Channel (0x0005)
        Command: LE Credit Based Connection Response
            Command Code: LE Credit Based Connection Response (0x15)
            Command Identifier: 0x03
            Command Length: 10
            Destination CID: Null identifier (0x0000)
            MTU: 0
            MPS: 0
            Initial Credits: 0
            LE Result: Connection Refused - No Resources Available (0x0004)
    

     I am currently registering a BLE observer as in all the examples I've seen.

        // Register a handler for BLE events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);

    However on the 52833DK the p_ble_evt->header.evt_id is never BLE_L2CAP_EVT_CH_SETUP_REFUSED or BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED in ble_event_handler. From https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsdk_nrf5_v16.0.0%2Findex.html Variant 2 I am expecting to see those events after 52840 Dongle refuses the L2CAP setup. Is there a special handler needed to catch L2CAP events?

Reply
  • Thank Kenneth, 

    I am getting a little bit closer to the setup mentioned above. I think now I am having trouble understanding the SDK. I have a 52833DK trying to set up an L2CAP channel with 52840 Dongle which is running the peripheral blinky app. I am simply using the blinky app since I can try to set up an L2CAP channel after connection is established. I also have a 52840DK acting as a sniffer.

    My code works as follows, the 52833 scans for device named "BLINKY" and connects to it. This part works.

    When BLE_GAP_EVT_CONNECTED is triggered on the 52833 I call sd_ble_l2cap_ch_setup with same params as the OTS example. At this point I can see in wireshark that everything is as I expect. 

    No.	Time	Source	PHY	Protocol	Length	Delta time (µs end to start)	SN	NESN	More Data	Event counter	Info
    834	20.674	c4:03:29:65:50:fe	LE 1M	LE LL	21	498				0	ADV_IND
    835	20.675	c4:03:29:65:50:fe	LE 1M	LE LL	21	1050				0	ADV_IND
    836	21.677	c4:03:29:65:50:fe	LE 1M	LE LL	21	1000658				0	ADV_IND
    837	21.678	f7:51:61:6c:70:ca	LE 1M	LE LL	34	151				0	CONNECT_REQ
    838	21.679	Master_0xb2a7e1bf	LE 1M	L2CAP	18	1253	0	0	False	0	LE Credit Based Connection Request (CID: 0040, Initial Credits: 0)
    839	21.679	Slave_0xb2a7e1bf	LE 1M	LE LL	0	150	0	1	False	0	Empty PDU
    840	21.707	Master_0xb2a7e1bf	LE 1M	LE LL	0	29545	1	1	False	1	Empty PDU
    841	21.708	Slave_0xb2a7e1bf	LE 1M	L2CAP	18	151	1	0	False	1	LE Credit Based Connection Response (CID: 0000, Initial Credits: 0)
    842	21.737	Master_0xb2a7e1bf	LE 1M	LE LL	0	29546	0	0	False	2	Empty PDU
    843	21.738	Slave_0xb2a7e1bf	LE 1M	LE LL	0	150	0	1	False	2	Empty PDU
    844	21.767	Master_0xb2a7e1bf	LE 1M	LE LL	0	29692	1	1	False	3	Empty PDU
    845	21.768	Slave_0xb2a7e1bf	LE 1M	LE LL	0	150	1	0	False	3	Empty PDU
    

    Since the 52840 Dongle is not set up for L2CAP it refuses the connection. In wireshark I can see LE Result: Connection Refused - No Resources Available (0x0004)

    Frame 841: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface wireshark_extcap2808, id 0
    Nordic BLE Sniffer
    Bluetooth Low Energy Link Layer
    Bluetooth L2CAP Protocol
        Length: 14
        CID: Low Energy L2CAP Signaling Channel (0x0005)
        Command: LE Credit Based Connection Response
            Command Code: LE Credit Based Connection Response (0x15)
            Command Identifier: 0x03
            Command Length: 10
            Destination CID: Null identifier (0x0000)
            MTU: 0
            MPS: 0
            Initial Credits: 0
            LE Result: Connection Refused - No Resources Available (0x0004)
    

     I am currently registering a BLE observer as in all the examples I've seen.

        // Register a handler for BLE events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);

    However on the 52833DK the p_ble_evt->header.evt_id is never BLE_L2CAP_EVT_CH_SETUP_REFUSED or BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED in ble_event_handler. From https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsdk_nrf5_v16.0.0%2Findex.html Variant 2 I am expecting to see those events after 52840 Dongle refuses the L2CAP setup. Is there a special handler needed to catch L2CAP events?

Children
Related