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

Understanding Advertisement of multiple 128 bit custom UUID

Hi Everyone, 

I am using nRF52832 with SDK v14.2 and SD v5.0.0 on a custom chip. 

I want to advertise 2 custom UUID (DFU and NUS) and i wanted to know the correct way to do it. I understand that advertisement packet is 31 bytes and so is scan response packet. So, having one custom UUID on advertisement packet and the other on scan response packet makes sense since custom UUID is 16 bytes long. 

I did the same way and with nRF connect app i can see both services but when i sniffed for the packets being transmitted, i saw only one UUID there. 

I have attached the code here for a look. I have also attached sniffer trace for advertisement and scan response packet for your reference. Please advise why is it not advertising NUS UUID and still be able to detect by the nRF connect app when connected? 

.AdvertisingPacketScanResponsePacket

 

ret_code_t advertising_init(void)
{
    ret_code_t u32ErrCode = NRF_SUCCESS;
    ble_uuid_t astAdvUuids[] =                                          /**< Universally unique service identifier. */
    {
      {BLE_DFU_UUID, DFU_SERVICE_UUID_TYPE},
      {BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}
    };
    ble_advertising_init_t stInit;

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

    stInit.advdata.name_type          = BLE_ADVDATA_FULL_NAME;
    stInit.advdata.include_appearance = false;
    stInit.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;

    stInit.advdata.uuids_complete.uuid_cnt = 1;
    stInit.advdata.uuids_complete.p_uuids = &astAdvUuids[0];

    stInit.srdata.uuids_more_available.uuid_cnt = 1;
    stInit.srdata.uuids_more_available.p_uuids  = &astAdvUuids[1];

    stInit.config.ble_adv_fast_enabled  = true;
    stInit.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
    stInit.config.ble_adv_fast_timeout  = APP_ADV_TIMEOUT_IN_SECONDS;

    stInit.evt_handler = on_adv_evt;

    u32ErrCode = ble_advertising_init(&m_advertising, &stInit);
    APP_ERROR_CHECK(u32ErrCode);

    ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);

    //nfc ble pair library init
    nrf_ble_pairing_init(&m_advertising);
    return u32ErrCode;
}

Thank you!

Parents Reply Children
  • Hi,

    Ah, you are right. I did not spot that. I cannot say why this is without seeing a bit more of your code, though. How have you defined BLE_DFU_UUID and DFU_SERVICE_UUID_TYPE?

  • I have defined them like below:

    #define DFU_SERVICE_UUID_TYPE           BLE_UUID_TYPE_VENDOR_BEGIN                  /**< UUID type for the Nordic DFU Service (vendor specific). */
    #define BLE_DFU_UUID                    0xFE59                                      /**< The 16-bit UUID of the Secure DFU Service. */

  • I see. Have you added the vendor-specific base UUID with sd_ble_uuid_vs_add(), and was that used with the first call (if you made more calls to it)? If you add more, you should use the type populated in the second parameter int he call to sd_ble_uuid_vs_add(), so that you know it is correct, regardless of the order things happen in.

  • I am calling sd_ble_uuid_vs_add() at two places, one where i am initializing the NUS service and the other for buttonless DFU service init. I do not understand the part where you say to use the type populated in the second parameter. Could you please give me an example on how to? 

    Attaching both ble_nus and dfu_buttonless service init snippet here for your reference. 

    uint32_t ble_nus_init(ble_nus_t * p_nus, ble_nus_init_t const * p_nus_init)
    {
        uint32_t      err_code;
        ble_uuid_t    ble_uuid;
        ble_uuid128_t nus_base_uuid = NUS_BASE_UUID;
    
        VERIFY_PARAM_NOT_NULL(p_nus);
        VERIFY_PARAM_NOT_NULL(p_nus_init);
    
        // Initialize the service structure.
        p_nus->conn_handle             = BLE_CONN_HANDLE_INVALID;
        p_nus->data_handler            = p_nus_init->data_handler;
        p_nus->is_notification_enabled = false;
    
        /**@snippet [Adding proprietary Service to the SoftDevice] */
        // Add a custom base UUID.
        err_code = sd_ble_uuid_vs_add(&nus_base_uuid, &p_nus->uuid_type);
        VERIFY_SUCCESS(err_code);
    
        ble_uuid.type = p_nus->uuid_type;
        ble_uuid.uuid = BLE_UUID_NUS_SERVICE;
    
        // Add the service.
        err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
                                            &ble_uuid,
                                            &p_nus->service_handle);
        /**@snippet [Adding proprietary Service to the SoftDevice] */
        VERIFY_SUCCESS(err_code);
    
        // Add the RX Characteristic.
        err_code = rx_char_add(p_nus, p_nus_init);
        VERIFY_SUCCESS(err_code);
    
        // Add the TX Characteristic.
        err_code = tx_char_add(p_nus, p_nus_init);
        VERIFY_SUCCESS(err_code);
    
        return NRF_SUCCESS;
    }

    uint32_t ble_dfu_buttonless_init(const ble_dfu_buttonless_init_t * p_dfu_init)
    {
        uint32_t        err_code;
        ble_uuid_t      service_uuid;
        ble_uuid128_t   nordic_base_uuid = BLE_NORDIC_VENDOR_BASE_UUID;
    
        VERIFY_PARAM_NOT_NULL(p_dfu_init);
    
        // Initialize the service structure.
        m_dfu.conn_handle                  = BLE_CONN_HANDLE_INVALID;
        m_dfu.evt_handler                  = p_dfu_init->evt_handler;
        m_dfu.is_waiting_for_reset         = false;
        m_dfu.is_ctrlpt_indication_enabled = false;
    
        err_code = ble_dfu_buttonless_backend_init(&m_dfu);
        VERIFY_SUCCESS(err_code);
        
        BLE_UUID_BLE_ASSIGN(service_uuid, BLE_DFU_SERVICE_UUID);
    
        // Add the DFU service declaration.
        err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
                                            &service_uuid,
                                            &(m_dfu.service_handle));
    
        VERIFY_SUCCESS(err_code);
    
        // Add vendor specific base UUID to use with the Buttonless DFU characteristic.
        err_code = sd_ble_uuid_vs_add(&nordic_base_uuid, &m_dfu.uuid_type);
        VERIFY_SUCCESS(err_code);
    
        // Add the Buttonless DFU Characteristic (with bonds/without bonds).
        err_code = ble_dfu_buttonless_char_add(&m_dfu);
        VERIFY_SUCCESS(err_code);
    
        return NRF_SUCCESS;
    }

  • Hi,

    I was not clear enough, but the point is that the UUID type depends on the order you call sd_ble_uuid_vs_add(). Therefore, the second parameter is a pointer to the UUID type as an output, and this is the type you should choose. Therefore, the first call to sd_ble_uuid_vs_add() will give you ID 2 (BLE_UUID_TYPE_VENDOR_BEGIN) and the second call will give you ID 3.

    This means that using a hardcoded value is problematic when adding more than one base UUID. You could always make sure to get it right, but then things will be messed up if you cange the order of which BLE service is initialized first. The alternative is to use the type provided when you call sd_ble_uuid_vs_add(). You can obtain that from m_nus (or whatever you named your NUS instance crated with BLE_NUS_DEF), like this: m_nus.uuid_type. But note that it will not be valid until after you have initialized the NUS service.

Related