Disconnection when trying to read long characteristic

⚠️
Hi there.. thanks for coming to the forums. Exciting news! we’re now in the process of moving to our new forum platform that will offer better functionality and is contained within the main Dialog website. All posts and accounts have been migrated. We’re now accepting traffic on the new forum only - please POST any new threads at https://www.dialog-semiconductor.com/support . We’ll be fixing bugs / optimising the searching and tagging over the coming days.
6 posts / 0 new
Last post
daleonpz2
Offline
Last seen: 1 year 5 months ago
Joined: 2020-11-13 17:39
Disconnection when trying to read long characteristic

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, &notif, 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");

}

 

Device: 
PM_Dialog
Offline
Last seen: 2 months 2 weeks ago
Staff
Joined: 2018-02-08 11:03
Hi daleonpz2.

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

daleonpz2
Offline
Last seen: 1 year 5 months ago
Joined: 2020-11-13 17:39
Hi,

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);

 

PM_Dialog
Offline
Last seen: 2 months 2 weeks ago
Staff
Joined: 2018-02-08 11:03
Hi daleonpz2,

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

daleonpz2
Offline
Last seen: 1 year 5 months ago
Joined: 2020-11-13 17:39
>>> So, do you meant that

>>> 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.

PM_Dialog
Offline
Last seen: 2 months 2 weeks ago
Staff
Joined: 2018-02-08 11:03
Hi daleonpz2,

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