macos: able to retrieve some of the info when scanning
Signed-off-by: Ron Evans <ron@hybridgroup.com>
This commit is contained in:
parent
51b2b4c2b2
commit
a620bacdb8
5 changed files with 138 additions and 70 deletions
|
@ -2,22 +2,109 @@ package bluetooth
|
|||
|
||||
import (
|
||||
"github.com/JuulLabs-OSS/cbgo"
|
||||
"github.com/tinygo-org/bluetooth/macbt"
|
||||
)
|
||||
|
||||
type Adapter struct {
|
||||
cm cbgo.CentralManager
|
||||
cmd macbt.CMDelegate
|
||||
cbgo.CentralManagerDelegateBase
|
||||
cbgo.PeripheralManagerDelegateBase
|
||||
|
||||
cm cbgo.CentralManager
|
||||
pm cbgo.PeripheralManager
|
||||
|
||||
peripheralFoundHandler func(*Adapter, ScanResult)
|
||||
cancelChan chan struct{}
|
||||
}
|
||||
|
||||
// DefaultAdapter is the default adapter on the system.
|
||||
//
|
||||
// Make sure to call Enable() before using it to initialize the adapter.
|
||||
var DefaultAdapter = &Adapter{}
|
||||
var DefaultAdapter = &Adapter{
|
||||
cm: cbgo.NewCentralManager(nil),
|
||||
pm: cbgo.NewPeripheralManager(nil),
|
||||
}
|
||||
|
||||
// Enable configures the BLE stack. It must be called before any
|
||||
// Bluetooth-related calls (unless otherwise indicated).
|
||||
func (a *Adapter) Enable() error {
|
||||
a.cm = cbgo.NewCentralManager(nil)
|
||||
a.cm.SetDelegate(a)
|
||||
// TODO: wait until powered
|
||||
a.pm.SetDelegate(a)
|
||||
// TODO: wait until powered
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CentralManager delegate functions
|
||||
|
||||
func (a *Adapter) CentralManagerDidUpdateState(cmgr cbgo.CentralManager) {
|
||||
}
|
||||
|
||||
// DidDiscoverPeripheral when peripheral is discovered.
|
||||
func (a *Adapter) DidDiscoverPeripheral(cmgr cbgo.CentralManager, prph cbgo.Peripheral,
|
||||
advFields cbgo.AdvFields, rssi int) {
|
||||
if a.peripheralFoundHandler != nil {
|
||||
sr := makeScanResult(prph, advFields, rssi)
|
||||
a.peripheralFoundHandler(a, sr)
|
||||
}
|
||||
}
|
||||
|
||||
// DidConnectPeripheral when peripheral is connected.
|
||||
func (a *Adapter) DidConnectPeripheral(cmgr cbgo.CentralManager, prph cbgo.Peripheral) {
|
||||
}
|
||||
|
||||
// DidDisconnectPeripheral when peripheral is disconnected.
|
||||
func (a *Adapter) DidDisconnectPeripheral(cmgr cbgo.CentralManager, prph cbgo.Peripheral, err error) {
|
||||
}
|
||||
|
||||
// PeripheralManager delegate functions
|
||||
|
||||
// PeripheralManagerDidUpdateState when state updated.
|
||||
func (a *Adapter) PeripheralManagerDidUpdateState(pmgr cbgo.PeripheralManager) {
|
||||
}
|
||||
|
||||
// DidAddService when service added.
|
||||
func (a *Adapter) DidAddService(pmgr cbgo.PeripheralManager, svc cbgo.Service, err error) {
|
||||
}
|
||||
|
||||
// DidStartAdvertising when advertising starts.
|
||||
func (a *Adapter) DidStartAdvertising(pmgr cbgo.PeripheralManager, err error) {
|
||||
}
|
||||
|
||||
// DidReceiveReadRequest when read request received.
|
||||
func (a *Adapter) DidReceiveReadRequest(pmgr cbgo.PeripheralManager, cbreq cbgo.ATTRequest) {
|
||||
}
|
||||
|
||||
// DidReceiveWriteRequests when write requests received.
|
||||
func (a *Adapter) DidReceiveWriteRequests(pmgr cbgo.PeripheralManager, cbreqs []cbgo.ATTRequest) {
|
||||
}
|
||||
|
||||
// CentralDidSubscribe when central subscribed.
|
||||
func (a *Adapter) CentralDidSubscribe(pmgr cbgo.PeripheralManager, cent cbgo.Central, cbchr cbgo.Characteristic) {
|
||||
}
|
||||
|
||||
// CentralDidUnsubscribe when central unsubscribed.
|
||||
func (a *Adapter) CentralDidUnsubscribe(pmgr cbgo.PeripheralManager, cent cbgo.Central, chr cbgo.Characteristic) {
|
||||
}
|
||||
|
||||
// makeScanResult creates a ScanResult when peripheral is found.
|
||||
func makeScanResult(prph cbgo.Peripheral, advFields cbgo.AdvFields, rssi int) ScanResult {
|
||||
// TODO: figure out the peripheral info.
|
||||
|
||||
// TODO: create a list of serviceUUIDs.
|
||||
|
||||
return ScanResult{
|
||||
RSSI: int16(rssi),
|
||||
Address: Address{
|
||||
// TODO: fill in this info
|
||||
//MAC: prph.Identifier(),
|
||||
//IsRandom: prph.Identifier == "random",
|
||||
},
|
||||
AdvertisementPayload: &advertisementFields{
|
||||
AdvertisementFields{
|
||||
LocalName: advFields.LocalName,
|
||||
// TODO: fill in this info
|
||||
//ServiceUUIDs: serviceUUIDs,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,59 @@
|
|||
package bluetooth
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/JuulLabs-OSS/cbgo"
|
||||
)
|
||||
|
||||
// Scan starts a BLE scan. It is stopped by a call to StopScan. A common pattern
|
||||
// is to cancel the scan when a particular device has been found.
|
||||
func (a *Adapter) Scan(callback func(*Adapter, ScanResult)) (err error) {
|
||||
return nil
|
||||
if callback == nil {
|
||||
return errors.New("must provide callback to Scan function")
|
||||
}
|
||||
|
||||
if a.cancelChan != nil {
|
||||
return errors.New("already calling Scan function")
|
||||
}
|
||||
|
||||
a.peripheralFoundHandler = callback
|
||||
|
||||
// Channel that will be closed when the scan is stopped.
|
||||
// Detecting whether the scan is stopped can be done by doing a non-blocking
|
||||
// read from it. If it succeeds, the scan is stopped.
|
||||
cancelChan := make(chan struct{})
|
||||
a.cancelChan = cancelChan
|
||||
|
||||
a.cm.Scan(nil, &cbgo.CentralManagerScanOpts{
|
||||
AllowDuplicates: true,
|
||||
})
|
||||
|
||||
for {
|
||||
// Check whether the scan is stopped. This is necessary to avoid a race
|
||||
// condition between the signal channel and the cancelScan channel when
|
||||
// the callback calls StopScan() (no new callbacks may be called after
|
||||
// StopScan is called).
|
||||
select {
|
||||
case <-cancelChan:
|
||||
// stop scanning here?
|
||||
return nil
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StopScan stops any in-progress scan. It can be called from within a Scan
|
||||
// callback to stop the current scan. If no scan is in progress, an error will
|
||||
// be returned.
|
||||
func (a *Adapter) StopScan() error {
|
||||
if a.cancelChan != nil {
|
||||
return errors.New("already calling Scan function")
|
||||
}
|
||||
|
||||
a.cm.StopScan()
|
||||
close(a.cancelChan)
|
||||
a.cancelChan = nil
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
// Implements the CentralManagerDelegate interface. CoreBluetooth
|
||||
// communicates events asynchronously via callbacks. This file implements a
|
||||
// synchronous interface by translating these callbacks into channel
|
||||
// operations.
|
||||
|
||||
package macbt
|
||||
|
||||
import (
|
||||
"github.com/JuulLabs-OSS/cbgo"
|
||||
)
|
||||
|
||||
// CMDelegate to handle callbacks from CoreBluetooth.
|
||||
type CMDelegate struct {
|
||||
}
|
||||
|
||||
func (d *CMDelegate) CentralManagerDidUpdateState(cmgr cbgo.CentralManager) {
|
||||
}
|
||||
|
||||
func (d *CMDelegate) DidDiscoverPeripheral(cmgr cbgo.CentralManager, prph cbgo.Peripheral,
|
||||
advFields cbgo.AdvFields, rssi int) {
|
||||
}
|
||||
|
||||
func (d *CMDelegate) DidConnectPeripheral(cmgr cbgo.CentralManager, prph cbgo.Peripheral) {
|
||||
}
|
||||
|
||||
func (d *CMDelegate) DidDisconnectPeripheral(cmgr cbgo.CentralManager, prph cbgo.Peripheral, err error) {
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
// Package macbt is wrapper to CoreBluetooth.
|
||||
package macbt
|
|
@ -1,35 +0,0 @@
|
|||
// Implements the PeripheralManagerDelegate interface.
|
||||
// CoreBluetooth communicates events asynchronously via callbacks. This file
|
||||
// implements a synchronous interface by translating these callbacks into
|
||||
// channel operations.
|
||||
|
||||
package macbt
|
||||
|
||||
import (
|
||||
"github.com/JuulLabs-OSS/cbgo"
|
||||
)
|
||||
|
||||
// PMDelegate to handle callbacks from CoreBluetooth.
|
||||
type PMDelegate struct {
|
||||
}
|
||||
|
||||
func (d *PMDelegate) PeripheralManagerDidUpdateState(pmgr cbgo.PeripheralManager) {
|
||||
}
|
||||
|
||||
func (d *PMDelegate) DidAddService(pmgr cbgo.PeripheralManager, svc cbgo.Service, err error) {
|
||||
}
|
||||
|
||||
func (d *PMDelegate) DidStartAdvertising(pmgr cbgo.PeripheralManager, err error) {
|
||||
}
|
||||
|
||||
func (d *PMDelegate) DidReceiveReadRequest(pmgr cbgo.PeripheralManager, cbreq cbgo.ATTRequest) {
|
||||
}
|
||||
|
||||
func (d *PMDelegate) DidReceiveWriteRequests(pmgr cbgo.PeripheralManager, cbreqs []cbgo.ATTRequest) {
|
||||
}
|
||||
|
||||
func (d *PMDelegate) CentralDidSubscribe(pmgr cbgo.PeripheralManager, cent cbgo.Central, cbchr cbgo.Characteristic) {
|
||||
}
|
||||
|
||||
func (d *PMDelegate) CentralDidUnsubscribe(pmgr cbgo.PeripheralManager, cent cbgo.Central, chr cbgo.Characteristic) {
|
||||
}
|
Loading…
Reference in a new issue