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

128-bit Characteristic UUID not based on Service UUID

Hi Nordic Team,

What I want to achieve is to add a service with a custom 128-bit UUID that has about 4 characteristics with a completely different 128-bit UUIDs that are NOT based on the service UUID ?

Is that possible ? If so, how can I implement that? I'm using SDK12.2.0 on nRF51822.

Many thanks in advance.

Kind Regards, Ayman.

Parents
  • Of course you can do it - you can use any UUID for a service or a characteristic and they don't have to be related in any way at all, they can be totally random.

    And how? Just come up with your 5 UUIDs, register the service under one of them and the characteristics under the other ones, every registration method takes a UUID, just supply them.

  • Hello,

    I have exactly same problem (or is this challenge). If you have some code example how to do this I will be very happy :)

  • It is fairly easy to do. You just need to add a new 128-bit UUID to the BLE stack table and then add a service/characteristic with that UUID.

    // To add a service
    // Declare 16-bit service and 128-bit base UUIDs and add them to BLE stack table
    ret_code_t	err_code;
    ble_uuid_t	service_uuid;
    
    BLE_UUID_BLE_ASSIGN(service_uuid, your_16_bit_uuid);
    
    ble_uuid128_t base_uuid = YOUR_CUSTOM_128_BIT_UUID;
    
    // Add the UUID to the BLE stack
    err_code = sd_ble_uuid_vs_add(&base_uuid, &service_uuid.type);
    APP_ERROR_CHECK(err_code);
    
    // Add your service
    err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
                                        &service_uuid,
                                        &service_handle);
    APP_ERROR_CHECK(err_code);
    

    // To add a characteristic
    // Add a custom characteristic UUID
    ret_code_t err_code;
    ble_uuid_t char_uuid;
    BLE_UUID_BLE_ASSIGN(char_uuid, your_16_bit_uuid);
    
    ble_uuid128_t base_uuid = YOUR_CUSTOM_128_BIT_UUID;
    
    // Add the UUID to the BLE stack
    err_code = sd_ble_uuid_vs_add(&base_uuid, &char_uuid.type);
    APP_ERROR_CHECK(err_code);
    
    [Initialize all attribute metadata and stuff]
    [Copy from any example]
    
    // Add our new characteristic to the service
    err_code = sd_ble_gatts_characteristic_add(service_handle,
                                               &char_md,
                                               &attr_char_value,
                                               &custom_char_handles);
    APP_ERROR_CHECK(err_code);

  • I am having exactly this problem; my code is essentially the same as above.  I don't know what I am doing wrong.

    What is happening is that the UUID of the data characteristic is the same as the UUID of the service.

    Here is what I am trying to achieve:

    Instead, I'm getting this:

    What am I doing wrong?

    Here is an excerpt of my code:

    #define BLE_UUID_SCS_SERVICE 0x0e04	/**< UUID of the SCS service */
    #define BLE_UUID_SCS_DATA    0xb607	/**< UUID of the data characteristic */
    
    typedef struct ble_scs_s ble_scs_t;
    
    /**@brief   Nordic UART Service structure.
     *
     * @details This structure contains status information related to the service.
     */
    struct ble_scs_s
    {
        uint8_t service_uuid_type;				/**< UUID type for SCS service base UUID */
        uint8_t data_uuid_type;					/**< UUID type for SCS data base UUID. */
        uint16_t service_handle;				/**< Handle for SCS service (as provided by the SoftDevice). */
        ble_gatts_char_handles_t service_handles;	/**< service characteristic handles */
        ble_gatts_char_handles_t data_handles;	    /**< data characteristic handles */
        uint16_t conn_handle;					/**< Handle of current connection */
        bool is_notification_enabled;			/**< Variable to indicate if the peer has enabled notification of the RX characteristic.*/
        ble_scs_data_handler_t data_handler;	/**< Event handler to be called for handling received data. */
    };
    
    static ble_uuid128_t const m_scs_base_uuid128 =
    {
    	{
    	   	0x17, 0x76, 0x6f, 0xcf, 0x10, 0x88, 0xbc, 0xb5,
    	   	0x6d, 0x4a, 0x61, 0xc2, 0x04, 0x0e, 0xbf, 0xe6
       	}
    };
    
    static ble_uuid128_t const m_scs_data_txchar_uuid128 =
    {
    	{
    	   	0x0d, 0xee, 0x3e, 0x5f, 0x8d, 0x2e, 0xfd, 0x97,
    	   	0x82, 0x4f, 0xe8, 0xf5, 0x07, 0xb6, 0x25, 0xc7
       	}
    };
    
    
    /**@brief Add data characteristic.
     *
     * @param[in] p_scs       SCS Service structure.
     * @param[in] p_scs_init  Information needed to initialize the service.
     *
     * @return NRF_SUCCESS on success, otherwise an error code.
     */
    static uint32_t scs_data_char_add(ble_scs_t *p_scs, ble_scs_init_t const *p_scs_init)
    {
        /**@snippet [Adding proprietary characteristic to the SoftDevice] */
        ble_gatts_char_md_t char_md;
        ble_gatts_attr_md_t cccd_md;
        ble_gatts_attr_t attr_char_value;
        ble_uuid_t char_uuid;
        ble_gatts_attr_md_t attr_md;
    	uint8_t initial_data[20];
    
    	BLE_UUID_BLE_ASSIGN(char_uuid, BLE_UUID_SCS_DATA);
        VERIFY_SUCCESS(sd_ble_uuid_vs_add(&m_scs_data_txchar_uuid128, &p_scs->data_uuid_type));
    
        memset(&cccd_md, 0, sizeof(cccd_md));
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
        cccd_md.vloc = BLE_GATTS_VLOC_STACK;
    
        memset(&char_md, 0, sizeof(char_md));
        char_md.char_props.write  = 1;
        char_md.char_props.indicate = 1;
        char_md.p_char_pf = NULL;
        char_md.p_user_desc_md = NULL;
        char_md.p_cccd_md = &cccd_md;
        char_md.p_sccd_md = NULL;
    
        memset(&attr_md, 0, sizeof(attr_md));
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
        attr_md.vloc = BLE_GATTS_VLOC_STACK;
        attr_md.rd_auth = 0;
        attr_md.wr_auth = 0;
        attr_md.vlen = 1;
    
        memset(&attr_char_value, 0, sizeof(attr_char_value));
    	memset(initial_data, 0, sizeof(initial_data));
        attr_char_value.p_uuid = &char_uuid;
        attr_char_value.p_attr_md = &attr_md;
        attr_char_value.init_len = sizeof(initial_data);
        attr_char_value.init_offs = 0;
        attr_char_value.max_len = sizeof(initial_data);
    	attr_char_value.p_value = initial_data;
    
        return sd_ble_gatts_characteristic_add(p_scs->service_handle,
                                               &char_md,
                                               &attr_char_value,
                                               &p_scs->data_handles);
    }
    
    
    uint32_t ble_scs_init(ble_scs_t *p_scs, ble_scs_init_t const *p_scs_init)
    {
        ble_uuid_t ble_uuid;
    
        VERIFY_PARAM_NOT_NULL(p_scs);
        VERIFY_PARAM_NOT_NULL(p_scs_init);
    
        // Initialize the service structure.
        p_scs->conn_handle = BLE_CONN_HANDLE_INVALID;
        p_scs->data_handler = p_scs_init->data_handler;
        p_scs->is_notification_enabled = false;
    
        /**@snippet [Adding proprietary Service to the SoftDevice] */
        // Add a custom base UUID.
    	BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_SCS_SERVICE);
        VERIFY_SUCCESS(sd_ble_uuid_vs_add(&m_scs_base_uuid128, &p_scs->service_uuid_type));
    
        // Add the service.
        VERIFY_SUCCESS(sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
    											&ble_uuid,
    										   	&p_scs->service_handle));
    
        // Add the data characteristic.
        VERIFY_SUCCESS(scs_data_char_add(p_scs, p_scs_init));
    
        return NRF_SUCCESS;
    }
    
    

    Thanks for any help you can give.

    --ken

  • Your problem is that you're passing different UUIDs to sd_ble_uuid_vs_add().

    Try changing 

    VERIFY_SUCCESS(sd_ble_uuid_vs_add(&m_scs_data_txchar_uuid128, &p_scs->data_uuid_type));

    to

    VERIFY_SUCCESS(sd_ble_uuid_vs_add(&m_scs_data_txchar_uuid128, &char_uuid.type));
    p_scs->data_uuid_type = char_uuid.type;

  • Andy,

    You are right, that was a bug (a vestige of previous attempts to solve this).  Thanks.

    Unfortunately, that doesn't fix the problem though.

    I am still getting the same UUID for the data characteristic as the service.

    --ken

Reply Children
Related