186 lines
5.7 KiB
Go
186 lines
5.7 KiB
Go
|
package cbgo
|
||
|
|
||
|
/*
|
||
|
// See cutil.go for C compiler flags.
|
||
|
#import "bt.h"
|
||
|
*/
|
||
|
import "C"
|
||
|
|
||
|
import (
|
||
|
"unsafe"
|
||
|
)
|
||
|
|
||
|
// CentralManagerRestoreOpts: https://developer.apple.com/documentation/corebluetooth/cbcentralmanager/central_manager_state_restoration_options
|
||
|
type CentralManagerRestoreOpts struct {
|
||
|
Peripherals []Peripheral
|
||
|
ScanServices []UUID
|
||
|
CentralManagerScanOpts *CentralManagerScanOpts // nil if none
|
||
|
}
|
||
|
|
||
|
// CentralManagerScanOpts: https://developer.apple.com/documentation/corebluetooth/cbcentralmanager/peripheral_scanning_options
|
||
|
type CentralManagerScanOpts struct {
|
||
|
AllowDuplicates bool
|
||
|
SolicitedServiceUUIDs []UUID
|
||
|
}
|
||
|
|
||
|
// DfltCentralManagerConnectOpts is the set of options that gets used when nil
|
||
|
// is passed to `Connect()`.
|
||
|
var DfltCentralManagerConnectOpts = CentralManagerConnectOpts{
|
||
|
NotifyOnConnection: true,
|
||
|
NotifyOnDisconnection: true,
|
||
|
NotifyOnNotification: true,
|
||
|
}
|
||
|
|
||
|
// DfltCentralManagerScanOpts is the set of options that gets used when nil is
|
||
|
// passed to `Scan()`.
|
||
|
var DfltCentralManagerScanOpts = CentralManagerScanOpts{}
|
||
|
|
||
|
// CentralManagerConnectOpts: https://developer.apple.com/documentation/corebluetooth/cbcentralmanager/peripheral_connection_options
|
||
|
type CentralManagerConnectOpts struct {
|
||
|
NotifyOnConnection bool
|
||
|
NotifyOnDisconnection bool
|
||
|
NotifyOnNotification bool
|
||
|
EnableTransportBridging bool
|
||
|
RequiresANCS bool
|
||
|
StartDelay int
|
||
|
}
|
||
|
|
||
|
// CentralManager: https://developer.apple.com/documentation/corebluetooth/cbcentralmanager?language=objc
|
||
|
type CentralManager struct {
|
||
|
ptr unsafe.Pointer
|
||
|
}
|
||
|
|
||
|
var cmgrPtrMap = newPtrMap()
|
||
|
|
||
|
func findCentralManagerDlg(ptr unsafe.Pointer) CentralManagerDelegate {
|
||
|
itf := cmgrPtrMap.find(ptr)
|
||
|
if itf == nil {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
return itf.(CentralManagerDelegate)
|
||
|
}
|
||
|
|
||
|
// NewCentralManager creates a central manager. Specify a nil `opts` value for
|
||
|
// defaults. Don't forget to call `SetDelegate()` afterwards!
|
||
|
func NewCentralManager(opts *ManagerOpts) CentralManager {
|
||
|
if opts == nil {
|
||
|
opts = &DfltManagerOpts
|
||
|
}
|
||
|
|
||
|
pwrAlert := C.bool(opts.ShowPowerAlert)
|
||
|
|
||
|
restoreID := (*C.char)(nil)
|
||
|
if opts.RestoreIdentifier != "" {
|
||
|
restoreID = C.CString(opts.RestoreIdentifier)
|
||
|
defer C.free(unsafe.Pointer(restoreID))
|
||
|
}
|
||
|
|
||
|
return CentralManager{
|
||
|
ptr: unsafe.Pointer(C.cb_alloc_cmgr(pwrAlert, restoreID)),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// SetDelegate configures a receiver for a central manager's asynchronous
|
||
|
// callbacks.
|
||
|
func (cm CentralManager) SetDelegate(d CentralManagerDelegate) {
|
||
|
if d != nil {
|
||
|
cmgrPtrMap.add(cm.ptr, d)
|
||
|
}
|
||
|
C.cb_cmgr_set_delegate(cm.ptr, C.bool(d != nil))
|
||
|
}
|
||
|
|
||
|
// State: https://developer.apple.com/documentation/corebluetooth/cbmanager/1648600-state
|
||
|
func (cm CentralManager) State() ManagerState {
|
||
|
return ManagerState(C.cb_cmgr_state(cm.ptr))
|
||
|
}
|
||
|
|
||
|
// Connect: https://developer.apple.com/documentation/corebluetooth/cbcentralmanager/1518766-connectperipheral
|
||
|
func (cm CentralManager) Connect(prph Peripheral, opts *CentralManagerConnectOpts) {
|
||
|
if opts == nil {
|
||
|
opts = &DfltCentralManagerConnectOpts
|
||
|
}
|
||
|
|
||
|
copts := C.struct_connect_opts{
|
||
|
notify_on_connection: C.bool(opts.NotifyOnConnection),
|
||
|
notify_on_disconnection: C.bool(opts.NotifyOnDisconnection),
|
||
|
notify_on_notification: C.bool(opts.NotifyOnNotification),
|
||
|
enable_transport_bridging: C.bool(opts.EnableTransportBridging),
|
||
|
requires_ancs: C.bool(opts.RequiresANCS),
|
||
|
start_delay: C.int(opts.StartDelay),
|
||
|
}
|
||
|
|
||
|
C.cb_cmgr_connect(cm.ptr, prph.ptr, &copts)
|
||
|
}
|
||
|
|
||
|
// CancelConnect: https://developer.apple.com/documentation/corebluetooth/cbcentralmanager/1518952-cancelperipheralconnection
|
||
|
func (cm CentralManager) CancelConnect(prph Peripheral) {
|
||
|
C.cb_cmgr_cancel_connect(cm.ptr, prph.ptr)
|
||
|
}
|
||
|
|
||
|
// RetrieveConnectedPeripheralsWithServices: https://developer.apple.com/documentation/corebluetooth/cbcentralmanager/1518924-retrieveconnectedperipheralswith
|
||
|
func (cm CentralManager) RetrieveConnectedPeripheralsWithServices(uuids []UUID) []Peripheral {
|
||
|
strs := uuidsToStrArr(uuids)
|
||
|
defer freeStrArr(&strs)
|
||
|
|
||
|
var prphs []Peripheral
|
||
|
|
||
|
prphPtrs := C.cb_cmgr_retrieve_prphs_with_svcs(cm.ptr, &strs)
|
||
|
defer C.free(unsafe.Pointer(prphPtrs.objs))
|
||
|
|
||
|
for i := 0; i < int(prphPtrs.count); i++ {
|
||
|
ptr := getObjArrElem(&prphPtrs, i)
|
||
|
prphs = append(prphs, Peripheral{ptr})
|
||
|
}
|
||
|
|
||
|
return prphs
|
||
|
}
|
||
|
|
||
|
// RetrievePeripheralsWithIdentifiers: https://developer.apple.com/documentation/corebluetooth/cbcentralmanager/1519127-retrieveperipheralswithidentifie
|
||
|
func (cm CentralManager) RetrievePeripheralsWithIdentifiers(uuids []UUID) []Peripheral {
|
||
|
strs := uuidsToStrArr(uuids)
|
||
|
defer freeStrArr(&strs)
|
||
|
|
||
|
var prphs []Peripheral
|
||
|
|
||
|
prphPtrs := C.cb_cmgr_retrieve_prphs(cm.ptr, &strs)
|
||
|
defer C.free(unsafe.Pointer(prphPtrs.objs))
|
||
|
|
||
|
for i := 0; i < int(prphPtrs.count); i++ {
|
||
|
ptr := getObjArrElem(&prphPtrs, i)
|
||
|
prphs = append(prphs, Peripheral{ptr})
|
||
|
}
|
||
|
|
||
|
return prphs
|
||
|
}
|
||
|
|
||
|
// Scan: https://developer.apple.com/documentation/corebluetooth/cbcentralmanager/1518986-scanforperipheralswithservices
|
||
|
func (cm CentralManager) Scan(serviceUUIDs []UUID, opts *CentralManagerScanOpts) {
|
||
|
arrSvcUUIDs := uuidsToStrArr(serviceUUIDs)
|
||
|
defer freeStrArr(&arrSvcUUIDs)
|
||
|
|
||
|
if opts == nil {
|
||
|
opts = &DfltCentralManagerScanOpts
|
||
|
}
|
||
|
|
||
|
arrSolSvcUUIDs := uuidsToStrArr(opts.SolicitedServiceUUIDs)
|
||
|
defer freeStrArr(&arrSolSvcUUIDs)
|
||
|
|
||
|
copts := C.struct_scan_opts{
|
||
|
allow_dups: C.bool(opts.AllowDuplicates),
|
||
|
sol_svc_uuids: arrSolSvcUUIDs,
|
||
|
}
|
||
|
|
||
|
C.cb_cmgr_scan(cm.ptr, &arrSvcUUIDs, &copts)
|
||
|
}
|
||
|
|
||
|
// StopScan: https://developer.apple.com/documentation/corebluetooth/cbcentralmanager/1518984-stopscan
|
||
|
func (cm CentralManager) StopScan() {
|
||
|
C.cb_cmgr_stop_scan(cm.ptr)
|
||
|
}
|
||
|
|
||
|
// IsScanning: https://developer.apple.com/documentation/corebluetooth/cbcentralmanager/1620640-isscanning
|
||
|
func (cm CentralManager) IsScanning() bool {
|
||
|
return bool(C.cb_cmgr_is_scanning(cm.ptr))
|
||
|
}
|