macos: fixed reentrant service discovery

This commit is contained in:
Baden Parr 2023-06-06 15:06:15 +12:00 committed by Ron Evans
parent 74e8f86261
commit a341e8f543
2 changed files with 24 additions and 14 deletions

View file

@ -93,8 +93,7 @@ type Device struct {
servicesChan chan error servicesChan chan error
charsChan chan error charsChan chan error
services map[UUID]*DeviceService services map[UUID]*DeviceService
characteristics map[UUID]*DeviceCharacteristic
} }
// Connect starts a connection attempt to the given peripheral device address. // Connect starts a connection attempt to the given peripheral device address.
@ -193,13 +192,17 @@ func (pd *peripheralDelegate) DidDiscoverCharacteristics(prph cbgo.Peripheral, s
// or receives a value for a read request. // or receives a value for a read request.
func (pd *peripheralDelegate) DidUpdateValueForCharacteristic(prph cbgo.Peripheral, chr cbgo.Characteristic, err error) { func (pd *peripheralDelegate) DidUpdateValueForCharacteristic(prph cbgo.Peripheral, chr cbgo.Characteristic, err error) {
uuid, _ := ParseUUID(chr.UUID().String()) uuid, _ := ParseUUID(chr.UUID().String())
if char, ok := pd.d.characteristics[uuid]; ok { svcuuid, _ := ParseUUID(chr.Service().UUID().String())
if err == nil && char.callback != nil {
go char.callback(chr.Value())
}
if char.readChan != nil { if svc, ok := pd.d.services[svcuuid]; ok {
char.readChan <- err if char, ok := svc.characteristics[uuid]; ok {
if err == nil && char.callback != nil {
go char.callback(chr.Value())
}
if char.readChan != nil {
char.readChan <- err
}
} }
} }
} }

View file

@ -42,9 +42,11 @@ func (d *Device) DiscoverServices(uuids []UUID) ([]DeviceService, error) {
} }
svc := DeviceService{ svc := DeviceService{
uuidWrapper: dsvcuuid, deviceService: &deviceService{
device: d, uuidWrapper: dsvcuuid,
service: dsvc, device: d,
service: dsvc,
},
} }
svcs = append(svcs, svc) svcs = append(svcs, svc)
d.services[svc.uuidWrapper] = &svc d.services[svc.uuidWrapper] = &svc
@ -61,11 +63,16 @@ type uuidWrapper = UUID
// DeviceService is a BLE service on a connected peripheral device. // DeviceService is a BLE service on a connected peripheral device.
type DeviceService struct { type DeviceService struct {
*deviceService // embdedded as pointer to enable returning by []value in DiscoverServices
}
type deviceService struct {
uuidWrapper uuidWrapper
device *Device device *Device
service cbgo.Service service cbgo.Service
characteristics map[UUID]*DeviceCharacteristic
} }
// UUID returns the UUID for this DeviceService. // UUID returns the UUID for this DeviceService.
@ -88,7 +95,7 @@ func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]DeviceCharacter
s.device.prph.DiscoverCharacteristics(cbuuids, s.service) s.device.prph.DiscoverCharacteristics(cbuuids, s.service)
// clear cache of characteristics // clear cache of characteristics
s.device.characteristics = make(map[UUID]*DeviceCharacteristic) s.characteristics = make(map[UUID]*DeviceCharacteristic)
// wait on channel for characteristic discovery // wait on channel for characteristic discovery
select { select {
@ -143,7 +150,7 @@ func (s *DeviceService) makeCharacteristic(uuid UUID, dchar cbgo.Characteristic)
characteristic: dchar, characteristic: dchar,
}, },
} }
s.device.characteristics[char.uuidWrapper] = &char s.characteristics[char.uuidWrapper] = &char
return char return char
} }