Compare commits
3 Commits
ec02bc7bcc
...
5955e369e4
Author | SHA1 | Date | |
---|---|---|---|
5955e369e4 | |||
fbb58a8d99 | |||
b87fea7fb3 |
122
ble_darwin.go
122
ble_darwin.go
|
@ -119,6 +119,7 @@ func (ps *Peripherals) Add(x Peripheral) bool {
|
||||||
}
|
}
|
||||||
//take ownership of this Objective-C object
|
//take ownership of this Objective-C object
|
||||||
x.p.Retain()
|
x.p.Retain()
|
||||||
|
runtime.SetFinalizer(x.p, nil)
|
||||||
x.p.GC()
|
x.p.GC()
|
||||||
item := PeripheralListItem{p: x, seen: time.Now()}
|
item := PeripheralListItem{p: x, seen: time.Now()}
|
||||||
ps.items = append(ps.items, item)
|
ps.items = append(ps.items, item)
|
||||||
|
@ -164,6 +165,8 @@ type DiscoverCharacteristicEvent struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateValueEvent struct {
|
type UpdateValueEvent struct {
|
||||||
|
Peripheral Peripheral
|
||||||
|
Characteristic *ns.CBCharacteristic
|
||||||
Data []byte
|
Data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,6 +228,9 @@ func (b *BLE) Scan() {
|
||||||
if b.state != (ns.CBManagerState)(ns.CBManagerStatePoweredOn) {
|
if b.state != (ns.CBManagerState)(ns.CBManagerStatePoweredOn) {
|
||||||
b.wantScan = true
|
b.wantScan = true
|
||||||
} else {
|
} else {
|
||||||
|
b.peripherals.Lock()
|
||||||
|
b.peripherals.items = b.peripherals.items[:0]
|
||||||
|
b.peripherals.Unlock()
|
||||||
fmt.Printf("Go: Scanning\n")
|
fmt.Printf("Go: Scanning\n")
|
||||||
b.cm.ScanForPeripheralsWithServices(nil, nil)
|
b.cm.ScanForPeripheralsWithServices(nil, nil)
|
||||||
}
|
}
|
||||||
|
@ -241,15 +247,41 @@ func (b *BLE) StopScan() {
|
||||||
b.cm.StopScan()
|
b.cm.StopScan()
|
||||||
}
|
}
|
||||||
|
|
||||||
func connectTracker(b *BLE, x ConnectionListItem) {
|
func CancelConnection(p Peripheral) {
|
||||||
|
b := pdLookup[p.p.Ptr()]
|
||||||
|
if b == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b.connections.Lock()
|
||||||
|
var ch chan string;
|
||||||
|
for _, item := range b.connections.items {
|
||||||
|
if item.p.Identifier == p.Identifier {
|
||||||
|
ch = item.state
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.connections.Unlock()
|
||||||
|
if ch != nil {
|
||||||
|
ch <- "cancel"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func connectTracker(b *BLE, x ConnectionListItem) bool {
|
||||||
fmt.Printf("connectTracker(): %s\n", x.p.Name)
|
fmt.Printf("connectTracker(): %s\n", x.p.Name)
|
||||||
tick := time.NewTicker(time.Second * 5)
|
b.connections.Lock()
|
||||||
select {
|
for _, item := range b.connections.items {
|
||||||
case <-b.connections.close:
|
if item.p.Identifier == x.p.Identifier {
|
||||||
fmt.Printf("Closing connection to %s\n", x.p.Name)
|
fmt.Printf("connectTracker(): already connecting to %s\n", x.p.Name)
|
||||||
b.cm.CancelPeripheralConnection(x.p.p)
|
b.connections.Unlock()
|
||||||
case <-tick.C:
|
return true
|
||||||
fmt.Printf("Connection to %s timed out\n", x.p.Name)
|
}
|
||||||
|
}
|
||||||
|
b.connections.items = append(b.connections.items, x)
|
||||||
|
b.connections.Unlock()
|
||||||
|
fmt.Printf("BLE.Connect(): calling cm.ConnectPeripheral(%p)\n", x.p.p.Ptr())
|
||||||
|
b.cm.ConnectPeripheral(x.p.p, nil)
|
||||||
|
|
||||||
|
cancel := func() {
|
||||||
b.cm.CancelPeripheralConnection(x.p.p)
|
b.cm.CancelPeripheralConnection(x.p.p)
|
||||||
b.connections.Lock()
|
b.connections.Lock()
|
||||||
for n, item := range b.connections.items {
|
for n, item := range b.connections.items {
|
||||||
|
@ -258,20 +290,34 @@ func connectTracker(b *BLE, x ConnectionListItem) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.connections.Unlock()
|
b.connections.Unlock()
|
||||||
b.events <- ConnectTimeoutEvent{x.p}
|
|
||||||
case state := <-x.state:
|
|
||||||
fmt.Printf("connectTracker: state\n")
|
|
||||||
if state == "connected" {
|
|
||||||
fmt.Printf("--connected")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
tick := time.NewTicker(time.Second * 5)
|
||||||
|
select {
|
||||||
|
case <-b.connections.close:
|
||||||
|
fmt.Printf("connectTracker(): Closing connection to %s\n", x.p.Name)
|
||||||
|
b.cm.CancelPeripheralConnection(x.p.p)
|
||||||
|
case <-tick.C:
|
||||||
|
fmt.Printf("connectTracker(): Connection to %s timed out\n", x.p.Name)
|
||||||
|
cancel()
|
||||||
|
b.events <- ConnectTimeoutEvent{x.p}
|
||||||
|
case state := <-x.state:
|
||||||
|
if state == "cancel" {
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
fmt.Printf("connectTracker(): state %s\n", state)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BLE) Connect(p Peripheral) {
|
func (b *BLE) Connect(p Peripheral) bool {
|
||||||
b.Lock()
|
b.Lock()
|
||||||
if !b.ready {
|
if !b.ready {
|
||||||
b.Unlock()
|
b.Unlock()
|
||||||
return
|
fmt.Printf("--BLE not ready\n")
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
b.Unlock()
|
b.Unlock()
|
||||||
if p.p == nil {
|
if p.p == nil {
|
||||||
|
@ -279,19 +325,37 @@ func (b *BLE) Connect(p Peripheral) {
|
||||||
ps := b.cm.RetrievePeripheralsWithIdentifiers(ns.NSArrayWithObjects(ns.NSUUIDAlloc().InitWithUUIDString(ns.NSStringWithGoString(p.Identifier))))
|
ps := b.cm.RetrievePeripheralsWithIdentifiers(ns.NSArrayWithObjects(ns.NSUUIDAlloc().InitWithUUIDString(ns.NSStringWithGoString(p.Identifier))))
|
||||||
if x := (int)(ps.Count()); x > 0 {
|
if x := (int)(ps.Count()); x > 0 {
|
||||||
fmt.Printf("--found %d\n", x)
|
fmt.Printf("--found %d\n", x)
|
||||||
p.p = ps.ObjectAtIndex(0).CBPeripheral()
|
cbp := ps.ObjectAtIndex(0).CBPeripheral()
|
||||||
|
//NOTE: ns.ObjectAtIndex() calls SetFinalizer for us, which will be a problem
|
||||||
|
//later when we call GC(), so we first clear the finalizer here.
|
||||||
|
runtime.SetFinalizer(cbp, nil)
|
||||||
|
p = newPeripheral(cbp)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("--none found\n")
|
fmt.Printf("--none found\n")
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item := ConnectionListItem{p, make(chan string)}
|
item := ConnectionListItem{p, make(chan string)}
|
||||||
b.connections.Add(item)
|
fmt.Printf("BLE.Connect() calling connectTracker\n")
|
||||||
go connectTracker(b, item)
|
return connectTracker(b, item)
|
||||||
//time.Sleep(time.Second/10)
|
}
|
||||||
fmt.Printf("BLE.Connect(): calling cm.ConnectPeripheral(%p)\n", p.p.Ptr())
|
|
||||||
b.cm.ConnectPeripheral(p.p, nil)
|
func Disconnect(p Peripheral) {
|
||||||
fmt.Printf("BLE.Connect() returned\n")
|
b := pdLookup[p.p.Ptr()]
|
||||||
|
found := false
|
||||||
|
b.connections.Lock()
|
||||||
|
for i, item := range b.connections.items {
|
||||||
|
if item.p.Identifier == p.Identifier {
|
||||||
|
found = true
|
||||||
|
b.connections.items = append(b.connections.items[:i], b.connections.items[i+1:]...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.connections.Unlock()
|
||||||
|
if !found {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b.cm.CancelPeripheralConnection(p.p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateState(c *ns.CBCentralManager) {
|
func updateState(c *ns.CBCentralManager) {
|
||||||
|
@ -303,11 +367,13 @@ func updateState(c *ns.CBCentralManager) {
|
||||||
} else {
|
} else {
|
||||||
if b.ready {
|
if b.ready {
|
||||||
close(b.connections.close)
|
close(b.connections.close)
|
||||||
|
b.connections.Lock()
|
||||||
for _, item := range b.connections.items {
|
for _, item := range b.connections.items {
|
||||||
fmt.Printf("Closing connection to %s\n", item.p.Name)
|
fmt.Printf("Closing connection to %s\n", item.p.Name)
|
||||||
b.cm.CancelPeripheralConnection(item.p.p)
|
b.cm.CancelPeripheralConnection(item.p.p)
|
||||||
}
|
}
|
||||||
b.connections.items = b.connections.items[:0]
|
b.connections.items = b.connections.items[:0]
|
||||||
|
b.connections.Unlock()
|
||||||
b.ready = false
|
b.ready = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,11 +385,15 @@ func discoverPeripheral(c *ns.CBCentralManager, p *ns.CBPeripheral, d *ns.NSDict
|
||||||
b := cdLookup[c.Ptr()]
|
b := cdLookup[c.Ptr()]
|
||||||
peripheral := newPeripheral(p)
|
peripheral := newPeripheral(p)
|
||||||
peripheral.RSSI = (int)(rssi.IntValue())
|
peripheral.RSSI = (int)(rssi.IntValue())
|
||||||
|
_discoverPeripheral(b, peripheral)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _discoverPeripheral(b *BLE, peripheral Peripheral) {
|
||||||
if peripheral.Name == "" {
|
if peripheral.Name == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ok := b.peripherals.Add(peripheral); ok {
|
if ok := b.peripherals.Add(peripheral); ok {
|
||||||
pdLookup[p.Ptr()] = b
|
pdLookup[peripheral.p.Ptr()] = b
|
||||||
b.events <- DiscoverPeripheralEvent{Peripheral: peripheral}
|
b.events <- DiscoverPeripheralEvent{Peripheral: peripheral}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -429,6 +499,8 @@ func updateValue(p *ns.CBPeripheral, chr *ns.CBCharacteristic, e *ns.NSError) {
|
||||||
b := pdLookup[p.Ptr()]
|
b := pdLookup[p.Ptr()]
|
||||||
v := chr.Value()
|
v := chr.Value()
|
||||||
b.events <-UpdateValueEvent{
|
b.events <-UpdateValueEvent{
|
||||||
|
Peripheral: newPeripheral(p),
|
||||||
|
Characteristic: chr,
|
||||||
Data: C.GoBytes(v.Bytes(), (C.int)(v.Length())),
|
Data: C.GoBytes(v.Bytes(), (C.int)(v.Length())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user