mplutka / tm-bt-led

Use your Thrustmaster BT LED with your Windows based racing sims on your PC.
MIT License
15 stars 4 forks source link

Linux Support (BlueZ) #7

Open isopix opened 3 years ago

isopix commented 3 years ago

Hi,

I guess you are not interested in Linux, but I wonder how hard it would be to port core functionality.

At fist I saw it's using crossplatform libUSB, so it should be relatively easy...but.. ...It's using USB for charging and firmware upgrade and Bluetooth for communication...so it's probably not the case

When connecting from linux PC to TM_BT_LED it fails. When connecting from to TM_BT_LED it connects and usually disconnects few seconds later. But sometimes stays connected for longer (not sure if it's not default default BlueZ LE 30sec limit for temporary devices.

There are some logs from linux system:

kernel: hid-generic 0005:044F:1000.0009: input,hidraw4: BLUETOOTH HID v1.00 Gamepad [TM BT LED DISPLAY] on 80:86:f2:0f:a6:21

[ 5405.474972] Bluetooth: hci0: LTK blocked for 00:08:d3:f2:03:21
[ 5405.475345] Bluetooth: hci0: unexpected SMP command 0x07 from 00:08:d3:f2:03:21
[ 5405.476335] Bluetooth: hci0: unexpected SMP command 0x08 from 00:08:d3:f2:03:21
[ 5405.476585] Bluetooth: hci0: unexpected SMP command 0x09 from 00:08:d3:f2:03:21

[ 5360.224505] input: TM BT LED DISPLAY as /devices/virtual/misc/uhid/0005:044F:1000.0008/input/input34
[ 5360.224802] input: TM BT LED DISPLAY as /devices/virtual/misc/uhid/0005:044F:1000.0008/input/input35
[ 5360.224957] hid-generic 0005:044F:1000.0008: input,hidraw4: BLUETOOTH HID v1.00 Gamepad [TM BT LED DISPLAY] on 80:86:f2:0f:a6:21
[ 5402.224853] input: TM BT LED DISPLAY as /devices/virtual/misc/uhid/0005:044F:1000.0009/input/input38
[ 5402.225503] input: TM BT LED DISPLAY as /devices/virtual/misc/uhid/0005:044F:1000.0009/input/input39
[ 5402.226053] hid-generic 0005:044F:1000.0009: input,hidraw4: BLUETOOTH HID v1.00 Gamepad [TM BT LED DISPLAY] on 80:86:f2:0f:a6:21
[ 5659.969301] input: TM BT LED DISPLAY as /devices/virtual/misc/uhid/0005:044F:1000.000A/input/input42
[ 5659.971163] input: TM BT LED DISPLAY as /devices/virtual/misc/uhid/0005:044F:1000.000A/input/input43
[ 5659.971296] hid-generic 0005:044F:1000.000A: input,hidraw4: BLUETOOTH HID v1.00 Gamepad [TM BT LED DISPLAY] on 80:86:f2:0f:a6:21
lip 15 21:59:40 sinistar kernel: input: TM BT LED DISPLAY as /devices/virtual/misc/uhid/0005:044F:1000.000A/input/input42
lip 15 21:59:40 sinistar kernel: input: TM BT LED DISPLAY as /devices/virtual/misc/uhid/0005:044F:1000.000A/input/input43
lip 15 21:59:40 sinistar kernel: hid-generic 0005:044F:1000.000A: input,hidraw4: BLUETOOTH HID v1.00 Gamepad [TM BT LED DISPLAY] on 80:86:f2:0f:a6:21
lip 15 21:59:40 sinistar sddm[4191]: (II) config/udev: Adding input device TM BT LED DISPLAY (/dev/input/js1)
lip 15 21:59:40 sinistar sddm[4191]: (II) No input driver specified, ignoring this device.
lip 15 21:59:40 sinistar sddm[4191]: (II) This device may have been added with another device file.
lip 15 21:59:40 sinistar sddm[4191]: (II) config/udev: Adding input device TM BT LED DISPLAY (/dev/input/js0)
lip 15 21:59:40 sinistar sddm[4191]: (II) No input driver specified, ignoring this device.
lip 15 21:59:40 sinistar sddm[4191]: (II) This device may have been added with another device file.
lip 15 21:59:40 sinistar systemd-udevd[290613]: event28: /etc/udev/rules.d/99-whatpulse-input.rules:1 Only network interfaces can be renamed, ignoring NAME="input/%k".
lip 15 21:59:40 sinistar sddm[4191]: (II) config/udev: Adding input device TM BT LED DISPLAY (/dev/input/event28)
lip 15 21:59:40 sinistar sddm[4191]: (II) No input driver specified, ignoring this device.
lip 15 21:59:40 sinistar sddm[4191]: (II) This device may have been added with another device file.
lip 15 21:59:40 sinistar systemd-udevd[290511]: event27: /etc/udev/rules.d/99-whatpulse-input.rules:1 Only network interfaces can be renamed, ignoring NAME="input/%k".
lip 15 21:59:40 sinistar sddm[4191]: (II) config/udev: Adding input device TM BT LED DISPLAY (/dev/input/event27)
lip 15 21:59:40 sinistar sddm[4191]: (II) No input driver specified, ignoring this device.
lip 15 21:59:40 sinistar sddm[4191]: (II) This device may have been added with another device file.
lip 15 21:59:40 sinistar bluedevil-wizard[290509]: bluedevil.wizard: Manager initialized
lip 15 21:59:40 sinistar bluedevil-wizard[290509]: bluedevil.wizard: Initialize Discover Page
lip 15 21:59:41 sinistar kded5[4278]: bluedevil: AGENT-RequestAuthorization
lip 15 21:59:41 sinistar sudo[290730]: pam_systemd_home(sudo:account): systemd-homed is not available: Could not activate remote peer.
lip 15 21:59:41 sinistar audit[290730]: USER_ACCT pid=290730 uid=1000 auid=1000 ses=3 subj==unconfined msg='op=PAM:accounting grantors=pam_unix,pam_permit,pam_time acct="badpixel" exe="/usr/bin/sudo" hostname=? addr=? terminal=? res=success'
lip 15 21:59:41 sinistar audit[290730]: CRED_REFR pid=290730 uid=1000 auid=1000 ses=3 subj==unconfined msg='op=PAM:setcred grantors=pam_pkcs11 acct="root" exe="/usr/bin/sudo" hostname=? addr=? terminal=? res=success'
lip 15 21:59:41 sinistar audit[290730]: USER_START pid=290730 uid=1000 auid=1000 ses=3 subj==unconfined msg='op=PAM:session_open grantors=pam_limits,pam_unix,pam_permit acct="root" exe="/usr/bin/sudo" hostname=? addr=? terminal=? res=success'
isopix commented 3 years ago

By using 'bluetoothctl' command and taking over (from KDE Plasma's BlueDevil, which is unable to pair) control over bluettoth management by calling 'default-agent', I was able to accept pairing and connect ^^

It presents itself as two joypads. First with 4 axes and 3 buttons. that somehow reacts to knobs and buttons, and second one that acts as joystivk with 4axes and 16buttons, thats dead. Not sure where I could manage display

info 00:08:D3:F2:03:21

Device 00:08:D3:F2:03:21 (public)
        Name: TM BT LED DISPLAY
        Alias: TM BT LED DISPLAY
        Appearance: 0x03c0
        Paired: yes
        Trusted: yes
        Blocked: no
        Connected: yes
        WakeAllowed: yes
        LegacyPairing: no
        UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
        UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
        UUID: Device Information        (0000180a-0000-1000-8000-00805f9b34fb)
        UUID: Battery Service           (0000180f-0000-1000-8000-00805f9b34fb)
        UUID: Human Interface Device    (00001812-0000-1000-8000-00805f9b34fb)
        Modalias: usb:v044Fp1000d0100
lip 15 22:52:08 sinistar kernel: input: TM BT LED DISPLAY as /devices/virtual/misc/uhid/0005:044F:1000.001B/input/input110
lip 15 22:52:08 sinistar kernel: input: TM BT LED DISPLAY as /devices/virtual/misc/uhid/0005:044F:1000.001B/input/input111
lip 15 22:52:08 sinistar kernel: hid-generic 0005:044F:1000.001B: input,hidraw4: BLUETOOTH HID v1.00 Gamepad [TM BT LED DISPLAY] on 80:86:f2:0f:a6:21
lip 15 22:52:08 sinistar sddm[4191]: (II) config/udev: Adding input device TM BT LED DISPLAY (/dev/input/js0)
lip 15 22:52:08 sinistar sddm[4191]: (II) config/udev: Adding input device TM BT LED DISPLAY (/dev/input/js1)
lip 15 22:52:08 sinistar sddm[4191]: (II) config/udev: Adding input device TM BT LED DISPLAY (/dev/input/event27)
lip 15 22:52:08 sinistar sddm[4191]: (II) config/udev: Adding input device TM BT LED DISPLAY (/dev/input/event28)

[ 8815.942124] Bluetooth: hci0: LTK blocked for 00:08:d3:f2:03:21
[ 8816.192126] Bluetooth: hci0: unexpected SMP command 0x07 from 00:08:d3:f2:03:21
[ 8816.442124] Bluetooth: hci0: unexpected SMP command 0x08 from 00:08:d3:f2:03:21
[ 8816.691998] Bluetooth: hci0: unexpected SMP command 0x09 from 00:08:d3:f2:03:21
isopix commented 3 years ago

It looks that hard part is node-irsdk.

When running: 'npm install @abandonware/noble'


npm ERR! code 1
npm ERR! git dep preparation failed
npm ERR! command /usr/bin/node /usr/lib/node_modules/npm/bin/npm-cli.js install --force --cache=/home/badpixel/.npm --prefer-offline=false --prefer-online=false --offline=false --no-progress --no-save --no-audit
npm ERR! > node-irsdk@2.1.6 install
npm ERR! > prebuild-install || node-gyp rebuild
npm ERR! 
npm ERR! make: Entering directory '/home/badpixel/.npm/_cacache/tmp/git-clone-4416e229/build'
npm ERR!   CXX(target) Release/obj.target/IrSdkNodeBindings/src/cpp/IrSdkNodeBindings.o
npm ERR! make: Leaving directory '/home/badpixel/.npm/_cacache/tmp/git-clone-4416e229/build'
npm ERR! npm WARN using --force Recommended protections disabled.
npm ERR! gyp info it worked if it ends with ok
npm ERR! gyp info using node-gyp@3.8.0
npm ERR! gyp info using node@14.16.0 | linux | x64
npm ERR! gyp info spawn /usr/bin/python2
npm ERR! gyp info spawn args [
npm ERR! gyp info spawn args   '/home/badpixel/.npm/_cacache/tmp/git-clone-4416e229/node_modules/node-gyp/gyp/gyp_main.py',
npm ERR! gyp info spawn args   'binding.gyp',
npm ERR! gyp info spawn args   '-f',
npm ERR! gyp info spawn args   'make',
npm ERR! gyp info spawn args   '-I',
npm ERR! gyp info spawn args   '/home/badpixel/.npm/_cacache/tmp/git-clone-4416e229/build/config.gypi',
npm ERR! gyp info spawn args   '-I',
npm ERR! gyp info spawn args   '/home/badpixel/.npm/_cacache/tmp/git-clone-4416e229/node_modules/node-gyp/addon.gypi',
npm ERR! gyp info spawn args   '-I',
npm ERR! gyp info spawn args   '/home/badpixel/.node-gyp/14.16.0/include/node/common.gypi',
npm ERR! gyp info spawn args   '-Dlibrary=shared_library',
npm ERR! gyp info spawn args   '-Dvisibility=default',
npm ERR! gyp info spawn args   '-Dnode_root_dir=/home/badpixel/.node-gyp/14.16.0',
npm ERR! gyp info spawn args   '-Dnode_gyp_dir=/home/badpixel/.npm/_cacache/tmp/git-clone-4416e229/node_modules/node-gyp',
npm ERR! gyp info spawn args 
```  '-Dnode_lib_file=/home/badpixel/.node-gyp/14.16.0/<(target_arch)/node.lib',
npm ERR! gyp info spawn args   '-Dmodule_root_dir=/home/badpixel/.npm/_cacache/tmp/git-clone-4416e229',
npm ERR! gyp info spawn args   '-Dnode_engine=v8',
npm ERR! gyp info spawn args   '--depth=.',
npm ERR! gyp info spawn args   '--no-parallel',
npm ERR! gyp info spawn args   '--generator-output',
npm ERR! gyp info spawn args   'build',
npm ERR! gyp info spawn args   '-Goutput_dir=.'
npm ERR! gyp info spawn args ]
npm ERR! gyp info spawn make
npm ERR! gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
npm ERR! ../src/cpp/IrSdkNodeBindings.cpp:1:6: warning: #pragma once in main file
npm ERR!     1 | #pragma once
npm ERR!       |      ^~~~
npm ERR! In file included from ../src/cpp/IRSDKWrapper.h:3,
npm ERR!                  from ../src/cpp/IrSdkNodeBindings.cpp:3:
npm ERR! ../src/cpp/irsdk/irsdk_defines.h:84:10: fatal error: tchar.h: No such file or directory
npm ERR!    84 | #include <tchar.h>
npm ERR!       |          ^~~~~~~~~
npm ERR! compilation terminated.
npm ERR! make: *** [IrSdkNodeBindings.target.mk:114: Release/obj.target/IrSdkNodeBindings/src/cpp/IrSdkNodeBindings.o] Error 1
npm ERR! gyp ERR! build error 
npm ERR! gyp ERR! stack Error: `make` failed with exit code: 2
npm ERR! gyp ERR! stack     at ChildProcess.onExit (/home/badpixel/.npm/_cacache/tmp/git-clone-4416e229/node_modules/node-gyp/lib/build.js:262:23)
npm ERR! gyp ERR! stack     at ChildProcess.emit (events.js:315:20)
npm ERR! gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:277:12)
npm ERR! gyp ERR! System Linux 5.13.1-zen1-1-zen
npm ERR! gyp ERR! command "/usr/bin/node" "/home/badpixel/.npm/_cacache/tmp/git-clone-4416e229/node_modules/.bin/node-gyp" "rebuild"
npm ERR! gyp ERR! cwd /home/badpixel/.npm/_cacache/tmp/git-clone-4416e229
npm ERR! gyp ERR! node -v v14.16.0
npm ERR! gyp ERR! node-gyp -v v3.8.0
npm ERR! gyp ERR! not ok 
npm ERR! npm ERR! code 1
npm ERR! npm ERR! path /home/badpixel/.npm/_cacache/tmp/git-clone-4416e229
npm ERR! npm ERR! command failed
npm ERR! npm ERR! command sh -c prebuild-install || node-gyp rebuild
npm ERR! 
npm ERR! npm ERR! A complete log of this run can be found in:
npm ERR! npm ERR!     /home/badpixel/.npm/_logs/2021-07-15T21_44_41_104Z-debug.log

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/badpixel/.npm/_logs/2021-07-15T21_45_31_839Z-debug.log
mplutka commented 3 years ago

First of all thank you for diving into this and your feedback. Linux support and escpecially connecting the TM BT Led to a Raspberry Pi was already on my agenda but no concrete plans for this. Linux then can only act as a receiver for UDP telemetry data. iRacing and all the other games dependent on shared memory access most likely won't work. So you could try to exclude it from installing and building.

The main point in talking to this device is using Bluetooh LE using the GATT protocol: https://www.jaredwolff.com/get-started-with-bluetooth-low-energy/. You should see several characteristics and handles published by the device. I reverse engineered (trial and error ;-) ) the internal bit representation of all led and display states and put them into a buffer. Using the tmBtLed.js lib, I can set certain bits and am write the modified buffer back to the device by writing it to handle 58 ( _this.peripheral.writeHandle("58", _this.buffer, true);) So thats basically how it's done.

isopix commented 1 year ago

Why it does need modified bluetooth stack and RAW access?

Because windows is limited, or it needs modified bluetooth system services, or even drivers to emulate some PS4/PS5 behaviour?

mplutka commented 1 year ago

The TM BT Led acts as a HID device in Windows and by design direct access to HID devices via the normal bluetooth stack is prohibited due to security reasons (keyloggers etc). Libusb on the other hand allows access without restrictions.