This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Bluetooth disconnects when notification enabled

Hi,

I'm using SDK 15.2. The bluetooth disconnects when I enable notifications on nrfConnect. This happens only if I increase the number of bytes to be sent. I'm writing a code for custom gatt. The references I used were - 

https://github.com/maidenone/custom_ble_service_example

https://devzone.nordicsemi.com/nordic/short-range-guides/b/bluetooth-low-energy/posts/ble-characteristics-a-beginners-tutorial

My code files - 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "sdk_common.h"
#include "ble_srv_common.h"
#include "ble_cus.h"
#include <string.h>
#include "nrf_gpio.h"
#include "boards.h"
#include "nrf_log.h"
/**@brief Function for handling the Connect event.
* @param[in] p_cus Custom Service structure.
* @param[in] p_ble_evt Event received from the BLE stack. */
static void on_connect(ble_cus_t * p_cus, ble_evt_t const * p_ble_evt)
{
p_cus->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
ble_cus_evt_t evt;
evt.evt_type = BLE_CUS_EVT_CONNECTED;
p_cus->evt_handler(p_cus, &evt);
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

ble_cus.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

sdk_config.h

Parents
  • Hello,

    Can you try to define DEBUG in your preprocessor defines, and monitor the log on the nRF? What does it say when you try to enable notifications?

    Best regards,

    Edvin

  • Its failing in ble_cus_custom_value_update() with fatal error.

  • did you define DEBUG in your preprocessor defines? If you are not sure how to do it, let me know what compiler/IDE you are using, and I can help you. Segger Embedded Studio? Keil? something else?

    When you define DEBUG it should tell you what the call to ble_cus_custom_value_update() returned, which is useful information, and not just that it returned != 0

  • Hi,

    The above error got fixed by referring to https://devzone.nordicsemi.com/f/nordic-q-a/34650/custom_ble_service_example---uint16_t-custom_value---nrf_error_data_size.

    But now I'm able to send only 20 bytes out of 29 bytes. 

    Changes I made - 

    In sdk_config.h -----------

    #define NRF_SDH_BLE_GAP_DATA_LENGTH 36

    #define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 32

    BLE_GATT_ATT_MTU_DEFAULT = 32 define in ble_gatt.h

    changed the RAM settings

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    static uint32_t custom_value_char_add(ble_cus_t * p_cus, const ble_cus_init_t * p_cus_init)
    {
    uint32_t err_code;
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_md_t cccd_md;
    ble_gatts_attr_t attr_char_value;
    ble_uuid_t ble_uuid;
    ble_gatts_attr_md_t attr_md;
    // Add Custom Value characteristic
    memset(&cccd_md, 0, sizeof(cccd_md));
    // Read operation on cccd should be possible without authentication.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
    cccd_md.write_perm = p_cus_init->custom_value_char_attr_md.cccd_write_perm;
    cccd_md.vloc = BLE_GATTS_VLOC_STACK;
    memset(&char_md, 0, sizeof(char_md));
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    uint32_t ble_cus_custom_value_update(ble_cus_t * p_cus, uint8_t * custom_value) /*NEW CHANGE*/
    {
    NRF_LOG_INFO("In ble_cus_custom_value_update. \r\n");
    if (p_cus == NULL)
    {
    return NRF_ERROR_NULL;
    }
    uint32_t err_code = NRF_SUCCESS;
    ble_gatts_value_t gatts_value;
    // Initialize value struct.
    memset(&gatts_value, 0, sizeof(gatts_value));
    gatts_value.len = 29*sizeof(uint8_t); /*NEW CHANGE*/
    gatts_value.offset = 0;
    gatts_value.p_value = custom_value;
    // Update database.
    err_code = sd_ble_gatts_value_set(p_cus->conn_handle, p_cus->custom_value_handles.value_handle, &gatts_value);
    if (err_code != NRF_SUCCESS)
    {
    return err_code;
    }
    // Send value if connected and notifying.
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Also how do I receive 20 bytes from host? Right now its just a byte.

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    static void on_write(ble_cus_t * p_cus, ble_evt_t const * p_ble_evt)
    {
    ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    // Custom Value Characteristic Written to.
    if (p_evt_write->handle == p_cus->custom_value_handles.value_handle)
    {
    nrf_gpio_pin_toggle(LED_4);
    NRF_LOG_INFO("GOT WRITE ON: %d",*p_evt_write->data);
    if(*p_evt_write->data == 0x01)
    {
    nrf_gpio_pin_clear(LED_3);
    }
    else if(*p_evt_write->data == 0x02)
    {
    nrf_gpio_pin_set(LED_3);
    }
    else
    {
    //Do nothing
    }
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    My files -

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #include "sdk_common.h"
    #include "ble_srv_common.h"
    #include "ble_cus.h"
    #include <string.h>
    #include "nrf_gpio.h"
    #include "boards.h"
    #include "nrf_log.h"
    /**@brief Function for handling the Connect event.
    * @param[in] p_cus Custom Service structure.
    * @param[in] p_ble_evt Event received from the BLE stack. */
    static void on_connect(ble_cus_t * p_cus, ble_evt_t const * p_ble_evt)
    {
    p_cus->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
    ble_cus_evt_t evt;
    evt.evt_type = BLE_CUS_EVT_CONNECTED;
    p_cus->evt_handler(p_cus, &evt);
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    2068.ble_cus.h

    257070.sdk_config.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /**
    * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
    *
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without modification,
    * are permitted provided that the following conditions are met:
    *
    * 1. Redistributions of source code must retain the above copyright notice, this
    * list of conditions and the following disclaimer.
    *
    * 2. Redistributions in binary form, except as embedded into a Nordic
    * Semiconductor ASA integrated circuit in a product or a software update for
    * such product, must reproduce the above copyright notice, this list of
    * conditions and the following disclaimer in the documentation and/or other
    * materials provided with the distribution.
    *
    * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
    * contributors may be used to endorse or promote products derived from this
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Reply
  • Hi,

    The above error got fixed by referring to https://devzone.nordicsemi.com/f/nordic-q-a/34650/custom_ble_service_example---uint16_t-custom_value---nrf_error_data_size.

    But now I'm able to send only 20 bytes out of 29 bytes. 

    Changes I made - 

    In sdk_config.h -----------

    #define NRF_SDH_BLE_GAP_DATA_LENGTH 36

    #define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 32

    BLE_GATT_ATT_MTU_DEFAULT = 32 define in ble_gatt.h

    changed the RAM settings

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    static uint32_t custom_value_char_add(ble_cus_t * p_cus, const ble_cus_init_t * p_cus_init)
    {
    uint32_t err_code;
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_md_t cccd_md;
    ble_gatts_attr_t attr_char_value;
    ble_uuid_t ble_uuid;
    ble_gatts_attr_md_t attr_md;
    // Add Custom Value characteristic
    memset(&cccd_md, 0, sizeof(cccd_md));
    // Read operation on cccd should be possible without authentication.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
    cccd_md.write_perm = p_cus_init->custom_value_char_attr_md.cccd_write_perm;
    cccd_md.vloc = BLE_GATTS_VLOC_STACK;
    memset(&char_md, 0, sizeof(char_md));
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    uint32_t ble_cus_custom_value_update(ble_cus_t * p_cus, uint8_t * custom_value) /*NEW CHANGE*/
    {
    NRF_LOG_INFO("In ble_cus_custom_value_update. \r\n");
    if (p_cus == NULL)
    {
    return NRF_ERROR_NULL;
    }
    uint32_t err_code = NRF_SUCCESS;
    ble_gatts_value_t gatts_value;
    // Initialize value struct.
    memset(&gatts_value, 0, sizeof(gatts_value));
    gatts_value.len = 29*sizeof(uint8_t); /*NEW CHANGE*/
    gatts_value.offset = 0;
    gatts_value.p_value = custom_value;
    // Update database.
    err_code = sd_ble_gatts_value_set(p_cus->conn_handle, p_cus->custom_value_handles.value_handle, &gatts_value);
    if (err_code != NRF_SUCCESS)
    {
    return err_code;
    }
    // Send value if connected and notifying.
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Also how do I receive 20 bytes from host? Right now its just a byte.

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    static void on_write(ble_cus_t * p_cus, ble_evt_t const * p_ble_evt)
    {
    ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    // Custom Value Characteristic Written to.
    if (p_evt_write->handle == p_cus->custom_value_handles.value_handle)
    {
    nrf_gpio_pin_toggle(LED_4);
    NRF_LOG_INFO("GOT WRITE ON: %d",*p_evt_write->data);
    if(*p_evt_write->data == 0x01)
    {
    nrf_gpio_pin_clear(LED_3);
    }
    else if(*p_evt_write->data == 0x02)
    {
    nrf_gpio_pin_set(LED_3);
    }
    else
    {
    //Do nothing
    }
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    My files -

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #include "sdk_common.h"
    #include "ble_srv_common.h"
    #include "ble_cus.h"
    #include <string.h>
    #include "nrf_gpio.h"
    #include "boards.h"
    #include "nrf_log.h"
    /**@brief Function for handling the Connect event.
    * @param[in] p_cus Custom Service structure.
    * @param[in] p_ble_evt Event received from the BLE stack. */
    static void on_connect(ble_cus_t * p_cus, ble_evt_t const * p_ble_evt)
    {
    p_cus->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
    ble_cus_evt_t evt;
    evt.evt_type = BLE_CUS_EVT_CONNECTED;
    p_cus->evt_handler(p_cus, &evt);
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    2068.ble_cus.h

    257070.sdk_config.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /**
    * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
    *
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without modification,
    * are permitted provided that the following conditions are met:
    *
    * 1. Redistributions of source code must retain the above copyright notice, this
    * list of conditions and the following disclaimer.
    *
    * 2. Redistributions in binary form, except as embedded into a Nordic
    * Semiconductor ASA integrated circuit in a product or a software update for
    * such product, must reproduce the above copyright notice, this list of
    * conditions and the following disclaimer in the documentation and/or other
    * materials provided with the distribution.
    *
    * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
    * contributors may be used to endorse or promote products derived from this
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Children
  • I suggest you look into the ble_app_uart example to see how to send more than 20 bytes. Increasing these:

    #define NRF_SDH_BLE_GAP_DATA_LENGTH 36

    #define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 32

    BLE_GATT_ATT_MTU_DEFAULT = 32 define in ble_gatt.h

    may require you to change your ram settings again.

     

    bscdb said:
    Also how do I receive 20 bytes from host? Right now its just a byte.

     To see how to "receive more than one byte", please refer to the ble_app_uart_c example. You probably receive more than one byte, but you need to look at the length field. Please check the function ble_nus_c_evt_handler() and the event BLE_NUS_C_EVT_NUS_TX_EVT. The data is located in p_ble_nus_evt->p_data,  and the length of the data is found in p_ble_nus_evt->data_len.

    Best regards,

    Edvin

  • Hi Edvin, I have already mentioned above that I made these changes -

    #define NRF_SDH_BLE_GAP_DATA_LENGTH 36

    #define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 32

    BLE_GATT_ATT_MTU_DEFAULT = 32 define in ble_gatt.h

    may require you to change your ram settings again.

    But still it does not send more than 20 bytes.

  • Ok. How do you determine that you are just able to send 20 bytes? I do believe you, but I want to know what symptoms you are seeing.

  • I checked it on nrfconnect. Even I was thinking the same that I'm correctly sending 29 bytes, may be nrfconnect does not display them?

    Can you check at your end if its the same?

    I also receive only 20 bytes from host. So both ways its restricted to 20 bytes only.

    For receiving 29 bytes, I changed the code to-

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    static void on_write(ble_cus_t * p_cus, ble_evt_t const * p_ble_evt)
    {
    ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    // Custom Value Characteristic Written to.
    if (p_evt_write->handle == p_cus->custom_value_handles.value_handle)
    {
    nrf_gpio_pin_toggle(LED_4);
    for(int i = 0; i < p_evt_write->len; i++)
    {
    NRF_LOG_INFO("Data Received: %d", p_evt_write->data[i]);
    }
    /*if(*p_evt_write->data == 0x01)
    {
    nrf_gpio_pin_clear(LED_3);
    }
    else if(*p_evt_write->data == 0x02)
    {
    nrf_gpio_pin_set(LED_3);
    }
    else
    {
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    When I send more than 20 bytes from nrfConnect, I get a message saying 

    When I was debugging, I got 

    Could you please check at your end? I cant seem to find any solution to this.

    ble_app_template_custom_packet.zip

    I'm using SDK15.2. My thinking is that the updated MTU size is not being exchanged between peripheral & central.

  • I tested your project against nRF Connect for Desktop:

    I was able to both receive and send 29 bytes.

    Does it not behave the same in your case?