Device Hint Filtering

Filtering devices during discovery and connection

The connections process uses a hints system to find a list of potentially viable devices attached to the user's system. From this list of possible devices, we ideally want to filter out anything we know isn't our hardware so the connections process doesn't try connecting to devices which obviously aren't compatible.

Once the filtered list of attached devices populates, the connections manager briefly connects to all viable devices and attempts a handshake. If the handshake is successful, the device appears on the connections page.

What to filter on?

The basic information provided for USB based hardware (most modern products) is as follows:

Identification MemberDescription
comName
manufacturerThe manufacturer of the hardware, this might be "FTDI Pty Ltd", or 'STMicroelectronics'
serialNumberUnique serial number provided as part of the USB device's enumeration
pnpId3-letter code for Plug and Play ID - identifier to unify devices using physical serial ports rather than USB.
locationId4-byte hex address of the device, unique for a given device AND the port it's connected to
vendorId2-byte hex code assigned by USB IF after paid registration
productId2-byte hex identifier set by the company/developer who created the hardware

Typically, your device will use specific USB to Serial converters, or the native USB interface will provide configuration options. If you are making a shipping commercial product, its highly recommended you register your company with the USB IF to get a VendorID assigned to you. From that point, filtering on vendorId will distinguish your hardware.

Many silicon manufacturers such as STMicroelectronics (and USB-TTL converter suppliers), allow users of their IC's to use their VID, which can save the high cost of registering your own VID.

For open source projects, pid.codes provides a method to claim your own PID under a shared VID.

Implementing filters

In your project's .../src/transport-manager/config/serial.ts file, there is a DiscoveryHintConsumer for the serial interface already stubbed out as part of the template.

The DiscoveryHintConsumer in this case processes a set of potential devices which are connected over serial, and then allows for additional filtering. Once hints have been consumed, it passes the hint up the connections chain with relevant baud rate configurations if needed.

const serialConsumer = new DiscoveryHintConsumer({
factory: serialTransportFactory,
canConsume: (hint: Hint) => {
if (hint.getTransportKey() === 'serial') {
const identification = hint.getIdentification()
// just return all serial devices
return true
}
return false
},
configure: (hint: Hint) => {
const identification = hint.getIdentification()
const configuration = hint.getConfiguration()
return {
SerialPort,
comPath: identification.comPath,
baudRate: configuration.baudRate,
}
},
})

To filter devices which only have a manufacturer string matching some specific requirements, you can easily modify the return true to include conditions like so:

return ( identification.manufacturer && identification.manufacturer.includes('Arduino') )

If you want to filter on many possible strings, just chain the logical tests together. Here we test that the manufacturer string has content, and contains text which matches some of the more common USB to Serial converter chipsets.

return (
identification.manufacturer &&
(identification.manufacturer.includes('FTDI') ||
identification.manufacturer.includes('SilliconLabs') ||
identification.manufacturer.includes('Prolific'))
)