@@ -19,10 +19,20 @@ var (
1919 errNoWriteWithoutResponse = errors .New ("bluetooth: write without response not supported" )
2020 errWriteFailed = errors .New ("bluetooth: write failed" )
2121 errNoRead = errors .New ("bluetooth: read not supported" )
22- errNoNotify = errors .New ("bluetooth: notify/indicate not supported" )
22+ errNoNotify = errors .New ("bluetooth: notify not supported" )
23+ errNoIndicate = errors .New ("bluetooth: indicate not supported" )
24+ errNoNotifyOrIndicate = errors .New ("bluetooth: notify or indicate not supported" )
25+ errInvalidNotificationMode = errors .New ("bluetooth: invalid notification mode" )
2326 errEnableNotificationsFailed = errors .New ("bluetooth: enable notifications failed" )
2427)
2528
29+ type NotificationMode = genericattributeprofile.GattCharacteristicProperties
30+
31+ const (
32+ NotificationModeNotify NotificationMode = genericattributeprofile .GattCharacteristicPropertiesNotify
33+ NotificationModeIndicate NotificationMode = genericattributeprofile .GattCharacteristicPropertiesIndicate
34+ )
35+
2636// DiscoverServices starts a service discovery procedure. Pass a list of service
2737// UUIDs you are interested in to this function. Either a slice of all services
2838// is returned (of the same length as the requested UUIDs and in the same
@@ -360,14 +370,44 @@ func (c DeviceCharacteristic) Read(data []byte) (int, error) {
360370 return len (readBuffer ), nil
361371}
362372
363- // EnableNotifications enables notifications in the Client Characteristic
373+ // EnableNotifications enables notifications or indicate in the Client Characteristic
374+ // Configuration Descriptor (CCCD). And it favors Notify over Indicate.
375+ func (c DeviceCharacteristic ) EnableNotifications (callback func (buf []byte )) error {
376+ var err error
377+ if c .properties & genericattributeprofile .GattCharacteristicPropertiesNotify == 0 {
378+ err = c .EnableNotificationsWithMode (NotificationModeNotify , callback )
379+ } else if c .properties & genericattributeprofile .GattCharacteristicPropertiesIndicate == 0 {
380+ err = c .EnableNotificationsWithMode (NotificationModeIndicate , callback )
381+ } else {
382+ return errNoNotifyOrIndicate
383+ }
384+
385+ if err != nil {
386+ return err
387+ }
388+ return nil
389+ }
390+
391+ // EnableNotificationsWithMode enables notifications in the Client Characteristic
364392// Configuration Descriptor (CCCD). This means that most peripherals will send a
365393// notification with a new value every time the value of the characteristic
366- // changes.
367- func (c DeviceCharacteristic ) EnableNotifications (callback func (buf []byte )) error {
368- if (c .properties & genericattributeprofile .GattCharacteristicPropertiesNotify == 0 ) &&
369- (c .properties & genericattributeprofile .GattCharacteristicPropertiesIndicate == 0 ) {
370- return errNoNotify
394+ // changes. And you can select the notify/indicate mode as you need.
395+ func (c DeviceCharacteristic ) EnableNotificationsWithMode (mode NotificationMode , callback func (buf []byte )) error {
396+ configValue := genericattributeprofile .GattClientCharacteristicConfigurationDescriptorValueNone
397+ if mode == NotificationModeIndicate {
398+ if c .properties & genericattributeprofile .GattCharacteristicPropertiesIndicate == 0 {
399+ return errNoIndicate
400+ }
401+ // set to indicate mode
402+ configValue = genericattributeprofile .GattClientCharacteristicConfigurationDescriptorValueIndicate
403+ } else if mode == NotificationModeNotify {
404+ if c .properties & genericattributeprofile .GattCharacteristicPropertiesNotify == 0 {
405+ return errNoNotify
406+ }
407+ // set to notify mode
408+ configValue = genericattributeprofile .GattClientCharacteristicConfigurationDescriptorValueNotify
409+ } else {
410+ return errInvalidNotificationMode
371411 }
372412
373413 // listen value changed event
@@ -404,12 +444,7 @@ func (c DeviceCharacteristic) EnableNotifications(callback func(buf []byte)) err
404444 return err
405445 }
406446
407- var writeOp * foundation.IAsyncOperation
408- if c .properties & genericattributeprofile .GattCharacteristicPropertiesNotify != 0 {
409- writeOp , err = c .characteristic .WriteClientCharacteristicConfigurationDescriptorAsync (genericattributeprofile .GattClientCharacteristicConfigurationDescriptorValueNotify )
410- } else {
411- writeOp , err = c .characteristic .WriteClientCharacteristicConfigurationDescriptorAsync (genericattributeprofile .GattClientCharacteristicConfigurationDescriptorValueIndicate )
412- }
447+ writeOp , err := c .characteristic .WriteClientCharacteristicConfigurationDescriptorAsync (configValue )
413448 if err != nil {
414449 return err
415450 }
0 commit comments