From c034fbca54942da80cc40b59a7bc3e8bd5a342f9 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Mon, 1 Jun 2020 18:04:03 +0200 Subject: [PATCH] all: change NewAdvertisement to DefaultAdvertisement Instead of attempting to allocate multiple advertisement instances, only use one by default. If needed, a NewAdvertisement method could be added in the future for devices that actually do support multiple advertisements at a time. The motivation for this change is fix an inconsistency with the nrf51 (which already had the behavior of DefaultAdvertisement) and the discovery that nrf52 devices also don't seem to support more than one advertisement instance, even though their API does allow for multiple instances. But the primary motivation is that for consistency with hosted systems, it would be best if the nrf port would automatically re-enable advertisement when a connection is lost (or made). While BlueZ does support more than one instance, it is implemented by simply iterating through the active advertisement instances so could also be implemented by doing that manually. I haven't checked the behavior of Windows and MacOS - but as always, the API is not yet stable and can be changed if needed. --- adapter_linux.go | 9 +++++---- examples/advertisement/main.go | 2 +- examples/heartrate/main.go | 2 +- examples/ledcolor/main.go | 2 +- gap_linux.go | 13 ++++++++----- gap_nrf51.go | 15 ++++++--------- gap_nrf528xx.go | 19 ++++++++++++------- 7 files changed, 34 insertions(+), 28 deletions(-) diff --git a/adapter_linux.go b/adapter_linux.go index 92af1db..b353bdc 100644 --- a/adapter_linux.go +++ b/adapter_linux.go @@ -8,10 +8,11 @@ import ( ) type Adapter struct { - adapter *adapter.Adapter1 - id string - handler func(Event) - cancelScan func() + adapter *adapter.Adapter1 + id string + handler func(Event) + cancelScan func() + defaultAdvertisement *Advertisement } // DefaultAdapter is the default adapter on the system. On Linux, it is the diff --git a/examples/advertisement/main.go b/examples/advertisement/main.go index 7a1f45f..1754ca2 100644 --- a/examples/advertisement/main.go +++ b/examples/advertisement/main.go @@ -10,7 +10,7 @@ var adapter = bluetooth.DefaultAdapter func main() { must("enable BLE stack", adapter.Enable()) - adv := adapter.NewAdvertisement() + adv := adapter.DefaultAdvertisement() must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ LocalName: "Go Bluetooth", Interval: bluetooth.NewAdvertisementInterval(100), diff --git a/examples/heartrate/main.go b/examples/heartrate/main.go index 2a90629..bb54117 100644 --- a/examples/heartrate/main.go +++ b/examples/heartrate/main.go @@ -15,7 +15,7 @@ func main() { println("starting") adapter.SetEventHandler(handleBluetoothEvents) must("enable BLE stack", adapter.Enable()) - adv := adapter.NewAdvertisement() + adv := adapter.DefaultAdvertisement() must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ LocalName: "Go HRS", Interval: bluetooth.NewAdvertisementInterval(100), diff --git a/examples/ledcolor/main.go b/examples/ledcolor/main.go index 5fa6e5c..2420953 100644 --- a/examples/ledcolor/main.go +++ b/examples/ledcolor/main.go @@ -23,7 +23,7 @@ func main() { println("starting") adapter.SetEventHandler(handleBluetoothEvents) must("enable BLE stack", adapter.Enable()) - adv := adapter.NewAdvertisement() + adv := adapter.DefaultAdvertisement() must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ LocalName: "LED colors", Interval: bluetooth.NewAdvertisementInterval(100), diff --git a/gap_linux.go b/gap_linux.go index d8d3ffd..0db50c1 100644 --- a/gap_linux.go +++ b/gap_linux.go @@ -16,12 +16,15 @@ type Advertisement struct { properties *advertising.LEAdvertisement1Properties } -// NewAdvertisement creates a new advertisement instance but does not configure -// it. -func (a *Adapter) NewAdvertisement() *Advertisement { - return &Advertisement{ - adapter: a, +// DefaultAdvertisement returns the default advertisement instance but does not +// configure it. +func (a *Adapter) DefaultAdvertisement() *Advertisement { + if a.defaultAdvertisement == nil { + a.defaultAdvertisement = &Advertisement{ + adapter: a, + } } + return a.defaultAdvertisement } // Configure this advertisement. diff --git a/gap_nrf51.go b/gap_nrf51.go index 1e17d66..b4ba347 100644 --- a/gap_nrf51.go +++ b/gap_nrf51.go @@ -16,18 +16,15 @@ type Advertisement struct { interval AdvertisementInterval } -var globalAdvertisement Advertisement +var defaultAdvertisement Advertisement -// NewAdvertisement creates a new advertisement instance but does not configure -// it. It can be called before the SoftDevice has been initialized. -// -// On the nrf51 only one advertisement is allowed at a given time, therefore -// this is a singleton. -func (a *Adapter) NewAdvertisement() *Advertisement { - return &globalAdvertisement +// DefaultAdvertisement returns the default advertisement instance but does not +// configure it. +func (a *Adapter) DefaultAdvertisement() *Advertisement { + return &defaultAdvertisement } -// Configure this advertisement. Must be called after SoftDevice initialization. +// Configure this advertisement. func (a *Advertisement) Configure(options AdvertisementOptions) error { var payload rawAdvertisementPayload payload.addFlags(0x06) diff --git a/gap_nrf528xx.go b/gap_nrf528xx.go index 8321cb7..70a6052 100644 --- a/gap_nrf528xx.go +++ b/gap_nrf528xx.go @@ -28,15 +28,20 @@ type Advertisement struct { handle uint8 } -// NewAdvertisement creates a new advertisement instance but does not configure -// it. It can be called before the SoftDevice has been initialized. -func (a *Adapter) NewAdvertisement() *Advertisement { - return &Advertisement{ - handle: C.BLE_GAP_ADV_SET_HANDLE_NOT_SET, - } +// The nrf528xx devices only seem to support one advertisement instance. The way +// multiple advertisements are implemented is by changing the packet data +// frequently. +var defaultAdvertisement = Advertisement{ + handle: C.BLE_GAP_ADV_SET_HANDLE_NOT_SET, } -// Configure this advertisement. Must be called after SoftDevice initialization. +// DefaultAdvertisement returns the default advertisement instance but does not +// configure it. +func (a *Adapter) DefaultAdvertisement() *Advertisement { + return &defaultAdvertisement +} + +// Configure this advertisement. func (a *Advertisement) Configure(options AdvertisementOptions) error { data := C.ble_gap_adv_data_t{} var payload rawAdvertisementPayload