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

Scanning for the Short Local Name of an iOS device from an nRF52 based product

In the products that I am developing we use advertising packets in the scan response to pass some data around our devices. We wanted a way for the app we've made for iOS to participate. Mac doesn't give us full control over the Bluetooth stack, but it gives us the option to change the Short Local Name (BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME). We are having it modify that name to pack our data in it and modifying the scanner code I've written to parse the Short Local Name. The problem is I never receive the Short Local Name data from in the event data pointer. I've checked the raw data and see all the other devices I'm working on around the office, but never the altered Short Local Name. Using nRF Connect I can find the device and watch it update values live. It seems like the Softdevice filters away data from iOS devices or even all smart phones. I'm not sure what it is and I haven't any documents that suggest that. So my question is: am I not getting the data because it's not passed along by the Softdevice and are there some settings that I can change to reconfigure the Softdevice to pass that information along to my code.

The below code parses out the device Short Local Names fine, but I don't think that the data is ever getting passes to this snippet of code from the iPod I'm using to test, but the iPod does seem to broadcast the altered Short Local Name. There are a few log hex dumps where I can observe the raw packets and what has been found.

NRF_SDH_BLE_OBSERVER(scanner_observer, SCANNER_BLE_OBSERVER_PRIO, scan_on_ble_evt, NULL);

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

	p_data = p_advdata->p_data;
//	NRF_LOG_HEXDUMP_DEBUG(p_data, 31);
	while (index < p_advdata->size) {
		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->size   = field_length - 1;
			return NRF_SUCCESS;
		}
		index += field_length + 1;
	}
	return NRF_ERROR_NOT_FOUND;
}

static void scan_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
{
	ret_code_t err_code;
	if (p_ble_evt == NULL)
	{
		NRF_LOG_DEBUG("Context: %02x Event %02x", p_context, p_ble_evt);
	}
	else if((p_ble_evt->header.evt_id == BLE_GAP_EVT_ADV_REPORT) && (scanner_enabled))
	{
		uint8_array_t adv_data;
		uint8_array_t dev_name;
		sensor_data_pkt_t snsr_dat;

		// Prepare advertisement report for parsing.
		adv_data.p_data = (uint8_t *)p_ble_evt->evt.gap_evt.params.adv_report.data.p_data;
		adv_data.size   = p_ble_evt->evt.gap_evt.params.adv_report.data.len;

		uint8_t dev_index;

		err_code = _adv_report_parse(BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA, &adv_data, &dev_name);
        if(err_code != NRF_SUCCESS)
		{
			err_code = _adv_report_parse(BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME, &adv_data, &dev_name);
			if(!err_code)
			{
				void * data_pkt = ble_advdata_parse((uint8_t*)adv_data.p_data, adv_data.size, BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME);
				if(data_pkt)
				{
					NRF_LOG_HEXDUMP_DEBUG(data_pkt, 10);
                    if(find_MAC(data_pkt, &dev_index))
					{
						memcpy(&snsr_dat.data, data_pkt + BLE_GAP_ADDR_LEN, adv_data.size - BLE_GAP_ADDR_LEN);
						snsr_dat.dev_idx = dev_index;
						xQueueSend(m_scanner_q, &snsr_dat.data, pdMS_TO_TICKS(10));
					}
				}
			}
		}
		if(!err_code)
		{
			void * data_pkt = ble_advdata_parse((uint8_t*)adv_data.p_data, adv_data.size, BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA);
			if(data_pkt)
			{
				if(!find_MAC((uint8_t *)p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr, &dev_index))
				{
					dev_index = 0xFF;	// TODO this can be made simpler by changing the find MAC function to return the index of 0xFF if not found.
				}
			memcpy(&snsr_dat.data, data_pkt, sizeof(snsr_dat.data));
			snsr_dat.dev_idx = dev_index;
			xQueueSend(m_scanner_q, &snsr_dat.data, pdMS_TO_TICKS(10));
//			NRF_LOG_HEXDUMP_DEBUG(snsr_dat.data, sizeof(snsr_dat));

			}
		}
		if(find_MAC((uint8_t *)p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr, &dev_index))
		{
			err_code = _adv_report_parse(BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA, &adv_data, &dev_name);
			if(err_code != NRF_SUCCESS)
				_adv_report_parse(BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, &adv_data, &dev_name);
			if (err_code == NRF_SUCCESS)
			{
				void * data_pkt = ble_advdata_parse((uint8_t*)adv_data.p_data, adv_data.size, BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA);
				if(data_pkt)
				{
					main_pkt_hdr_t* p_main_hdr = (main_pkt_hdr_t*)(data_pkt + 2);
					if(p_main_hdr->counter != m_dev_trig.devs[dev_index].ctr)
					{
						NRF_LOG_DEBUG("New packet! Current counter: %d, Incoming counter: %d", m_dev_trig.devs[dev_index].ctr, p_main_hdr->counter);
						m_dev_trig.devs[dev_index].ctr = p_main_hdr->counter;
						memcpy(&snsr_dat.data, data_pkt, sizeof(snsr_dat.data));
						snsr_dat.dev_idx = dev_index;
						xQueueSend(m_scanner_q, &snsr_dat.data, pdMS_TO_TICKS(10));
						NRF_LOG_HEXDUMP_DEBUG(snsr_dat.data, sizeof(snsr_dat));
					}
				}
			}
		}
	}
	// ALWAYS resume scanning
	if (scanner_enabled)
	{
		err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer);
		if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE))
		{
			APP_ERROR_CHECK(err_code);
		}
	}
}

Here's a screen shot of the correct data in nRF Connect:

I'm using SDK15.3 and Softdevice 6.1.1 with my Windows 10 workstation running Segger Embedded Studio V4.50

Parents Reply Children
No Data
Related