How much info does one need to spin a port back up?
Currently, when a developer requests the list of available ports, they get back an object that contains the following properties:
- [ ] comName
- [ ] path
- [ ] pndId
- [ ] manufacturer
- [ ] locationID
- [ ] vendorID
- [ ] productId
- [ ] serialNumber
There are two use cases for this data (that I can think of... if there are more, please add below!):
- Support UI - example, creating a list with a bunch of details about the port.
- Re-establish a connection to an previously used port.
Of the data above, is everything there really needed?
Screenshot that illustrates use case 1.

So, in #20, it turns out that you can only reliably expect to get the path component. Which means all of the above can go away.
Aren't comName and path redundant?
@dhylands, do you mean equivalent? Probably... btw, what do these things look like on Windows?
Found this: http://batchloaf.wordpress.com/2013/02/12/simple-trick-for-sending-characters-to-a-serial-port-in-windows/
So comName seems very windows specific.
path seems like what's important to the OS, and using the basename of the path would give you something to present to the user.
So on windows, path could be COM4 or .\COM4 and you'd present COM4 to the user. On linux, path might be /dev/ttyUSB0 and you'd present ttyUSB0 to the user.
@dhylands I agree. I'm going to drop comName and say that that is the path.
Ok, so, it's seems fairly likely that the serial port will be hooked up via USB. So, to get the min amount of interop, we can guarrantee path. However, if the other details are available, we should supply them too. So, I'm going to propose that we have a SerialPortDetails object that is guaranteed to have a path.
To clarify a bit more, the other properties (pndId, manufacturer, etc.) will be present but set to null if the system can't get to them.
:+1: I think the other data would be very valuable to present to a user
Francis Gulotta [email protected]
On Wed, Nov 6, 2013 at 5:15 PM, Marcos Caceres [email protected]:
To clarify a bit more, the other properties (pndId, manufacturer, etc.) will be present but set to null if the system can't get to them.
— Reply to this email directly or view it on GitHubhttps://github.com/whatwg/serial/issues/19#issuecomment-27919248 .
it's seems fairly likely that the serial port will be hooked up via USB
… or Bluetooth. Anybody have an example on what the interface says for Bluetooth? Or does it act they same way Serial-over-USB does?
Reminder: Even if most use cases for this API is Serial-over-USB, one must not forget that there are valid uses cases for "plain" RS232 serial ports as well, and we should make sure that they work equally well with this API.
@fbender agree. RS232 is a requirement, and I think getting the serial port's path covers this.
i also agree with with @marcoscaceres suggestion regarding path being guaranteed and the rest of the info provided in case we can get them.
just a note: setting them to null if we don't know them might not be the ideal solution. would there be a case where the OS gives us null as a valid value for some of those? if so, i don't know how you would diversify between "we don't know it" and "it's null"?
@voodootikigod or @fbender do you have any insight on this?
I guess we need to do a bit of digging here about the returned values across OSs. It can get a bit messed up between returning undefined, null, or an empty string. The convention on the Web platform is to return null when the value is unknown, AFAIK.
So, in #20, I proposed we use a ES6 map to capture this information.
If we leave SerialPortInformation as a map, then the user agent is free to provide whatever information it can scrape from the OS - with "path" being the guaranteed key value pair in the map.
I think that would be quite useful and would basically solve the "is it null or undefined?" problem - as things that are not defined will simply be missing in the map. Things that are null can literally just be null - otherwise, the values are strings.
WDYT?
In node-serialport we just have null or a string as values. The proposed map in #20 lgtm.
:+1: @marcoscaceres
ok! massive PR coming in a few mins.
The Path in Windows is '//./COM9' whereas the COM Name is just 'COM9'. Basically Windows doesn't ever show users the Path, but you always open the device via its path.
HI Jay,
On Mon, Nov 11, 2013 at 6:05 PM, Jay Beavers [email protected]:
The Path in Windows is '//./COM9' whereas the COM Name is just 'COM9'. Basically Windows doesn't ever show users the Path, but you always open the device via its path.
Well, in Windows you can open using either //./COM9 or .\COM9 or just plain COM9, or COM9:
They'll all work. Using the //./COM9 is the only one thats guaranteed to work regardless of the current working directory/user space mode. IIRC using the //. syntax is also the only way to open COM ports with a number greater than 9.
I was prosing that for linux or windows you can get the COM name by taking the basename of the path.
Most people don't know it, but windows actually supports multiple flavors of user space. Microsoft actually produced a set of posix command line tools (available on the MSDN Resource Kit) that would allow you to create files on NTFS file systems that differed only by case. Or create a file named COM9.
If you happened to get a file named COM9, the ONLY way to actually remove it was to use a posix subsystem rm command.
Dave Hylands Shuswap, BC, Canada http://www.davehylands.com
I'll just note that the path in the implementation side would be only for author convenience (see them more as hints - they are opaque strings): we would not want to allow real paths to be specified by developers to the actual user's device as this has obvious security and possibly privacy implications.
So, it's always the system that says exactly what paths can be accessed (either as strings - or maybe we could look at ES6 symbols?). But it's never the author that get's to construct or structure them.
Just to be clear, a path of "/dev/cu.usbmodem1411" or "COM9" should be visible to the developer (as it would obviously help a lot to know explicitly what port one is speaking to!); but if the developer changes any of those in any way, that would not match anything (hence "//./COM9" should not open any port). Internally, the implementation might resolve things a bit more intelligently.
There are two related but different problems developers are encountering when it comes to the information available about a port. The first, as is framed in this issue, is what information is needed in order to "spin up" a connection to the port. The current draft specification (and what is implemented and shipping in Chromium) sidesteps this somewhat by keeping the method used to map a SerialPort instance to an operating system path an internal implementation detail. Each of the objects returned by navigator.serial.getPorts() corresponds to a valid path even if the path itself is not exposed to developers.
There remains however the question of what a developer should do if there is more than one device returned by navigator.serial.getPorts() and it is important to distinguish between them. To provide an arbitrary example, a point-of-sale system may be connected to both a barcode scanner and cash drawer via serial ports. As currently specified these two devices would create SerialPort instances which are identical.
The simplest solution to this problem is to introduce a random identifier which is associated with a port at the time when the user grants the site permission to access it and is cleared if that permission is revoked (either explicitly or by clearing site data in general). During initial setup the site could ask the user to select the port for each purpose and remember the ID that the browser provides. Internally these IDs could be mapped to properties such as USB serial numbers, plug & play IDs or other stable identifiers as applicable to the type of device and host operating system.
This solution does not however solve the problem of automatically identifying which port should be used for a particular purpose. Some developers have asked, for example, to have access to the USB product name or serial number strings because these strings include information that could determine a device model or version number. Different devices speak different protocols and so this information could be very useful to prevent sending invalid commands to devices in an attempt to probe for more information or requiring the user to make this distinction manually by selecting the necessary ports in the correct order.
I would like to tackle these difficulties with the simplest solution first as providing additional device details, particularly strings, raises more difficult concerns about fingerprinting.
thanks @reillyeon for all the work on webserial - it's been a boon to be able to use it!
i'll share how i've been rather inelegantly working around the inability to get the serial number - i ask users to grant access to the usb device on top of the port. the code essentially is
async connect() {
let devices = await navigator.usb.getDevices({filters: [{vendorId: 0x0403}]});
let ports = await navigator.serial.getPorts({filters: [{usbVendorId: 0x0403}]});
if (!devices.length) {
await navigator.usb.requestDevice({filters: [{vendorId: 0x0403}]});
devices = await navigator.usb.getDevices({filters: [{vendorId: 0x0403}]});
}
if (devices.length) {
this.serialNumber = devices[0].serialNumber;
if (!ports.length) {
await navigator.serial.requestPort({filters: [{usbVendorId: 0x0403}]});
ports = await navigator.serial.getPorts({filters: [{usbVendorId: 0x0403}]});
}
}
}
I don't know enough about the fingerprinting, but to me and to the users these two permission requests look very similar - pretty much the same popup appearing twice, the second showing slightly different values
as such - considering the serialNumber is available via requestDevice, would requestPort really introduce any additional security considerations?
being able to just get port and ask for the serial from the getInfo() would get rid of the extra popup and all the unnecessary back and forth in the code, shortening it to 4 lines
谢谢@reillyeon对于 webserial 上的所有工作 - 能够使用它真是一件幸事!
我将分享我如何相当不优雅地解决无法获取序列号的问题 - 我要求用户授予端口顶部的 USB 设备的访问权限。代码本质上是
async connect() { let devices = await navigator.usb.getDevices({filters: [{vendorId: 0x0403}]}); let ports = await navigator.serial.getPorts({filters: [{usbVendorId: 0x0403}]}); if (!devices.length) { await navigator.usb.requestDevice({filters: [{vendorId: 0x0403}]}); devices = await navigator.usb.getDevices({filters: [{vendorId: 0x0403}]}); } if (devices.length) { this.serialNumber = devices[0].serialNumber; if (!ports.length) { await navigator.serial.requestPort({filters: [{usbVendorId: 0x0403}]}); ports = await navigator.serial.getPorts({filters: [{usbVendorId: 0x0403}]}); } } }我对指纹识别了解不多,但对我和用户来说,这两个权限请求看起来非常相似——几乎相同的弹出窗口出现两次,第二次显示的值略有不同
因此 - 考虑到 serialNumber 可通过 requestDevice 获得,requestPort 是否真的会引入任何额外的安全考虑?
能够直接获取端口并请求串行,这样
getInfo()就可以消除额外的弹出窗口以及代码中所有不必要的来回,将其缩短到 4 行
@tstriker How can I obtain the names of the serial ports, such as COM1, COM2, that are connected and authorized by the user in WebSerial or WebUsb? I can only get {usbProductId: 10, usbVendorId: 8580} via SerialPort.getInfo(), but this is not what I'm looking for."
Let me know if you'd like any adjustments! help me thank u
There are two related but different problems developers are encountering when it comes to the information available about a port. The first, as is framed in this issue, is what information is needed in order to "spin up" a connection to the port. The current draft specification (and what is implemented and shipping in Chromium) sidesteps this somewhat by keeping the method used to map a
SerialPortinstance to an operating system path an internal implementation detail. Each of the objects returned bynavigator.serial.getPorts()corresponds to a valid path even if the path itself is not exposed to developers.There remains however the question of what a developer should do if there is more than one device returned by
navigator.serial.getPorts()and it is important to distinguish between them. To provide an arbitrary example, a point-of-sale system may be connected to both a barcode scanner and cash drawer via serial ports. As currently specified these two devices would createSerialPortinstances which are identical.The simplest solution to this problem is to introduce a random identifier which is associated with a port at the time when the user grants the site permission to access it and is cleared if that permission is revoked (either explicitly or by clearing site data in general). During initial setup the site could ask the user to select the port for each purpose and remember the ID that the browser provides. Internally these IDs could be mapped to properties such as USB serial numbers, plug & play IDs or other stable identifiers as applicable to the type of device and host operating system.
This solution does not however solve the problem of automatically identifying which port should be used for a particular purpose. Some developers have asked, for example, to have access to the USB product name or serial number strings because these strings include information that could determine a device model or version number. Different devices speak different protocols and so this information could be very useful to prevent sending invalid commands to devices in an attempt to probe for more information or requiring the user to make this distinction manually by selecting the necessary ports in the correct order.
I would like to tackle these difficulties with the simplest solution first as providing additional device details, particularly strings, raises more difficult concerns about fingerprinting.
How can I obtain the names of the serial ports, such as COM1, COM2, that are connected and authorized by the user in WebSerial or WebUsb? I can only get {usbProductId: 10, usbVendorId: 8580} via SerialPort.getInfo(), but this is not what I'm looking for."
Let me know if you'd like any adjustments! help me thank u
@SvenMeiLing, it is not currently possible to obtain the names of the serial ports.