Skip to content

Commit 63ea32c

Browse files
authored
fix(darwin): add DidUpdateNotificationState when enabling notifications (#433)
* fix(darwin): add DidUpdateNotificationState when enabling notifications Currently, enabling notifications does not check for errors. * apply code review
1 parent 7fa3de8 commit 63ea32c

2 files changed

Lines changed: 45 additions & 4 deletions

File tree

gap_darwin.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,20 @@ func (pd *peripheralDelegate) DidWriteValueForCharacteristic(_ cbgo.Peripheral,
256256
}
257257
}
258258
}
259+
260+
// DidUpdateNotificationState is called when the notification state for a characteristic
261+
// has been updated. It reports whether enabling/disabling notifications succeeded.
262+
func (pd *peripheralDelegate) DidUpdateNotificationState(prph cbgo.Peripheral, chr cbgo.Characteristic, err error) {
263+
uuid, _ := ParseUUID(chr.UUID().String())
264+
svcuuid, _ := ParseUUID(chr.Service().UUID().String())
265+
266+
if svc, ok := pd.d.services[svcuuid]; ok {
267+
for _, char := range svc.characteristics {
268+
if char.characteristic == chr && uuid == char.UUID() {
269+
if char.notifyChan != nil {
270+
char.notifyChan <- err
271+
}
272+
}
273+
}
274+
}
275+
}

gattc_darwin.go

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ import (
88
"github.com/tinygo-org/cbgo"
99
)
1010

11-
var errCannotSendWriteWithoutResponse = errors.New("bluetooth: cannot send write without response (buffer full)")
11+
var (
12+
errCannotSendWriteWithoutResponse = errors.New("bluetooth: cannot send write without response (buffer full)")
13+
errTimeoutEnableNotifications = errors.New("timeout on EnableNotifications")
14+
)
1215

1316
var (
1417
_ GATTCService = (*DeviceService)(nil)
@@ -208,6 +211,7 @@ type deviceCharacteristic struct {
208211
callback func(buf []byte)
209212
readChan chan error
210213
writeChan chan error
214+
notifyChan chan error
211215
}
212216

213217
// UUID returns the UUID for this DeviceCharacteristic.
@@ -256,15 +260,35 @@ func (c DeviceCharacteristic) WriteWithoutResponse(p []byte) (int, error) {
256260
// changes.
257261
// Users may call EnableNotifications with a nil callback to disable notifications.
258262
func (c DeviceCharacteristic) EnableNotifications(callback func(buf []byte)) error {
259-
// If callback is nil, disable notifications
263+
c.notifyChan = make(chan error)
264+
260265
if callback == nil {
261266
c.service.device.prph.SetNotify(false, c.characteristic)
262-
c.callback = nil // Clear notification callback
263267
} else {
264-
// Enable notifications and set notification callback
265268
c.callback = callback
266269
c.service.device.prph.SetNotify(true, c.characteristic)
267270
}
271+
272+
// Wait for CoreBluetooth to confirm the notification state change.
273+
var err error
274+
select {
275+
case err = <-c.notifyChan:
276+
case <-time.After(10 * time.Second):
277+
err = errTimeoutEnableNotifications
278+
}
279+
280+
c.notifyChan = nil
281+
282+
if err != nil {
283+
c.callback = nil
284+
return err
285+
}
286+
287+
// Clear callback after confirmed disable.
288+
if callback == nil {
289+
c.callback = nil
290+
}
291+
268292
return nil
269293
}
270294

0 commit comments

Comments
 (0)