mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
Xbox One S BT Controller now can connect without repairing every time
This commit is contained in:
parent
a321ad36ab
commit
d5c72511a0
2 changed files with 126 additions and 5 deletions
117
BTD.cpp
117
BTD.cpp
|
@ -639,11 +639,24 @@ void BTD::HCI_event_task() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_LINK_KEY_REQUEST:
|
case EV_LINK_KEY_REQUEST: //For the Xbox One S Controller we can't use the negative reply, other controllers use negative_reply
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nReceived Key Request"), 0x80);
|
Notify(PSTR("\r\nReceived Key Request"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
if ((!pairWithHIDDevice || incomingHIDDevice) && incomingXboxOneS) {
|
||||||
|
for(uint8_t i = 0; i < 16; i ++) {
|
||||||
|
link_key[i] = EEPROM.read(i+6);
|
||||||
|
}
|
||||||
|
hci_link_key_request_reply();
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nhci_link_key_request_reply"), 0x80);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
hci_link_key_request_negative_reply();
|
hci_link_key_request_negative_reply();
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nhci_link_key_request_negative_reply"), 0x80);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_AUTHENTICATION_COMPLETE:
|
case EV_AUTHENTICATION_COMPLETE:
|
||||||
|
@ -718,6 +731,39 @@ void BTD::HCI_event_task() {
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EV_LINK_KEY_NOTIFICATION: //Xbox One S BT Controller, when pairing write the address and link key to EEPROM
|
||||||
|
if(incomingXboxOneS) {
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nLink Key Notification"), 0x80);
|
||||||
|
#endif
|
||||||
|
for(uint8_t i = 0; i < 16; i++) {
|
||||||
|
link_key[i] = hcibuf[8 + i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(uint8_t i = 0; i < 6; i++) {
|
||||||
|
EEPROM.write(i, disc_bdaddr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(uint8_t i = 0; i < 16; i++) {
|
||||||
|
EEPROM.write(i + 6, link_key[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nBD_ADDR: "), 0x80);
|
||||||
|
for(uint8_t i = 0; i < 6; i++) {
|
||||||
|
Notify(PSTR(" "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (hcibuf[2 + i], 0x80);
|
||||||
|
}
|
||||||
|
Notify(PSTR("\r\nLink Key for the associated BD_ADDR: "), 0x80);
|
||||||
|
for(uint8_t i = 0; i < 16; i++) {
|
||||||
|
Notify(PSTR(" "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (hcibuf[8 + i], 0x80);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
/* We will just ignore the following events */
|
/* We will just ignore the following events */
|
||||||
case EV_MAX_SLOTS_CHANGE:
|
case EV_MAX_SLOTS_CHANGE:
|
||||||
case EV_NUM_COMPLETE_PKT:
|
case EV_NUM_COMPLETE_PKT:
|
||||||
|
@ -728,7 +774,6 @@ void BTD::HCI_event_task() {
|
||||||
case EV_DATA_BUFFER_OVERFLOW:
|
case EV_DATA_BUFFER_OVERFLOW:
|
||||||
case EV_CHANGE_CONNECTION_LINK:
|
case EV_CHANGE_CONNECTION_LINK:
|
||||||
case EV_QOS_SETUP_COMPLETE:
|
case EV_QOS_SETUP_COMPLETE:
|
||||||
case EV_LINK_KEY_NOTIFICATION:
|
|
||||||
case EV_ENCRYPTION_CHANGE:
|
case EV_ENCRYPTION_CHANGE:
|
||||||
case EV_READ_REMOTE_VERSION_INFORMATION_COMPLETE:
|
case EV_READ_REMOTE_VERSION_INFORMATION_COMPLETE:
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
|
@ -1015,8 +1060,37 @@ void BTD::HCI_task() {
|
||||||
#endif
|
#endif
|
||||||
incomingPSController = true;
|
incomingPSController = true;
|
||||||
}
|
}
|
||||||
if((pairWithWii || pairWithHIDDevice) && checkRemoteName)
|
|
||||||
|
if(strncmp((const char*)remote_name, "Xbox Wireless Controller", 24 ) == 0) {
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nXbox One S controller is connecting"), 0x80);
|
||||||
|
#endif
|
||||||
|
incomingXboxOneS = true;
|
||||||
|
if(!pairWithHIDDevice) { //If an Xbox One S BT Controller is connecting and it is not in pair mode, check EEPROM for the controller's address
|
||||||
|
pairedDevice = true;
|
||||||
|
for(uint8_t i = 0; i < 6; i++) {
|
||||||
|
if(disc_bdaddr[i] != EEPROM.read(i)) {
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nXbox One S Controller did not match EEPROM"), 0x80);
|
||||||
|
#endif
|
||||||
|
pairedDevice = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!pairedDevice) {
|
||||||
|
hci_state = HCI_SCANNING_STATE;
|
||||||
|
} else {
|
||||||
|
hci_accept_connection();
|
||||||
|
hci_state = HCI_CONNECTED_STATE;
|
||||||
|
}
|
||||||
|
} else { //If the Xbox One S BT controlelr is in pair mode instead
|
||||||
hci_state = HCI_CONNECT_DEVICE_STATE;
|
hci_state = HCI_CONNECT_DEVICE_STATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if((pairWithWii || pairWithHIDDevice) && checkRemoteName) {
|
||||||
|
hci_state = HCI_CONNECT_DEVICE_STATE;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
hci_accept_connection();
|
hci_accept_connection();
|
||||||
hci_state = HCI_CONNECTED_STATE;
|
hci_state = HCI_CONNECTED_STATE;
|
||||||
|
@ -1059,6 +1133,8 @@ void BTD::HCI_task() {
|
||||||
if(hci_check_flag(HCI_FLAG_DISCONNECT_COMPLETE)) {
|
if(hci_check_flag(HCI_FLAG_DISCONNECT_COMPLETE)) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHCI Disconnected from Device"), 0x80);
|
Notify(PSTR("\r\nHCI Disconnected from Device"), 0x80);
|
||||||
|
disconnect(); //xbox one bt s <- doesn't work without this!
|
||||||
|
//Need for the controller to be able to reconnect
|
||||||
#endif
|
#endif
|
||||||
hci_event_flag = 0; // Clear all flags
|
hci_event_flag = 0; // Clear all flags
|
||||||
|
|
||||||
|
@ -1069,10 +1145,11 @@ void BTD::HCI_task() {
|
||||||
connectToWii = incomingWii = pairWithWii = false;
|
connectToWii = incomingWii = pairWithWii = false;
|
||||||
connectToHIDDevice = incomingHIDDevice = pairWithHIDDevice = checkRemoteName = false;
|
connectToHIDDevice = incomingHIDDevice = pairWithHIDDevice = checkRemoteName = false;
|
||||||
incomingPSController = false;
|
incomingPSController = false;
|
||||||
|
incomingXboxOneS = false;
|
||||||
hci_state = HCI_SCANNING_STATE;
|
hci_state = HCI_SCANNING_STATE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1341,6 +1418,38 @@ void BTD::hci_pin_code_negative_request_reply() {
|
||||||
HCI_Command(hcibuf, 9);
|
HCI_Command(hcibuf, 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BTD::hci_link_key_request_reply() {
|
||||||
|
hcibuf[0] = 0x0B; // HCI OCF = 0B
|
||||||
|
hcibuf[1] = 0x01 << 2; // HCI OGF = 1
|
||||||
|
hcibuf[2] = 0x16; // parameter length 22
|
||||||
|
//for(uint8_t i = 0; i < 6; i++) hcibuf[i + 3] = disc_bdaddr[i]; // 6 octet bdaddr
|
||||||
|
hcibuf[3] = disc_bdaddr[0]; // 6 octet bdaddr
|
||||||
|
hcibuf[4] = disc_bdaddr[1];
|
||||||
|
hcibuf[5] = disc_bdaddr[2];
|
||||||
|
hcibuf[6] = disc_bdaddr[3];
|
||||||
|
hcibuf[7] = disc_bdaddr[4];
|
||||||
|
hcibuf[8] = disc_bdaddr[5];
|
||||||
|
//for(uint8_t i = 0; i < 16; i++) hcibuf[i + 9] = link_key[i]; // 16 octet link_key
|
||||||
|
hcibuf[9] = link_key[0]; // 16 octet link_key
|
||||||
|
hcibuf[10] = link_key[1];
|
||||||
|
hcibuf[11] = link_key[2];
|
||||||
|
hcibuf[12] = link_key[3];
|
||||||
|
hcibuf[13] = link_key[4];
|
||||||
|
hcibuf[14] = link_key[5];
|
||||||
|
hcibuf[15] = link_key[6];
|
||||||
|
hcibuf[16] = link_key[7];
|
||||||
|
hcibuf[17] = link_key[8];
|
||||||
|
hcibuf[18] = link_key[9];
|
||||||
|
hcibuf[19] = link_key[10];
|
||||||
|
hcibuf[20] = link_key[11];
|
||||||
|
hcibuf[21] = link_key[12];
|
||||||
|
hcibuf[22] = link_key[13];
|
||||||
|
hcibuf[23] = link_key[14];
|
||||||
|
hcibuf[24] = link_key[15];
|
||||||
|
|
||||||
|
HCI_Command(hcibuf, 25);
|
||||||
|
}
|
||||||
|
|
||||||
void BTD::hci_link_key_request_negative_reply() {
|
void BTD::hci_link_key_request_negative_reply() {
|
||||||
hcibuf[0] = 0x0C; // HCI OCF = 0C
|
hcibuf[0] = 0x0C; // HCI OCF = 0C
|
||||||
hcibuf[1] = 0x01 << 2; // HCI OGF = 1
|
hcibuf[1] = 0x01 << 2; // HCI OGF = 1
|
||||||
|
|
12
BTD.h
12
BTD.h
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
#include "usbhid.h"
|
#include "usbhid.h"
|
||||||
|
#include <EEPROM.h>
|
||||||
|
|
||||||
//PID and VID of the Sony PS3 devices
|
//PID and VID of the Sony PS3 devices
|
||||||
#define PS3_VID 0x054C // Sony Corporation
|
#define PS3_VID 0x054C // Sony Corporation
|
||||||
|
@ -372,6 +373,8 @@ public:
|
||||||
void hci_pin_code_request_reply();
|
void hci_pin_code_request_reply();
|
||||||
/** Respons when no pin was set. */
|
/** Respons when no pin was set. */
|
||||||
void hci_pin_code_negative_request_reply();
|
void hci_pin_code_negative_request_reply();
|
||||||
|
/** Used when we have already been paired, we will use the key in eeprom */
|
||||||
|
void hci_link_key_request_reply();
|
||||||
/**
|
/**
|
||||||
* Command is used to reply to a Link Key Request event from the BR/EDR Controller
|
* Command is used to reply to a Link Key Request event from the BR/EDR Controller
|
||||||
* if the Host does not have a stored Link Key for the connection.
|
* if the Host does not have a stored Link Key for the connection.
|
||||||
|
@ -486,6 +489,10 @@ public:
|
||||||
uint8_t disc_bdaddr[6];
|
uint8_t disc_bdaddr[6];
|
||||||
/** First 30 chars of last remote name. */
|
/** First 30 chars of last remote name. */
|
||||||
char remote_name[30];
|
char remote_name[30];
|
||||||
|
/** Link key **/
|
||||||
|
uint8_t link_key[16];
|
||||||
|
/** Stored Bluetooth address. */
|
||||||
|
uint8_t stored_bdaddr[6];
|
||||||
/**
|
/**
|
||||||
* The supported HCI Version read from the Bluetooth dongle.
|
* The supported HCI Version read from the Bluetooth dongle.
|
||||||
* Used by the PS3BT library to check the HCI Version of the Bluetooth dongle,
|
* Used by the PS3BT library to check the HCI Version of the Bluetooth dongle,
|
||||||
|
@ -509,6 +516,9 @@ public:
|
||||||
/** True if it's a Wii U Pro Controller. */
|
/** True if it's a Wii U Pro Controller. */
|
||||||
bool wiiUProController;
|
bool wiiUProController;
|
||||||
|
|
||||||
|
/** True if an Xbox One S Controller is Connecting. */
|
||||||
|
bool incomingXboxOneS;
|
||||||
|
|
||||||
/** Call this function to pair with a HID device */
|
/** Call this function to pair with a HID device */
|
||||||
void pairWithHID() {
|
void pairWithHID() {
|
||||||
waitingForConnection = false;
|
waitingForConnection = false;
|
||||||
|
@ -521,6 +531,8 @@ public:
|
||||||
bool incomingHIDDevice;
|
bool incomingHIDDevice;
|
||||||
/** True when it should pair with a device like a mouse or keyboard. */
|
/** True when it should pair with a device like a mouse or keyboard. */
|
||||||
bool pairWithHIDDevice;
|
bool pairWithHIDDevice;
|
||||||
|
/** True when the device is paired. */
|
||||||
|
bool pairedDevice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the poll interval taken from the endpoint descriptors.
|
* Read the poll interval taken from the endpoint descriptors.
|
||||||
|
|
Loading…
Reference in a new issue