Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

How to respond to BLE_L2CAP_EVT_CH_SETUP_REQUEST

I am trying to create a L2CAP CoC between a nRF52840 SoC using nRF5 SDK version 15.3.0 and a Pixel 3 XL running Android 12 without the use of GATT. Currently I use GAP for the discovery and connection setup, after which I try and create a L2CAP CoC. On Android my (pseudo)code looks like this:

scanner.startScan()

if (device.name == "L2CAP_COC_DEMO") {

socket = device.createInsecureL2capChannel(psm)

socket.connect()

}

As I completely control both sides of this connection I chose to hardcode the PSM on both sides. This causes the nRF52840 so produce the following flow:


<info> app: STARTING ADVERTISING
<info> app: BLE EVT: BLE_GAP_EVT_CONNECTED, EVT CODE: 16
<info> app: Connected
<info> app: BLE EVT: BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST, EVT CODE: 35
<info> app: BLE EVT: BLE_GAP_EVT_DATA_LENGTH_UPDATE, EVT CODE: 36
<info> app: BLE EVT: BLE_GAP_EVT_PHY_UPDATE_REQUEST, EVT CODE: 33
<info> app: BLE EVT: BLE_GAP_EVT_PHY_UPDATE, EVT CODE: 34
<info> app: BLE EVT: BLE_L2CAP_EVT_CH_SETUP_REQUEST, EVT CODE: 112
<info> app: BLE EVT: BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED, EVT CODE: 116
<info> app: BLE EVT: BLE_L2CAP_EVT_CH_SETUP_REFUSED, EVT CODE: 113
<error> app: BLE_L2CAP_CH_SETUP_REFUSED_SRC_REMOTE
<error> app: BLE_L2CAP_CH_STATUS_CODE_LE_PSM_NOT_SUPPORTED

As a result I started looking in the Nordic documentation for how to respond to the BLE_L2CAP_EVT_CH_SETUP_REQUEST event, this is what I found:

  • Reply to a setup request of an L2CAP channel (if called in response to a BLE_L2CAP_EVT_CH_SETUP_REQUEST event): sends an LE Credit Based Connection Response packet to a peer.

This is talking about the sd_ble_l2cap_ch_setup() method. However when looking at the variables the method needs to function, it shows this:

[in] conn_handle Connection Handle.
[in,out] p_local_cid Pointer to a uint16_t containing Local Channel ID of the L2CAP channel:
[in] p_params L2CAP channel parameters.

For p_local_cid it clearly states as input it is possible to get a local_cid which is provided in BLE_L2CAP_EVT_CH_SETUP_REQUEST event when replying. However, when looking at ble_l2cap_evt_ch_setup_request_t which is the struct supplied by the event, it supplies no local_cid. Below is a copy from the documentation (and no, the ble_l2cap_ch_tx_params_t struct also does not contain a local_cid field).

Data Fields

ble_l2cap_ch_tx_params_t  tx_params
 
uint16_t  le_psm
 

Here are some links to the relevant documentation to save you some surfing time:
https://docs.nordicsemi.com/bundle/s140_v6.1.1_api/page/structble_l2cap_evt_ch_setup_request_t.html

https://docs.nordicsemi.com/bundle/s140_v6.1.1_api/page/group_b_l_e_l2_c_a_p_f_u_n_c_t_i_o_n_s.html#ga69199818fd81b20baf5c7db0656962c9

So my question is how to correctly respond to the BLE_L2CAP_EVT_CH_SETUP_REQUEST event. Additionally, it seems the documentation is either incomplete or incorrect. Any responses are appreciated, thanks in advance!

Parents
  • It seems like in so many other instances, concretely writing down the question brings one to new insight. The Nordic documentation is actually not incorrect, it is just not very clear. The local_cid one should use in the sd_ble_l2cap_ch_setup() call is a field inside the higher level, generic L2CAP event struct, not specifically inside the ble_l2cap_evt_ch_setup_request_t struct, which is implied in the documentation of the method.

Reply
  • It seems like in so many other instances, concretely writing down the question brings one to new insight. The Nordic documentation is actually not incorrect, it is just not very clear. The local_cid one should use in the sd_ble_l2cap_ch_setup() call is a field inside the higher level, generic L2CAP event struct, not specifically inside the ble_l2cap_evt_ch_setup_request_t struct, which is implied in the documentation of the method.

Children
No Data
Related