-
Notifications
You must be signed in to change notification settings - Fork 187
fix: Darwin services ordering in DiscoverServices #417
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ package bluetooth | |
|
|
||
| import ( | ||
| "errors" | ||
| "slices" | ||
| "time" | ||
|
|
||
| "github.com/tinygo-org/cbgo" | ||
|
|
@@ -24,33 +25,34 @@ func (d Device) DiscoverServices(uuids []UUID) ([]DeviceService, error) { | |
| select { | ||
| case <-d.servicesChan: | ||
| svcs := []DeviceService{} | ||
|
|
||
| if len(uuids) > 0 { | ||
| // The caller wants to get a list of services in a specific | ||
| // order. | ||
| svcs = make([]DeviceService, len(uuids)) | ||
| } | ||
|
|
||
| for _, dsvc := range d.prph.Services() { | ||
| dsvcuuid, _ := ParseUUID(dsvc.UUID().String()) | ||
| // add if in our original list | ||
|
|
||
| // only include services that are included in the input filter | ||
| if len(uuids) > 0 { | ||
| found := false | ||
| for _, uuid := range uuids { | ||
| for j, uuid := range uuids { | ||
| if dsvcuuid.String() == uuid.String() { | ||
| // one of the services we're looking for. | ||
| found = true | ||
| break | ||
| // One of the services we're looking for. | ||
| svcs[j] = d.makeService(dsvcuuid, dsvc) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the loop should probably break as soon as the service uuid is found, but this raises the question if duplicate uuids are allowed in the input of the method (which documentation does not prevent and the code does not check for).
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAIK duplicates should be allowed. |
||
| } | ||
| } | ||
| if !found { | ||
| continue | ||
| } | ||
| } else { | ||
| // The caller wants to get all services, in any order. | ||
| svcs = append(svcs, d.makeService(dsvcuuid, dsvc)) | ||
| } | ||
|
Comment on lines
+46
to
49
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe move this case to the beginning of the loop for clarity |
||
| } | ||
|
|
||
| svc := DeviceService{ | ||
| deviceService: &deviceService{ | ||
| uuidWrapper: dsvcuuid, | ||
| device: d, | ||
| service: dsvc, | ||
| }, | ||
| } | ||
| svcs = append(svcs, svc) | ||
| d.services[svc.uuidWrapper] = svc | ||
| if slices.Contains(svcs, (DeviceService{})) { | ||
| return nil, errors.New("bluetooth: did not find all requested services") | ||
| } | ||
|
|
||
| return svcs, nil | ||
| case <-time.NewTimer(10 * time.Second).C: | ||
| return nil, errors.New("timeout on DiscoverServices") | ||
|
|
@@ -61,6 +63,20 @@ func (d Device) DiscoverServices(uuids []UUID) ([]DeviceService, error) { | |
| // struct method of the same name. | ||
| type uuidWrapper = UUID | ||
|
|
||
| // Small helper to create a DeviceService object. | ||
| func (d Device) makeService(dsvcuuid uuidWrapper, dsvc cbgo.Service) DeviceService { | ||
| svc := DeviceService{ | ||
| deviceService: &deviceService{ | ||
| uuidWrapper: dsvcuuid, | ||
| device: d, | ||
| service: dsvc, | ||
| }, | ||
| } | ||
| // Cache the service in the device's services map, so that we can find it | ||
| d.services[svc.uuidWrapper] = svc | ||
| return svc | ||
| } | ||
|
|
||
| // DeviceService is a BLE service on a connected peripheral device. | ||
| type DeviceService struct { | ||
| *deviceService // embdedded as pointer to enable returning by []value in DiscoverServices | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be simplified:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've used the same "algorithm" that was already implemented in other OS specific.
Should we change it in this PR ?
Should we change all algorithms ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we should look into seeing if we can use shared/improved code for all of them, but probably not in this PR.