Jakeler / ble-serial

"RFCOMM for BLE" a UART over Bluetooth low energy (4+) bridge for Linux, Mac and Windows
https://blog.ja-ke.tech/tags/#bluetooth
MIT License
264 stars 37 forks source link

feature possible? tty instead of pts #6

Closed elepete closed 4 years ago

elepete commented 4 years ago

The ble-serial works great - thanks - I have tried it on Debian Buster to connect a HM-11, that I want to use in drones (betaflight / INAV) to connect to the PC to configure. The issue I have is that the pts is not accepted by the program (INAV Configurator). I am not sure on the exact reason, but without any deeper knowledge I attribute that to the difference between tty and pts. Is this something that can be changed in ble-serial?

Jakeler commented 4 years ago

I can reproduce this with Betaflight configurator and looked into it. It runs on NW.js, which is basically a Chrome browser, so I installed the SDK and opened DevTools. They are using the builtin serial method: https://developer.chrome.com/apps/serial#method-connect Connection immediately fails, unfortunately the runtime.lastError message is not helpful, just says "Failed to connect to the port". I could not find any more specific info... Can be also tested in the console:

chrome.serial.connect('/tmp/ttyBLE', con => con)

That is unexpected, because every other serial tool that I tried had no problem opening the pseudo tty. (Let me know when you find anything else). In theory it should not make a difference.

In addition I have now tried tty0tty, a kernel module that more closely emulates a serial device. But Chrome fails also with that. It seems to only accept real ports, but I don't know why. Would require looking into the chromium source... I don't think there is any alternative for ble-serial to create a tty.

Edit: Relevant chromium source: https://source.chromium.org/chromium/chromium/src/+/master:extensions/browser/api/serial/serial_api.cc;l=167;drc=c490c976f9de5ed4f068bc84c91ba0940d89f034;bpv=0;bpt=1?originalUrl=https:%2F%2Fcs.chromium.org%2F Any help and clues are appreciated.

elepete commented 4 years ago

Thank you - just reading here and trying to connect dots. Yesterday, when I tried a real UART in the Configurator through a symbolic link, the open fails with the same error. That was an unexpected behaviour. But in that way, I would say the real test is to directly (no symlink) open the device, because the link may overshadow the real behaviour.

Jakeler commented 4 years ago

That is interesting (and annoying) not being able to use symlinks. Still confuses me that tty0tty is not accepted, it creates files directly under /dev from the kernel driver, permissions are the same, ls shows it as character special file, just like any real UART driver.

I came bit further reading chromium source, serial is handled with Mojo: https://source.chromium.org/chromium/chromium/src/+/refs/tags/83.0.4103.105:services/device/public/mojom/serial.mojom;bpv=0;bpt=0?originalUrl=https:%2F%2Fcs.chromium.org%2F This also explains why there is only a generic error message, it returns just a boolean to indicate if it was successful.

Two suspicions now:

elepete commented 4 years ago

Very interesting - I am not in the detail of this stuff, but an observation that I have made is. Only "devices" that are in the pyserial list come as options. Example, if the Configurator is started only 'ttySx' (in my case, 1-4) hardware serial are selectable. Plugging a ttyACM or ttyUSB style it adds to the list of selectable devices in the Configurator. May that be that there is a whitelist like in pyserial (pyserial also explains the symlink treatment)? Could it be that the group needs to be 'dialout' (the working ones {ttyS, ttyACM, ttyUSB} are always dialout group)?

Jakeler commented 4 years ago

No, the group does not matter, for me (on ArchLinux) it would be uucp and i have already tried changing the tty0tty ports to it.

Now I think I am finally close to the serial implementation here (whole folder): https://source.chromium.org/chromium/chromium/src/+/refs/tags/84.0.4147.8:services/device/serial/serial_device_enumerator_linux.cc;bpv=0;bpt=1?originalUrl=https:%2F%2Fcs.chromium.org%2F First of all it explains how the list is generated: udev devices are enumerated and then a filter applied, either it is a serial driver from /proc/tty/drivers or USB or bluetooth (classic rfcomm), otherwise the port is not added. Its is pretty well commented, in the latest revision they even mention that this filters out system tty and pty. Nothing wrong with that for listing, makes sense for normal usage. Still I don't know why it does fail to connect with manually specified ports...

But I noticed something else: This code is constantly changing with different version/tags and on master. So I experimented with a bunch of different versions and found out that it works with NW.js 0.36 (chromium 72)! No problems with pty or symlinks! Starting with NW.js 0.37+ (chromium 73+) it fails. Try BF Configurator 10.6.0, it uses NW.js 0.36.4 per default. It is also possible to run Configurator 10.7.0 on the old NW.js. I haven't tested it extensively, but it does at least connect and commands come through.

elepete commented 4 years ago

I am impressed on your ability to understand and surprised on these changes. As a user of INAV (a betaflight fork with much improved GPS based flying) I went back to INAV Configurator 2.1, that is based on Chromium 71. It works and connects - as expected - well via the HM-11 to flight controller. Issue is at betaflight like INAV with the evolution of the code the configurator moves on, so older versions are no use... :-( And INAV configurator comes for Linux only ready compiled, I never managed to compile the INAV Configurator, again :-( This is sad for me, but I am very thankful, to you taking time to look into this interesting issue. As it seems there is no easy solution - so I only can say thank you!

Jakeler commented 4 years ago

No problem, this is also interesting for me. I used INAV about 2 years ago, then had no real use for it anymore and dissembled the quadcopter. Now I just do some racing with Betaflight, so I had the BF Configurator already installed and that is why I used it for testing. In addition I maintain the nwjs and betaflight-configurator package for Arch, so it is not all new for me ;) Chromium source is new though and I am far away from fully understanding it... I guess we have to create a bug report there to get this properly fixed (or at least find out the reason, if they intentionally block pty).

It is a bit offtopic, but BF and INAV Configurator are technology wise the same. Both are actually very simple and fast to build:

  1. Make sure you have node(js), npm and yarn installed
  2. Download the source code archive, extract it and open a shell in that folder
  3. Run: yarn install and ./node_modules/.bin/gulp dist --linux64
  4. Done! The complete generated app is in the dist subfolder

This is basically a web app (html, js, etc) and doesn't need to be packaged with NW.js (like they do for the standard release). You can download NW.js separately, it is nice that they provide all old releases. Then again extract, open a shell and simply run ./nw /path/to/your/dist

elepete commented 4 years ago

Many thanks! Now you write the procedure. I did manage to compile the Configurator once in the past, but had some issue that made me not thinking properly on that. At least up to here I can say the ble-serial works well, I played a little with it and have to say one limitation of the bay BLE is implemented is, that for serial having a reliable communication speed needs to be limited to 9600 bit/s. Reading a little in the web on that, it is in the genes of the protocol. I was expecting a 19200 just borderline. Testing that with a 'dump all’ in CLI, I saw a few characters missing, at 9600 all communication clean and super. I like your intention to flag that for chromium. It should work as you say always in the manual mode (if there is no intention to really limit).

Jakeler commented 4 years ago

I have opened a chromium bug now: https://crbug.com/1102349

Closing this issue for now, because it can't be fixed in ble-serial alone.

reillyeon commented 4 years ago

Bumping this issue since we didn't get any feedback on crbug/1102349.

Can someone explain the use case for using the Serial API to connect to a PTY?