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.
This commit is contained in:
parent
03d77ace1c
commit
b06d666dbf
15 changed files with 30 additions and 56 deletions
|
@ -6,6 +6,6 @@ const debug = false
|
||||||
// SetConnectHandler sets a handler function to be called whenever the adaptor connects
|
// 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 disconnects. You must call this before you call adaptor.Connect() for centrals
|
||||||
// or adaptor.Start() for peripherals in order for it to work.
|
// 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
|
a.connectHandler = c
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ type Adapter struct {
|
||||||
// used to allow multiple callers to call Connect concurrently.
|
// used to allow multiple callers to call Connect concurrently.
|
||||||
connectMap sync.Map
|
connectMap sync.Map
|
||||||
|
|
||||||
connectHandler func(device Addresser, connected bool)
|
connectHandler func(device Address, connected bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultAdapter is the default adapter on the system.
|
// DefaultAdapter is the default adapter on the system.
|
||||||
|
@ -35,7 +35,7 @@ var DefaultAdapter = &Adapter{
|
||||||
pm: cbgo.NewPeripheralManager(nil),
|
pm: cbgo.NewPeripheralManager(nil),
|
||||||
connectMap: sync.Map{},
|
connectMap: sync.Map{},
|
||||||
|
|
||||||
connectHandler: func(device Addresser, connected bool) {
|
connectHandler: func(device Address, connected bool) {
|
||||||
return
|
return
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ type Adapter struct {
|
||||||
cancelChan chan struct{}
|
cancelChan chan struct{}
|
||||||
defaultAdvertisement *Advertisement
|
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
|
// 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.
|
// Make sure to call Enable() before using it to initialize the adapter.
|
||||||
var DefaultAdapter = &Adapter{
|
var DefaultAdapter = &Adapter{
|
||||||
connectHandler: func(device Addresser, connected bool) {
|
connectHandler: func(device Address, connected bool) {
|
||||||
return
|
return
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ func handleEvent() {
|
||||||
switch id {
|
switch id {
|
||||||
case C.BLE_GAP_EVT_CONNECTED:
|
case C.BLE_GAP_EVT_CONNECTED:
|
||||||
currentConnection.Reg = gapEvent.conn_handle
|
currentConnection.Reg = gapEvent.conn_handle
|
||||||
DefaultAdapter.connectHandler(nil, true)
|
DefaultAdapter.connectHandler(Address{}, true)
|
||||||
case C.BLE_GAP_EVT_DISCONNECTED:
|
case C.BLE_GAP_EVT_DISCONNECTED:
|
||||||
if defaultAdvertisement.isAdvertising.Get() != 0 {
|
if defaultAdvertisement.isAdvertising.Get() != 0 {
|
||||||
// The advertisement was running but was automatically stopped
|
// The advertisement was running but was automatically stopped
|
||||||
|
@ -60,7 +60,7 @@ func handleEvent() {
|
||||||
defaultAdvertisement.start()
|
defaultAdvertisement.start()
|
||||||
}
|
}
|
||||||
currentConnection.Reg = C.BLE_CONN_HANDLE_INVALID
|
currentConnection.Reg = C.BLE_CONN_HANDLE_INVALID
|
||||||
DefaultAdapter.connectHandler(nil, false)
|
DefaultAdapter.connectHandler(Address{}, false)
|
||||||
case C.BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
|
case C.BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
|
||||||
// Respond with the default PPCP connection parameters by passing
|
// Respond with the default PPCP connection parameters by passing
|
||||||
// nil:
|
// nil:
|
||||||
|
|
|
@ -36,14 +36,14 @@ func handleEvent() {
|
||||||
println("evt: connected in peripheral role")
|
println("evt: connected in peripheral role")
|
||||||
}
|
}
|
||||||
currentConnection.Reg = gapEvent.conn_handle
|
currentConnection.Reg = gapEvent.conn_handle
|
||||||
DefaultAdapter.connectHandler(nil, true)
|
DefaultAdapter.connectHandler(Address{}, true)
|
||||||
case C.BLE_GAP_ROLE_CENTRAL:
|
case C.BLE_GAP_ROLE_CENTRAL:
|
||||||
if debug {
|
if debug {
|
||||||
println("evt: connected in central role")
|
println("evt: connected in central role")
|
||||||
}
|
}
|
||||||
connectionAttempt.connectionHandle = gapEvent.conn_handle
|
connectionAttempt.connectionHandle = gapEvent.conn_handle
|
||||||
connectionAttempt.state.Set(2) // connection was successful
|
connectionAttempt.state.Set(2) // connection was successful
|
||||||
DefaultAdapter.connectHandler(nil, true)
|
DefaultAdapter.connectHandler(Address{}, true)
|
||||||
}
|
}
|
||||||
case C.BLE_GAP_EVT_DISCONNECTED:
|
case C.BLE_GAP_EVT_DISCONNECTED:
|
||||||
if debug {
|
if debug {
|
||||||
|
@ -66,7 +66,7 @@ func handleEvent() {
|
||||||
// necessary.
|
// necessary.
|
||||||
C.sd_ble_gap_adv_start(defaultAdvertisement.handle, C.BLE_CONN_CFG_TAG_DEFAULT)
|
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:
|
case C.BLE_GAP_EVT_ADV_REPORT:
|
||||||
advReport := gapEvent.params.unionfield_adv_report()
|
advReport := gapEvent.params.unionfield_adv_report()
|
||||||
if debug && &scanReportBuffer.data[0] != advReport.data.p_data {
|
if debug && &scanReportBuffer.data[0] != advReport.data.p_data {
|
||||||
|
|
|
@ -33,7 +33,7 @@ func handleEvent() {
|
||||||
println("evt: connected in peripheral role")
|
println("evt: connected in peripheral role")
|
||||||
}
|
}
|
||||||
currentConnection.Reg = gapEvent.conn_handle
|
currentConnection.Reg = gapEvent.conn_handle
|
||||||
DefaultAdapter.connectHandler(nil, true)
|
DefaultAdapter.connectHandler(Address{}, true)
|
||||||
case C.BLE_GAP_EVT_DISCONNECTED:
|
case C.BLE_GAP_EVT_DISCONNECTED:
|
||||||
if debug {
|
if debug {
|
||||||
println("evt: disconnected")
|
println("evt: disconnected")
|
||||||
|
@ -49,7 +49,7 @@ func handleEvent() {
|
||||||
// necessary.
|
// necessary.
|
||||||
C.sd_ble_gap_adv_start(defaultAdvertisement.handle, C.BLE_CONN_CFG_TAG_DEFAULT)
|
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:
|
case C.BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
|
||||||
// We need to respond with sd_ble_gap_data_length_update. Setting
|
// We need to respond with sd_ble_gap_data_length_update. Setting
|
||||||
// both parameters to nil will make sure we send the default values.
|
// both parameters to nil will make sure we send the default values.
|
||||||
|
|
|
@ -49,7 +49,7 @@ type Adapter struct {
|
||||||
scanning bool
|
scanning bool
|
||||||
charWriteHandlers []charWriteHandler
|
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,
|
// 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.
|
// Make sure to call Enable() before using it to initialize the adapter.
|
||||||
var DefaultAdapter = &Adapter{isDefault: true,
|
var DefaultAdapter = &Adapter{isDefault: true,
|
||||||
connectHandler: func(device Addresser, connected bool) {
|
connectHandler: func(device Address, connected bool) {
|
||||||
return
|
return
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|
|
@ -12,14 +12,14 @@ import (
|
||||||
type Adapter struct {
|
type Adapter struct {
|
||||||
watcher *advertisement.BluetoothLEAdvertisementWatcher
|
watcher *advertisement.BluetoothLEAdvertisementWatcher
|
||||||
|
|
||||||
connectHandler func(device Addresser, connected bool)
|
connectHandler func(device Address, connected bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultAdapter is the default adapter on the system.
|
// DefaultAdapter is the default adapter on the system.
|
||||||
//
|
//
|
||||||
// Make sure to call Enable() before using it to initialize the adapter.
|
// Make sure to call Enable() before using it to initialize the adapter.
|
||||||
var DefaultAdapter = &Adapter{
|
var DefaultAdapter = &Adapter{
|
||||||
connectHandler: func(device Addresser, connected bool) {
|
connectHandler: func(device Address, connected bool) {
|
||||||
return
|
return
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ func main() {
|
||||||
neo.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
neo.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
ws = ws2812.New(neo)
|
ws = ws2812.New(neo)
|
||||||
|
|
||||||
adapter.SetConnectHandler(func(d bluetooth.Addresser, c bool) {
|
adapter.SetConnectHandler(func(d bluetooth.Address, c bool) {
|
||||||
connected = c
|
connected = c
|
||||||
|
|
||||||
if !connected && !disconnected {
|
if !connected && !disconnected {
|
||||||
|
|
|
@ -21,7 +21,7 @@ func main() {
|
||||||
must("config adv", adv.Configure(bluetooth.AdvertisementOptions{
|
must("config adv", adv.Configure(bluetooth.AdvertisementOptions{
|
||||||
LocalName: "Go Bluetooth",
|
LocalName: "Go Bluetooth",
|
||||||
}))
|
}))
|
||||||
adapter.SetConnectHandler(func(device bluetooth.Addresser, connected bool) {
|
adapter.SetConnectHandler(func(device bluetooth.Address, connected bool) {
|
||||||
if connected {
|
if connected {
|
||||||
println("connected, not advertising...")
|
println("connected, not advertising...")
|
||||||
advState = false
|
advState = false
|
||||||
|
|
23
gap.go
23
gap.go
|
@ -69,32 +69,11 @@ func NewDuration(interval time.Duration) Duration {
|
||||||
// Connection is a numeric identifier that indicates a connection handle.
|
// Connection is a numeric identifier that indicates a connection handle.
|
||||||
type Connection uint16
|
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
|
// ScanResult contains information from when an advertisement packet was
|
||||||
// received. It is passed as a parameter to the callback of the Scan method.
|
// received. It is passed as a parameter to the callback of the Scan method.
|
||||||
type ScanResult struct {
|
type ScanResult struct {
|
||||||
// Bluetooth address of the scanned device.
|
// Bluetooth address of the scanned device.
|
||||||
Address Addresser
|
Address Address
|
||||||
|
|
||||||
// RSSI the last time a packet from this device has been received.
|
// RSSI the last time a packet from this device has been received.
|
||||||
RSSI int16
|
RSSI int16
|
||||||
|
|
|
@ -95,15 +95,14 @@ type Device struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect starts a connection attempt to the given peripheral device address.
|
// Connect starts a connection attempt to the given peripheral device address.
|
||||||
func (a *Adapter) Connect(address Addresser, params ConnectionParams) (*Device, error) {
|
func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, error) {
|
||||||
adr := address.(Address)
|
uuid, err := cbgo.ParseUUID(address.UUID.String())
|
||||||
uuid, err := cbgo.ParseUUID(adr.UUID.String())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
prphs := a.cm.RetrievePeripheralsWithIdentifiers([]cbgo.UUID{uuid})
|
prphs := a.cm.RetrievePeripheralsWithIdentifiers([]cbgo.UUID{uuid})
|
||||||
if len(prphs) == 0 {
|
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()
|
id := prphs[0].Identifier().String()
|
||||||
|
@ -127,7 +126,7 @@ func (a *Adapter) Connect(address Addresser, params ConnectionParams) (*Device,
|
||||||
d.delegate = &peripheralDelegate{d: d}
|
d.delegate = &peripheralDelegate{d: d}
|
||||||
p.SetDelegate(d.delegate)
|
p.SetDelegate(d.delegate)
|
||||||
|
|
||||||
a.connectHandler(nil, true)
|
a.connectHandler(Address{}, true)
|
||||||
|
|
||||||
return d, nil
|
return d, nil
|
||||||
case <-time.NewTimer(10 * time.Second).C:
|
case <-time.NewTimer(10 * time.Second).C:
|
||||||
|
|
|
@ -276,9 +276,8 @@ type Device struct {
|
||||||
// Connect starts a connection attempt to the given peripheral device address.
|
// Connect starts a connection attempt to the given peripheral device address.
|
||||||
//
|
//
|
||||||
// On Linux and Windows, the IsRandom part of the address is ignored.
|
// On Linux and Windows, the IsRandom part of the address is ignored.
|
||||||
func (a *Adapter) Connect(address Addresser, params ConnectionParams) (*Device, error) {
|
func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, error) {
|
||||||
adr := address.(Address)
|
devicePath := dbus.ObjectPath(string(a.adapter.Path()) + "/dev_" + strings.Replace(address.MAC.String(), ":", "_", -1))
|
||||||
devicePath := dbus.ObjectPath(string(a.adapter.Path()) + "/dev_" + strings.Replace(adr.MAC.String(), ":", "_", -1))
|
|
||||||
dev, err := device.NewDevice1(devicePath)
|
dev, err := device.NewDevice1(devicePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -294,7 +293,7 @@ func (a *Adapter) Connect(address Addresser, params ConnectionParams) (*Device,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: a proper async callback.
|
// TODO: a proper async callback.
|
||||||
a.connectHandler(nil, true)
|
a.connectHandler(Address{}, true)
|
||||||
|
|
||||||
return &Device{
|
return &Device{
|
||||||
device: dev,
|
device: dev,
|
||||||
|
|
|
@ -113,13 +113,12 @@ var connectionAttempt struct {
|
||||||
// connection attempt at once and that the address parameter must have the
|
// 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
|
// IsRandom bit set correctly. This bit is set correctly for scan results, so
|
||||||
// you can reuse that address directly.
|
// you can reuse that address directly.
|
||||||
func (a *Adapter) Connect(address Addresser, params ConnectionParams) (*Device, error) {
|
func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, error) {
|
||||||
adr := address.(Address)
|
|
||||||
// Construct an address object as used in the SoftDevice.
|
// Construct an address object as used in the SoftDevice.
|
||||||
var addr C.ble_gap_addr_t
|
var addr C.ble_gap_addr_t
|
||||||
addr.addr = adr.MAC
|
addr.addr = address.MAC
|
||||||
if address.IsRandom() {
|
if address.IsRandom() {
|
||||||
switch adr.MAC[5] >> 6 {
|
switch address.MAC[5] >> 6 {
|
||||||
case 0b11:
|
case 0b11:
|
||||||
addr.set_bitfield_addr_type(C.BLE_GAP_ADDR_TYPE_RANDOM_STATIC)
|
addr.set_bitfield_addr_type(C.BLE_GAP_ADDR_TYPE_RANDOM_STATIC)
|
||||||
case 0b01:
|
case 0b01:
|
||||||
|
|
|
@ -163,9 +163,7 @@ type Device struct {
|
||||||
// Connect starts a connection attempt to the given peripheral device address.
|
// Connect starts a connection attempt to the given peripheral device address.
|
||||||
//
|
//
|
||||||
// On Linux and Windows, the IsRandom part of the address is ignored.
|
// On Linux and Windows, the IsRandom part of the address is ignored.
|
||||||
func (a *Adapter) Connect(addresser Addresser, params ConnectionParams) (*Device, error) {
|
func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, error) {
|
||||||
address := addresser.(Address).MACAddress
|
|
||||||
|
|
||||||
var winAddr uint64
|
var winAddr uint64
|
||||||
for i := range address.MAC {
|
for i := range address.MAC {
|
||||||
winAddr += uint64(address.MAC[i]) << (8 * i)
|
winAddr += uint64(address.MAC[i]) << (8 * i)
|
||||||
|
|
Loading…
Reference in a new issue