From b06d666dbfcb15f0c2893034d2ea4244edc79fa0 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Tue, 25 Apr 2023 02:12:05 +0200 Subject: [PATCH] all: remove Addresser Remove the Addresser type. It isn't really necessary (the Address type can change between OSes) and makes it difficult to fix a heap allocation in interrupts (on the Nordic SoftDevices). This is a backwards incompatible change, but only programs that use SetConnectHandler should notice this. --- adapter.go | 2 +- adapter_darwin.go | 4 ++-- adapter_linux.go | 4 ++-- adapter_nrf51.go | 4 ++-- adapter_nrf528xx-full.go | 6 +++--- adapter_nrf528xx-peripheral.go | 4 ++-- adapter_sd.go | 4 ++-- adapter_windows.go | 4 ++-- examples/circuitplay/main.go | 2 +- examples/stop-advertisement/main.go | 2 +- gap.go | 23 +---------------------- gap_darwin.go | 9 ++++----- gap_linux.go | 7 +++---- gap_nrf528xx-central.go | 7 +++---- gap_windows.go | 4 +--- 15 files changed, 30 insertions(+), 56 deletions(-) diff --git a/adapter.go b/adapter.go index ecd07b9..f3f4528 100644 --- a/adapter.go +++ b/adapter.go @@ -6,6 +6,6 @@ const debug = false // SetConnectHandler sets a handler function to be called whenever the adaptor connects // or disconnects. You must call this before you call adaptor.Connect() for centrals // or adaptor.Start() for peripherals in order for it to work. -func (a *Adapter) SetConnectHandler(c func(device Addresser, connected bool)) { +func (a *Adapter) SetConnectHandler(c func(device Address, connected bool)) { a.connectHandler = c } diff --git a/adapter_darwin.go b/adapter_darwin.go index 6c3f683..982d86f 100644 --- a/adapter_darwin.go +++ b/adapter_darwin.go @@ -24,7 +24,7 @@ type Adapter struct { // used to allow multiple callers to call Connect concurrently. connectMap sync.Map - connectHandler func(device Addresser, connected bool) + connectHandler func(device Address, connected bool) } // DefaultAdapter is the default adapter on the system. @@ -35,7 +35,7 @@ var DefaultAdapter = &Adapter{ pm: cbgo.NewPeripheralManager(nil), connectMap: sync.Map{}, - connectHandler: func(device Addresser, connected bool) { + connectHandler: func(device Address, connected bool) { return }, } diff --git a/adapter_linux.go b/adapter_linux.go index a329a20..529e02b 100644 --- a/adapter_linux.go +++ b/adapter_linux.go @@ -19,7 +19,7 @@ type Adapter struct { cancelChan chan struct{} defaultAdvertisement *Advertisement - connectHandler func(device Addresser, connected bool) + connectHandler func(device Address, connected bool) } // DefaultAdapter is the default adapter on the system. On Linux, it is the @@ -27,7 +27,7 @@ type Adapter struct { // // Make sure to call Enable() before using it to initialize the adapter. var DefaultAdapter = &Adapter{ - connectHandler: func(device Addresser, connected bool) { + connectHandler: func(device Address, connected bool) { return }, } diff --git a/adapter_nrf51.go b/adapter_nrf51.go index a11869f..29cfb50 100644 --- a/adapter_nrf51.go +++ b/adapter_nrf51.go @@ -48,7 +48,7 @@ func handleEvent() { switch id { case C.BLE_GAP_EVT_CONNECTED: currentConnection.Reg = gapEvent.conn_handle - DefaultAdapter.connectHandler(nil, true) + DefaultAdapter.connectHandler(Address{}, true) case C.BLE_GAP_EVT_DISCONNECTED: if defaultAdvertisement.isAdvertising.Get() != 0 { // The advertisement was running but was automatically stopped @@ -60,7 +60,7 @@ func handleEvent() { defaultAdvertisement.start() } currentConnection.Reg = C.BLE_CONN_HANDLE_INVALID - DefaultAdapter.connectHandler(nil, false) + DefaultAdapter.connectHandler(Address{}, false) case C.BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: // Respond with the default PPCP connection parameters by passing // nil: diff --git a/adapter_nrf528xx-full.go b/adapter_nrf528xx-full.go index 22d45ff..a0be0a9 100644 --- a/adapter_nrf528xx-full.go +++ b/adapter_nrf528xx-full.go @@ -36,14 +36,14 @@ func handleEvent() { println("evt: connected in peripheral role") } currentConnection.Reg = gapEvent.conn_handle - DefaultAdapter.connectHandler(nil, true) + DefaultAdapter.connectHandler(Address{}, true) case C.BLE_GAP_ROLE_CENTRAL: if debug { println("evt: connected in central role") } connectionAttempt.connectionHandle = gapEvent.conn_handle connectionAttempt.state.Set(2) // connection was successful - DefaultAdapter.connectHandler(nil, true) + DefaultAdapter.connectHandler(Address{}, true) } case C.BLE_GAP_EVT_DISCONNECTED: if debug { @@ -66,7 +66,7 @@ func handleEvent() { // necessary. C.sd_ble_gap_adv_start(defaultAdvertisement.handle, C.BLE_CONN_CFG_TAG_DEFAULT) } - DefaultAdapter.connectHandler(nil, false) + DefaultAdapter.connectHandler(Address{}, false) case C.BLE_GAP_EVT_ADV_REPORT: advReport := gapEvent.params.unionfield_adv_report() if debug && &scanReportBuffer.data[0] != advReport.data.p_data { diff --git a/adapter_nrf528xx-peripheral.go b/adapter_nrf528xx-peripheral.go index 11b6b92..84e7c57 100644 --- a/adapter_nrf528xx-peripheral.go +++ b/adapter_nrf528xx-peripheral.go @@ -33,7 +33,7 @@ func handleEvent() { println("evt: connected in peripheral role") } currentConnection.Reg = gapEvent.conn_handle - DefaultAdapter.connectHandler(nil, true) + DefaultAdapter.connectHandler(Address{}, true) case C.BLE_GAP_EVT_DISCONNECTED: if debug { println("evt: disconnected") @@ -49,7 +49,7 @@ func handleEvent() { // necessary. C.sd_ble_gap_adv_start(defaultAdvertisement.handle, C.BLE_CONN_CFG_TAG_DEFAULT) } - DefaultAdapter.connectHandler(nil, false) + DefaultAdapter.connectHandler(Address{}, false) case C.BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: // We need to respond with sd_ble_gap_data_length_update. Setting // both parameters to nil will make sure we send the default values. diff --git a/adapter_sd.go b/adapter_sd.go index ad0e4cf..6f2bd03 100644 --- a/adapter_sd.go +++ b/adapter_sd.go @@ -49,7 +49,7 @@ type Adapter struct { scanning bool charWriteHandlers []charWriteHandler - connectHandler func(device Addresser, connected bool) + connectHandler func(device Address, connected bool) } // DefaultAdapter is the default adapter on the current system. On Nordic chips, @@ -57,7 +57,7 @@ type Adapter struct { // // Make sure to call Enable() before using it to initialize the adapter. var DefaultAdapter = &Adapter{isDefault: true, - connectHandler: func(device Addresser, connected bool) { + connectHandler: func(device Address, connected bool) { return }} diff --git a/adapter_windows.go b/adapter_windows.go index 72ef0fe..619ceaa 100644 --- a/adapter_windows.go +++ b/adapter_windows.go @@ -12,14 +12,14 @@ import ( type Adapter struct { watcher *advertisement.BluetoothLEAdvertisementWatcher - connectHandler func(device Addresser, connected bool) + connectHandler func(device Address, connected bool) } // DefaultAdapter is the default adapter on the system. // // Make sure to call Enable() before using it to initialize the adapter. var DefaultAdapter = &Adapter{ - connectHandler: func(device Addresser, connected bool) { + connectHandler: func(device Address, connected bool) { return }, } diff --git a/examples/circuitplay/main.go b/examples/circuitplay/main.go index 234cb24..bd19ccf 100644 --- a/examples/circuitplay/main.go +++ b/examples/circuitplay/main.go @@ -39,7 +39,7 @@ func main() { neo.Configure(machine.PinConfig{Mode: machine.PinOutput}) ws = ws2812.New(neo) - adapter.SetConnectHandler(func(d bluetooth.Addresser, c bool) { + adapter.SetConnectHandler(func(d bluetooth.Address, c bool) { connected = c if !connected && !disconnected { diff --git a/examples/stop-advertisement/main.go b/examples/stop-advertisement/main.go index e56cd73..ea60c6e 100644 --- a/examples/stop-advertisement/main.go +++ b/examples/stop-advertisement/main.go @@ -21,7 +21,7 @@ func main() { must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ LocalName: "Go Bluetooth", })) - adapter.SetConnectHandler(func(device bluetooth.Addresser, connected bool) { + adapter.SetConnectHandler(func(device bluetooth.Address, connected bool) { if connected { println("connected, not advertising...") advState = false diff --git a/gap.go b/gap.go index 57f07da..a912bc9 100644 --- a/gap.go +++ b/gap.go @@ -69,32 +69,11 @@ func NewDuration(interval time.Duration) Duration { // Connection is a numeric identifier that indicates a connection handle. type Connection uint16 -// Addresser contains a Bluetooth address, which is a MAC address plus some extra -// information. -type Addresser interface { - // String of the address - String() string - - // Set the address - Set(val string) - - // 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/ - // 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 Addresser + Address Address // RSSI the last time a packet from this device has been received. RSSI int16 diff --git a/gap_darwin.go b/gap_darwin.go index 50770a3..cd546fd 100644 --- a/gap_darwin.go +++ b/gap_darwin.go @@ -95,15 +95,14 @@ type Device struct { } // Connect starts a connection attempt to the given peripheral device address. -func (a *Adapter) Connect(address Addresser, params ConnectionParams) (*Device, error) { - adr := address.(Address) - uuid, err := cbgo.ParseUUID(adr.UUID.String()) +func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, error) { + uuid, err := cbgo.ParseUUID(address.UUID.String()) if err != nil { return nil, err } prphs := a.cm.RetrievePeripheralsWithIdentifiers([]cbgo.UUID{uuid}) if len(prphs) == 0 { - return nil, fmt.Errorf("Connect failed: no peer with address: %s", adr.UUID.String()) + return nil, fmt.Errorf("Connect failed: no peer with address: %s", address.UUID.String()) } id := prphs[0].Identifier().String() @@ -127,7 +126,7 @@ func (a *Adapter) Connect(address Addresser, params ConnectionParams) (*Device, d.delegate = &peripheralDelegate{d: d} p.SetDelegate(d.delegate) - a.connectHandler(nil, true) + a.connectHandler(Address{}, true) return d, nil case <-time.NewTimer(10 * time.Second).C: diff --git a/gap_linux.go b/gap_linux.go index 68a3f4b..c236374 100644 --- a/gap_linux.go +++ b/gap_linux.go @@ -276,9 +276,8 @@ 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 Addresser, params ConnectionParams) (*Device, error) { - adr := address.(Address) - devicePath := dbus.ObjectPath(string(a.adapter.Path()) + "/dev_" + strings.Replace(adr.MAC.String(), ":", "_", -1)) +func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, error) { + devicePath := dbus.ObjectPath(string(a.adapter.Path()) + "/dev_" + strings.Replace(address.MAC.String(), ":", "_", -1)) dev, err := device.NewDevice1(devicePath) if err != nil { return nil, err @@ -294,7 +293,7 @@ func (a *Adapter) Connect(address Addresser, params ConnectionParams) (*Device, } // TODO: a proper async callback. - a.connectHandler(nil, true) + a.connectHandler(Address{}, true) return &Device{ device: dev, diff --git a/gap_nrf528xx-central.go b/gap_nrf528xx-central.go index bc8fa33..ba13d21 100644 --- a/gap_nrf528xx-central.go +++ b/gap_nrf528xx-central.go @@ -113,13 +113,12 @@ 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 Addresser, params ConnectionParams) (*Device, error) { - adr := address.(Address) +func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, error) { // Construct an address object as used in the SoftDevice. var addr C.ble_gap_addr_t - addr.addr = adr.MAC + addr.addr = address.MAC if address.IsRandom() { - switch adr.MAC[5] >> 6 { + switch address.MAC[5] >> 6 { case 0b11: addr.set_bitfield_addr_type(C.BLE_GAP_ADDR_TYPE_RANDOM_STATIC) case 0b01: diff --git a/gap_windows.go b/gap_windows.go index 21040ea..0a8efb9 100644 --- a/gap_windows.go +++ b/gap_windows.go @@ -163,9 +163,7 @@ 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(addresser Addresser, params ConnectionParams) (*Device, error) { - address := addresser.(Address).MACAddress - +func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, error) { var winAddr uint64 for i := range address.MAC { winAddr += uint64(address.MAC[i]) << (8 * i)