all: distinguish between public and random addresses

This is necessary when connecting to a device when using the SoftDevice.
The information is not set on Linux and Windows and is ignored on those
platform when connecting.
This commit is contained in:
Ayke van Laethem 2020-06-04 12:41:36 +02:00
parent ac6ef1697f
commit d07cf38d66
No known key found for this signature in database
GPG key ID: E97FF5335DFDFDED
4 changed files with 26 additions and 6 deletions

View file

@ -71,7 +71,8 @@ func handleEvent() {
// callback. // callback.
scanReportBuffer.len = byte(advReport.data.len) scanReportBuffer.len = byte(advReport.data.len)
globalScanResult.RSSI = int16(advReport.rssi) globalScanResult.RSSI = int16(advReport.rssi)
globalScanResult.Address = advReport.peer_addr.addr globalScanResult.Address.MAC = advReport.peer_addr.addr
globalScanResult.Address.IsRandom = advReport.peer_addr.bitfield_addr_type() != 0
globalScanResult.AdvertisementPayload = &scanReportBuffer globalScanResult.AdvertisementPayload = &scanReportBuffer
// Signal to the main thread that there was a scan report. // Signal to the main thread that there was a scan report.
// Scanning will be resumed (from the main thread) once the scan // Scanning will be resumed (from the main thread) once the scan

22
gap.go
View file

@ -38,11 +38,29 @@ func NewAdvertisementInterval(intervalMillis uint32) AdvertisementInterval {
// Connection is a numeric identifier that indicates a connection handle. // Connection is a numeric identifier that indicates a connection handle.
type Connection uint16 type Connection uint16
// Address contains a Bluetooth address, which is a MAC address plus some extra
// information.
type Address struct {
// The MAC address of a Bluetooth device.
MAC
// Is this address a random address?
// Bluetooth addresses are roughly split in two kinds: public
// (IEEE-assigned) addresses and random (not IEEE assigned) addresses.
// "Random" here doesn't mean it is exactly random but at least it looks
// random. Sometimes, it contains a hash.
// For more information:
// https://www.novelbits.io/bluetooth-address-privacy-ble/
//
// This field is unused under Windows and Linux.
IsRandom bool
}
// ScanResult contains information from when an advertisement packet was // ScanResult contains information from when an advertisement packet was
// received. It is passed as a parameter to the callback of the Scan method. // received. It is passed as a parameter to the callback of the Scan method.
type ScanResult struct { type ScanResult struct {
// MAC address of the scanned device. // Bluetooth address of the scanned device.
Address MAC Address Address
// RSSI the last time a packet from this device has been received. // RSSI the last time a packet from this device has been received.
RSSI int16 RSSI int16

View file

@ -156,7 +156,7 @@ func makeScanResult(dev *device.Device1) ScanResult {
return ScanResult{ return ScanResult{
RSSI: dev.Properties.RSSI, RSSI: dev.Properties.RSSI,
Address: addr, Address: Address{addr, false}, // the 'IsRandom' bit is not supported
AdvertisementPayload: &advertisementFields{ AdvertisementPayload: &advertisementFields{
AdvertisementFields{ AdvertisementFields{
LocalName: dev.Properties.Name, LocalName: dev.Properties.Name,

View file

@ -24,10 +24,11 @@ func (a *Adapter) Scan(callback func(*Adapter, ScanResult)) (err error) {
var result ScanResult var result ScanResult
result.RSSI = args.RawSignalStrengthInDBm() result.RSSI = args.RawSignalStrengthInDBm()
addr := args.BluetoothAddress() addr := args.BluetoothAddress()
for i := range result.Address { for i := range result.Address.MAC {
result.Address[i] = byte(addr) result.Address.MAC[i] = byte(addr)
addr >>= 8 addr >>= 8
} }
// Note: the IsRandom bit is never set.
advertisement := args.Advertisement() advertisement := args.Advertisement()
result.AdvertisementPayload = &advertisementFields{ result.AdvertisementPayload = &advertisementFields{
AdvertisementFields{ AdvertisementFields{