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.
This commit is contained in:
Ayke van Laethem 2020-06-01 18:04:03 +02:00
parent 086c797e0f
commit c034fbca54
No known key found for this signature in database
GPG key ID: E97FF5335DFDFDED
7 changed files with 34 additions and 28 deletions

View file

@ -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

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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.

View file

@ -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)

View file

@ -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