Hello to everyone,
I was told to develop a simple BLE scanner using NRF52 DK (NRF52832). The idea is just to identify surrounding devices but we don't want to initiate connection with them, so it plays only an observer role. The code is a modification version of ble_app_uart_c.
Initially I wanted only to obtain the address but didnt know how to do it because the SDK and Softdevice are a little bit confusing, although this post gave me a really good start and helped me to understand some of the functions, structures and macros: https://devzone.nordicsemi.com/f/nordic-q-a/43747/nrf52832-ble-scan
memset(m_device[idx].addr, 0, sizeof(p_adv_report->peer_addr.addr)); memcpy(m_device[idx].addr, p_adv_report->peer_addr.addr, sizeof(p_adv_report->peer_addr.addr)); printf("Device number %d\r\n",device_number); printf("Address: "); for(i=0; i< (uint16_t)(sizeof(p_adv_report->peer_addr.addr));i++) { if(i==0) { printf("%02X",m_device[idx].addr[i]); } else { printf(":%02X",m_device[idx].addr[i]); //add colon in order to give format to address } } printf("\r\n"); m_device[idx].size = p_adv_report->data.len; memset(m_device[idx].data_buffer, 0, p_adv_report->data.len); memcpy(m_device[idx].data_buffer, p_adv_report->data.p_data, p_adv_report->data.len); printf("Adv Data: "); for(i=0; i< p_adv_report->data.len;i++) { printf("%x",m_device[idx].data_buffer[i]); } printf("\r\n"); //uint8_t * full_name_data = ble_advdata_parse(m_device[idx].data_buffer, m_device[idx].size,BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME); uint16_t len_full_name = ble_advdata_search(m_device[idx].data_buffer,m_device[idx].size, &offset,BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME); memset(m_device[idx].dev_name, 0, len_full_name); memcpy(m_device[idx].dev_name, &m_device[idx].data_buffer[offset], len_full_name); printf("Device Name: "); for(i=0; i<len_full_name;i++) { printf("%c",m_device[idx].data_buffer[offset+i]); } printf("\r\n"); m_device[idx].rssi = p_adv_report->rssi; printf("RSSI: %d dBm\r\n",m_device[idx].rssi);
So the idea is the following: every time a NRF_BLE_SCAN_EVT_NOT_FOUND scan event happens (because I'm not using any filter on scanning mode), I call the function add_device_to_list(ble_gap_evt_adv_report_t const * p_adv_report), where the code above is implemented within it and obtains information from the GAP EVT ADV REPORT. This is an example of what I get in the console:
Device number 54
Address: C0:39:F1:28:18:A0
Adv Data: 211abff4c09634c0a805
Device Name:
RSSI: -86 dBm
Device number 55 (Note: this is my phone using NRF Connect app, advertising without any services)
Address: 45:94:68:7D:FA:5C
Adv Data: 211ad94d61746961736950686f6e65
Device Name: MatiasiPhone
RSSI: -30 dBm
Device number 56
Address: 39:7A:9C:6B:34:7F
Adv Data: 211a2acbff4c01064a1e256190cc
Device Name:
RSSI: -87 dBm
I thought that reading the field peer_addr I would easily obtain the MAC address of the peer device and that would be enough. But that is not quite true, as I can tell from this post: https://devzone.nordicsemi.com/f/nordic-q-a/27012/how-to-distinguish-between-random-and-public-gap-addresses
My questions are the following:
1) is there any way I can identify surrounding devices using a value that doesnt change over time with the adv data packages I'm able to receive? (Could it be anyone of these: https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile/ ?? ), I think I can't use the address because it depends on the peer peripheral configuration and it can change if it is private. And it looks like not every device necessarily advertise a public address (I guess the public address it is the MAC address from the manufacturer? correct me if I'm wrong). Please, veryfy this statement: reading the manufacturer MAC address it will totally depend on if the client device is configurated to advertise it beforehand?
2) does the GAP EVT ADV REPORT already extract information from the adversiting physical channel PDU (Vol 6, Part B, section 2.3)? I'm not sure if p_adv_report->data.p_data is the actual PDU received (header + payload) or just the payload.
3) What kind of Advertising types I'm receiving? and How can I check that? for example if it is a legacy type advertising PDU?
4) is this code, softdevice and SDK suitable for finding EDR/BR Bluetooth devices? How would it be the format and the Adv packet in that case?
5) [just curious] Can anyone explain me how the ble_app_uart_c example works regarding uart and ble? I realized that if I add the UART service in the NRF Connect App and start adversiting, my scanning stops or just freeze in the console. I read in other post that as soon the NRF52 finds that service, it connects automatically to it. Where is that within the code? I can't find it.
6) [just curious] How the softdevices manages the interrupts and priorities? is realted to supervisor calls? Where can I understand and configure that? I would apprecciate a lot the development of a simple BLE application as an example using the softdevice with a flow chart or flow diagram of the program. I'm really concerned about adding others features in the future which can collide with current features or events or interrupt me while I'm doing something.