From 3e31cedee97a68e7f251134909b25a9002173a48 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Sat, 3 Oct 2020 23:02:35 +0200 Subject: [PATCH] gattc: always return pointers to DeviceService and DeviceCharacteristic types to ensure consistency Signed-off-by: deadprogram --- gattc_darwin.go | 20 ++++++++++---------- gattc_linux.go | 17 +++++++++-------- gattc_sd.go | 16 ++++++++-------- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/gattc_darwin.go b/gattc_darwin.go index 91cc06b..81f3541 100644 --- a/gattc_darwin.go +++ b/gattc_darwin.go @@ -14,7 +14,7 @@ import ( // // Passing a nil slice of UUIDs will return a complete list of // services. -func (d *Device) DiscoverServices(uuids []UUID) ([]DeviceService, error) { +func (d *Device) DiscoverServices(uuids []UUID) ([]*DeviceService, error) { cbuuids := []cbgo.UUID{} for _, u := range uuids { uuid, _ := cbgo.ParseUUID(u.String()) @@ -29,16 +29,16 @@ func (d *Device) DiscoverServices(uuids []UUID) ([]DeviceService, error) { // wait on channel for service discovery select { case <-d.servicesChan: - svcs := []DeviceService{} + svcs := []*DeviceService{} for _, dsvc := range d.prph.Services() { uuid, _ := ParseUUID(dsvc.UUID().String()) - svc := DeviceService{ + svc := &DeviceService{ uuidWrapper: uuid, device: d, service: dsvc, } svcs = append(svcs, svc) - d.services[svc.uuidWrapper] = &svc + d.services[svc.uuidWrapper] = svc } return svcs, nil case <-time.NewTimer(10 * time.Second).C: @@ -73,7 +73,7 @@ func (s *DeviceService) UUID() UUID { // // Passing a nil slice of UUIDs will return a complete list of // characteristics. -func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]DeviceCharacteristic, error) { +func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]*DeviceCharacteristic, error) { cbuuids := []cbgo.UUID{} for _, u := range uuids { uuid, _ := cbgo.ParseUUID(u.String()) @@ -88,16 +88,16 @@ func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]DeviceCharacter // wait on channel for characteristic discovery select { case <-s.device.charsChan: - chars := []DeviceCharacteristic{} + chars := []*DeviceCharacteristic{} for _, dchar := range s.service.Characteristics() { uuid, _ := ParseUUID(dchar.UUID().String()) - char := DeviceCharacteristic{ + char := &DeviceCharacteristic{ uuidWrapper: uuid, service: s, characteristic: dchar, } chars = append(chars, char) - s.device.characteristics[char.uuidWrapper] = &char + s.device.characteristics[char.uuidWrapper] = char } return chars, nil case <-time.NewTimer(10 * time.Second).C: @@ -125,7 +125,7 @@ func (c *DeviceCharacteristic) UUID() UUID { // call will return before all data has been written. A limited number of such // writes can be in flight at any given time. This call is also known as a // "write command" (as opposed to a write request). -func (c DeviceCharacteristic) WriteWithoutResponse(p []byte) (n int, err error) { +func (c *DeviceCharacteristic) WriteWithoutResponse(p []byte) (n int, err error) { c.service.device.prph.WriteCharacteristic(p, c.characteristic, false) return len(p), nil @@ -135,7 +135,7 @@ func (c DeviceCharacteristic) WriteWithoutResponse(p []byte) (n int, err error) // Configuration Descriptor (CCCD). This means that most peripherals will send a // notification with a new value every time the value of the characteristic // changes. -func (c DeviceCharacteristic) EnableNotifications(callback func(buf []byte)) error { +func (c *DeviceCharacteristic) EnableNotifications(callback func(buf []byte)) error { if callback == nil { return errors.New("must provide a callback for EnableNotifications") } diff --git a/gattc_linux.go b/gattc_linux.go index 2b89bcd..865aec1 100644 --- a/gattc_linux.go +++ b/gattc_linux.go @@ -37,7 +37,7 @@ func (s *DeviceService) UUID() UUID { // // On Linux with BlueZ, this just waits for the ServicesResolved signal (if // services haven't been resolved yet) and uses this list of cached services. -func (d *Device) DiscoverServices(uuids []UUID) ([]DeviceService, error) { +func (d *Device) DiscoverServices(uuids []UUID) ([]*DeviceService, error) { for { resolved, err := d.device.GetServicesResolved() if err != nil { @@ -50,7 +50,7 @@ func (d *Device) DiscoverServices(uuids []UUID) ([]DeviceService, error) { time.Sleep(10 * time.Millisecond) } - services := []DeviceService{} + services := []*DeviceService{} uuidServices := make(map[string]string) servicesFound := 0 @@ -98,7 +98,7 @@ func (d *Device) DiscoverServices(uuids []UUID) ([]DeviceService, error) { } uuid, _ := ParseUUID(service.Properties.UUID) - ds := DeviceService{uuidWrapper: uuid, + ds := &DeviceService{uuidWrapper: uuid, service: service, } @@ -136,8 +136,8 @@ func (c *DeviceCharacteristic) UUID() UUID { // // Passing a nil slice of UUIDs will return a complete // list of characteristics. -func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]DeviceCharacteristic, error) { - chars := []DeviceCharacteristic{} +func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]*DeviceCharacteristic, error) { + chars := []*DeviceCharacteristic{} uuidChars := make(map[string]string) characteristicsFound := 0 @@ -185,7 +185,8 @@ func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]DeviceCharacter } uuid, _ := ParseUUID(char.Properties.UUID) - dc := DeviceCharacteristic{uuidWrapper: uuid, + dc := &DeviceCharacteristic{ + uuidWrapper: uuid, characteristic: char, } @@ -205,7 +206,7 @@ func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]DeviceCharacter // call will return before all data has been written. A limited number of such // writes can be in flight at any given time. This call is also known as a // "write command" (as opposed to a write request). -func (c DeviceCharacteristic) WriteWithoutResponse(p []byte) (n int, err error) { +func (c *DeviceCharacteristic) WriteWithoutResponse(p []byte) (n int, err error) { err = c.characteristic.WriteValue(p, nil) if err != nil { return 0, err @@ -217,7 +218,7 @@ func (c DeviceCharacteristic) WriteWithoutResponse(p []byte) (n int, err error) // Configuration Descriptor (CCCD). This means that most peripherals will send a // notification with a new value every time the value of the characteristic // changes. -func (c DeviceCharacteristic) EnableNotifications(callback func(buf []byte)) error { +func (c *DeviceCharacteristic) EnableNotifications(callback func(buf []byte)) error { ch, err := c.characteristic.WatchProperties() if err != nil { return err diff --git a/gattc_sd.go b/gattc_sd.go index 716ba86..6a5fedf 100644 --- a/gattc_sd.go +++ b/gattc_sd.go @@ -62,7 +62,7 @@ func (s *DeviceService) UUID() UUID { // // On the Nordic SoftDevice, only one service discovery procedure may be done at // a time. -func (d *Device) DiscoverServices(uuids []UUID) ([]DeviceService, error) { +func (d *Device) DiscoverServices(uuids []UUID) ([]*DeviceService, error) { if discoveringService.state.Get() != 0 { // Not concurrency safe, but should catch most concurrency misuses. return nil, errAlreadyDiscovering @@ -72,7 +72,7 @@ func (d *Device) DiscoverServices(uuids []UUID) ([]DeviceService, error) { if len(uuids) > 0 { sz = len(uuids) } - services := make([]DeviceService, 0, sz) + services := make([]*DeviceService, 0, sz) var shortUUIDs []C.ble_uuid_t @@ -133,7 +133,7 @@ func (d *Device) DiscoverServices(uuids []UUID) ([]DeviceService, error) { } // Store the discovered service. - svc := DeviceService{ + svc := &DeviceService{ uuid: suuid, connectionHandle: d.connectionHandle, startHandle: startHandle, @@ -191,7 +191,7 @@ var discoveringCharacteristic struct { // // Passing a nil slice of UUIDs will return a complete // list of characteristics. -func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]DeviceCharacteristic, error) { +func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]*DeviceCharacteristic, error) { if discoveringCharacteristic.handle_value.Get() != 0 { return nil, errAlreadyDiscovering } @@ -200,7 +200,7 @@ func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]DeviceCharacter if len(uuids) > 0 { sz = len(uuids) } - characteristics := make([]DeviceCharacteristic, 0, sz) + characteristics := make([]*DeviceCharacteristic, 0, sz) var shortUUIDs []C.ble_uuid_t @@ -276,7 +276,7 @@ func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]DeviceCharacter permissions |= CharacteristicIndicatePermission } - dc := DeviceCharacteristic{uuid: discoveringCharacteristic.uuid} + dc := &DeviceCharacteristic{uuid: discoveringCharacteristic.uuid} dc.permissions = permissions dc.valueHandle = foundCharacteristicHandle @@ -319,7 +319,7 @@ func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]DeviceCharacter // call will return before all data has been written. A limited number of such // writes can be in flight at any given time. This call is also known as a // "write command" (as opposed to a write request). -func (c DeviceCharacteristic) WriteWithoutResponse(p []byte) (n int, err error) { +func (c *DeviceCharacteristic) WriteWithoutResponse(p []byte) (n int, err error) { if len(p) == 0 { return 0, nil } @@ -356,7 +356,7 @@ var gattcNotificationCallbacks []gattcNotificationCallback // Warning: when using the SoftDevice, the callback is called from an interrupt // which means there are various limitations (such as not being able to allocate // heap memory). -func (c DeviceCharacteristic) EnableNotifications(callback func(buf []byte)) error { +func (c *DeviceCharacteristic) EnableNotifications(callback func(buf []byte)) error { if c.permissions&CharacteristicNotifyPermission == 0 { return errNoNotify }