UsbSerialDiscovery - what should it register?

Regarding the Bluetooth binding finder, it only looks for one device, it seems:

	<discovery-methods>
		<discovery-method>
			<service-type>usb</service-type>
			<match-properties>
				<match-property>
					<name>manufacturer</name>
					<regex>(?i).*bluegiga.*</regex>
				</match-property>
				<match-property>
					<name>chipId</name>
					<regex>0258:0001</regex>
				</match-property>
			</match-properties>
		</discovery-method>
	</discovery-methods>

And, impressively, that device seems to have the wrong spec, according to an online lookup I did:

0x2458 0x0001 Bluegiga Technologies BLED112 Bluetooth 4.0 Single Mode Dongle

(Note that the vendorId is different)

This makes me wonder if this finder has ever worked/found anything.

The discovery “filter” comes from the above PR:

https://github.com/openhab/openhab-addons/pull/17099

Are the match-property entries ANDed or ORed? If they are ORed, it will probably work based on the manufacturer text match.

edit: What I also find strange here is that this discovery match is on org.openhab.binding.bluetooth, the pull request was about org.openhab.binding.bluetooth.hdpowerview, which seems to be completely independent of the Bluegiga stick, and the actual support for the stick is in org.openhab.binding.bluetooth.bluegiga. I can’t test this as I don’t have these devices, but does this work at all? Does installing org.openhab.binding.bluetooth automatically install all the “sub-bundles”? If so, it would at least explain why the discovery match is on the “wrong bundle”.

I can only find one UsbSerialDiscoveryParticipant implementation, and that is the EnOcean binding. Neither Z-wave nor Zigbee seem to support bridge discovery, at least not using UsbSerialDiscovery.

Regarding Bluetooth adapter/stick/dongles, I can only find 3 implementations:

  • BlueGiga
  • BlueZ
  • Roaming

A Roaming adapter seems to work by connecting through another adapter, so it’s not really an actual adapter implementation. That leaves BlueGiga and BlueZ.

As said before, from what I can figure out, BlueGiga uses serial communication to control the adapter/stick/dongle.

Interestingly, BlueZ does not. It indeed goes down the other road I mentioned, using JNA/JNI (JNI in the implementations I’ve looked at here) to communicate with the OS and its drivers. It only supports DBus, so it can only ever work on Linux. Furthermore, it requires manual configuration of the Linux installation to work at all. So, a finder might be moot here anyway, since merely installing the binding wouldn’t make anything work.

To sum it up, the only case I can find where the serial port is not used for communication is on Linux, where interestingly, only USB devices with serial port emulation are discovered. A device might have serial port emulation and still be accessed through DBus, obviously, but it would still mean a pretty “random restriction” to what devices are found.

So, to me, it seems like some cleanup is needed here. Either, we should stick to the existing “infrastructure” of USB devices with serial port emulation only, or the interface documentation should be modified and the Linux USB scanning should be altered to work differently. Unfortunately, I’m way too unfamiliar with the sysfs system to even attempt to modify that Linux discovery, the way it’s done today is to first enumerate serial ports, and then find which of these are backed by USB devices. So, the “fundamental logic” of the discovery would have to be altered, USB devices should probably be enumerated on the first level, and the serial port just be another property of the discovered devices.

edit: BlueZ doesn’t seem to use UsbSerialDiscovery, but uses a DeviceManager that probably wraps some Linux native entity. Everything else (that communicates with USB devices) seems to use SerialPortManager to gain access to devices, and in fact there’s very little interaction with UsbSerialDeviceInformation at all. I can’t even find a link between UsbSerialDiscovery and a SerialPortProvider, which is a bit strange. I would have thought that the result of this discovery would at least plug in there, but maybe it would be pointless without an actual way to interact with said serial port. The only places I can find that the information is used, is by the SerialConfigOptionProvider - probably so that discovered USB emulated serial ports are listed for configuration parameters of the correct type/context.

I’ve discovered another “curiosity” - the UsbSerialDiscoveryService does “discover” USB devices (only with serial ports for Linux, with or without for Windows), but there are no participants, so no Things are actually created as a result. I’m trying to wrap my head around how this is supposed to work, and I’ve found that the origin of the service is here:

https://github.com/eclipse-archived/smarthome/pull/5315

You’ll have to excuse my confusion, it’s a bit too many moving parts here, and my mind goes in circles sometimes. The UsbSerialDiscoveryService works as expected, only the EnOcean binding implements a participant, so only if it is installed, something is actually done. That’s fine. I guess what confused me is that “found” devices are logged (with DEBUG) even when there’s no participant to create a discovery result - which is also fine, but it got me down a rabbit hole because I found that it reported a new discovery, but nothing happened to it.

I do see now that it was discussed whether all USB devices should be discovered, or only those with an associated serial port. It seems like it ended up being “serial port only” simply because that was what was simplest to make using the sysfs parsing, and that it was thought of as “good enough”. As such, I think that the current Windows implementation is actually “better”, there’s no reason why it shouldn’t register USB devices without serial ports, although their use might be limited.

But, sadly, this implementation limitation, has made its way into the naming and JavaDocs all over the place, so the way it is now (e.g. UsbSerialDiscoveryService), there’s no reason for anybody to assume that non-serial port emulating USB devices can be found here.

I’d vote for “promoting” it to a general USB discovery service, even if the Linux implementation can currently only find those with serial ports. It should at the very least be documented, but ideally, there should be a fair bit of renaming too. Renaming means breaking though, so I’m not sure what’s the best approach here..?

It seems that only the EnOcean binding would be affected by a renaming among the official add-ons, so it would be easy enough to take care of. But, we have no idea about unofficial bindings. There might potentially also be other “components” that use these classes, although I kind of doubt it.

I see 3 possible options:

  • Do the renaming now, and modify the EnOcean binding accordingly. Leave it up to any non-official add-ons to deal with it.
  • Do some JavaDoc changes now, and “schedule” renaming for 6.0, where the EnOcean binding would be modified accordingly. Non-official add-ons would have more reason to expect breaking on a major version shift.
  • Don’t do any renaming, live with misleading names but explain in the JavaDocs what they are misleading.

Any views on this?