all: use Addresser interface to handle fact that macOS uses UUID instead of MAC as the BLE address for a peripheral
Signed-off-by: Ron Evans <ron@hybridgroup.com>
This commit is contained in:
parent
a620bacdb8
commit
c1114ad708
8 changed files with 144 additions and 19 deletions
|
@ -36,6 +36,7 @@ func (a *Adapter) Enable() error {
|
|||
|
||||
// CentralManager delegate functions
|
||||
|
||||
// CentralManagerDidUpdateState when central manager state updated.
|
||||
func (a *Adapter) CentralManagerDidUpdateState(cmgr cbgo.CentralManager) {
|
||||
}
|
||||
|
||||
|
@ -88,15 +89,16 @@ func (a *Adapter) CentralDidUnsubscribe(pmgr cbgo.PeripheralManager, cent cbgo.C
|
|||
|
||||
// makeScanResult creates a ScanResult when peripheral is found.
|
||||
func makeScanResult(prph cbgo.Peripheral, advFields cbgo.AdvFields, rssi int) ScanResult {
|
||||
// TODO: figure out the peripheral info.
|
||||
var u [16]byte
|
||||
copy(u[:], prph.Identifier())
|
||||
uuid := NewUUID(u)
|
||||
|
||||
// TODO: create a list of serviceUUIDs.
|
||||
|
||||
return ScanResult{
|
||||
RSSI: int16(rssi),
|
||||
RSSI: int16(rssi),
|
||||
Address: Address{
|
||||
// TODO: fill in this info
|
||||
//MAC: prph.Identifier(),
|
||||
UUID: uuid,
|
||||
//IsRandom: prph.Identifier == "random",
|
||||
},
|
||||
AdvertisementPayload: &advertisementFields{
|
||||
|
|
|
@ -102,8 +102,8 @@ func handleEvent() {
|
|||
// callback.
|
||||
scanReportBuffer.len = byte(advReport.data.len)
|
||||
globalScanResult.RSSI = int16(advReport.rssi)
|
||||
globalScanResult.Address.MAC = advReport.peer_addr.addr
|
||||
globalScanResult.Address.IsRandom = advReport.peer_addr.bitfield_addr_type() != 0
|
||||
globalScanResult.Address.Set(advReport.peer_addr.addr)
|
||||
globalScanResult.Address.SetRandom(advReport.peer_addr.bitfield_addr_type() != 0)
|
||||
globalScanResult.AdvertisementPayload = &scanReportBuffer
|
||||
// Signal to the main thread that there was a scan report.
|
||||
// Scanning will be resumed (from the main thread) once the scan
|
||||
|
|
17
gap.go
17
gap.go
|
@ -41,11 +41,14 @@ func NewDuration(interval time.Duration) Duration {
|
|||
// Connection is a numeric identifier that indicates a connection handle.
|
||||
type Connection uint16
|
||||
|
||||
// Address contains a Bluetooth address, which is a MAC address plus some extra
|
||||
// Addresser contains a Bluetooth address, which is a MAC address plus some extra
|
||||
// information.
|
||||
type Address struct {
|
||||
// The MAC address of a Bluetooth device.
|
||||
MAC
|
||||
type Addresser interface {
|
||||
// String of the address
|
||||
String() string
|
||||
|
||||
// Set the address
|
||||
Set(val interface{})
|
||||
|
||||
// Is this address a random address?
|
||||
// Bluetooth addresses are roughly split in two kinds: public
|
||||
|
@ -54,14 +57,16 @@ type Address struct {
|
|||
// random. Sometimes, it contains a hash.
|
||||
// For more information:
|
||||
// https://www.novelbits.io/bluetooth-address-privacy-ble/
|
||||
IsRandom bool
|
||||
// Set the address
|
||||
SetRandom(bool)
|
||||
IsRandom() bool
|
||||
}
|
||||
|
||||
// ScanResult contains information from when an advertisement packet was
|
||||
// received. It is passed as a parameter to the callback of the Scan method.
|
||||
type ScanResult struct {
|
||||
// Bluetooth address of the scanned device.
|
||||
Address Address
|
||||
Address Addresser
|
||||
|
||||
// RSSI the last time a packet from this device has been received.
|
||||
RSSI int16
|
||||
|
|
|
@ -6,6 +6,30 @@ import (
|
|||
"github.com/JuulLabs-OSS/cbgo"
|
||||
)
|
||||
|
||||
// Address contains a Bluetooth address, which is a MAC address plus some extra
|
||||
// information.
|
||||
type Address struct {
|
||||
// UUID if this is macOS.
|
||||
UUID
|
||||
|
||||
isRandom bool
|
||||
}
|
||||
|
||||
// IsRandom if the address is randomly created.
|
||||
func (ad Address) IsRandom() bool {
|
||||
return ad.isRandom
|
||||
}
|
||||
|
||||
// SetRandom if is a random address.
|
||||
func (ad Address) SetRandom(val bool) {
|
||||
ad.isRandom = val
|
||||
}
|
||||
|
||||
// Set the address
|
||||
func (ad Address) Set(val interface{}) {
|
||||
ad.UUID = val.(UUID)
|
||||
}
|
||||
|
||||
// Scan starts a BLE scan. It is stopped by a call to StopScan. A common pattern
|
||||
// is to cancel the scan when a particular device has been found.
|
||||
func (a *Adapter) Scan(callback func(*Adapter, ScanResult)) (err error) {
|
||||
|
|
30
gap_linux.go
30
gap_linux.go
|
@ -11,6 +11,29 @@ import (
|
|||
"github.com/muka/go-bluetooth/bluez/profile/device"
|
||||
)
|
||||
|
||||
// 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
|
||||
isRandom bool
|
||||
}
|
||||
|
||||
// IsRandom if the address is randomly created.
|
||||
func (ad Address) IsRandom() bool {
|
||||
return ad.isRandom
|
||||
}
|
||||
|
||||
// SetRandom if is a random address.
|
||||
func (ad Address) SetRandom(val bool) {
|
||||
ad.isRandom = val
|
||||
}
|
||||
|
||||
// Set the address
|
||||
func (ad Address) Set(val interface{}) {
|
||||
ad.MAC = val.(MAC)
|
||||
}
|
||||
|
||||
// Advertisement encapsulates a single advertisement instance.
|
||||
type Advertisement struct {
|
||||
adapter *Adapter
|
||||
|
@ -218,7 +241,7 @@ func makeScanResult(props *device.Device1Properties) ScanResult {
|
|||
RSSI: props.RSSI,
|
||||
Address: Address{
|
||||
MAC: addr,
|
||||
IsRandom: props.AddressType == "random",
|
||||
isRandom: props.AddressType == "random",
|
||||
},
|
||||
AdvertisementPayload: &advertisementFields{
|
||||
AdvertisementFields{
|
||||
|
@ -237,8 +260,9 @@ type Device struct {
|
|||
// Connect starts a connection attempt to the given peripheral device address.
|
||||
//
|
||||
// On Linux and Windows, the IsRandom part of the address is ignored.
|
||||
func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, error) {
|
||||
devicePath := dbus.ObjectPath(string(a.adapter.Path()) + "/dev_" + strings.Replace(address.MAC.String(), ":", "_", -1))
|
||||
func (a *Adapter) Connect(address Addresser, params ConnectionParams) (*Device, error) {
|
||||
adr := address.(Address)
|
||||
devicePath := dbus.ObjectPath(string(a.adapter.Path()) + "/dev_" + strings.Replace(adr.MAC.String(), ":", "_", -1))
|
||||
dev, err := device.NewDevice1(devicePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
23
gap_nrf51.go
23
gap_nrf51.go
|
@ -16,6 +16,29 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// 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
|
||||
isRandom bool
|
||||
}
|
||||
|
||||
// IsRandom if the address is randomly created.
|
||||
func (ad Address) IsRandom() bool {
|
||||
return ad.isRandom
|
||||
}
|
||||
|
||||
// SetRandom if is a random address.
|
||||
func (ad Address) SetRandom(val bool) {
|
||||
ad.isRandom = val
|
||||
}
|
||||
|
||||
// Set the address
|
||||
func (ad Address) Set(val interface{}) {
|
||||
ad.MAC = val.(MAC)
|
||||
}
|
||||
|
||||
// Advertisement encapsulates a single advertisement instance.
|
||||
type Advertisement struct {
|
||||
interval Duration
|
||||
|
|
|
@ -27,6 +27,29 @@ var (
|
|||
globalScanResult ScanResult
|
||||
)
|
||||
|
||||
// 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
|
||||
isRandom bool
|
||||
}
|
||||
|
||||
// IsRandom if the address is randomly created.
|
||||
func (ad Address) IsRandom() bool {
|
||||
return ad.isRandom
|
||||
}
|
||||
|
||||
// SetRandom if is a random address.
|
||||
func (ad Address) SetRandom(val bool) {
|
||||
ad.isRandom = val
|
||||
}
|
||||
|
||||
// Set the address
|
||||
func (ad Address) Set(val interface{}) {
|
||||
ad.MAC = val.(MAC)
|
||||
}
|
||||
|
||||
// Advertisement encapsulates a single advertisement instance.
|
||||
type Advertisement struct {
|
||||
handle uint8
|
||||
|
@ -169,12 +192,13 @@ var connectionAttempt struct {
|
|||
// connection attempt at once and that the address parameter must have the
|
||||
// IsRandom bit set correctly. This bit is set correctly for scan results, so
|
||||
// you can reuse that address directly.
|
||||
func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, error) {
|
||||
func (a *Adapter) Connect(address Addresser, params ConnectionParams) (*Device, error) {
|
||||
adr := address.(Address)
|
||||
// Construct an address object as used in the SoftDevice.
|
||||
var addr C.ble_gap_addr_t
|
||||
addr.addr = address.MAC
|
||||
if address.IsRandom {
|
||||
switch address.MAC[5] >> 6 {
|
||||
addr.addr = adr.MAC
|
||||
if address.IsRandom() {
|
||||
switch adr.MAC[5] >> 6 {
|
||||
case 0b11:
|
||||
addr.set_bitfield_addr_type(C.BLE_GAP_ADDR_TYPE_RANDOM_STATIC)
|
||||
case 0b01:
|
||||
|
|
|
@ -4,6 +4,29 @@ import (
|
|||
"github.com/tinygo-org/bluetooth/winbt"
|
||||
)
|
||||
|
||||
// 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
|
||||
isRandom bool
|
||||
}
|
||||
|
||||
// IsRandom if the address is randomly created.
|
||||
func (ad Address) IsRandom() bool {
|
||||
return ad.isRandom
|
||||
}
|
||||
|
||||
// SetRandom if is a random address.
|
||||
func (ad Address) SetRandom(val bool) {
|
||||
ad.isRandom = val
|
||||
}
|
||||
|
||||
// Set the address
|
||||
func (ad Address) Set(val interface{}) {
|
||||
ad.MAC = val.(MAC)
|
||||
}
|
||||
|
||||
// Scan starts a BLE scan. It is stopped by a call to StopScan. A common pattern
|
||||
// is to cancel the scan when a particular device has been found.
|
||||
func (a *Adapter) Scan(callback func(*Adapter, ScanResult)) (err error) {
|
||||
|
|
Loading…
Reference in a new issue