Skip to content

Commit 5717af5

Browse files
aykevldeadprogram
authored andcommitted
linux: fix characteristic scan order
This is very much like #161, but for Linux instead. In fact, I've copied the structure of the code because it works for macOS. I have tested that the scan order is now as requested. I also verified that multiple characteristics with the same UUID are now supported, but support is still a bit buggy: they appear in a random order (due to Go map iteration order). I will fix this in the next commit.
1 parent 7b36b30 commit 5717af5

File tree

1 file changed

+32
-29
lines changed

1 file changed

+32
-29
lines changed

gattc_linux.go

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,12 @@ func (c *DeviceCharacteristic) UUID() UUID {
143143
// Passing a nil slice of UUIDs will return a complete
144144
// list of characteristics.
145145
func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]DeviceCharacteristic, error) {
146-
chars := []DeviceCharacteristic{}
147-
uuidChars := make(map[string]string)
148-
characteristicsFound := 0
146+
var chars []DeviceCharacteristic
147+
if len(uuids) > 0 {
148+
// The caller wants to get a list of characteristics in a specific
149+
// order.
150+
chars = make([]DeviceCharacteristic, len(uuids))
151+
}
149152

150153
// Iterate through all objects managed by BlueZ, hoping to find the
151154
// characteristic we're looking for.
@@ -165,43 +168,43 @@ func (s *DeviceService) DiscoverCharacteristics(uuids []UUID) ([]DeviceCharacter
165168
if len(strings.Split(suffix, "/")) != 1 {
166169
continue
167170
}
168-
char, err := gatt.NewGattCharacteristic1(objectPath)
171+
characteristic, err := gatt.NewGattCharacteristic1(objectPath)
169172
if err != nil {
170173
return nil, err
171174
}
175+
cuuid, _ := ParseUUID(characteristic.Properties.UUID)
176+
char := DeviceCharacteristic{
177+
uuidWrapper: cuuid,
178+
characteristic: characteristic,
179+
}
172180

173181
if len(uuids) > 0 {
174-
found := false
175-
for _, uuid := range uuids {
176-
if char.Properties.UUID == uuid.String() {
177-
// One of the services we're looking for.
178-
found = true
182+
// The caller wants to get a list of characteristics in a specific
183+
// order. Check whether this is one of those.
184+
for i, uuid := range uuids {
185+
if chars[i] != (DeviceCharacteristic{}) {
186+
// To support multiple identical characteristics, we need to
187+
// ignore the characteristics that are already found. See:
188+
// https://github.com/tinygo-org/bluetooth/issues/131
189+
continue
190+
}
191+
if cuuid == uuid {
192+
// one of the characteristics we're looking for.
193+
chars[i] = char
179194
break
180195
}
181196
}
182-
if !found {
183-
continue
184-
}
185-
}
186-
187-
if _, ok := uuidChars[char.Properties.UUID]; ok {
188-
// There is more than one characteristic with the same UUID?
189-
// Don't overwrite it, to keep the servicesFound count correct.
190-
continue
197+
} else {
198+
// The caller wants to get all characteristics, in any order.
199+
chars = append(chars, char)
191200
}
192-
193-
uuid, _ := ParseUUID(char.Properties.UUID)
194-
dc := DeviceCharacteristic{uuidWrapper: uuid,
195-
characteristic: char,
196-
}
197-
198-
chars = append(chars, dc)
199-
characteristicsFound++
200-
uuidChars[char.Properties.UUID] = char.Properties.UUID
201201
}
202202

203-
if characteristicsFound < len(uuids) {
204-
return nil, errors.New("bluetooth: could not find some characteristics")
203+
// Check that we have found all characteristics.
204+
for _, char := range chars {
205+
if char == (DeviceCharacteristic{}) {
206+
return nil, errors.New("bluetooth: could not find some characteristics")
207+
}
205208
}
206209

207210
return chars, nil

0 commit comments

Comments
 (0)