Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cursed Bluetooth Hardware #4

Open
Poohl opened this issue May 1, 2021 · 18 comments
Open

Cursed Bluetooth Hardware #4

Poohl opened this issue May 1, 2021 · 18 comments

Comments

@Poohl
Copy link
Owner

Poohl commented May 1, 2021

thread on what we know about bluetooth-adapters and how to make them work: (TLDR commands below)

Brands & Chips

Brand Chip works Notes for V12
Cypress Raspi 3B+, 4B yes see below for v12
Cambridge Silicon Radio ZEXMTE 4.0 yes see Raspi notes or JaredEzz's comment
Cambridge Silicon Radio Generic probably no no bdaddr available
Intel Gigabyte PCIE card no refuses to stay connected
Intel HP Laptop probably no try, intel method.
Intel 9560 in a Thinkpad yes see intel notes
Qualcomm Acer Laptop pre V12 also won't change mac
ASUS BT-400 yes According to #5 the switch absolutely loves it and connects no matter the spd or name...

How it should be

tested on Raspi 4B and switch V10 - v12.0.1

pairing

  1. Disable SDP-records by disabling BlueZ plugins
    change the ExecStart option in /lib/systemd/system/bluetooth.service to
    ExecStart=/usr/lib/bluetooth/bluetoothd -C -P sap,input,avrcp
    (After this BT-controllers, headphones etc. stop working due to a lack of drivers)
  2. restart bluetooth.service (latest patch does this, but any manual changes still require it)
    sudo systemctl daemon-reload
    sudo systemctl restart bluetooth.service

reconnecting

The switch doesn't care a bit beyond the automated class and alias change.
You can change ExecStart back and restart bluetooth to get other bluetooth functionality back.

How to improve success sometimes

Raspi 3/4 "code is running to slow"

FYI: the code is not nearly running as fast as intended. Currently it's targeting 60Hz instead of the default 120Hz for the PRO_CONTROLLER (because I can't get it any higher). However on RasPi 3 and 4 (and potentially others) you can improve the situation by disabling the builtin WIFI. The issue seems to be that the integrated Bluetooth and Wifi are attached to the same Bus (UART 0) and don't cooperate as well as they should affecting performance. You can verify this by running a speedtest over WIFI while running joycontrol.

Switch V12+ connection issues

credit to @thxomas and @JaredEzz for figuring this out
When V12 released, we had better success with the following additional modifications. This however might just have been correlation and not causation.

Change mac

When the MAC is in nintendo's range (94:58:CB:) it sometimes works better. All examples will try to change hci0's address to 94:58:CB:44:55:66

In general:

bdaddr -i hci0 "94:58:CB:44:55:66"
<then soft-reset the controller somehow:>
hciconfig hci0 reset
<or>
bdaddr -i hci0 -r
<or try un- and re-plugging it>

If bdaddr reports "Unsupported Manufacturer" you have the wrong version of bdaddr for your chip vendor.

Intel Bluetooth adapters in Laptops

Thanks to @thxomas, you can use this version of bdaddr compatible with Intel chips and proceed like normal or use the following magic numbers for hcitool to change the MAC (instead of bdaddr):

hcitool cmd 0x3f 0x0031 0x66 0x55 0x44 0xCB 0x58 0x94

Raspi 3B+ & 4B

the included bdaddr should work, but after a fresh boot you once have to use these magic numbers additionally:

hcitool cmd 0x3f 0x001 0x66 0x55 0x44 0xCB 0x58 0x94

Change Name

Usually the alias is enough, but the name can be changed to.
Either in /etc/bluetooth/main.conf or in /etc/machine-info if you have the latter and the hostinfo bluez plugin enabled (default).

Pause input

If you get consistent disconnects in some situation do the following:

  1. [If you want it fixed]:
    install tshark and run tshark -i bluetooth0 -w output.pcapng while it happens (started preferably before joycontrol). Submit an Issue with the file (eg on Gdrive) and output of bluetoothctl show while joycontrol runs.
  2. try to issue pause just before it happens. This will stop any input and usually prevents disconnects for 10 seconds. But you have to unpause within those 10 seconds, else the connection times out.

Troubleshooting

Most commonly: It worked and now it doesn't...

  1. Make sure you're unpaired before pairing on the Change Grip,Order Screen (see unpair.sh)
  2. This is where the title of this thread comes from. For some reason the Switch refuses to ever connect to a given MAC again if the pairing aborted in the wrong moment. Deleting any Bluetooth-pairings inside the switch doesn't work either for some reason, you just have to use another MAC (e.g. increment the last byte by 1) and then retry from the Change Grip,Order Screen
  3. If you loose connection immediately when leaving the pairing screen, now try with the -r <switches mac> option (keep the pairing) and see if you can get a connection on the home screen
  4. When unlocking the switch a takes a second before any button presses are registered: reboot it, you fucked up the input-service inside. (hold power for 6 sec, choose power options -> reboot)
  5. Random disconnects: We're working on it, no clue why...
  6. It's laggy as heck: close any bluetooth settings and disable scanning. (bluetoothctl scan off)
  7. Make sure you're on the v12_fixes branch (git checkout v12_fixes) if you try to connect to v12 switches

TLDR - Just gimme the commands

change mac related stuff

Minor warning: hcitool cmd checks formatting, but other than that the ones and zeros are just send as command to the controller like that.

rpi: hcitool cmd 0x3f 0x001 0x66 0x55 0x44 0xCB 0x58 0x94
intel: hcitool cmd 0x3f 0x0031 0x66 0x55 0x44 0xCB 0x58 0x94
bdaddr -i hci0 "94:58:CB:44:55:66"
bdaddr -i hci0 -r
hciconfig hci0 reset
systemctl daemon-reload
systemctl restart bluetooth.service
./scripts/change_btaddr.sh [opional mac here]

bluetooth configs

/lib/systemd/system/bluetooth.service
/etc/bluetooth/main.conf
/etc/machine-info

pairing related stuff

bluetoothctl paired-devices
bluetoothctl show
bluetoothctl remove <mac here>
./scripts/unpair.sh
@thxomas
Copy link

thxomas commented May 2, 2021

Hi @Poohl !

Tip of the day : Change MAC Address on Intel Wireless Bluetooth Adapters (got Intel 9560 in my Thinkpad)

hcitool cmd 0x3f 0x0031 0x01 0x02 0x03 0xCB 0x58 0x94

I also patched bdaddr to support Intel, but don't know how to share
thxomas

@Poohl
Copy link
Owner Author

Poohl commented May 2, 2021

@thxomas You could push your source to a github repo maybe? or How does the patch look? Modified C-Code? Some fancy bash scripting?

Anyway I'll update the post.

@thxomas
Copy link

thxomas commented May 3, 2021

Basically, bdaddr identifies the BT chip manufacturer then sends the corresponding HCI command.
My patch is just copy-paste a block of C code and change some values to the one I found for Intel.

Made a repo :
https://github.com/thxomas/bdaddr

@Poohl
Copy link
Owner Author

Poohl commented May 3, 2021

@thxomas Just confirmed on my PCIE-Card that the magic numbers actually work.
Question: How the hell did you figure this out? Did you just try random numbers till it changed or is there a method to the madness? Would be intrested in my Qualcomm Atheros thing in my Laptop working again too.

Also: You might wanna consider contributing this to BlueZ's bdaddr .
Procedure for this on github is as follows:

  • Click on Fork (top right) on the repo you want to contribute to.
  • you will then have a copy of that repo, clone it.
  • make the changes, commit and push them
  • open github again, there will be a button "compare and pull request"

@thxomas
Copy link

thxomas commented May 3, 2021

I've been digging the web for BT datasheets, forums, and quickly got sure that the feature was available but it seems Intel decided to disable it in recent windows drivers.
Then I just had to find the right ogf/ocf... I looked for Intel datasheets but they are not public, I tried to search old driver source code and after a couple hours, wireshark source saved my soul : all codes are in the BT dissector !

So here is the magic trick revealed for Intel : 😁

OGF 0x3f means VENDOR_CMD
OCF 0x0031 is Intel opcode for "Write BD Addr"
Followed by parameter (MAC Address to write)

I have no clue whether it works on all Intel controllers or just a subset. I'd just guess that the vendor codes do not change often, and that it worked with my recent Wireless 9560 model so there's a chance it's global.

The fact that Intel decided to remove the feature, made me hesitate to push it to bluez, so I dirty cloned a repo with the bdaddr files only. You can look at the commits to see what I've patched.

I'm now testing joycontrol with a third setup : laptop Intel BT Ubuntu 20. Pairing is successful but reconnects get refused immediately. The SDP is messy and I think they are too many interfering plugins/daemons to keep the hacked Class in place while joycontrolling.

Last but not least : still no clue on why the Switch drops the connection when trying NFC 😭 anyway I enjoy researching this.

Let's keep up !
Thxomas

@Poohl
Copy link
Owner Author

Poohl commented May 3, 2021

@thxomas Something interesting you might want to look into: when the simulated controller is paired, pair a real on aswell and try to read an amiibo on that.
It'll kick the simulated one for no good reason but the real one can read no problem. This leads me to believe that there is something either related to Sniff mode or the number of slots.
I looked into various datasheets already, couldn't find anything helpful yet regarding what the chips in the Controllers do when that happens or how to trigger it manually to simulate it to a controller.

@thxomas
Copy link

thxomas commented May 3, 2021

@Poohl unfortunately I have zero true amiibo.

My actual theory is Max Slots Changed may mean that the switch is closing channnels and I suspect it has requested sniff mode before, but the host refuses hence the disconnect. (Remember my previous tip on link policy to disable SNIFF mode ? I cannot reconnect when it's disabled, so the Switch may request it sometimes.)

Fact against this theory : sniff mode is for powersaving when low traffic, is it a good idea for 60/120Hz messages when you want to minimize input lag ?)

@thxomas
Copy link

thxomas commented May 3, 2021

Sniff mode is very low level in the controller, and bluetoothd debug messages have no hints on why the host would request the controller to deactivate sniff mode after the request from the Switch.

@Poohl
Copy link
Owner Author

Poohl commented May 3, 2021

@thxomas You don't need an amiibo. It kicks the simulated controller as soon as you enter the "read amiibo" screen.
Regarding the SNIFF mode, I tried to set the policy to RSWITCH and NONE, but had the same Issue. No connection.

Sniff mode can also be used to talk to another devices when not busy with the one the Sniff-policy is negotiated with. When proxying you see a Sniff-mode change after every 2 packets or so, since it switches to talking to the other device. (and it works despite that), I'll try to get some NFC going with the Proxy.

So I assume there is some weird behaviour in that Mode-change. It might signal the controller to lower the rate or to go to some kind of sleep mode. Since the controllers-code lives within this low level enviroment of the Bluetooth controller, I think this would be feasable.

@thxomas
Copy link

thxomas commented May 11, 2021

Hello,
I just made my bdaddr fork a release

It now also supports Cypress Semiconductor chips found in the Pi4.

@RawBOT
Copy link

RawBOT commented May 14, 2021

Had some trouble getting it to work on v12.0.1. I basically tried everything multiple times. I don't know exactly what made it work, but it did. I used a RPi 4B, with a Cypress BT adapter.

NFC emulation worked in MH Rise as a Pro Controller. I had to remove and reconnect the joycons for it to trigger, somehow. First time, after setting amiibo content via cmd >> nfc amiibo.bin, it wouldn't trigger in-game. But after I removed one joycon, it successfully worked. I tried again with another amiibo, with my joycons still unplugged, and got it to trigger by reconnecting them physically.

@Poohl
Copy link
Owner Author

Poohl commented May 14, 2021

@RawBOT How did you trigger the NFC-read in game?
My standard procedure is

  • go to home-screen
  • joycontrol -r auto PRO_CONTROLLER
  • cmd >> nfc amiibo.bin
  • cmd >> click home (to get back in game, some get confused when the controller disconnects ingame)
  • cmd >> click a (to start the read)
    Also: what joycons? the Amiibos will be read from either the first controller or the controller that was last used to input. If neither has NFC some other priority-list takes over.
    So for best resuts: have the simulated controller be first and the one to click a or whatever to start the read.

@tangerinetech101
Copy link

tangerinetech101 commented Oct 25, 2021

I still can't get mine to connect. I get too many SPD-records active, Switch might refuse connection.

It says try modifieing /lib/systemd/system/bluetooth.service.

I modified it already with ExecStart=/usr/lib/bluetooth/bluetoothd -C -P sap,input,avrcp. And before that, I had ExecStart=/usr/lib/bluetooth/bluetoothd --noplugin=input because of some other issue that it warned me about.

Anything else I need to do?

It hangs on joycontrol.server create_hid_server::124 INFO - Waiting for Switch to connect... Please open the "Change Grip/Order" menu.

To clarify, I'm on a Raspberry Pi 3B, and like everyone else, pre-v12.0.0 it worked.

@duplicitousfox
Copy link

duplicitousfox commented Nov 19, 2021

Just wanted to mention that I installed Linux Mint on a ASUS ROG laptop that had long since had its screen busted. Wasn't using it for anything else, so I figured why not, right?

Turns out that it has a Broadcomm bluetooth adapter. Had to manually install the driver, but...

$ dmesg | grep -i bluetooth
[ 26.149192] Bluetooth: Core ver 2.22
[ 26.149218] Bluetooth: HCI device and connection manager initialized
[ 26.149230] Bluetooth: HCI socket layer initialized
[ 26.149232] Bluetooth: L2CAP socket layer initialized
[ 26.149234] Bluetooth: SCO socket layer initialized
[ 26.954601] Bluetooth: hci0: BCM: chip id 63
[ 26.955601] Bluetooth: hci0: BCM: features 0x07
[ 26.971641] Bluetooth: hci0: BCM20702A
[ 26.972616] Bluetooth: hci0: BCM20702A1 (001.002.014) build 0000
[ 27.946588] Bluetooth: hci0: BCM20702A1 (001.002.014) build 1479
[ 27.962680] Bluetooth: hci0: Broadcom Bluetooth Device
[ 41.683295] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[ 41.683297] Bluetooth: BNEP filters: protocol multicast
[ 41.683302] Bluetooth: BNEP socket layer initialized
[ 64.397924] Bluetooth: RFCOMM TTY layer initialized
[ 64.397935] Bluetooth: RFCOMM socket layer initialized
[ 64.397944] Bluetooth: RFCOMM ver 1.11

Works perfectly. And I could never get the darned BT adapter working at all when it was alive and running Windows 10. Decided to post this so you can add it to the pile of hardware that works.

too many SPD-records active, Switch might refuse connection.
try modifieing /lib/systemd/system/bluetooth.service and see
https://github.com/Poohl/joycontrol/issues/4 if it doesn't work
[07:27:22] joycontrol.device set_name::114 INFO - setting device name to Pro Controller...
[07:27:22] joycontrol.server create_hid_server::104 INFO - Advertising the Bluetooth SDP record...
[07:27:22] joycontrol.device set_class::104 INFO - setting device class to 0x002508...
[07:27:23] joycontrol.utils run_system_command::75 DEBUG - ['hciconfig hci0 class 0x002508' exited with 0]
[07:27:23] joycontrol.server create_hid_server::117 INFO - Waiting for Switch to connect... Please open the "Change Grip/Order" menu.
[07:27:27] joycontrol.server create_hid_server::121 INFO - Accepted connection at psm 17 from ('7C:BB:8A:DB:18:BB', 17)
[07:27:27] joycontrol.server create_hid_server::123 INFO - Accepted connection at psm 19 from ('7C:BB:8A:DB:18:BB', 19)
[07:27:27] joycontrol.protocol connection_made::256 DEBUG - Connection established.
[07:27:28] joycontrol.transport pause_writing::198 INFO - pause transport write
[07:27:29] root _reply_to_sub_command::204 INFO - received Sub command SubCommand.REQUEST_DEVICE_INFO
cmd >> [07:27:29] joycontrol.transport resume_writing::202 INFO - resume transport write
[07:27:29] root _reply_to_sub_command::204 INFO - received Sub command SubCommand.SET_SHIPMENT_STATE
[07:27:30] root _reply_to_sub_command::204 INFO - received Sub command SubCommand.SPI_FLASH_READ
[07:27:30] root _reply_to_sub_command::204 INFO - received Sub command SubCommand.SPI_FLASH_READ
[07:27:30] root _reply_to_sub_command::204 INFO - received Sub command SubCommand.SET_INPUT_REPORT_MODE
[07:27:30] root _reply_to_sub_command::204 INFO - received Sub command SubCommand.TRIGGER_BUTTONS_ELAPSED_TIME
[07:27:30] root _reply_to_sub_command::204 INFO - received Sub command SubCommand.SPI_FLASH_READ
[07:27:30] root _reply_to_sub_command::204 INFO - received Sub command SubCommand.SPI_FLASH_READ
[07:27:30] root _reply_to_sub_command::204 INFO - received Sub command SubCommand.SPI_FLASH_READ
[07:27:30] root _reply_to_sub_command::204 INFO - received Sub command SubCommand.SPI_FLASH_READ
[07:27:31] root _reply_to_sub_command::204 INFO - received Sub command SubCommand.SPI_FLASH_READ
[07:27:31] root _reply_to_sub_command::204 INFO - received Sub command SubCommand.ENABLE_6AXIS_SENSOR
[07:27:32] root _reply_to_sub_command::204 INFO - received Sub command SubCommand.ENABLE_VIBRATION
[07:27:32] root _reply_to_sub_command::204 INFO - received Sub command SubCommand.SET_NFC_IR_MCU_CONFIG
[07:27:32] root _reply_to_sub_command::204 INFO - received Sub command SubCommand.SET_PLAYER_LIGHTS
[07:27:32] joycontrol.protocol _writer::167 INFO - writer started

JuanPotato added a commit to JuanPotato/joycontrolrs that referenced this issue May 5, 2022
Mac address needs to be changed to start with 94:58:CB: ? maybe ?
Poohl/joycontrol#4

Probably will move back away from async. Not sure why I was doing it, but this is some old code
@lolomatiko256
Copy link

i dont know what im doing wrong cus i did everything i changed the mac addres changend this thing with the input flashed my raspberry 3b+ multiple times and the raspberry pi even says connection succesfull on a little pop up (not the on the console) but i just cant get out of the change grip order step (the bluetooth menu says something about no being able to connect cause its a non usable device or something) i just dont know what im doing wrong it just doesnt work and it would be nice if a video tutorial for the raspberry installation would be on youtube cause theres only one italian guy that made such a video and that method doesnt work pls help

@MrNerdversum
Copy link

MrNerdversum commented Feb 10, 2023

@Poohl just for the list of cursed bluetooth hardware (broadcom manufacturer btw)

Macs with M1 work
Unbenannt

@joodle229
Copy link

i keep getting an attribute error when trying to run the pro controller command, what should i do? (i'm new to linux sorry)

attribute error libhidapi

@MrNerdversum
Copy link

MrNerdversum commented Nov 27, 2023

i keep getting an attribute error when trying to run the pro controller command, what should i do? (i'm new to linux sorry)

attribute error libhidapi

On the JoyConDroid discord u find a solution for that. In later versions (1.0.5+) of the HID package they removed some functionality we use so downgrade to 1.0.4 and it works

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants