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

How to read Value if Service 128bit UUID is completely different from Characteristics 128 bit UUID ?

I am able to pair a peripheral device using advertising 16bit UUID to the Central Device(nRF52840-DK board).

Also I am able to read the Battery level service and Device  information service using bas_c_init() and dis_c_inti(). That' Good.

Now device has Some other Custom Primary services with different 128bit service UUID & 128bit Characteristics UUID. See Image Below 

 

To read such values from Unknown Characteristics which function we need to use ? 

I am using nRF52840-DK with nRF5_SDK_17.0.2 and S140

Parents
  • Hi,

    You need to implement your own client for that custom service. This is a service with a long (128 bit) UUID, so you should refer to one of the custom service client implementations in the SDK and adapt it to the service you want to use. I suspect the LBS service might be a good starting point here, so take a look at components\ble\ble_services\ble_lbs_c\ble_lbs_c.c and components\ble\ble_services\ble_lbs_c\ble_lbs_c.h.

  • Hi Einar,

    I am getting Fatal Error when I am changing the UUID base and  UUID Service like below.

    Also I was not able to define both Service And Characteristics 128bit different as image shown in the primary question.   

  • Hi,

    For the ble_lbs_c.c there are no changes from SDK 15.3 except some uncommented cocde. For the ble_lbs_c.h you have modified the UUID and that is the only change in the lbs service implementation, and that does not cause an error.

    When it comes to your main.c file it uses things that are not defined. Where is BLE_UUID_XYLEM_PRES_SERVICE? Here I clearly need a modified SES project that includes the lbs_c service and a sdk_config.h that sets BLE_LBS_C_ENABLED to 1. Please make sure in the future to provide all your changes so that it can be easily reproduced.

    If I fix the above three problems the project builds. Then I test and get an error. However, I always test with the Debug build, as should you. You select the debug build target like this:

    so the error message looks like this:

    <error> app: ERROR 4 [NRF_ERROR_NO_MEM] at C:\Users\eith\SDK\nRF5_SDK_15.3.0_59ac345\examples\ble_central\ble_app_rscs_c\main.c:771
    PC at: 0x00030287
    <error> app: End of error report

    which is much more informative then what you get with the Release build:

    <error> app: Fatal error

    From the error I see that you get NRF_ERROR_NO_MEM at line 771, so that is the return value from ble_lbs_c_init(). This adds a new vendor specific UUID base so it is reasonable to think that the problem is that you need to increase NRF_SDH_BLE_VS_UUID_COUNT from 0 to 1 in sdk_config.h. Do that, and test again.

    Now we get another error, which is expected as the change increased the SoftDevice memory usage:

    <error> nrf_sdh_ble: sd_ble_enable() returned NRF_ERROR_NO_MEM.
    <error> app: ERROR 4 [NRF_ERROR_NO_MEM] at C:\Users\eith\SDK\nRF5_SDK_15.3.0_59ac345\examples\ble_central\ble_app_rscs_c\main.c:401
    PC at: 0x0002FA13
    <error> app: End of error report

    So you try to set the app RAM start address a bit higher and reduce the size accordingly, by the approach described in this tutorial:

    After changing the log configuration defines as described under step 8. in the tutorial above, you get this log output:

    <debug> nrf_sdh: State request: 0x00000000
    <debug> nrf_sdh: Notify observer 0x0003B3F8 => ready
    <debug> nrf_sdh: State change: 0x00000000
    <debug> nrf_sdh: State change: 0x00000001
    <warning> nrf_sdh_ble: Insufficient RAM allocated for the SoftDevice.
    <warning> nrf_sdh_ble: Change the RAM start location from 0x20001CD0 to 0x20001CE0.
    <warning> nrf_sdh_ble: Maximum RAM size for application is 0x3E320.
    <error> nrf_sdh_ble: sd_ble_enable() returned NRF_ERROR_NO_MEM.
    401
    PC at: 0x0002FA8F

    This tells us the correct RAM start address and size for the current SoftDevice configuration (after we adjusted NRF_SDH_BLE_VS_UUID_COUNT). Update it like this:

    And now it all works.

    Please note that these are all generic concepts with the nRF5 SDK and SoftDevice, so it makes sense to play a bit with it to understand how the SDK and SoftDevice works. Spending some time on these basics will save you time in the end.

  • Hi Einar,

    You are right about the debug build instead of release build. Appreciate your help and guidance.

    I was able to reproduce all error above you mentioned. 

    And after correcting all of them it was connecting to the Custom 128bit UUID service and showing DB_DISCOVERY_COMPLETE.

    But  my end goal is to read value of Characteristic which has different 128 bit UUID Base than service 128 bit UUID.

    how we can add different 128bit characteristic UUID. as in ble_lbs_c.h allow us to add only 16 bit characteristic UUID only.

  • Hi, 

    Vipul2988 said:
    how we can add different 128bit characteristic UUID. as in ble_lbs_c.h allow us to add only 16 bit characteristic UUID only.

    In fact, the LBS is also a 128 bit characteristic, so you should do exactly as demonstrated there. The way it works is that you create a base UUID (referred to as uuid_type). So when you make a new base UUID, that is referred to by the type. When you then make a new characteristic and refer to the type of the base UUID, you only provide the extra 2 bytes / 16 bit, that are combined with the base UUID of the type to make the 128 bit UUID.

  • HI Einar,

    When I am trying to connect only service with 128bit UUID it is found and connected.

    But when I am adding another 128bit UUID for Characteristics in ble_lbs_c_init() function, it is not giving any error but also not connecting to service and characteristics.

    Please find attached zip file and open ble_central example. 

     

    nRF5_SDK_15.3.0.zip

  • Hi,

    I did not understand exactly what you meant, can you elaborate?

    In any case I see something which does not look correct. You have two calls to sd_ble_uuid_vs_add() where you try to add two bases. But the ID is output to the same variable (&p_ble_lbs_c->uuid_type), so the first is overwritten. And then cannot be used. Please double check the code so that you avoid suck mistakes.

    (Another detail I see is that you ignore the return value of the fist call to sd_ble_uuid_vs_add(). While it does not fail in this case, ignoring return value is never a good idea and typically prevents you from discovering issues early).

Reply
  • Hi,

    I did not understand exactly what you meant, can you elaborate?

    In any case I see something which does not look correct. You have two calls to sd_ble_uuid_vs_add() where you try to add two bases. But the ID is output to the same variable (&p_ble_lbs_c->uuid_type), so the first is overwritten. And then cannot be used. Please double check the code so that you avoid suck mistakes.

    (Another detail I see is that you ignore the return value of the fist call to sd_ble_uuid_vs_add(). While it does not fail in this case, ignoring return value is never a good idea and typically prevents you from discovering issues early).

Children
  • HI Einar,

    I means to say whey I am serching services with only 128bit base, it is working good.

    but as and when I tried to add characteristics with diffferent128 bit, I am not getting any output and Error as well.   

    Can you suggest how my ble_lbs_c_init() function should look like ?

    uint32_t ble_lbs_c_init(ble_lbs_c_t * p_ble_lbs_c, ble_lbs_c_init_t * p_ble_lbs_c_init)
    {
        uint32_t      err_code;
    
        ble_uuid_t    lbs_uuid;
        ble_uuid128_t lbs_base_uuid = {PRESS_SER_UUID_BASE};
        ble_uuid_t    lbs_char_uuid;
        ble_uuid128_t lbs_char_base_uuid = {PRESS_CHAR_UUID_BASE};
    
        VERIFY_PARAM_NOT_NULL(p_ble_lbs_c);
        VERIFY_PARAM_NOT_NULL(p_ble_lbs_c_init);
        VERIFY_PARAM_NOT_NULL(p_ble_lbs_c_init->evt_handler);
    
        p_ble_lbs_c->peer_lbs_db.button_cccd_handle = BLE_GATT_HANDLE_INVALID;
        p_ble_lbs_c->peer_lbs_db.button_handle      = BLE_GATT_HANDLE_INVALID;
        p_ble_lbs_c->peer_lbs_db.led_handle         = BLE_GATT_HANDLE_INVALID;
        p_ble_lbs_c->conn_handle                    = BLE_CONN_HANDLE_INVALID;
        p_ble_lbs_c->evt_handler                    = p_ble_lbs_c_init->evt_handler;
    
        err_code = sd_ble_uuid_vs_add(&lbs_base_uuid, &p_ble_lbs_c->uuid_type);
        err_code = sd_ble_uuid_vs_add(&lbs_char_base_uuid, &p_ble_lbs_c->uuid_type);
    
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
        VERIFY_SUCCESS(err_code);
    
       lbs_uuid.type = p_ble_lbs_c->uuid_type;
       lbs_uuid.uuid = LBS_UUID_SERVICE;
    
        //lbs_uuid.type = p_ble_lbs_c->uuid_type;
        //lbs_uuid.uuid = PRESS_SER_UUID;
    
        lbs_char_uuid.type = p_ble_lbs_c->uuid_type;
        lbs_char_uuid.uuid = PRESS_CHAR_UUID;
    
        return ble_db_discovery_evt_register(&lbs_uuid);
        return ble_db_discovery_evt_register(&lbs_char_uuid);
    }

  • It looks like it should be something like this (note the comment that you must also update ble_lbs_c_t in this case):

    uint32_t ble_lbs_c_init(ble_lbs_c_t * p_ble_lbs_c, ble_lbs_c_init_t * p_ble_lbs_c_init)
    {
        uint32_t      err_code;
    
        ble_uuid_t    lbs_uuid;
        ble_uuid128_t lbs_base_uuid = {PRESS_SER_UUID_BASE};
        ble_uuid_t    lbs_char_uuid;
        ble_uuid128_t lbs_char_base_uuid = {PRESS_CHAR_UUID_BASE};
    
        VERIFY_PARAM_NOT_NULL(p_ble_lbs_c);
        VERIFY_PARAM_NOT_NULL(p_ble_lbs_c_init);
        VERIFY_PARAM_NOT_NULL(p_ble_lbs_c_init->evt_handler);
    
        p_ble_lbs_c->peer_lbs_db.button_cccd_handle = BLE_GATT_HANDLE_INVALID;
        p_ble_lbs_c->peer_lbs_db.button_handle      = BLE_GATT_HANDLE_INVALID;
        p_ble_lbs_c->peer_lbs_db.led_handle         = BLE_GATT_HANDLE_INVALID;
        p_ble_lbs_c->conn_handle                    = BLE_CONN_HANDLE_INVALID;
        p_ble_lbs_c->evt_handler                    = p_ble_lbs_c_init->evt_handler;
    
        err_code = sd_ble_uuid_vs_add(&lbs_base_uuid, &p_ble_lbs_c->uuid_type);
    
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
        VERIFY_SUCCESS(err_code);
    
        err_code = sd_ble_uuid_vs_add(&lbs_char_base_uuid, &p_ble_lbs_c->uuid_type_char); // You need to add uuid_type_char in the ble_lbs_c_t so that it exists
    
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
        VERIFY_SUCCESS(err_code);
    
        lbs_uuid.type = p_ble_lbs_c->uuid_type;
        lbs_uuid.uuid = LBS_UUID_SERVICE;
    
        lbs_char_uuid.type = p_ble_lbs_c->uuid_type_char;
        lbs_char_uuid.uuid = PRESS_CHAR_UUID;
    
        return ble_db_discovery_evt_register(&lbs_uuid);
        return ble_db_discovery_evt_register(&lbs_char_uuid);
    }

Related