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