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

Scanning for particular UUID if present get device name from adv_report

Hi,

I am using the ble_app_uart_c example for scanning the peripheral.

My requirement is I need a name of the device when UUID is being checked.

Means when isUUIDpresent function sends true after that I need the name of the device, but in this case field type in adv_report is BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE not the BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME. So the adv_report_parse is returning NRF_ERROR_NOT_FOUND error.

A suggestion would be appreciated of getting both the field type in adv_report of gap params. I am adding code on how I want to deal this.

case BLE_GAP_EVT_ADV_REPORT:
{
	const ble_gap_evt_adv_report_t * p_adv_report = &p_gap_evt->params.adv_report;


			if (is_uuid_present(&m_nus_uuid, p_adv_report)){
                  on_adv_report(p_ble_evt);
	         }

	break;

is_uuid_present is same as given in example, I just added on_adv_report() function

        static void on_adv_report(const ble_evt_t * const p_ble_evt)
     {
uint32_t err_code;
data_t   adv_data;
bool     do_connect = false;
data_t   dev_name;

// For readibility.
const ble_gap_evt_t * const  p_gap_evt  = &p_ble_evt->evt.gap_evt;
//	const ble_gap_addr_t * const peer_addr  = &p_gap_evt->params.adv_report.peer_addr;
{
	// Initialize advertisement report for parsing
	adv_data.p_data     = (uint8_t *)p_gap_evt->params.adv_report.data;
	adv_data.data_len   = p_gap_evt->params.adv_report.dlen;


	//search for advertising names
	bool found_name = false;
	err_code = adv_report_parse(BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME,
			&adv_data,
			&dev_name);
   printf("error_code %u\r\n",err_code);
}

}

and adv_report_parse as follows

static uint32_t adv_report_parse(uint8_t type, data_t * p_advdata, data_t * p_typedata)
 {
uint32_t  index = 0;
uint8_t * p_data;

p_data = p_advdata->p_data;



while (index < p_advdata->data_len)
{
	uint8_t field_length = p_data[index];
	uint8_t field_type   = p_data[index+1];

	if (field_type == type)
	{
		p_typedata->p_data   = &p_data[index+2];
		p_typedata->data_len = field_length-1;
		printf("name\r\n");
		for(int i=0;i<p_typedata->data_len;i++){
			printf("%02x,",p_typedata->p_data[i]);
		}
		printf("\r\n");
		return NRF_SUCCESS;
	}
	index += field_length + 1;

}

return NRF_ERROR_NOT_FOUND;
 }

Error handling is not proper right now.

Parents Reply Children
  • Hi Jorgen, Thanks for the reply. I am thinking that you didn't get what I am asking for. My requirement is at first I need to parse UUID from the adv_report structure of gap event params. if UUID is present I need to parse the name of the device from the adv_report structure. I am trying to get peripheral devices with unique UUID. Until now I am able to parse only one either name or UUID not both at same time.

  • The reason that you are not able to check both UUID and name in the same event is that this is split into advertising data and scan response package in the BLE UART example. You will get a BLE_GAP_EVT_ADV_REPORT event for the advertising package (which contains the name of the device), and one BLE_GAP_EVT_ADV_REPORT event for the scan response package (containing the 128-bit vendor specific UUID). The scan responce package will have the scan_rsp of the ble_gap_evt_adv_report_t struct set.

    To check both UUID and name of devices that split the data into two packages, you need to store the addresses of devices that advertise the UUID and check the name of devices with an address matching an address in this list.

    Other alternatives are to put both name and UUID in advertising data and leave out the scan response. The limitation of this method is that the maximum payload of the advertising packet is 27 bytes (could be increased to 251 with Bluetooth 5). Second solution is to check the name of the device, connect if this match and then do a service discovery. If the UUID is not discovered, you could simply disconnect from the device.

Related