scratchfoundation / scratch-link

Device interoperability layer for Windows and MacOS
BSD 3-Clause "New" or "Revised" License
104 stars 84 forks source link

Discover devices based on BLE Advertisement Data #112

Closed knandersen closed 5 years ago

knandersen commented 5 years ago

All LEGO devices running the LEGO Wireless Protocol 3.0 and later, such as LEGO Boost, share the same BLE Service and Characteristic UUIDs. This means that with the current implementation of Scratch Link and Scratch VM, searching for a LEGO device only based on UUIDs will discover (and connect to) all other LEGO devices.

According to the protocol, product distinction is done based on BLE Advertisement Data (ref: https://lego.github.io/lego-ble-wireless-protocol-docs/index.html#advertising). Examples of LEGO BLE Advertisement Manufacturer Data:

LEGO Boost: 97 03 00 40 07 00 41 00 LEGO System 2 Port Hub (included in City Train set): 97 03 00 41 07 27 63 00

The most significant byte in this case is the 4th byte, which according to the documentation describes the LEGO System Type and Device Number. 40 is LEGO Boost, 41 is the LEGO System 2 Port Hub.

A proposal could be for the Scratch Extension to provide an additional filter when asking Scratch Link to scan for devices. In the LEGO case, asking for devices with a particular Service UUID + a certain byte value at a certain location in the advertisement data. Curious to hear your thoughts on this!

cwillisf commented 5 years ago

I suggest we follow the current Web Bluetooth proposal:

For example, to discover the LEGO Boost but not the LEGO System 2 Port Hub, the discovery request would look something like this:

{
...
  "filters": [
    {
      "services": [...],
      "manufacturerData": {
        ??: {
          "dataPrefix": [0, 0, 0, 0x40],
          "mask": [0, 0, 0, 0xFF]
        }
      }
    }
  ]
}

...where the ?? is whichever ID the LEGO devices send that manufacturer data under. Possibly 0x0397?

evhan55 commented 5 years ago

@knandersen @cwillisf

I'm about to start work on https://github.com/LLK/scratch-link/issues/104, is it possibly related to the work in this Issue or is it different enough?

knandersen commented 5 years ago

@cwillisf probably knows more about this than me, but I'd say it's different enough!

cwillisf commented 5 years ago

@evhan55 @knandersen yeah, I think the work for #104 and the work for this issue will probably not overlap. Let me know if that turns out to be wrong... I can help with merge conflicts if needed ;)

evhan55 commented 5 years ago

A note from @cwillisf about the implementation for Windows:

I think it would make sense to adjust the Windows version to ignore unknown parts of a filter... if that turns a filter "trivial" then that's fine -- the discovery process will ignore that filter and act accordingly, but if the unknown part is in the same filter as other conditions then it must be making the filter stricter, so accepting the "more general than intended" filter seems fine as a compatibility feature.