felis / USB_Host_Shield_2.0

Revision 2.0 of USB Host Library for Arduino.
https://chome.nerpa.tech
1.79k stars 780 forks source link

Xbox One S BT Controller does not seem to be connect if already paired #623

Open MasterJubei opened 3 years ago

MasterJubei commented 3 years ago

Hi everyone, Using version 1.5.0 I am using an Arduino Uno for this test. I can do the initial pair the Xbox One S BT controller and it works just fine.

However I cannot get the controller to connect without pairing. The controller is already paired, so I change the line XBOXONESBT Xbox(&Btd, PAIR); to XBOXONESBT Xbox(&Btd); but the controller can't connect.

In other words, the controller only works if I also pair it. It cannot reconnect without the controller and UHS in pair mode.

The PS4 controller example works just fine without needing to be paired each time.

When I set debugging on, this is the output of XBOXONESBT Xbox(&Btd, PAIR);

Xbox One S Bluetooth Library Started
Bluetooth Dongle Initialized
HCI Reset complete
Write class of device
Local Bluetooth Address: 5C:F3:70:A1:E5:EF
Dongle supports secure simple pairing (controller support)
Simple pairing was enabled
Set event mask completed
Please enable discovery of your device
Gamepad found
HID device found
Now just create the instance like so:
BTHID bthid(&Btd);
And then press any button on the device
Remote Name: Xbox Wireless Controller
Connecting to HID device
Connected to HID device
Received Key Request
Received IO Capability Request
SDP Incoming Connection Request
SDP Successfully Configured
Disconnect Request: SDP Channel
Disconnected SDP Channel
User confirmation Request
SDP Incoming Connection Request
SDP Successfully Configured
Disconnect Request: SDP Channel
Disconnected SDP Channel
SDP Incoming Connection Request
SDP Successfully Configured
Disconnect Request: SDP Channel
Disconnected SDP Channel
Pairing successful with HID device
Send HID Control Connection Request
Send HID Control Config Request
Set protocol mode: 00
Send HID Interrupt Connection Request
Send HID Interrupt Config Request
HID Channels Established
Wait For Incoming Connection Request
HCI Disconnected from Device
Wait For Incoming Connection Request
Gamepad is connecting
Incoming Connection Request
Remote Name: Xbox Wireless Controller
Connected to Device: C8:3F:26:46:19:47
Received Key Request
Wait For Incoming Connection Request
HCI Disconnected from Device
Wait For Incoming Connection Request

If I just have XBOXONESBT Xbox(&Btd);

Xbox One S Bluetooth Library Started
Bluetooth Dongle Initialized
HCI Reset complete
Write class of device
Local Bluetooth Address: 5C:F3:70:A1:E5:EF
Dongle supports secure simple pairing (controller support)
Simple pairing was enabled
Set event mask completed
Wait For Incoming Connection Request
HisashiKato commented 3 years ago

This library does not implement the function to save the Link Key generated by pairing (bonding) of Bluetooth Classic SSP on the host side. So, if you turn off the power, reset, rewrite the sketch, etc, the pairing information will be lost. You need to perform the pairing operation every time.

If you used the Library shown below, what are the results? https://github.com/HisashiKato/USB_Host_Shield_Library_2.0_BTXBOX This is a library I make personally. There is no guarantee, so be careful if you use it Please.

If the my library works fine, please ask the author of the original library (USB Host Library 2.0) to implement the function to save the Bluetooth Classic SSP Link Key somewhere.

(it use Google translate)

MasterJubei commented 3 years ago

@HisashiKato Hello, thanks for the link to your project and I see you were the one who did a lot of the work to get the controller working in the first place.

I tried the XB1SBT_Rumble_Demo, and I see it already is defaulted to pair. But my bluetooth dongle does not go into pairing mode with your project. So I cannot pair the controller. In the serial monitor it says:

Xb1s Bluetooth Library Started
Unknown Device Connected - VID: 0A5C PID: 21E8
BTDSSP Init Failed, error code: D1

https://www.amazon.com/gp/product/B007Q45EF4/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1 I am using that dongle. Pairing works fine with the standard USB Host Shield Library, so I don't think it is the dongle.

EDIT: I see you changed the BTD.cpp to BTDSPP.cpp and stored the bluetooth address and key to eeprom. Is that the main change? Thanks

HisashiKato commented 3 years ago

That Bluetooth USB adapter is specially treated by the original USB Host Library. https://github.com/felis/USB_Host_Shield_2.0/blob/master/BTD.h#L30-L34 https://github.com/felis/USB_Host_Shield_2.0/blob/master/BTD.cpp#L226-L236 However, in my library, I decided this was a special case and removed it to reduce the binary capacity as much as possible. If it revert this part to the same as the original library, it will probably work.

MasterJubei commented 3 years ago

Thanks, I still can't seem to get it working. I will keep trying though. https://github.com/HisashiKato/USB_Host_Shield_Library_2.0_BTXBOX/blob/master/src/BTDSSP.cpp#L186-#L193

I changed to

for(uint8_t i = 0; i < num_of_conf; i++) {
        if((VID == IOGEAR_GBU521_VID && PID == IOGEAR_GBU521_PID) || (VID == BELKIN_F8T065BF_VID && PID == BELKIN_F8T065BF_PID)) {
                ConfigDescParser<USB_CLASS_VENDOR_SPECIFIC, WI_SUBCLASS_RF, WI_PROTOCOL_BT, CP_MASK_COMPARE_ALL> confDescrParser(this); // Workaround issue with some dongles
                rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
        } else {
                ConfigDescParser<USB_CLASS_WIRELESS_CTRL, WI_SUBCLASS_RF, WI_PROTOCOL_BT, CP_MASK_COMPARE_ALL> confDescrParser(this); // Set class id according to the specification
                rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
        }
        if(rcode) // Check error code
                goto FailGetConfDescr;
        if(bNumEP >= BTDSSP_MAX_ENDPOINTS) // All endpoints extracted
                break;
}

I also added the #defines

When I run the program

Xb1s Bluetooth Library Started
Bluetooth Dongle Initialized
HCI Reset complete
Write class of device
Simple pairing was enabled
Set Event Mask
HCI_CHECK_DEVICE_SERVICE
pairWithHIDDevice = 01
Please enable discovery of your device.
Gamepad found
BD_ADDR: 00:02:5B:00:0C:EA
HID device found

The bluetooth dongle flashes quickly meaning it is in pairing mode, then after a few seconds it stops pairing. It says it finds the Gamepad even if the Xbox controller is not in pairing mode. If I try to pair the controller quickly, it still does not connect.

EDIT: I tried a different bluetooth dongle, this one does not need the code edit. But it also says the same thing where it finds a Gamepad. But I am not sure why it is doing that.

EDIT2: That mac address belongs to my bluetooth speaker 'RoxaPlus'. That's a bug I guess, I will disconnect it and try it again.

EDIT3: Ah it works now! I can connect the controller without being in pair mode after the initial pair. Thanks a lot!

I will go ahead and see if I can modify the original usb host shield bluetooth files to get the same functionality.

MasterJubei commented 3 years ago

Not the most knowledgeable about git,

But I have managed to get it working with most of the changes you have made and made some of my own. I made it more obvious which requests the Xbox is responsible for and so that it doesn't break compatibility with other controllers. I can connect the controller successfully now without repairing.

I also tested with a PS4 controller to make sure I didn't break anything, all is good there. You can pair, and also reconnect the PS4 controller.

https://github.com/felis/USB_Host_Shield_2.0/compare/master...MasterJubei:xbox_one_s_bt

Works great with the Arduino Uno. I mainly plan to use the Xbox one controller with stm32, so this will require the stm32 library include the arduino EEPROM library.