const uint8_t *serialNumber() | const uint8_t *serialNumber() | ||||
{ return ((btdevice == nullptr) || (btdevice->strbuf == nullptr)) ? nullptr : &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_SERIAL]]; } | { return ((btdevice == nullptr) || (btdevice->strbuf == nullptr)) ? nullptr : &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_SERIAL]]; } | ||||
private: | private: | ||||
virtual bool claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class) {return false;} | |||||
virtual bool claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class, uint8_t *remoteName) {return false;} | |||||
virtual bool process_bluetooth_HID_data(const uint8_t *data, uint16_t length) {return false;} | virtual bool process_bluetooth_HID_data(const uint8_t *data, uint16_t length) {return false;} | ||||
virtual void release_bluetooth() {}; | virtual void release_bluetooth() {}; | ||||
virtual void remoteNameComplete(const uint8_t *remoteName) {}; | |||||
virtual bool remoteNameComplete(const uint8_t *remoteName) {return true;} | |||||
virtual void connectionComplete(void) {}; | virtual void connectionComplete(void) {}; | ||||
void add_to_list(); | void add_to_list(); | ||||
BTHIDInput *next = NULL; | BTHIDInput *next = NULL; | ||||
enum {SP_NEED_CONNECT=0x1, SP_PS3_IDS=0x2}; | enum {SP_NEED_CONNECT=0x1, SP_PS3_IDS=0x2}; | ||||
uint8_t special_process_required = 0; | uint8_t special_process_required = 0; | ||||
Device_t *btdevice = NULL; | Device_t *btdevice = NULL; | ||||
strbuf_t *btstrbuf = NULL; | |||||
}; | }; | ||||
void init(); | void init(); | ||||
// Bluetooth data | // Bluetooth data | ||||
virtual bool claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class); | |||||
virtual bool claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class, uint8_t *remoteName); | |||||
virtual bool process_bluetooth_HID_data(const uint8_t *data, uint16_t length); | virtual bool process_bluetooth_HID_data(const uint8_t *data, uint16_t length); | ||||
virtual bool remoteNameComplete(const uint8_t *remoteName); | |||||
virtual void release_bluetooth(); | virtual void release_bluetooth(); | ||||
virtual void disconnect_collection(Device_t *dev); | virtual void disconnect_collection(Device_t *dev); | ||||
// Bluetooth data | // Bluetooth data | ||||
virtual bool claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class); | |||||
virtual bool claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class, uint8_t *remoteName); | |||||
virtual bool process_bluetooth_HID_data(const uint8_t *data, uint16_t length); | virtual bool process_bluetooth_HID_data(const uint8_t *data, uint16_t length); | ||||
virtual void release_bluetooth(); | virtual void release_bluetooth(); | ||||
virtual bool hid_process_out_data(const Transfer_t *transfer); | virtual bool hid_process_out_data(const Transfer_t *transfer); | ||||
// Bluetooth data | // Bluetooth data | ||||
virtual bool claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class); | |||||
virtual bool claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class, uint8_t *remoteName); | |||||
virtual bool process_bluetooth_HID_data(const uint8_t *data, uint16_t length); | virtual bool process_bluetooth_HID_data(const uint8_t *data, uint16_t length); | ||||
virtual void release_bluetooth(); | virtual void release_bluetooth(); | ||||
virtual void remoteNameComplete(const uint8_t *remoteName); | |||||
virtual bool remoteNameComplete(const uint8_t *remoteName); | |||||
virtual void connectionComplete(void); | virtual void connectionComplete(void); | ||||
private: | private: | ||||
virtual void disconnect(); | virtual void disconnect(); | ||||
virtual void timer_event(USBDriverTimer *whichTimer); | virtual void timer_event(USBDriverTimer *whichTimer); | ||||
BTHIDInput * find_driver(uint32_t device_type); | |||||
BTHIDInput * find_driver(uint32_t device_type, uint8_t *remoteName=nullptr); | |||||
// Hack to allow PS3 to maybe change values | // Hack to allow PS3 to maybe change values | ||||
uint16_t connection_rxid_ = 0; | uint16_t connection_rxid_ = 0; |
#define print USBHost::print_ | #define print USBHost::print_ | ||||
#define println USBHost::println_//#define DEBUG_BT | #define println USBHost::println_//#define DEBUG_BT | ||||
//#define DEBUG_BT | |||||
//#define DEBUG_BT_VERBOSE | |||||
#define DEBUG_BT | |||||
#define DEBUG_BT_VERBOSE | |||||
#ifndef DEBUG_BT | #ifndef DEBUG_BT | ||||
#undef DEBUG_BT_VERBOSE | #undef DEBUG_BT_VERBOSE | ||||
// When a new top level collection is found, this function asks drivers | // When a new top level collection is found, this function asks drivers | ||||
// if they wish to claim it. The driver taking ownership of the | // if they wish to claim it. The driver taking ownership of the | ||||
// collection is returned, or NULL if no driver wants it. | // collection is returned, or NULL if no driver wants it. | ||||
BTHIDInput * BluetoothController::find_driver(uint32_t device_type) | |||||
BTHIDInput * BluetoothController::find_driver(uint32_t device_type, uint8_t *remoteName) | |||||
{ | { | ||||
USBHDBGSerial.printf("BluetoothController::find_driver"); | USBHDBGSerial.printf("BluetoothController::find_driver"); | ||||
BTHIDInput *driver = available_bthid_drivers_list; | BTHIDInput *driver = available_bthid_drivers_list; | ||||
while (driver) { | while (driver) { | ||||
USBHDBGSerial.printf(" driver %x\n", (uint32_t)driver); | USBHDBGSerial.printf(" driver %x\n", (uint32_t)driver); | ||||
if (driver->claim_bluetooth(this, device_type)) { | |||||
if (driver->claim_bluetooth(this, device_type, remoteName)) { | |||||
USBHDBGSerial.printf(" *** Claimed ***\n"); | USBHDBGSerial.printf(" *** Claimed ***\n"); | ||||
return driver; | return driver; | ||||
} | } | ||||
for (uint8_t *psz = &rxbuf_[9]; *psz; psz++) DBGPrintf("%c", *psz); | for (uint8_t *psz = &rxbuf_[9]; *psz; psz++) DBGPrintf("%c", *psz); | ||||
DBGPrintf("\n"); | DBGPrintf("\n"); | ||||
} | } | ||||
// Lets try to allocate a string buffer to store the name out... | |||||
if (device_driver_) { | |||||
if (!device_driver_->remoteNameComplete(&rxbuf_[9])) { | |||||
device_driver_->release_bluetooth(); | |||||
device_driver_ = nullptr; | |||||
} | |||||
} | |||||
if (!device_driver_) { | |||||
device_driver_ = find_driver(device_class_, &rxbuf_[9]); | |||||
// not sure I should call remote name again, but they already process... | |||||
} | |||||
if (device_driver_) { | if (device_driver_) { | ||||
device_driver_->remoteNameComplete(&rxbuf_[9]); | |||||
if (device_driver_->special_process_required & BTHIDInput::SP_PS3_IDS) { | if (device_driver_->special_process_required & BTHIDInput::SP_PS3_IDS) { | ||||
// Real hack see if PS3... | // Real hack see if PS3... | ||||
control_dcid_ = 0x40; | control_dcid_ = 0x40; | ||||
} | } | ||||
} else if (scid == interrupt_dcid_) { | } else if (scid == interrupt_dcid_) { | ||||
// Enable SCan to page mode | // Enable SCan to page mode | ||||
sendHCIWriteScanEnable(2); | |||||
connection_complete_ = true; | connection_complete_ = true; | ||||
sendHCIWriteScanEnable(2); | |||||
} | } | ||||
} | } | ||||
// TODO: free resources | // TODO: free resources | ||||
} | } | ||||
bool JoystickController::claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class) | |||||
bool JoystickController::claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class, uint8_t *remoteName) | |||||
{ | { | ||||
if ((((bluetooth_class & 0xff00) == 0x2500) || (((bluetooth_class & 0xff00) == 0x500))) && ((bluetooth_class & 0x3C) == 0x08)) { | if ((((bluetooth_class & 0xff00) == 0x2500) || (((bluetooth_class & 0xff00) == 0x500))) && ((bluetooth_class & 0x3C) == 0x08)) { | ||||
DBGPrintf("JoystickController::claim_bluetooth TRUE\n"); | DBGPrintf("JoystickController::claim_bluetooth TRUE\n"); | ||||
btdevice = (Device_t*)driver; // remember this way | btdevice = (Device_t*)driver; // remember this way | ||||
return true; | return true; | ||||
} | } | ||||
if (remoteName && (strncmp((const char *)remoteName, "PLAYSTATION(R)3 Controller", 26) == 0)) { | |||||
DBGPrintf("JoystickController::claim_bluetooth TRUE PS3 hack...\n"); | |||||
btdriver_ = driver; | |||||
btdevice = (Device_t*)driver; // remember this way | |||||
special_process_required = SP_PS3_IDS; // PS3 maybe needs different IDS. | |||||
joystickType = PS3; | |||||
return true; | |||||
} | |||||
return false; | return false; | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
void JoystickController::remoteNameComplete(const uint8_t *remoteName) | |||||
bool JoystickController::remoteNameComplete(const uint8_t *remoteName) | |||||
{ | { | ||||
// Sort of a hack, but try to map the name given from remote to a type... | // Sort of a hack, but try to map the name given from remote to a type... | ||||
if (!remoteName) return; | |||||
if (strncmp((const char *)remoteName, "Wireless Controller", 19) == 0) { | if (strncmp((const char *)remoteName, "Wireless Controller", 19) == 0) { | ||||
DBGPrintf(" JoystickController::remoteNameComplete %s - set to PS4\n", remoteName); | DBGPrintf(" JoystickController::remoteNameComplete %s - set to PS4\n", remoteName); | ||||
special_process_required = SP_NEED_CONNECT; // We need to force this. | special_process_required = SP_NEED_CONNECT; // We need to force this. | ||||
DBGPrintf(" JoystickController::remoteNameComplete %s - set to PS3\n", remoteName); | DBGPrintf(" JoystickController::remoteNameComplete %s - set to PS3\n", remoteName); | ||||
special_process_required = SP_PS3_IDS; // PS3 maybe needs different IDS. | special_process_required = SP_PS3_IDS; // PS3 maybe needs different IDS. | ||||
joystickType = PS3; | joystickType = PS3; | ||||
// Hack to see if setting control/interrupt ids will help on PS3... | |||||
// btdriver_->control_dcid_ = 0x40; | |||||
// btdriver_->interrupt_dcid_ = 0x41; | |||||
} else { | |||||
DBGPrintf(" JoystickController::remoteNameComplete %s - Unknown\n", remoteName); | |||||
} | } | ||||
return true; | |||||
} | } | ||||
void JoystickController::connectionComplete() | void JoystickController::connectionComplete() |
} | } | ||||
} | } | ||||
bool KeyboardController::claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class) | |||||
bool KeyboardController::claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class, uint8_t *remoteName) | |||||
{ | { | ||||
USBHDBGSerial.printf("Keyboard Controller::claim_bluetooth - Class %x\n", bluetooth_class); | USBHDBGSerial.printf("Keyboard Controller::claim_bluetooth - Class %x\n", bluetooth_class); | ||||
if ((((bluetooth_class & 0xff00) == 0x2500) || (((bluetooth_class & 0xff00) == 0x500))) && (bluetooth_class & 0x40)) { | if ((((bluetooth_class & 0xff00) == 0x2500) || (((bluetooth_class & 0xff00) == 0x500))) && (bluetooth_class & 0x40)) { | ||||
if (remoteName && (strncmp((const char *)remoteName, "PLAYSTATION(R)3 Controller", 26) == 0)) { | |||||
USBHDBGSerial.printf("KeyboardController::claim_bluetooth Reject PS3 hack\n"); | |||||
return false; | |||||
} | |||||
USBHDBGSerial.printf("KeyboardController::claim_bluetooth TRUE\n"); | USBHDBGSerial.printf("KeyboardController::claim_bluetooth TRUE\n"); | ||||
//btdevice = driver; | //btdevice = driver; | ||||
return true; | return true; | ||||
return false; | return false; | ||||
} | } | ||||
bool KeyboardController::remoteNameComplete(const uint8_t *remoteName) | |||||
{ | |||||
// Real Hack some PS3 controllers bluetoot class is keyboard... | |||||
if (strncmp((const char *)remoteName, "PLAYSTATION(R)3 Controller", 26) == 0) { | |||||
USBHDBGSerial.printf(" KeyboardController::remoteNameComplete %s - Oops PS3 unclaim\n", remoteName); | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
bool KeyboardController::process_bluetooth_HID_data(const uint8_t *data, uint16_t length) | bool KeyboardController::process_bluetooth_HID_data(const uint8_t *data, uint16_t length) | ||||
{ | { | ||||
// Example DATA from bluetooth keyboard: | // Example DATA from bluetooth keyboard: |
} | } | ||||
bool MouseController::claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class) | |||||
bool MouseController::claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class, uint8_t *remoteName) | |||||
{ | { | ||||
// How to handle combo devices? | // How to handle combo devices? | ||||
USBHDBGSerial.printf("MouseController Controller::claim_bluetooth - Class %x\n", bluetooth_class); | USBHDBGSerial.printf("MouseController Controller::claim_bluetooth - Class %x\n", bluetooth_class); |