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

error code 0x04

My development environment is sdk15 s132 pca10040
The product concept provides central link 7, peripheral 1 on one 52832 ..
1 peripheral provides nus to work with smartphones
7 central communicates 7 52832 based on lbs.
Question 1: An error of NRF_ERROR_NO_MEM occurs in blcm_link_ctx_get () function. When I trace the cause, the variable values ​​are as follows. max_links_cnt = 0x01; conn_id = 0x02 When BLE_GAP_EVT_CONNECTED occurs in the on_ble_peripheral_evt () function p_ble_evt-> evt.gap_evt.conn_handle = 0x2
Question 2: #define DEVICE_NAME "Church_Product" If the nus service is not available, the device name appears on the smartphone. However, if it include nus,
device name is "Chur" only on my smartphone.

Please, reply.
Parents
  • Question 1:

    My suspicion is that the following lines causes the error (inside blcm_link_ctx_get() ):

        if (conn_id >= p_link_ctx_storage->max_links_cnt)
        {
            return NRF_ERROR_NO_MEM;
        }

    At the top of main.c, the NUS service instance is created through BLE_NUS_DEF(m_nus, NRF_SDH_BLE_TOTAL_LINK_COUNT), and here you send in the total link count (specified in sdk_config.h), as an argument. This will be added to the NUS stucture: m_nus.p_link_ctx_storage->max_links_cnt. If you increase NRF_SDH_BLE_TOTAL_LINK_COUNT in the sdk_config.h file, this might solve your problem. You may also have to increase the RAM start address consecutively. 

    Question 2:

    I assume you are talking about the device name from the advertising data (the name you see before connection). I am not sure how including the service should make a difference to the length of the name, maybe you could upload your code and I could take a look? However, the length of the advertising data name is specified in the function advertising_init(), by the fields init.advdata.name_type and init.advdata.short_name_len. Taking a look at that function might help you.

    Best regards, Simon

  • Hi, Simon

    Thank you for your response

    <Question 1>

    I changed BLE_NUS_DEF(m_nus, NRF_SDH_BLE_PERIPHERAL_LINK_COUNT) to BLE_NUS_DEF(m_nus, NRF_SDH_BLE_TOTAL_LINK_COUNT) on your advice 

    max_links_cnt changed to 0x08

    After connecting like the message below
    0> <info> app: Peripheral connected. conn_handle: 0x7
    an error occurred in ble_nus_data_send ()
    if (!p_client->is_notification_enabled)
    {
    return NRF_ERROR_INVALID_STATE;
    }

    <Question 2>
    static void advertising_init(void)
    {
    ret_code_t err_code;
    ble_advertising_init_t init;

    memset(&init, 0, sizeof(init));

    init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
    init.advdata.include_appearance = true;
    init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    init.advdata.uuids_complete.p_uuids = m_adv_uuids;

    init.config.ble_adv_fast_enabled = true;
    init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
    init.config.ble_adv_fast_timeout = APP_ADV_DURATION;

    init.evt_handler = on_adv_evt;

    err_code = ble_advertising_init(&m_advertising, &init);
    APP_ERROR_CHECK(err_code);

    ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
    }

Reply
  • Hi, Simon

    Thank you for your response

    <Question 1>

    I changed BLE_NUS_DEF(m_nus, NRF_SDH_BLE_PERIPHERAL_LINK_COUNT) to BLE_NUS_DEF(m_nus, NRF_SDH_BLE_TOTAL_LINK_COUNT) on your advice 

    max_links_cnt changed to 0x08

    After connecting like the message below
    0> <info> app: Peripheral connected. conn_handle: 0x7
    an error occurred in ble_nus_data_send ()
    if (!p_client->is_notification_enabled)
    {
    return NRF_ERROR_INVALID_STATE;
    }

    <Question 2>
    static void advertising_init(void)
    {
    ret_code_t err_code;
    ble_advertising_init_t init;

    memset(&init, 0, sizeof(init));

    init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
    init.advdata.include_appearance = true;
    init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    init.advdata.uuids_complete.p_uuids = m_adv_uuids;

    init.config.ble_adv_fast_enabled = true;
    init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
    init.config.ble_adv_fast_timeout = APP_ADV_DURATION;

    init.evt_handler = on_adv_evt;

    err_code = ble_advertising_init(&m_advertising, &init);
    APP_ERROR_CHECK(err_code);

    ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
    }

Children
  • I can answer the first question right away. If you take a look at the two characteristics in nRF Connect, "RX Characteristic" and "TX Characteristic", notice that they have different properties. The RX char. is intended for sending data from the client/central (phone) to the server/peripheral (nrf52832), and the property WRITE allows for this. While the TX Char. has the property NOTIFY, which makes it possible to notify a change of the GATT database, from the peripheral to the central. 

    In order to perform a notification, it needs to be enabled by the client. This can be done by clicking on the three arrows to the right of TX Char. in nRF Connect. The peripheral will receive this information and p_client->is_notification_enabled will be set to true. Then you should be able to use the function ble_nus_data_send() without returning an invalid state.

    UPDATE(10/24/2018):

    Question 2:

    I guess this problem is due to the limited size of the advertising payload, which is 31 bytes. The advertising payload contains data such as names, flags and service UUIDs. When the service is included in addition to a the full name, this may exceed the advertising payload of 31 bytes. If you look at the function advertising_init()-->ble_advertising_init(..)-->ble_advdata_encode(..)-->name_encode(..), the following lines appears:

    // Check if device intend to use short name and it can fit available data size.
        // If the name is shorter than the preferred short name length then it is no longer 
        // a short name and is in fact the complete name of the device.
        if (((p_advdata->name_type == BLE_ADVDATA_FULL_NAME) || 
            (actual_length <= p_advdata->short_name_len)) && 
            (actual_length <= rem_adv_data_len))
        {
            // Complete device name can fit, setting Complete Name in Adv Data.
            adv_data_format = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
        }
        else
        {
            // Else short name needs to be used. Or application has requested use of short name.
            adv_data_format = BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME;
    .
    .
    .

    Try setting a break point inside the else condition, and debug project with the service included. If the break point stops the execution, you have located the problem. Another solution might be to set init.advdata.include_appearance to false (This link explains the appearance field).

    Here is a link that explains the advertising packet and how it is constructed:

    https://www.silabs.com/community/wireless/bluetooth/knowledge-base.entry.html/2017/02/10/bluetooth_advertisin-hGsf

    Here is a case similar to yours:

    https://devzone.nordicsemi.com/f/nordic-q-a/12322/device-name-too-short

    Best regards, Simon

Related