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

Image Transfer Demo: ble_srv_is_notification_enabled flag not set

Hello.

I connected the Image transfer service (running on a nrf52840) to another nrf52840 running a modified BLE_NUS_C service.

However, a BLE packet won't be send out, because the function ble_its_img_info_send(&m_its, &image_info) (lined below) will be aborted because of the check: 

if ((!p_its->is_info_char_notification_enabled))
    {
        printf("Failed with NRF_ERROR_INVALID_STATE, because \"is_info_char_notification_enabled\"==false\n");
        return NRF_ERROR_INVALID_STATE;
    }

uint32_t ble_its_img_info_send(ble_its_t * p_its, ble_its_img_info_t * img_info)
{
    uint8_t data_buf[1 + sizeof(ble_its_img_info_t)];
    ble_gatts_hvx_params_t hvx_params;

    VERIFY_PARAM_NOT_NULL(p_its);

    if ((p_its->conn_handle == BLE_CONN_HANDLE_INVALID))
    {
        printf("Failed: BLE_CONN_HANDLE_INVALIDn");
        return NRF_ERROR_INVALID_STATE;
    }
    if ((!p_its->is_info_char_notification_enabled))
    {
        printf("Failed with NRF_ERROR_INVALID_STATE, because \"is_info_char_notification_enabled\"==false\n");
        return NRF_ERROR_INVALID_STATE;
    }


    uint16_t length = 1 + sizeof(ble_its_img_info_t);

    data_buf[0] = 1;
    memcpy(&data_buf[1], img_info, sizeof(ble_its_img_info_t));

    memset(&hvx_params, 0, sizeof(hvx_params));
    
    hvx_params.handle = p_its->img_info_handles.value_handle;
    hvx_params.p_data = data_buf;
    hvx_params.p_len  = &length;
    hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;

    return sd_ble_gatts_hvx(p_its->conn_handle, &hvx_params);
}

When searching for the is_info_char_notification_enabled variable/flag, it is controlled in the on_write() function triggered by the BLE_GATTS_EVT_WRITE event.

/**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the S110 SoftDevice.
 *
 * @param[in] p_its     Nordic UART Service structure.
 * @param[in] p_ble_evt Pointer to the event received from BLE stack.
 */
static void on_write(ble_its_t * p_its, ble_evt_t const * p_ble_evt)
{
    ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;

    if (
        (p_evt_write->handle == p_its->tx_handles.cccd_handle)
        &&
        (p_evt_write->len == 2)
       )
    {
        if (ble_srv_is_notification_enabled(p_evt_write->data))
        {
            p_its->is_notification_enabled = true;
        }
        else
        {
            p_its->is_notification_enabled = false;
        }
    }
    else if (
        (p_evt_write->handle == p_its->img_info_handles.cccd_handle)
        &&
        (p_evt_write->len == 2)
       )
    {
        if (ble_srv_is_notification_enabled(p_evt_write->data))
        {
            printf("CHAR NOTIFICATION ENABLED\n");
            p_its->is_info_char_notification_enabled = true;                    //HERE
        }
        else
        {
            printf("CHAR NOTIFICATION DISABLED\n");
            p_its->is_info_char_notification_enabled = false;
        }
    }
    else if (
             (p_evt_write->handle == p_its->rx_handles.value_handle)
             &&
             (p_its->data_handler != NULL)
            )
    {
        p_its->data_handler(p_its, p_evt_write->data, p_evt_write->len);
    }
    else
    {
        // Do Nothing. This event is not relevant for this service.
    }
}

What does this variable/flag mean?
What is missing that it won't be set when connecting to my BLE_NUS_C service, however, it is working when connecting to the Image_Transfer_Demo Andoid APP?
How can I solve that?


Thnaks!

  • Hello,

    The image transfer demo has something called a service, with the image transfer demo (its) that it uses to send data through notifications. However, a peripheral can't send notifications unless the central has enabled notifications on that service. 

    In the ble_app_uart_c example, which uses the ble_nus_c service is actually a service that handles the ble_nus service which is used in the ble_app_uart example. If you look in the main.c file and ble_nus_c.c file in the ble_app_uart_c example, you can see how it enables notifications on the ble_nus TX characteristic. You have to adapt this to enable notifications on the hts characteristic instead.

  • Ahh ok, thanks.
    I wasn't really into BLE services yet....


    So that means, currently I have the ble_nus service on my BLE central board
    and the ble_its service on my BLE peripheral board.
    Do I have to implement the ble_its service on my central board instead of the ble_nus service? Or is it possible that the TX_characteristic of the ble_nus service receives the notifications of the ble_its service? And thus, I need to configure that the ble_its notifies the ble_nus TX_characteristic?

    What will be the more useful option?

  • No. The ble_its service and ble_nus service has different IDs (called UUID), so they do not work together. 

    I don't know what you are trying to do, but if you want to transfer data from one device (peripheral) to another (central), I suggest that you look into the ble_app_uart and ble_app_uart_c examples. 

    If you want to transfer data through the ble_its service, you need to create the ble_its_c (c for central). It will probably look a lot like the ble_nus_c, but with a different UUID for the service and the characteristics.

    The ble_nus service has two characteristics, while I bet the ble_its service only has one.

    If you have 2 DKs, I suggest that you program one with the ble_its example, and use the other to connect to it with nRF Connect for Desktop. This way, you can see what services and characteristics the device has. If the UUID is not shown automatically (not a familiar service) hovering the mouse over the name of the service will tell you the UUID.

    Best regards,

    Edvin

  • OK, thanks.

    Yes, I have two nrf52840.
    One is running the Image tragsfer demo (slightly modified).
    The other one is running the BLE NUS central example.

    I established a connection between both boards already by adapting the target BASE_UUID on the central board. 
    So, now I will try to modify the ble_nus_c service in a way that it connects to the ble_its service on the peripheral board. 

    Finally, I want to transfer the image stream from the image_transfer_demo board to the other board, yes.

Related