all: change advertisement interval type

Use a new Duration type, which is used throughout the BLE stack for
durations. The resolutions are sometimes different (connection
parameters have half the resolution) but overall it should improve the
ease of use of this type.

This commit also provides a default advertisement interval that is
recommended by Apple (which I think is as good as any recommendation).
This might help to speed up discovery by Apple (and Android?) phones.
This commit is contained in:
Ayke van Laethem 2020-06-06 20:47:05 +02:00
parent e0314251c9
commit ccb9c84db8
No known key found for this signature in database
GPG key ID: E97FF5335DFDFDED
7 changed files with 32 additions and 20 deletions

View file

@ -13,7 +13,6 @@ func main() {
adv := adapter.DefaultAdvertisement()
must("config adv", adv.Configure(bluetooth.AdvertisementOptions{
LocalName: "Go Bluetooth",
Interval: bluetooth.NewAdvertisementInterval(100 * time.Millisecond),
}))
must("start adv", adv.Start())

View file

@ -18,7 +18,6 @@ func main() {
must("config adv", adv.Configure(bluetooth.AdvertisementOptions{
LocalName: "Go HRS",
ServiceUUIDs: []bluetooth.UUID{bluetooth.New16BitUUID(0x2A37)},
Interval: bluetooth.NewAdvertisementInterval(100 * time.Millisecond),
}))
must("start adv", adv.Start())

View file

@ -25,7 +25,6 @@ func main() {
adv := adapter.DefaultAdvertisement()
must("config adv", adv.Configure(bluetooth.AdvertisementOptions{
LocalName: "LED colors",
Interval: bluetooth.NewAdvertisementInterval(100 * time.Millisecond),
}))
must("start adv", adv.Start())

View file

@ -8,8 +8,6 @@ package main
// Code to interact with a raw terminal is in separate files with build tags.
import (
"time"
"github.com/tinygo-org/bluetooth"
)
@ -27,7 +25,6 @@ func main() {
must("config adv", adv.Configure(bluetooth.AdvertisementOptions{
LocalName: "NUS", // Nordic UART Service
ServiceUUIDs: []bluetooth.UUID{serviceUUID},
Interval: bluetooth.NewAdvertisementInterval(100 * time.Millisecond),
}))
must("start adv", adv.Start())

19
gap.go
View file

@ -23,20 +23,19 @@ type AdvertisementOptions struct {
// 128-bit UUIDs".
ServiceUUIDs []UUID
// Interval in BLE-specific units. Create an interval by using
// NewAdvertiseInterval.
Interval AdvertisementInterval
// Interval in BLE-specific units. Create an interval by using NewDuration.
Interval Duration
}
// AdvertisementInterval is the advertisement interval in 0.625µs units.
type AdvertisementInterval uint32
// Duration is the unit of time used in BLE, in 0.625µs units. This unit of time
// is used throughout the BLE stack.
type Duration uint16
// NewAdvertisementInterval returns a new advertisement interval. Advertisement
// intervals are in units of 0.625µs, so the precision will not be greater than
// that.
func NewAdvertisementInterval(interval time.Duration) AdvertisementInterval {
// NewDuration returns a new Duration, in units of 0.625µs. It is used both for
// advertisement intervals and for connection parameters.
func NewDuration(interval time.Duration) Duration {
// Convert an interval to units of 0.625µs.
return AdvertisementInterval(uint64(interval / (625 * time.Microsecond)))
return Duration(uint64(interval / (625 * time.Microsecond)))
}
// Connection is a numeric identifier that indicates a connection handle.

View file

@ -11,11 +11,14 @@ package bluetooth
*/
import "C"
import "runtime/volatile"
import (
"runtime/volatile"
"time"
)
// Advertisement encapsulates a single advertisement instance.
type Advertisement struct {
interval AdvertisementInterval
interval Duration
isAdvertising volatile.Register8
}
@ -29,6 +32,14 @@ func (a *Adapter) DefaultAdvertisement() *Advertisement {
// Configure this advertisement.
func (a *Advertisement) Configure(options AdvertisementOptions) error {
// Fill empty options with reasonable defaults.
if options.Interval == 0 {
// Pick an advertisement interval recommended by Apple (section 35.5
// Advertising Interval):
// https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf
options.Interval = NewDuration(152500 * time.Microsecond) // 152.5ms
}
// Construct payload.
var payload rawAdvertisementPayload
if !payload.addFromOptions(options) {

View file

@ -45,6 +45,14 @@ func (a *Adapter) DefaultAdvertisement() *Advertisement {
// Configure this advertisement.
func (a *Advertisement) Configure(options AdvertisementOptions) error {
// Fill empty options with reasonable defaults.
if options.Interval == 0 {
// Pick an advertisement interval recommended by Apple (section 35.5
// Advertising Interval):
// https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf
options.Interval = NewDuration(152500 * time.Microsecond) // 152.5ms
}
// Construct payload.
var payload rawAdvertisementPayload
if !payload.addFromOptions(options) {
@ -87,8 +95,8 @@ func (a *Adapter) Scan(callback func(*Adapter, ScanResult)) error {
scanParams := C.ble_gap_scan_params_t{}
scanParams.set_bitfield_extended(0)
scanParams.set_bitfield_active(0)
scanParams.interval = uint16(NewAdvertisementInterval(100 * time.Millisecond))
scanParams.window = uint16(NewAdvertisementInterval(100 * time.Millisecond))
scanParams.interval = uint16(NewDuration(40 * time.Millisecond))
scanParams.window = uint16(NewDuration(30 * time.Millisecond))
scanParams.timeout = C.BLE_GAP_SCAN_TIMEOUT_UNLIMITED
scanReportBufferInfo := C.ble_data_t{
p_data: &scanReportBuffer.data[0],