linux: all for DiscoverServices and DiscoverCharacteristics to discover all when no specific list of UUIDs

Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
deadprogram 2020-09-02 20:44:17 +02:00 committed by Ayke
parent ac98835ed3
commit fd89ad24a8
2 changed files with 66 additions and 32 deletions

View file

@ -11,6 +11,9 @@ import (
// UUIDs you are interested in to this function. Either a slice of all services // UUIDs you are interested in to this function. Either a slice of all services
// is returned (of the same length as the requested UUIDs and in the same // is returned (of the same length as the requested UUIDs and in the same
// order), or if some services could not be discovered an error is returned. // order), or if some services could not be discovered an error is returned.
//
// 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{} cbuuids := []cbgo.UUID{}
for _, u := range uuids { for _, u := range uuids {
@ -58,6 +61,9 @@ type DeviceService struct {
// discovered an error is returned. If there is no error, the characteristics // discovered an error is returned. If there is no error, the characteristics
// slice has the same length as the UUID slice with characteristics in the same // slice has the same length as the UUID slice with characteristics in the same
// order in the slice as in the requested UUID list. // order in the slice as in the requested UUID list.
//
// 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{} cbuuids := []cbgo.UUID{}
for _, u := range uuids { for _, u := range uuids {

View file

@ -23,8 +23,7 @@ type DeviceService struct {
// is returned (of the same length as the requested UUIDs and in the same // is returned (of the same length as the requested UUIDs and in the same
// order), or if some services could not be discovered an error is returned. // order), or if some services could not be discovered an error is returned.
// //
// Passing a nil slice of UUIDs will currently result in zero services being // Passing a nil slice of UUIDs will return a complete list of
// returned, but this may be changed in the future to return a complete list of
// services. // services.
// //
// On Linux with BlueZ, this just waits for the ServicesResolved signal (if // On Linux with BlueZ, this just waits for the ServicesResolved signal (if
@ -42,7 +41,8 @@ func (d *Device) DiscoverServices(uuids []UUID) ([]DeviceService, error) {
time.Sleep(10 * time.Millisecond) time.Sleep(10 * time.Millisecond)
} }
services := make([]DeviceService, len(uuids)) services := []DeviceService{}
uuidServices := make(map[string]string)
servicesFound := 0 servicesFound := 0
// Iterate through all objects managed by BlueZ, hoping to find the services // Iterate through all objects managed by BlueZ, hoping to find the services
@ -67,24 +67,38 @@ func (d *Device) DiscoverServices(uuids []UUID) ([]DeviceService, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
for i, uuid := range uuids {
if service.Properties.UUID != uuid.String() { if len(uuids) > 0 {
// Not one of the services we're looking for. found := false
for _, uuid := range uuids {
if service.Properties.UUID == uuid.String() {
// One of the services we're looking for.
found = true
break
}
}
if !found {
continue continue
} }
if services[i].service != nil {
// There is more than one service with the same UUID?
// Don't overwrite it, to keep the servicesFound count correct.
continue
}
services[i].UUID = uuid
services[i].service = service
servicesFound++
break
} }
if _, ok := uuidServices[service.Properties.UUID]; ok {
// There is more than one service with the same UUID?
// Don't overwrite it, to keep the servicesFound count correct.
continue
}
uuid, _ := ParseUUID(service.Properties.UUID)
ds := DeviceService{UUID: uuid,
service: service,
}
services = append(services, ds)
servicesFound++
uuidServices[service.Properties.UUID] = service.Properties.UUID
} }
if servicesFound != len(uuids) { if servicesFound <= len(uuids) {
return nil, errors.New("bluetooth: could not find some services") return nil, errors.New("bluetooth: could not find some services")
} }
@ -106,11 +120,11 @@ type DeviceCharacteristic struct {
// slice has the same length as the UUID slice with characteristics in the same // slice has the same length as the UUID slice with characteristics in the same
// order in the slice as in the requested UUID list. // order in the slice as in the requested UUID list.
// //
// Passing a nil slice of UUIDs will currently result in zero characteristics // Passing a nil slice of UUIDs will return a complete
// being returned, but this may be changed in the future to return a complete
// list of characteristics. // list of characteristics.
func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]DeviceCharacteristic, error) { func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]DeviceCharacteristic, error) {
chars := make([]DeviceCharacteristic, len(uuids)) chars := []DeviceCharacteristic{}
uuidChars := make(map[string]string)
characteristicsFound := 0 characteristicsFound := 0
// Iterate through all objects managed by BlueZ, hoping to find the // Iterate through all objects managed by BlueZ, hoping to find the
@ -135,24 +149,38 @@ func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]DeviceCharacter
if err != nil { if err != nil {
return nil, err return nil, err
} }
for i, uuid := range uuids {
if char.Properties.UUID != uuid.String() { if len(uuids) > 0 {
// Not one of the characteristics we're looking for. found := false
for _, uuid := range uuids {
if char.Properties.UUID == uuid.String() {
// One of the services we're looking for.
found = true
break
}
}
if !found {
continue continue
} }
if chars[i].characteristic != nil {
// There is more than one characteristic with the same UUID?
// Don't overwrite it, to keep the servicesFound count correct.
continue
}
chars[i].UUID = uuid
chars[i].characteristic = char
characteristicsFound++
break
} }
if _, ok := uuidChars[char.Properties.UUID]; ok {
// There is more than one characteristic with the same UUID?
// Don't overwrite it, to keep the servicesFound count correct.
continue
}
uuid, _ := ParseUUID(char.Properties.UUID)
dc := DeviceCharacteristic{UUID: uuid,
characteristic: char,
}
chars = append(chars, dc)
characteristicsFound++
uuidChars[char.Properties.UUID] = char.Properties.UUID
} }
if characteristicsFound != len(uuids) { if characteristicsFound < len(uuids) {
return nil, errors.New("bluetooth: could not find some characteristics") return nil, errors.New("bluetooth: could not find some characteristics")
} }