I'm doing an application as as Central based on ble_central code.
I'm scanning bluetooth devices (also dialog microcontrollers DA14681), connect to one of them and read a specific characteristic with value is larger than 20 bytes. The value can be up to 50 bytes.
I know that usually BLE can read up to 20bytes and write up to 18 bytes. But if one set MTU to some value with
ble_gap_mtu_size_set(512), it's possible to read/write more bytes.
However, sometimes my application called
handle_evt_gap_disconnected((ble_evt_gap_scan_completed_t *) hdr);
when reading the characteristic instead of
handle_evt_gattc_read_completed((ble_evt_gattc_read_completed_t *) hdr);
Why is that? I think I set up correctly the MTU to be able to read more then 20 bytes.
The peripheral code also uses ble_gap_mtu_size_set(512).
In addition, I made a simple "ble central "example in python with bluepy from my computer and I saw similar behavior. Disconnection when reading the characteristic. Then I changed the MTU in python to 512 and then my application worked.
My central task is:
````
void ble_central_task(void *params)
{
int8_t wdog_id;
ble_central_task_handle = OS_GET_CURRENT_TASK();
/* register ble_central task to be monitored by watchdog */
wdog_id = sys_watchdog_register(false);
#if (!CFG_USE_BROWSE_API)
queue_init(&services);
queue_init(&characteristics);
#endif
ble_central_start();
ble_gap_mtu_size_set(512);
ble_register_app();
printf("BLE Central application started\r\n");
OS_TASK_CREATE("com_gateway",
com_gateway_rx_task,
NULL,
1024,
COM_GATEWAY_TASK_PRIORITY,
com_gateway_h);
OS_ASSERT(com_gateway_h);
for (;;)
{
OS_BASE_TYPE ret;
uint32_t notif;
/* notify watchdog on each loop */
sys_watchdog_notify(wdog_id);
/* suspend watchdog while blocking on OS_TASK_NOTIFY_WAIT() */
sys_watchdog_suspend(wdog_id);
/*
* Wait on any of the notification bits, then clear them all
*/
ret = OS_TASK_NOTIFY_WAIT(0, OS_TASK_NOTIFY_ALL_BITS, ¬if, OS_TASK_NOTIFY_FOREVER);
/* Blocks forever waiting for task notification. The return value must be OS_OK */
OS_ASSERT(ret == OS_OK);
/* resume watchdog */
sys_watchdog_notify_and_resume(wdog_id);
/* notified from BLE manager, can get event */
if (notif & BLE_APP_NOTIFY_MASK)
{
ble_evt_hdr_t *hdr;
hdr = ble_get_event(false);
if (!hdr) {
goto no_event;
}
if (!ble_service_handle_event(hdr)) {
switch (hdr->evt_code) {
case BLE_EVT_GAP_CONNECTED:
handle_evt_gap_connected((ble_evt_gap_connected_t *) hdr);
break;
case BLE_EVT_GAP_DISCONNECTED:
handle_evt_gap_disconnected((ble_evt_gap_disconnected_t *) hdr);
break;
case BLE_EVT_GAP_SECURITY_REQUEST:
handle_evt_gap_security_request((ble_evt_gap_security_request_t *) hdr);
break;
case BLE_EVT_GAP_PAIR_COMPLETED:
handle_evt_gap_pair_completed((ble_evt_gap_pair_completed_t *) hdr);
break;
case BLE_EVT_GAP_ADV_REPORT:
handle_evt_gap_adv_report((ble_evt_gap_adv_report_t *) hdr);
break;
case BLE_EVT_GAP_SCAN_COMPLETED:
handle_evt_gap_scan_completed((ble_evt_gap_scan_completed_t *) hdr);
break;
case BLE_EVT_GATTC_DISCOVER_SVC:
handle_evt_gattc_discover_svc((ble_evt_gattc_discover_svc_t *) hdr);
break;
case BLE_EVT_GATTC_DISCOVER_CHAR:
handle_evt_gattc_discover_char((ble_evt_gattc_discover_char_t *) hdr);
break;
case BLE_EVT_GATTC_READ_COMPLETED:
handle_evt_gattc_read_completed((ble_evt_gattc_read_completed_t *) hdr);
break;
case BLE_EVT_GATTC_WRITE_COMPLETED:
handle_evt_gattc_write_completed((ble_evt_gattc_write_completed_t *) hdr);
break;
case BLE_EVT_GATTC_NOTIFICATION:
handle_evt_gattc_notification((ble_evt_gattc_notification_t *) hdr);
break;
case BLE_EVT_GATTC_INDICATION:
handle_evt_gattc_indication((ble_evt_gattc_indication_t *) hdr);
break;
default:
ble_handle_event_default(hdr);
break;
}
}
OS_FREE(hdr);
no_event:
// notify again if there are more events to process in queue
if (ble_has_event())
{
OS_TASK_NOTIFY(OS_GET_CURRENT_TASK(), BLE_APP_NOTIFY_MASK, eSetBits);
}
}
}
}
```
My code for reading the characteristic
```
static bluegiga_return_code_t _bluegiga_read_OUT_char(const uint8_t* input)
{
uint8_t connection = input[4];
printf("Call Read Characteristic\r\n");
if( BLUEGIGA_STATE_CONNECTING != bluegiga_state_g)
{
printf("Cannot read Char. Device not connected\r\n");
return BLUEGIGA_ERROR;
}
ble_gattc_read(connection, bluegiga_out_char_handle_g, 0);
return BLUEGIGA_READ_OUT_CHAR;
}
```
Reading event
static void handle_evt_gattc_read_completed(ble_evt_gattc_read_completed_t *evt)
{
printf("--- Read complete\r\n");
for( uint16_t i =0; i<evt->length; i++)
{
printf("%02hhX ", evt->value[i]);
}
printf("\r\n");
}
Hi daleonpz2.
Thanks for your question online. Since this occurs sometimes, I would recommend first checking the reason of the disconnection, so that we can understand what is getting wrong.
If you check the ble_evt_gap_disconnected_t, the “reason” item holds the reason of disconnection. So, when this occurs, can you please add a break point into the disconnection function and read the reason? You could also print the reason of the disconnection to a Serial Terminal. What is its value?
Thanks, PM_Dialog
Hi,
I get 0x3E: BLE_HCI_ERROR_CONN_FAILED_TO_BE_EST.
But I could the connection established.
[handle_evt_gap_connected] Connection Handle
00> [handle_evt_gap_connected] Connection Handle
00> [handle_evt_gap_connection_completed] Connection Completed Handle
00> [handle_evt_gap_connection_completed] connection status 0x00
00> [devicepool_task] trying to read OUT char from device
00> [handle_evt_gap_disconnected] Disconnection Handle
00> [handle_evt_gap_disconnected] Disconnection reason 0x3E
When I could read, the output is like this:
00> [handle_evt_gap_connected] Connection Handle
00> [handle_evt_gap_connection_completed] Connection Completed Handle
00> [handle_evt_gap_connection_completed] connection status 0x00
00> [devicepool_task] trying to read OUT char from device
00> [handle_evt_gattc_read_completed] --- Read complete
00> [devicepool_task] Data Read:
00> 7DEBB6BEAC79B933001000000000000000
00> [devicepool_task] We're done... disconnecting
00> [handle_evt_gap_disconnected] Disconnection Handle
00> [handle_evt_gap_disconnected] Disconnection reason 0x1F
Here are the connection parameters:
static const gap_conn_params_t cp = {
.interval_min = BLE_CONN_INTERVAL_FROM_MS(10),
.interval_max = BLE_CONN_INTERVAL_FROM_MS(20),
.slave_latency = 0,
.sup_timeout = BLE_SUPERVISION_TMO_FROM_MS(300),
};
status = ble_gap_connect(&(dev->address), &cp);
Hi daleonpz2,
Thanks for getting back.
>>>But I could the connection established.
So, do you meant that after the disconnection, the device still advertises, and you are able to connect?
Would it be possible to use a BLE Sniffer tool and share a sniffer capture, so that we can check what is happening over the air?
Since this is happening sometimes, it would be very helpful to under tang what messages are exchanged over the air. Otherwise it would be very hard to understand what is getting wrong.
Thanks, PM_Dialog
>>> So, do you meant that after the disconnection, the device still advertises, and you are able to connect?
yes
We found the problem. There was an iphone that was interfering. We turned it off and worked.
Hi daleonpz2,
Glad that you got it working and thanks for the indication.
If you have any other question, feel free to raise a new forum post.
Thanks, PM_Dialog