Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Discovery of conn handles not feasible with nrf52-ble-app-uart-c-multilink-master and BK3432_QFN32 BLE modules

Dear,

We are working on a project where we have to request and read out data from multiple (up to 50, but can split up to 8 per central device) BLE modules (BK3432_QFN32) containing battery information within its service 0xFFF0. 
As we are familiar with BLE communication using the nRF52 chipset, we selected the nRF52840-DK as central and tried out the ble_app_uart_c and later on the nrf52-ble-app-uart-c-multilink-master. The latter is more useful to us as we want to connect and request data from multiple peripherals. 

In a first development stage, we checked if we can connect to the BLE modules and request data via the nRF Connect BLE app. 
A snapshot is shown here below which indicates that we are able to make a connection and receive the battery state response: 

The nRF BLE sniffer response is shown here: 

109862	54556.040	ShenZhen_28:4d:f7	LE 1M	LE LL	28	1196µs				0	ADV_IND
109863	54556.538	ShenZhen_28:4d:f7	LE 1M	LE LL	28	497714µs				0	ADV_IND
109864	54556.540	ShenZhen_28:4d:f7	LE 1M	LE LL	28	1197µs				0	ADV_IND
109865	54556.541	ShenZhen_28:4d:f7	LE 1M	LE LL	28	1196µs				0	ADV_IND
109866	54557.044	ShenZhen_28:4d:f7	LE 1M	LE LL	28	502712µs				0	ADV_IND
109867	54557.046	ShenZhen_28:4d:f7	LE 1M	LE LL	28	1196µs				0	ADV_IND
109868	54557.047	ShenZhen_28:4d:f7	LE 1M	LE LL	28	1196µs				0	ADV_IND
109869	54557.549	ShenZhen_28:4d:f7	LE 1M	LE LL	28	501455µs				0	ADV_IND
109870	54557.551	ShenZhen_28:4d:f7	LE 1M	LE LL	28	1196µs				0	ADV_IND
109871	54557.552	ShenZhen_28:4d:f7	LE 1M	LE LL	28	1196µs				0	ADV_IND
109872	54557.553	e8:6f:7e:12:6a:73	LE 1M	LE LL	34	151µs				0	CONNECT_IND
109875	54557.562	Slave_0x38f7c93f	LE 1M	ATT	7	151µs	0	1	False	1	Rcvd Exchange MTU Request, Client Rx MTU: 256
109886	54557.607	Master_0x38f7c93f	LE 1M	ATT	11	7189µs	0	0	False	7	Sent Read By Group Type Request, GATT Primary Service Declaration, Handles: 0x0001..0xffff
109888	54557.614	Master_0x38f7c93f	LE 1M	ATT	7	7101µs	1	1	False	8	Sent Exchange MTU Response, Server Rx MTU: 247
109889	54557.614	Slave_0x38f7c93f	LE 1M	ATT	24	150µs	1	0	False	8	Rcvd Read By Group Type Response, Attribute List Length: 3, Generic Access Profile, Generic Attribute Profile, Unknown
109890	54557.622	Master_0x38f7c93f	LE 1M	ATT	11	6941µs	0	0	False	9	Sent Read By Group Type Request, GATT Primary Service Declaration, Handles: 0x000b..0xffff
109893	54557.629	Slave_0x38f7c93f	LE 1M	ATT	12	151µs	1	0	False	10	Rcvd Read By Group Type Response, Attribute List Length: 1, Device Information
109894	54557.637	Master_0x38f7c93f	LE 1M	ATT	11	7093µs	0	0	False	11	Sent Read By Group Type Request, GATT Primary Service Declaration, Handles: 0x001e..0xffff
109897	54557.644	Slave_0x38f7c93f	LE 1M	ATT	26	151µs	1	0	False	12	Rcvd Read By Group Type Response, Attribute List Length: 1, Unknown
109898	54557.652	Master_0x38f7c93f	LE 1M	ATT	11	6980µs	0	0	False	13	Sent Read By Group Type Request, GATT Primary Service Declaration, Handles: 0x0027..0xffff
109901	54557.659	Slave_0x38f7c93f	LE 1M	ATT	9	150µs	1	0	False	14	Rcvd Error Response - Attribute Not Found, Handle: 0x0027 (Unknown: Unknown)
109902	54557.667	Master_0x38f7c93f	LE 1M	ATT	7	7118µs	0	0	False	15	Sent Read Request, Handle: 0x001e (Unknown)
109905	54557.674	Slave_0x38f7c93f	LE 1M	ATT	21	150µs	1	0	False	16	Rcvd Read Response, Handle: 0x001e (Unknown)
109910	54557.697	Master_0x38f7c93f	LE 1M	ATT	11	7189µs	0	0	False	19	Sent Read By Type Request, GATT Characteristic Declaration, Handles: 0x0001..0x0005
109913	54557.704	Slave_0x38f7c93f	LE 1M	ATT	20	151µs	1	0	False	20	Rcvd Read By Type Response, Attribute List Length: 2, Device Name, Appearance
109914	54557.712	Master_0x38f7c93f	LE 1M	ATT	7	7029µs	0	0	False	21	Sent Read Request, Handle: 0x0003 (Generic Access Profile: Device Name)
109917	54557.719	Slave_0x38f7c93f	LE 1M	ATT	5	151µs	1	0	False	22	Rcvd Read Response, Handle: 0x0003 (Generic Access Profile: Device Name)
109918	54557.727	Master_0x38f7c93f	LE 1M	ATT	7	7148µs	0	0	False	23	Sent Read Request, Handle: 0x0005 (Generic Access Profile: Appearance)
109919	54557.727	Slave_0x38f7c93f	LE 1M	ATT	5	151µs	1	0	False	23	Rcvd Read Response, Handle: 0x0005 (Generic Access Profile: Appearance)
109920	54557.734	Master_0x38f7c93f	LE 1M	ATT	7	7092µs	0	0	False	24	Sent Read Request, Handle: 0x0005 (Generic Access Profile: Appearance)
109923	54557.742	Slave_0x38f7c93f	LE 1M	ATT	7	151µs	1	0	False	25	Rcvd Read Response, Handle: 0x0005 (Generic Access Profile: Appearance)
109928	54557.764	Master_0x38f7c93f	LE 1M	ATT	9	7190µs	0	0	False	28	Sent Find Information Request, Handles: 0x0004..0x0005
109931	54557.772	Slave_0x38f7c93f	LE 1M	ATT	14	150µs	1	0	False	29	Rcvd Find Information Response, Handle: 0x0004 (Generic Access Profile: Device Name: GATT Characteristic Declaration), Handle: 0x0005 (Generic Access Profile: Device Name: Appearance)
109934	54557.787	Master_0x38f7c93f	LE 1M	ATT	9	7189µs	1	1	False	31	Sent Find Information Request, Handles: 0x0006..0x0005
109937	54557.794	Slave_0x38f7c93f	LE 1M	ATT	9	150µs	0	1	False	32	Rcvd Error Response - Invalid Handle, Handle: 0x0006 (Generic Attribute Profile)
109940	54557.809	Master_0x38f7c93f	LE 1M	ATT	7	7189µs	0	0	False	34	Sent Read Request, Handle: 0x0003 (Generic Access Profile: Device Name)
109942	54557.817	Master_0x38f7c93f	LE 1M	ATT	7	7142µs	0	0	False	35	Sent Read Request, Handle: 0x0003 (Generic Access Profile: Device Name)
109945	54557.824	Slave_0x38f7c93f	LE 1M	ATT	5	151µs	1	0	False	36	Rcvd Read Response, Handle: 0x0003 (Generic Access Profile: Device Name)
110140	54558.567	Slave_0x38f7c93f	LE 1M	L2CAP	16	150µs	0	1	False	135	Connection Parameter Update Request
110141	54558.574	Master_0x38f7c93f	LE 1M	L2CAP	10	7062µs	1	1	False	136	Connection Parameter Update Response (Accepted)
110143	54558.582	Master_0x38f7c93f	LE 1M	LE LL	12	7109µs	0	0	False	137	Control Opcode: LL_CONNECTION_UPDATE_IND
110401	54564.826	Master_0x38f7c93f	LE 1M	ATT	11	49688µs	1	1	False	267	Sent Read By Type Request, GATT Characteristic Declaration, Handles: 0x0007..0x000a
110404	54564.877	Slave_0x38f7c93f	LE 1M	ATT	13	151µs	0	1	False	268	Rcvd Read By Type Response, Attribute List Length: 1, Unknown
110405	54564.926	Master_0x38f7c93f	LE 1M	ATT	11	49583µs	1	1	False	269	Sent Read By Type Request, GATT Characteristic Declaration, Handles: 0x0009..0x000a
110408	54564.977	Slave_0x38f7c93f	LE 1M	ATT	9	151µs	0	1	False	270	Rcvd Error Response - Attribute Not Found, Handle: 0x0009 (Unknown: Unknown)
110409	54565.026	Master_0x38f7c93f	LE 1M	ATT	7	49615µs	1	1	False	271	Sent Read Request, Handle: 0x0009 (Unknown: Unknown)
110412	54565.077	Slave_0x38f7c93f	LE 1M	ATT	5	151µs	0	1	False	272	Rcvd Read Response, Handle: 0x0009 (Unknown: Unknown)
110415	54565.176	Master_0x38f7c93f	LE 1M	ATT	9	49687µs	0	0	False	274	Sent Find Information Request, Handles: 0x000a..0x000a
110418	54565.227	Slave_0x38f7c93f	LE 1M	ATT	10	151µs	1	0	False	275	Rcvd Find Information Response, Handle: 0x000a (Unknown: Unknown: Client Characteristic Configuration)
110419	54565.276	Master_0x38f7c93f	LE 1M	ATT	7	49607µs	0	0	False	276	Sent Read Request, Handle: 0x000a (Unknown: Unknown: Client Characteristic Configuration)
110422	54565.327	Slave_0x38f7c93f	LE 1M	ATT	7	151µs	1	0	False	277	Rcvd Read Response, Handle: 0x000a (Unknown: Unknown: Client Characteristic Configuration)
110670	54571.626	Master_0x38f7c93f	LE 1M	ATT	9	49687µs	0	0	False	403	Sent Write Request, Handle: 0x000a (Unknown: Unknown: Client Characteristic Configuration)
110673	54571.676	Slave_0x38f7c93f	LE 1M	ATT	5	150µs	1	0	False	404	Rcvd Write Response, Handle: 0x000a (Unknown: Unknown: Client Characteristic Configuration)
111113	54582.926	Master_0x38f7c93f	LE 1M	ATT	13	49688µs	1	1	False	629	Sent Write Request, Handle: 0x0009 (Unknown: Unknown)
111116	54582.976	Slave_0x38f7c93f	LE 1M	ATT	5	150µs	0	1	True	630	Rcvd Write Response, Handle: 0x0009 (Unknown: Unknown)
111118	54582.976	Slave_0x38f7c93f	LE 1M	ATT	17	151µs	1	0	False	630	Rcvd Handle Value Notification, Handle: 0x0009 (Unknown: Unknown)

Then, we implemented some changes to the nrf52-ble-app-uart-c-multilink-master example in order to connect to multiple devices with the UUID (0xFFF0).
We were able to do so, however the discovery does not show as been completed as can be seen in the snapshot below and from the response of LED1 we know we are in the connection state: 

The nRF BLE sniffer response is shown here: 

116063	54719.794	ShenZhen_28:4d:f7	LE 1M	LE LL	28	1196µs				0	ADV_IND
116064	54719.796	ShenZhen_28:4d:f7	LE 1M	LE LL	28	1196µs				0	ADV_IND
116065	54720.300	ShenZhen_28:4d:f7	LE 1M	LE LL	28	504026µs				0	ADV_IND
116066	54720.301	c6:95:cc:54:97:22	LE 1M	LE LL	34	150µs				0	CONNECT_IND
116067	54720.302	Master_0x3172651f	LE 1M	ATT	7	1252µs	0	0	False	0	Sent Exchange MTU Request, Client Rx MTU: 247
116068	54720.332	Master_0x3172651f	LE 1M	ATT	7	29865µs	0	0	True	1	Sent Exchange MTU Request, Client Rx MTU: 247
116069	54720.332	Slave_0x3172651f	LE 1M	ATT	7	150µs	0	1	False	1	Rcvd Exchange MTU Request, Client Rx MTU: 256
116070	54720.333	Master_0x3172651f	LE 1M	LE LL	9	150µs	1	1	False	1	Control Opcode: LL_LENGTH_REQ
116072	54720.362	Master_0x3172651f	LE 1M	ATT	7	29046µs	0	0	False	2	Sent Exchange MTU Response, Server Rx MTU: 247
116073	54720.362	Slave_0x3172651f	LE 1M	LE LL	9	150µs	0	1	True	2	Control Opcode: LL_LENGTH_RSP
116075	54720.392	Slave_0x3172651f	LE 1M	ATT	7	151µs	1	0	False	3	Rcvd Exchange MTU Response, Server Rx MTU: 256
116076	54720.422	Master_0x3172651f	LE 1M	ATT	27	29634µs	0	0	False	4	Sent Find By Type Value Request, GATT Primary Service Declaration, Handles: 0x0001..0xffff
116079	54720.452	Slave_0x3172651f	LE 1M	ATT	9	150µs	1	0	False	5	Rcvd Error Response - Attribute Not Found, Handle: 0x0027 (Unknown: Unknown)
116137	54721.322	Slave_0x3172651f	LE 1M	L2CAP	16	151µs	0	1	False	34	Connection Parameter Update Request
116138	54721.352	Master_0x3172651f	LE 1M	L2CAP	10	29562µs	1	1	False	35	Connection Parameter Update Response (Accepted)
116140	54721.382	Master_0x3172651f	LE 1M	LE LL	12	29610µs	0	0	False	36	Control Opcode: LL_CONNECTION_UPDATE_IND

Hereby, the question arises how to make sure the ble discovery is completed and if this is not possible, how to bypass this step. 

FYI we were able to send write request and receive a response on the connection handle 0x0009 directly by changing the code of the ble_nus_c_string_send() via: 

uint32_t ble_nus_c_string_send(ble_nus_c_t * p_ble_nus_c, uint8_t * p_string, uint16_t length)
{
    VERIFY_PARAM_NOT_NULL(p_ble_nus_c);

    nrf_ble_gq_req_t write_req;

    memset(&write_req, 0, sizeof(nrf_ble_gq_req_t));

    if (length > BLE_NUS_MAX_DATA_LEN)
    {
        NRF_LOG_WARNING("Content too long.");
        return NRF_ERROR_INVALID_PARAM;
    }
    if (p_ble_nus_c->conn_handle == BLE_CONN_HANDLE_INVALID)
    {
        NRF_LOG_WARNING("Connection handle invalid.");
        return NRF_ERROR_INVALID_STATE;
    }

    write_req.type                        = NRF_BLE_GQ_REQ_GATTC_WRITE;
    write_req.error_handler.cb            = gatt_error_handler;
    write_req.error_handler.p_ctx         = p_ble_nus_c;
    write_req.params.gattc_write.handle   = 0x0009;  //p_ble_nus_c->handles.nus_rx_handle; 
    write_req.params.gattc_write.len      = length;
    write_req.params.gattc_write.offset   = 0;
    write_req.params.gattc_write.p_value  = p_string;
    write_req.params.gattc_write.write_op = BLE_GATT_OP_WRITE_REQ; //Request instead of cmd as it seemed to be used with nRF connect BLE_GATT_OP_WRITE_CMD;
    write_req.params.gattc_write.flags    = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE;
    
    return nrf_ble_gq_item_add(p_ble_nus_c->p_gatt_queue, &write_req, p_ble_nus_c->conn_handle);
}

Response nRF BLE sniffer was however not the one we expected: 

Via the nRF connect BLE application we received the handle value notification (which was not the case in the above):

All input and help is welcome. 
Thanks in advance. 

Tom

Parents
  • Hi Tom

    I discussed this with a colleague, as there shouldn't be much to do in terms of editing the BAS files, as the 0xFFF0 service seems to do exactly the same things as the standard BAS service, so it should be sufficient just switching out the BLE_UUID_BATTERY_SERVICE define with 0xFFF0 and BLE_UUID_BATTERY_LEVEL_CHAR define with 0xFFF1. That should make it work by using the standard battery service library as far as we can tell. 

    Please note that 16 bit UUIDs like the one your peripheral board is using won't be approved during by the BT SIG unless it is registered as an "official" 16-bit UUID, and I can't find it in this list. So you should keep that in mind if it is a commercial product. This shouldn't stop it from working with other devices though, but it won't be an approved Bluetooth device.

    Lastly, my colleague pointed out something I missed. Since you have multiple connections we recommend you use the link context manager in the BAS implementation to handle these connections (blcm_link_ctx_get() in the SDK). But this shouldn't be necessary to get it up and running with the one device you're testing with now.

    Best regards,

    Simon

  • Hi Simon, 

    Thanks for having a discussion with your colleague. 

    I have changed the defines as you said in the function ble_bas_on_db_disc_evt() with BLE_UUID_KILO_SERVICE = 0xFFF0  and BLE_UUID_KILO_BAT_CHAR = 0xFFF1. During debugging, I do get the output that the battery service was discovered at the peer. However, only 1 battery characteristic (0x000a) has been found as depicted in the below screenshot. 

    In my opinion this is incomplete as above nRF sniffer outputs showed with nRF Connect that multiple attribute connection handles were found. How can I make sure all characteristics are discovered? 
    For your information, the complete subscribe address UUID for the battery information is 0000fff1-0000-1000-8000-00805f9b34fb.

    Regarding BLE SIG UUID, thanks for mentioning, however we are aware of this and this won't be a commercial product. 

    Regarding blcm_link_ctx_get() in the SDK, could you guide me in which file this function is defined? Where should I call this function? Is there any example that makes use of this?

    Tom

  • Hi

    It should keep discovereing characteristics based on what the char_count is set to in the for loop which should be equal to the number of characteristics present in the service.

    The blcm_link_ctx_get() function is defined in the ble_link_ctx_manager.c/.h files, and is used by I.E. the ble_app_uart example in the ble_nus.c file.

    Best regards,

    Simon

Reply
  • Hi

    It should keep discovereing characteristics based on what the char_count is set to in the for loop which should be equal to the number of characteristics present in the service.

    The blcm_link_ctx_get() function is defined in the ble_link_ctx_manager.c/.h files, and is used by I.E. the ble_app_uart example in the ble_nus.c file.

    Best regards,

    Simon

Children
Related