Writing some value into a characteristic of specific UUID of a peripheral device by using a central device

Hey Nordic,

My project is based on "ble_app_uart" and "ble_app_uart_c" examples. I modified them to some extent. You can download them from here.

Normally, I can write some values into any characteristic of my custom service as shown above in nRF Connect. But I want to do the same thing automatically with my central device to the peripheral one. I want the central to discover this custom service, and write some predefined value into a characteristic specified by a UUID.

I tried to log the discovered characteristics in db_disc_handler() function but it seems that it can only discover or log the characteristics of the NUS service to J-Link RTT Viewer as shown below:

00> <info> app_timer: RTC: initialized.
00> 
00> <info> app: BLE UART central example started.
00> 
00> <info> app: Connecting to target 7F0F251956F2
00> 
00> <info> app: ATT MTU exchange completed.
00> 
00> <info> app: Ble NUS max data length set to 0xF4(244)
00> 
00> <info> app: Discovery complete.
00> 
00> <info> app: Connected to device with Nordic UART Service.
00> 
00> <info> app: srv_uuid.uuid: 0x1
00> 
00> <info> app: srv_uuid.type: 2
00> 
00> <info> app: char_count: 2
00> 
00> <info> app: chars[0].char.uuid.uuid: 0x2
00> 
00> <info> app: chars[1].char.uuid.uuid: 0x3

So, how can I discover my custom service and write some value into a specific-UUID characteristic of the peripheral device using my central device?

Thanks,

Omer

Parents
  • Hello,

    I was not able to download your project through your link.

    Can you please upload it here (drag and drop into the editor when you are writing your reply). 

    If it only sees the NUS service, I guess you have told it to look for that specifically, using e.g.:

    	err = bt_gatt_dm_start(conn,
    			       BT_UUID_NUS_SERVICE,
    			       &discovery_cb,
    			       &nus_client);

    Take a look at the declaration (the header file that declares bt_gatt_dm_start() in gatt_dm.h. You either need to call bt_gatt_dm_start() with svc_uuid = NULL, or you need to call it another time with the UUID that you are looking for.

    Best regards,

    Edvin

  • gatt_dm

    I uploaded the project folders into this reply.

    Also, I could find neither bt_gatt_dm_start() function nor gatt_dm.h file in my SDK (v17.1.0).

    Actually, there might be a error related to NRF_LOG_INFO() function. The reason is that when I add an if statement before the NRF_LOG_INFO() functions so that it passes the first discovered service without logging as below:

    uint8_t discover_pass = 1;
    
    /**@brief Function for handling database discovery events.
     *
     * @details This function is a callback function to handle events from the database discovery module.
     *          Depending on the UUIDs that are discovered, this function forwards the events
     *          to their respective services.
     *
     * @param[in] p_event  Pointer to the database discovery event.
     */
    static void db_disc_handler(ble_db_discovery_evt_t * p_evt)
    {
        uint8_t index = 0;
        ble_nus_c_on_db_disc_evt(&m_ble_nus_c, p_evt);
    
        //NRF_LOG_INFO("*");
        //NRF_LOG_FLUSH();
        if(discover_pass > 0)
        {
            discover_pass--;
            return;
        }
    
        NRF_LOG_INFO("srv_uuid.uuid: 0x%x", p_evt->params.discovered_db.srv_uuid.uuid);
        //NRF_LOG_FLUSH();
    
        NRF_LOG_INFO("srv_uuid.type: %d", p_evt->params.discovered_db.srv_uuid.type);
        //NRF_LOG_FLUSH();
    
        NRF_LOG_INFO("char_count: %d", p_evt->params.discovered_db.char_count);
        //NRF_LOG_FLUSH();
    
        for(index = 0; index < p_evt->params.discovered_db.char_count; index++)
        {
            NRF_LOG_INFO("chars[%d].char.uuid.uuid: 0x%x", index, p_evt->params.discovered_db.charateristics[index].characteristic.uuid.uuid);
            //NRF_LOG_FLUSH();
        }
    
        //NRF_LOG_INFO("*");
        //NRF_LOG_FLUSH();
    }

    It prints out a random-like UUID of 0 type and 0 count, instead of my custom characteristics, in J-Link RTT Viewer at the central side:

    00> <info> app_timer: RTC: initialized.
    00> 
    00> <info> app: BLE UART central example started.
    00> 
    00> <info> app: Connecting to target 7F0F251956F2
    00> 
    00> <info> app: ATT MTU exchange completed.
    00> 
    00> <info> app: Ble NUS max data length set to 0x20(32)
    00> 
    00> <info> app: Discovery complete.
    00> 
    00> <info> app: Connected to device with Nordic UART Service.
    00> 
    00> <info> app: srv_uuid.uuid: 0x2874
    00> 
    00> <info> app: srv_uuid.type: 0
    00> 
    00> <info> app: char_count: 0

    Thanks in advance,

    Omer

  • Hello Omer,

    Sorry, my last snippet was from another SDK. I see now that you are using the nRF5 SDK.

    The mechanism, however, is the same. 

    Ömer said:
    I uploaded the project folders into this reply.

    I believe it wasn't uploaded.

    I see from your sniffer that you have commented out a lot of calls to NRF_LOG_FLUSH(). Please be aware that you must not (!) use NRF_LOG_FLUSH() anywhere but in your main loop, as that may cause undefined behavior. If you struggle with logs being lost, you can set NRF_LOG_DEFERRED to 0 in sdk_config.h, which will process the log on the fly, or you can increase the log buffer in sdk_config.h.

    So regarding the discovery process:

    Please see this description from ble_db_discovery.h:

    ble_gatt_db_srv_t   discovered_db;  /**< Structure containing the information about the GATT Database at the server. This will be filled when the event type is @ref BLE_DB_DISCOVERY_COMPLETE. The UUID field of this will be filled when the event type is @ref BLE_DB_DISCOVERY_SRV_NOT_FOUND. */
    The issue is that you don't check what type of event it is. So if the event type is BLE_DB_DISCOVERY_AVAILABLE, then none of the parameters that you are printing will hold what you think it does (just random RAM data). So you need to check the event type before you start reading out the event specific parameters.

    In addition, since you have at least 3 services (from your mobile screenshot), probably 4 services, you probably want to remove the part:

        if(discover_pass > 0)
        {
            discover_pass--;
            return;
        }

    because or else it will only run the first time, as long as discovery_pass is set to 1. And this is probably not even a BLE_DB_DISCOVERY_COMPLETE event.

    I suggest you look at how the ble_nus_c_on_db_disc_evt() is implemented, and try to do something similar with your custom service.

    Best regards,

    Edvin

  • Hi Edvin,

    I don't understand why the files could not be uploaded. There seems no problem on my side. But anyway I will attach them again.

    Based on your suggestion, I deleted all NRF_LOG_FLUSH() calls. I had used them since I had difficulty with using NRF_LOG_INFO(), that is, I can always get a limited amount of logs in J-Link RTT Viewer when I use more logs. I was aware of the dangers but tried to solve the log issue by using it. Unfortunately, it had not worked for me. After setting NRF_LOG_DEFERRED to 0 and NRF_LOG_BUFSIZE from 1024 to 2048, it seems to work better now.

    As you suggest I printed out the event types, this is the log window from J-Link RTT Viewer:

    00> <info> app_timer: RTC: initialized.
    00> 
    00> <info> app: BLE UART central example started.
    00> 
    00> <info> app: Discovery complete.
    00> 
    00> <info> app: ************************
    00> 
    00> <info> app: p_evt->evt_type: 0x0
    00> 
    00> <info> app: srv_uuid.uuid: 0x1
    00> 
    00> <info> app: srv_uuid.type: 2
    00> 
    00> <info> app: char_count: 2
    00> 
    00> <info> app: chars[0].char.uuid.uuid: 0x2
    00> 
    00> <info> app: chars[1].char.uuid.uuid: 0x3
    00> 
    00> <info> app: ************************
    00> 
    00> <info> app: p_evt->evt_type: 0x3
    00> 
    00> <info> app: srv_uuid.uuid: 0x2870
    00> 
    00> <info> app: srv_uuid.type: 0
    00> 
    00> <info> app: char_count: 0

    Actually, this part

        if(discover_pass > 0)
        {
            discover_pass--;
            return;
        }

    was to bypass logging of NUS, in case of maybe only the first discovered service is loggable. But I deleted it, as I said before logging seems to be working fine now. I can additionally see a service of event type 0x3 as above.

    I examined ble_nus_c_on_db_disc_evt(), and now it seems to me that it has nothing to do with service discovery. Since I can print them using p_evt struct, and it is not edited in this function. It has something to do with only NUS. It doesn't affect my discovery problem whether I delete it.

    ble_app_uart_char_lorem8182022.zip

    ble_app_uart_c_copy.zip

    Edit 1: Actually, what I want to do is exactly this:

     RE: scan filters for custom uuid is not matching 

    But somehow, custom uuid filter doesn't work, it connects using UUID of NUS.

    Thanks,

    Omer

  • What do I do to reproduce your issue? I downloaded both projects, unzipped them in an unmodified SDK17.1.0, and programmed two pca10056 boards. They connect, but the central doesn't say anything in the log after connecting, other than 

    You need to register the UUID that you are looking for the same way that it is done inside ble_nus_c_init() -> ble_db_discovery_evt_register() -> 

    Best regards,

    Edvin

Reply
  • What do I do to reproduce your issue? I downloaded both projects, unzipped them in an unmodified SDK17.1.0, and programmed two pca10056 boards. They connect, but the central doesn't say anything in the log after connecting, other than 

    You need to register the UUID that you are looking for the same way that it is done inside ble_nus_c_init() -> ble_db_discovery_evt_register() -> 

    Best regards,

    Edvin

Children
Related