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

SoftDevice S140 L2CAP Recombination

I am attempting to port a BLE application to the nRF52840. The original application used a standard HCI serial interface so I am trying to adapt that to use the Nordic SoftDevice.

I am trying to determine how L2CAP recombination/reassembly is performed when using the SoftDevice. HCI ACL packets include the PB flags which indicate first and continuing packets that the host can use to reassemble L2CAP packets.

Based on my examination of nRF5_SDK_16.0.0_98a08e2 source code and SoftDevice API documentation, it seems that I need to register an observer using NRF_SDH_BLE_OBSERVER to receive BLE notifications from the SoftDevice and subsequently retrieve events using `sd_ble_evt_get()` and then look for various event types such as BLE_L2CAP_EVT_CH_RX to receive the L2CAP packets.

However, I can find no mention of the PB flags in the `ble_evt_t` struct returned by `sd_ble_evt_get()`.

Does the SoftDevice handle recombination (reassembly)?

Regards,

mike

  • Hi,

    The SoftDevice does not use the HCI defined in the Bluetooth specification, as it (simply put) implements both host and controller as one opaque unit. You interface it through the SoftDevice API (which can also be serialized, if you use the SoC running the SoftDevice for network mcu.)

    There is a BLE HCI controller example which is part of the Zephyr project, that is compatible with the nRF52 series devices, if a pure Bluetooth HCI controller is what you are looking for.

    With a bit more information about the project, I may be able to better point you in the right direction. I am afraid it is a bit unclear to me at the moment, what you need.

    Regards,
    Terje

  • Hi Terje,

    I am not interested in using the nRF52 as an HCI BLE device through a serial-port. Instead, I want to port my application to run on the nRF52840 and use the SoftDevice.

    I have a rather large BLE application that was written against a standard HCI/serial-port. The application works well in this configuration, but I would like to port it to the nRF52840 and take advantage of the SoftDevice.

    The application is layered pretty well with implementation for GATT/ATT/L2CAP/HCI. I would like to "simply" replace the L2CAP and HCI layer with one written for the  SoftDevice. Obviously, my current L2CAP/HCI Host implementation  handles producing/consuming ACL packets.

    Also, as part of the L2CAP this layer deals with what the Bluetooth Specification calls ''recombination'' for fragmented L2CAP packets that are received. HCI ACL packets include a "Packet Boundary" field that is used in this recombination process.

    I cannot find any such field in the events that are returned from the SoftDevice (`BLE_L2CAP_EVT_CH_RX` ble_evt_t`), which I would expect to contain that information.

    I have spent days staring at the various examples, with a particular focus on the `ble_app_hrs_freertos` example.

    Obviously, these examples use many parts of the SoftDevice BLE stack that I do not need. For example, I already have implementations for GATT, ATT and the profiles that run on these.

    I have not found good documentation for how to use the SoftDevice L2CAP directly.

    I hope that "clarifies" my situation.

    regards,

    mike

  • I used the L2CAP support in the S140 SoftDevice in a project some time ago. You can find the source code for it here:

    https://github.com/netik/dc27_badge/tree/master/software/firmware/badge

    In particular you want to look at the ble_lld.c and ble_l2cap_lld.c modules.

    You do not need to manually reassemble fragments when handling L2CAP packets. The SoftDevice takes care of all that for you. This is why the data structures related to L2CAP handling don't include the kinds of fields you're looking for.

    What you do have to do is set up some L2CAP-related parameters when you initialize the SoftDevice. In my code, in ble_lld.c:bleEnable(), I do this:

    	/* Set L2CAP connection limits. */
    
    	memset (&cfg, 0, sizeof(cfg));
    
    	cfg.conn_cfg.conn_cfg_tag = BLE_IDES_APP_TAG;
    	cfg.conn_cfg.params.l2cap_conn_cfg.rx_mps = BLE_IDES_L2CAP_MPS;
    	cfg.conn_cfg.params.l2cap_conn_cfg.tx_mps = BLE_IDES_L2CAP_MPS;
    	cfg.conn_cfg.params.l2cap_conn_cfg.rx_queue_size = 10;
    	cfg.conn_cfg.params.l2cap_conn_cfg.tx_queue_size = 10;
    	cfg.conn_cfg.params.l2cap_conn_cfg.ch_count = 1;
    
    	r = sd_ble_cfg_set (BLE_CONN_CFG_L2CAP, &cfg, ram_start);

    BLE frames themselves are limited to about 31 bytes. The MPS value here indicates the L2CAP packet size (which I define to be 128). Each L2CAP packet is fragmented across several BLE frames. Additionally, when you create an L2CAP connection using sd_ble_l2cap_ch_connect(), you can specify an MTU. This is the largest contiguous block of data you can send using the channel in a single TX operation. The data in that transmission will be fragmented across multiple MPS-sized L2CAP packets, which in turn will be fragmented into multiple BLE frames.

    The reassembly of the data will be done automatically by the SoftDevice on the other end.

    Note that all of this is built on top of the SoftDevice's own GAP implementation.

    Ultimately what this means is that you just get to use the L2CAP channel for exchanging unformatted data. I don't think it's intended as an intermediate layer for you to build your own GATTC/GATTS layer on top. The expectation is that you'll use the SoftDevice's GATTC/GATTS layers instead.

    -Bill

  • Hi,

    Thanks for the clarification.

    The L2CAP feature available through the SoftDevice is LE Credit Based Flow Control Mode, which is used for LE L2CAP connection oriented channels. For GATT based services I would strongly recommend to use the GATT implementation of the SoftDevice directly. The L2CAP API of the SoftDevice is not intended for building ATT/GATT on top of.

    In addition to the SoftDevice API documentation, I recommend having a look at the SoftDevice specification, of which in particular the Bluetooth Low Energy features page should be of interest for figuring out what functionalities of the SoftDevice to use

    Regards,
    Terje

  • Thank you . You answered my question about L2CAP recombination/reassembly and more.

    I went through the process of installing Zephyr (Yikes!) and building the hci_uart example for the nrf52840_pca10056 board to track down the nordic source files for that implementation

    It appears that Zephyr is using the nRF5 hardware directly with no use of the SoftDevice, which to my mind is quite interesting.

    In particular the `subsys/bluetooth/controller` directory, all of which seems to contain that implementations from Nordic which I *assume* adapts the nRF5 to the Zephyr environment.

    I'm going to need a lot of coffee.

    Please correct me if I'm on the wrong track.

Related