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

Building a list of available BLE devices

Hello, I want to build a list of available BLE devices and show the device names to the user via a display (pretty normal BLE search). The search shall be done for devices with the same base uuid. I started with the example "ble_app_uart_c_S120". I was able to change the project, so that the search is done for the base UUID I want to. But now, the project direcly connects to the device that is found. Do I need to connect to a device, to get the the device name? The device name should be sent by the advertising packages. So a connection should not be needed!? Where can I get the advertising data after starting the search with "scan_start();"? Especially, if there are more than one device on-air with the same base uuid?

Thanks and best regards, BTprogrammer

PS: I am using nRF51822 with S120 softdevice of course, in central role.

[Edit:]

I found this tutorial here: central tutorial

Now I tried to read out the data from p_adv_report->data[i]. But I didn`t find the advertised device name. Is it stored in that data field?

Parents
  • Ok, I think I got it... :-) The p_adv_report->data field must be parsed for the device name. I struggled with the position I did this. For me, the trick was to do it before the function is_uuid_present() is called. This function seems to change the data field. After this function call, the device name isn`t content of the data field. That is what it looks like for me... Maybe some Nordic expert can give a better explanation about that.

    I wrote a quick and dirty device name parse function. Hope this code helps someone:

    static bool parseDeviceName(const ble_uuid_t *p_target_uuid, 
                            const ble_gap_evt_adv_report_t *p_adv_report){
    uint32_t index = 0;
    uint8_t *p_data = (uint8_t *)p_adv_report->data;
    
    while (index < p_adv_report->dlen)
    {
        uint8_t field_length = p_data[index];
        uint8_t field_type   = p_data[index+1];
    			if ( (field_type == BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME)
    								|| (field_type == BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME)
    								)
    			{
    					printf("length_1: %d\r", field_length);
    					memcpy(deviceName, p_adv_report->data+2, field_length);
    					deviceName[p_adv_report->data[0]] = 0x00;
    					printf("Name: %s\r", deviceName);
    					return true;
    			}
    			index += field_length + 1;
    	}
    return false;
    }
    

    "deviceName" is a global static char array. After calling the parseDeviceName() funtion, the received name is stored in that array and can be used.

    Regards, BTprogrammer

Reply
  • Ok, I think I got it... :-) The p_adv_report->data field must be parsed for the device name. I struggled with the position I did this. For me, the trick was to do it before the function is_uuid_present() is called. This function seems to change the data field. After this function call, the device name isn`t content of the data field. That is what it looks like for me... Maybe some Nordic expert can give a better explanation about that.

    I wrote a quick and dirty device name parse function. Hope this code helps someone:

    static bool parseDeviceName(const ble_uuid_t *p_target_uuid, 
                            const ble_gap_evt_adv_report_t *p_adv_report){
    uint32_t index = 0;
    uint8_t *p_data = (uint8_t *)p_adv_report->data;
    
    while (index < p_adv_report->dlen)
    {
        uint8_t field_length = p_data[index];
        uint8_t field_type   = p_data[index+1];
    			if ( (field_type == BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME)
    								|| (field_type == BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME)
    								)
    			{
    					printf("length_1: %d\r", field_length);
    					memcpy(deviceName, p_adv_report->data+2, field_length);
    					deviceName[p_adv_report->data[0]] = 0x00;
    					printf("Name: %s\r", deviceName);
    					return true;
    			}
    			index += field_length + 1;
    	}
    return false;
    }
    

    "deviceName" is a global static char array. After calling the parseDeviceName() funtion, the received name is stored in that array and can be used.

    Regards, BTprogrammer

Children
Related