|
|
@@ -30,8 +30,8 @@ |
|
|
|
#define print USBHost::print_ |
|
|
|
#define println USBHost::println_//#define DEBUG_BT |
|
|
|
|
|
|
|
//#define DEBUG_BT |
|
|
|
//#define DEBUG_BT_VERBOSE |
|
|
|
#define DEBUG_BT |
|
|
|
#define DEBUG_BT_VERBOSE |
|
|
|
|
|
|
|
#ifndef DEBUG_BT |
|
|
|
#undef DEBUG_BT_VERBOSE |
|
|
@@ -320,12 +320,12 @@ bool BluetoothController::claim(Device_t *dev, int type, const uint8_t *descript |
|
|
|
void BluetoothController::disconnect() |
|
|
|
{ |
|
|
|
USBHDBGSerial.printf("Bluetooth Disconnect"); |
|
|
|
if (device_driver_) { |
|
|
|
device_driver_->release_bluetooth(); |
|
|
|
device_driver_->remote_name_[0] = 0; |
|
|
|
device_driver_ = nullptr; |
|
|
|
if (connections_[current_connection_].device_driver_) { |
|
|
|
connections_[current_connection_].device_driver_->release_bluetooth(); |
|
|
|
connections_[current_connection_].device_driver_->remote_name_[0] = 0; |
|
|
|
connections_[current_connection_].device_driver_ = nullptr; |
|
|
|
} |
|
|
|
connection_complete_ = false; |
|
|
|
connections_[current_connection_].connection_complete_ = false; |
|
|
|
} |
|
|
|
|
|
|
|
void BluetoothController::timer_event(USBDriverTimer *whichTimer) |
|
|
@@ -555,9 +555,9 @@ void BluetoothController::handle_hci_command_complete() |
|
|
|
case HCI_WRITE_SCAN_ENABLE: //0x0c1a |
|
|
|
DBGPrintf("Write_Scan_enable Completed\n"); |
|
|
|
// See if we have driver and a remote |
|
|
|
if (device_driver_ && connection_complete_) { // We have a driver call their |
|
|
|
device_driver_->connectionComplete(); |
|
|
|
connection_complete_ = false; // only call once |
|
|
|
if (connections_[current_connection_].device_driver_ && connections_[current_connection_].connection_complete_) { // We have a driver call their |
|
|
|
connections_[current_connection_].device_driver_->connectionComplete(); |
|
|
|
connections_[current_connection_].connection_complete_ = false; // only call once |
|
|
|
} |
|
|
|
break; |
|
|
|
case HCI_WRITE_SSP_MODE: //0x0c56 |
|
|
@@ -638,9 +638,9 @@ void BluetoothController::queue_next_hci_command() |
|
|
|
void BluetoothController::handle_hci_command_status() |
|
|
|
{ |
|
|
|
// <event type><param count><status><num packets allowed to be sent><CMD><CMD> |
|
|
|
#ifdef DEBUG_BT |
|
|
|
uint16_t hci_command = rxbuf_[4] + (rxbuf_[5] << 8); |
|
|
|
if (rxbuf_[2]) { |
|
|
|
#ifdef DEBUG_BT |
|
|
|
DBGPrintf(" Command %x Status %x - ", hci_command, rxbuf_[2]); |
|
|
|
switch (rxbuf_[2]) { |
|
|
|
case 0x01: DBGPrintf("Unknown HCI Command\n"); break; |
|
|
@@ -660,10 +660,23 @@ void BluetoothController::handle_hci_command_status() |
|
|
|
case 0x0F: DBGPrintf("Connection Rejected due to Unacceptable BD_ADDR\n"); break; |
|
|
|
default: DBGPrintf("???\n"); break; |
|
|
|
} |
|
|
|
#endif |
|
|
|
// lets try recovering from some errors... |
|
|
|
switch (hci_command) { |
|
|
|
case HCI_OP_ACCEPT_CONN_REQ: |
|
|
|
// We assume that the connection failed... |
|
|
|
DBGPrintf("### Connection Failed ###"); |
|
|
|
if (count_connections_) count_connections_--; |
|
|
|
break; |
|
|
|
default: |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
#ifdef DEBUG_BT |
|
|
|
VDBGPrintf(" Command %x Status %x\n", hci_command, rxbuf_[2]); |
|
|
|
#endif |
|
|
|
} |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
void BluetoothController::handle_hci_inquiry_result(bool fRSSI) |
|
|
@@ -704,13 +717,13 @@ void BluetoothController::handle_hci_inquiry_result(bool fRSSI) |
|
|
|
} |
|
|
|
|
|
|
|
// BUGBUG, lets hard code to go to new state... |
|
|
|
for (uint8_t i = 0; i < 6; i++) device_bdaddr_[i] = rxbuf_[index_bd+i]; |
|
|
|
device_class_ = bluetooth_class; |
|
|
|
device_driver_ = find_driver(device_class_); |
|
|
|
for (uint8_t i = 0; i < 6; i++) connections_[current_connection_].device_bdaddr_[i] = rxbuf_[index_bd+i]; |
|
|
|
connections_[current_connection_].device_class_ = bluetooth_class; |
|
|
|
connections_[current_connection_].device_driver_ = find_driver(connections_[current_connection_].device_class_); |
|
|
|
|
|
|
|
device_ps_repetion_mode_ = rxbuf_[index_ps]; // mode |
|
|
|
device_clock_offset_[0] = rxbuf_[index_clock_offset]; |
|
|
|
device_clock_offset_[1] = rxbuf_[index_clock_offset+1]; |
|
|
|
connections_[current_connection_].device_ps_repetion_mode_ = rxbuf_[index_ps]; // mode |
|
|
|
connections_[current_connection_].device_clock_offset_[0] = rxbuf_[index_clock_offset]; |
|
|
|
connections_[current_connection_].device_clock_offset_[1] = rxbuf_[index_clock_offset+1]; |
|
|
|
|
|
|
|
// Now we need to bail from inquiry and setup to try to connect... |
|
|
|
sendHCIInquiryCancel(); |
|
|
@@ -768,22 +781,22 @@ void BluetoothController::handle_hci_extended_inquiry_result() |
|
|
|
} |
|
|
|
|
|
|
|
// BUGBUG, lets hard code to go to new state... |
|
|
|
for (uint8_t i = 0; i < 6; i++) device_bdaddr_[i] = rxbuf_[index_bd+i]; |
|
|
|
device_class_ = bluetooth_class; |
|
|
|
device_driver_ = find_driver(device_class_, index_local_name? &rxbuf_[index_local_name] : nullptr); |
|
|
|
for (uint8_t i = 0; i < 6; i++) connections_[current_connection_].device_bdaddr_[i] = rxbuf_[index_bd+i]; |
|
|
|
connections_[current_connection_].device_class_ = bluetooth_class; |
|
|
|
connections_[current_connection_].device_driver_ = find_driver(connections_[current_connection_].device_class_, index_local_name? &rxbuf_[index_local_name] : nullptr); |
|
|
|
|
|
|
|
device_ps_repetion_mode_ = rxbuf_[index_ps]; // mode |
|
|
|
device_clock_offset_[0] = rxbuf_[index_clock_offset]; |
|
|
|
device_clock_offset_[1] = rxbuf_[index_clock_offset+1]; |
|
|
|
connections_[current_connection_].device_ps_repetion_mode_ = rxbuf_[index_ps]; // mode |
|
|
|
connections_[current_connection_].device_clock_offset_[0] = rxbuf_[index_clock_offset]; |
|
|
|
connections_[current_connection_].device_clock_offset_[1] = rxbuf_[index_clock_offset+1]; |
|
|
|
|
|
|
|
// and if we found a driver, save away the name |
|
|
|
if (device_driver_ && index_local_name && size_local_name) { |
|
|
|
if (connections_[current_connection_].device_driver_ && index_local_name && size_local_name) { |
|
|
|
uint8_t buffer_index; |
|
|
|
for (buffer_index = 0; size_local_name && (buffer_index < BTHIDInput::REMOTE_NAME_SIZE-1); buffer_index++) { |
|
|
|
device_driver_->remote_name_[buffer_index] = rxbuf_[index_local_name+buffer_index]; |
|
|
|
connections_[current_connection_].device_driver_->remote_name_[buffer_index] = rxbuf_[index_local_name+buffer_index]; |
|
|
|
size_local_name--; |
|
|
|
} |
|
|
|
device_driver_->remote_name_[buffer_index] = 0; // make sure null terminated |
|
|
|
connections_[current_connection_].device_driver_->remote_name_[buffer_index] = 0; // make sure null terminated |
|
|
|
} |
|
|
|
|
|
|
|
// Now we need to bail from inquiry and setup to try to connect... |
|
|
@@ -800,16 +813,16 @@ void BluetoothController::handle_hci_connection_complete() { |
|
|
|
// 0 1 2 3 4 5 6 7 8 9 10 11 12 |
|
|
|
// ST CH CH BD BD BD BD BD BD LT EN |
|
|
|
// 03 0b 04 00 00 40 25 00 58 4b 00 01 00 |
|
|
|
device_connection_handle_ = rxbuf_[3]+ (uint16_t)(rxbuf_[4]<<8); |
|
|
|
DBGPrintf(" Connection Complete - ST:%x LH:%x\n", rxbuf_[2], device_connection_handle_); |
|
|
|
if (do_pair_device_ && !(device_driver_ && (device_driver_->special_process_required & BTHIDInput::SP_DONT_NEED_CONNECT))) { |
|
|
|
connections_[current_connection_].device_connection_handle_ = rxbuf_[3]+ (uint16_t)(rxbuf_[4]<<8); |
|
|
|
DBGPrintf(" Connection Complete - ST:%x LH:%x\n", rxbuf_[2], connections_[current_connection_].device_connection_handle_); |
|
|
|
if (do_pair_device_ && !(connections_[current_connection_].device_driver_ && (connections_[current_connection_].device_driver_->special_process_required & BTHIDInput::SP_DONT_NEED_CONNECT))) { |
|
|
|
sendHCIAuthenticationRequested(); |
|
|
|
pending_control_ = PC_AUTHENTICATION_REQUESTED; |
|
|
|
} else if (device_driver_ && (device_driver_->special_process_required & BTHIDInput::SP_NEED_CONNECT)) { |
|
|
|
} else if (connections_[current_connection_].device_driver_ && (connections_[current_connection_].device_driver_->special_process_required & BTHIDInput::SP_NEED_CONNECT)) { |
|
|
|
DBGPrintf(" Needs connect to device(PS4?)\n"); |
|
|
|
// The PS4 requires a connection request to it. |
|
|
|
delay(1); |
|
|
|
sendl2cap_ConnectionRequest(device_connection_handle_, connection_rxid_, control_dcid_, HID_CTRL_PSM); |
|
|
|
sendl2cap_ConnectionRequest(connections_[current_connection_].device_connection_handle_, connections_[current_connection_].connection_rxid_, connections_[current_connection_].control_dcid_, HID_CTRL_PSM); |
|
|
|
#if 0 |
|
|
|
delay(1); |
|
|
|
|
|
|
@@ -838,11 +851,13 @@ void BluetoothController::handle_hci_incoming_connect() { |
|
|
|
case 8: DBGPrintf(" Gamepad\n"); break; |
|
|
|
case 0xc: DBGPrintf(" Remote Control\n"); break; |
|
|
|
} |
|
|
|
device_driver_ = find_driver(class_of_device); |
|
|
|
if (count_connections_ < MAX_CONNECTIONS) current_connection_ = count_connections_++; |
|
|
|
|
|
|
|
connections_[current_connection_].device_driver_ = find_driver(class_of_device); |
|
|
|
|
|
|
|
// We need to save away the BDADDR and class link type? |
|
|
|
for(uint8_t i=0; i<6; i++) device_bdaddr_[i] = rxbuf_[i+2]; |
|
|
|
device_class_ = class_of_device; |
|
|
|
for(uint8_t i=0; i<6; i++) connections_[current_connection_].device_bdaddr_[i] = rxbuf_[i+2]; |
|
|
|
connections_[current_connection_].device_class_ = class_of_device; |
|
|
|
sendHCIRemoteNameRequest(); |
|
|
|
} |
|
|
|
|
|
|
@@ -888,19 +903,31 @@ void BluetoothController::handle_hci_disconnect_complete() |
|
|
|
//5 4 0 48 0 13 |
|
|
|
DBGPrintf(" Event: HCI Disconnect complete(%d): handle: %x, reason:%x\n", rxbuf_[2], |
|
|
|
rxbuf_[3]+(rxbuf_[4]<<8), rxbuf_[5]); |
|
|
|
if (device_driver_) { |
|
|
|
device_driver_->release_bluetooth(); |
|
|
|
device_driver_->remote_name_[0] = 0; |
|
|
|
device_driver_ = nullptr; |
|
|
|
if (connections_[current_connection_].device_driver_) { |
|
|
|
connections_[current_connection_].device_driver_->release_bluetooth(); |
|
|
|
connections_[current_connection_].device_driver_->remote_name_[0] = 0; |
|
|
|
connections_[current_connection_].device_driver_ = nullptr; |
|
|
|
|
|
|
|
// Restore to normal... |
|
|
|
control_dcid_ = 0x70; |
|
|
|
interrupt_dcid_ = 0x71; |
|
|
|
connections_[current_connection_].control_dcid_ = 0x70; |
|
|
|
connections_[current_connection_].interrupt_dcid_ = 0x71; |
|
|
|
} |
|
|
|
// Probably should clear out connection data. |
|
|
|
device_connection_handle_ = 0; |
|
|
|
device_class_ = 0; |
|
|
|
memset(device_bdaddr_, 0, sizeof(device_bdaddr_)); |
|
|
|
#if 0 |
|
|
|
connections_[current_connection_].device_connection_handle_ = 0; |
|
|
|
connections_[current_connection_].device_class_ = 0; |
|
|
|
memset(connections_[current_connection_].device_bdaddr_, 0, sizeof(connections_[current_connection_].device_bdaddr_)); |
|
|
|
#endif |
|
|
|
// Now we need to remove that item from our list of connections. |
|
|
|
count_connections_--; |
|
|
|
if (count_connections_ == 0) { |
|
|
|
// reset the next connection counts back to initial states. |
|
|
|
next_dcid_ = 0x70; // Lets try not hard coding control and interrupt dcid |
|
|
|
} |
|
|
|
|
|
|
|
for (uint8_t i = current_connection_; i < count_connections_; i++) connections_[i] = connections_[i+1]; |
|
|
|
current_connection_ = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void BluetoothController::handle_hci_authentication_complete() |
|
|
@@ -909,8 +936,8 @@ void BluetoothController::handle_hci_authentication_complete() |
|
|
|
DBGPrintf(" Event: HCI Authentication complete(%d): handle: %x\n", rxbuf_[2], |
|
|
|
rxbuf_[3]+(rxbuf_[4]<<8)); |
|
|
|
// Start up lcap connection... |
|
|
|
connection_rxid_ = 0; |
|
|
|
sendl2cap_ConnectionRequest(device_connection_handle_, connection_rxid_, control_dcid_, HID_CTRL_PSM); |
|
|
|
connections_[current_connection_].connection_rxid_ = 0; |
|
|
|
sendl2cap_ConnectionRequest(connections_[current_connection_].device_connection_handle_, connections_[current_connection_].connection_rxid_, connections_[current_connection_].control_dcid_, HID_CTRL_PSM); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@@ -925,41 +952,44 @@ void BluetoothController::handle_hci_remote_name_complete() { |
|
|
|
DBGPrintf("\n"); |
|
|
|
} |
|
|
|
|
|
|
|
if (device_driver_) { |
|
|
|
if (!device_driver_->remoteNameComplete(&rxbuf_[9])) { |
|
|
|
device_driver_->release_bluetooth(); |
|
|
|
device_driver_ = nullptr; |
|
|
|
if (connections_[current_connection_].device_driver_) { |
|
|
|
if (!connections_[current_connection_].device_driver_->remoteNameComplete(&rxbuf_[9])) { |
|
|
|
connections_[current_connection_].device_driver_->release_bluetooth(); |
|
|
|
connections_[current_connection_].device_driver_ = nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!device_driver_) { |
|
|
|
device_driver_ = find_driver(device_class_, &rxbuf_[9]); |
|
|
|
if (!connections_[current_connection_].device_driver_) { |
|
|
|
connections_[current_connection_].device_driver_ = find_driver(connections_[current_connection_].device_class_, &rxbuf_[9]); |
|
|
|
// not sure I should call remote name again, but they already process... |
|
|
|
if (device_driver_) { |
|
|
|
device_driver_->remoteNameComplete(&rxbuf_[9]); |
|
|
|
if (connections_[current_connection_].device_driver_) { |
|
|
|
connections_[current_connection_].device_driver_->remoteNameComplete(&rxbuf_[9]); |
|
|
|
} |
|
|
|
} |
|
|
|
if (device_driver_) { |
|
|
|
if (connections_[current_connection_].device_driver_) { |
|
|
|
// lets save away the string. |
|
|
|
uint8_t buffer_index; |
|
|
|
for (buffer_index = 0; buffer_index < BTHIDInput::REMOTE_NAME_SIZE-1; buffer_index++) { |
|
|
|
device_driver_->remote_name_[buffer_index] = rxbuf_[9+buffer_index]; |
|
|
|
if (!device_driver_->remote_name_[buffer_index]) break; |
|
|
|
connections_[current_connection_].device_driver_->remote_name_[buffer_index] = rxbuf_[9+buffer_index]; |
|
|
|
if (!connections_[current_connection_].device_driver_->remote_name_[buffer_index]) break; |
|
|
|
} |
|
|
|
device_driver_->remote_name_[buffer_index] = 0; // make sure null terminated |
|
|
|
connections_[current_connection_].device_driver_->remote_name_[buffer_index] = 0; // make sure null terminated |
|
|
|
|
|
|
|
if (device_driver_->special_process_required & BTHIDInput::SP_PS3_IDS) { |
|
|
|
if (connections_[current_connection_].device_driver_->special_process_required & BTHIDInput::SP_PS3_IDS) { |
|
|
|
// Real hack see if PS3... |
|
|
|
control_dcid_ = 0x40; |
|
|
|
interrupt_dcid_ = 0x41; |
|
|
|
connections_[current_connection_].control_dcid_ = 0x40; |
|
|
|
connections_[current_connection_].interrupt_dcid_ = 0x41; |
|
|
|
} else { |
|
|
|
connections_[current_connection_].control_dcid_ = next_dcid_++; |
|
|
|
connections_[current_connection_].interrupt_dcid_ = next_dcid_++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// If we are in the connection complete mode, then this is a pairing state and needed to call |
|
|
|
// get remote name later. |
|
|
|
if (connection_complete_) { |
|
|
|
if (device_driver_) { // We have a driver call their |
|
|
|
device_driver_->connectionComplete(); |
|
|
|
connection_complete_ = false; // only call once |
|
|
|
if (connections_[current_connection_].connection_complete_) { |
|
|
|
if (connections_[current_connection_].device_driver_) { // We have a driver call their |
|
|
|
connections_[current_connection_].device_driver_->connectionComplete(); |
|
|
|
connections_[current_connection_].connection_complete_ = false; // only call once |
|
|
|
} |
|
|
|
} else { |
|
|
|
sendHCIAcceptConnectionRequest(); |
|
|
@@ -969,13 +999,13 @@ void BluetoothController::handle_hci_remote_name_complete() { |
|
|
|
void BluetoothController::handle_hci_remote_version_information_complete() { |
|
|
|
// STAT bd bd bd bd bd bd |
|
|
|
//c 8 0 48 0 5 45 0 0 0 |
|
|
|
remote_ver_ = rxbuf_[6]; |
|
|
|
remote_man_ = rxbuf_[7]+((uint16_t)rxbuf_[8]<< 8); |
|
|
|
remote_subv_ = rxbuf_[9]; |
|
|
|
connections_[current_connection_].remote_ver_ = rxbuf_[6]; |
|
|
|
connections_[current_connection_].remote_man_ = rxbuf_[7]+((uint16_t)rxbuf_[8]<< 8); |
|
|
|
connections_[current_connection_].remote_subv_ = rxbuf_[9]; |
|
|
|
|
|
|
|
DBGPrintf(" Event: handle_hci_remote_version_information_complete(%d): ", rxbuf_[2]); |
|
|
|
DBGPrintf(" Handle: %x, Ver:%x, Man: %x, SV: %x\n", |
|
|
|
rxbuf_[3]+((uint16_t)rxbuf_[4]<< 8), remote_ver_, remote_man_, remote_subv_); |
|
|
|
rxbuf_[3]+((uint16_t)rxbuf_[4]<< 8), connections_[current_connection_].remote_ver_, connections_[current_connection_].remote_man_, connections_[current_connection_].remote_subv_); |
|
|
|
// Lets now try to accept the connection. |
|
|
|
sendHCIAcceptConnectionRequest(); |
|
|
|
} |
|
|
@@ -997,6 +1027,14 @@ void BluetoothController::rx2_data(const Transfer_t *transfer) |
|
|
|
// uint16_t rsp_packet_length = buffer[10] + ((uint16_t)buffer[11]<<8); |
|
|
|
if ((hci_length == (l2cap_length + 4)) /*&& (hci_length == (rsp_packet_length+8))*/) { |
|
|
|
// All the lengths appear to be correct... need to do more... |
|
|
|
// See if we should set the current_connection... |
|
|
|
for (uint8_t i = 0; i < count_connections_; i++) { |
|
|
|
//if (connections_[i].interrupt_dcid_ == buffer[6]) { |
|
|
|
if (connections_[i].device_connection_handle_ == buffer[0]) { |
|
|
|
current_connection_ = i; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
switch (buffer[8]) { |
|
|
|
case L2CAP_CMD_CONNECTION_REQUEST: |
|
|
|
process_l2cap_connection_request(&buffer[8]); |
|
|
@@ -1089,10 +1127,10 @@ void BluetoothController::sendHCICreateConnection() { |
|
|
|
//0x05 0x04 0x0D 0x79 0x22 0x23 0x0A 0xC5 0xCC 0x18 0xCC 0x01 0x00 0x00 0x00 0x00 |
|
|
|
// 05 04 0d 40 25 00 c4 01 00 18 cc 01 00 00 00 00 |
|
|
|
|
|
|
|
for (uint8_t i=0; i<6; i++) connection_data[i] = device_bdaddr_[i]; |
|
|
|
for (uint8_t i=0; i<6; i++) connection_data[i] = connections_[current_connection_].device_bdaddr_[i]; |
|
|
|
connection_data[6] = 0x18; //DM1/DH1 |
|
|
|
connection_data[7] = 0xcc; // |
|
|
|
connection_data[8] = device_ps_repetion_mode_; // from device |
|
|
|
connection_data[8] = connections_[current_connection_].device_ps_repetion_mode_; // from device |
|
|
|
connection_data[9] = 0; // |
|
|
|
connection_data[10] = 0; // clock offset |
|
|
|
connection_data[11] = 0; // clock offset |
|
|
@@ -1108,7 +1146,7 @@ void BluetoothController::sendHCIAcceptConnectionRequest() { |
|
|
|
// 0 1 2 3 4 5 6 7 8 9 10 11 12 |
|
|
|
// BD BD BD BD BD BD role |
|
|
|
//0x79 0x22 0x23 0x0A 0xC5 0xCC 0x00 |
|
|
|
for (uint8_t i=0; i<6; i++) connection_data[i] = device_bdaddr_[i]; |
|
|
|
for (uint8_t i=0; i<6; i++) connection_data[i] = connections_[current_connection_].device_bdaddr_[i]; |
|
|
|
connection_data[6] = 0; // Role as master |
|
|
|
sendHCICommand(HCI_OP_ACCEPT_CONN_REQ, sizeof(connection_data), connection_data); |
|
|
|
} |
|
|
@@ -1117,8 +1155,8 @@ void BluetoothController::sendHCIAcceptConnectionRequest() { |
|
|
|
void BluetoothController::sendHCIAuthenticationRequested() { |
|
|
|
DBGPrintf("HCI_AUTH_REQUESTED called ("); |
|
|
|
uint8_t connection_data[2]; |
|
|
|
connection_data[0] = device_connection_handle_ & 0xff; |
|
|
|
connection_data[1] = (device_connection_handle_>>8) & 0xff; |
|
|
|
connection_data[0] = connections_[current_connection_].device_connection_handle_ & 0xff; |
|
|
|
connection_data[1] = (connections_[current_connection_].device_connection_handle_>>8) & 0xff; |
|
|
|
sendHCICommand(HCI_AUTH_REQUESTED, sizeof(connection_data), connection_data); |
|
|
|
} |
|
|
|
|
|
|
@@ -1126,7 +1164,7 @@ void BluetoothController::sendHCIAuthenticationRequested() { |
|
|
|
void BluetoothController::sendHCILinkKeyNegativeReply() { |
|
|
|
DBGPrintf("HCI_LINK_KEY_NEG_REPLY called ("); |
|
|
|
uint8_t connection_data[6]; |
|
|
|
for (uint8_t i=0; i<6; i++) connection_data[i] = device_bdaddr_[i]; |
|
|
|
for (uint8_t i=0; i<6; i++) connection_data[i] = connections_[current_connection_].device_bdaddr_[i]; |
|
|
|
sendHCICommand(HCI_LINK_KEY_NEG_REPLY, sizeof(connection_data), connection_data); |
|
|
|
} |
|
|
|
|
|
|
@@ -1139,7 +1177,7 @@ void BluetoothController::sendHCIPinCodeReply() { |
|
|
|
uint8_t connection_data[23]; |
|
|
|
uint8_t i; |
|
|
|
|
|
|
|
for (i=0; i<6; i++) connection_data[i] = device_bdaddr_[i]; |
|
|
|
for (i=0; i<6; i++) connection_data[i] = connections_[current_connection_].device_bdaddr_[i]; |
|
|
|
|
|
|
|
for (i=0; pair_pincode_[i] !=0; i++) connection_data[7+i] = pair_pincode_[i]; |
|
|
|
connection_data[6] = i; // remember the length |
|
|
@@ -1185,7 +1223,7 @@ void BluetoothController::sendHCIRemoteNameRequest() { // 0x0419 |
|
|
|
|
|
|
|
DBGPrintf("HCI_OP_REMOTE_NAME_REQ called ("); |
|
|
|
uint8_t connection_data[10]; |
|
|
|
for (uint8_t i=0; i<6; i++) connection_data[i] = device_bdaddr_[i]; |
|
|
|
for (uint8_t i=0; i<6; i++) connection_data[i] = connections_[current_connection_].device_bdaddr_[i]; |
|
|
|
connection_data[6] = 1; // page scan repeat mode... |
|
|
|
connection_data[7] = 0; // 0 |
|
|
|
connection_data[8] = 0; // Clk offset |
|
|
@@ -1199,8 +1237,8 @@ void BluetoothController::sendHCIRemoteVersionInfoRequest() { // 0x041D |
|
|
|
|
|
|
|
DBGPrintf("HCI_OP_READ_REMOTE_VERSION_INFORMATION called ("); |
|
|
|
uint8_t connection_data[2]; |
|
|
|
connection_data[0] = device_connection_handle_ & 0xff; |
|
|
|
connection_data[1] = (device_connection_handle_>>8) & 0xff; |
|
|
|
connection_data[0] = connections_[current_connection_].device_connection_handle_ & 0xff; |
|
|
|
connection_data[1] = (connections_[current_connection_].device_connection_handle_>>8) & 0xff; |
|
|
|
sendHCICommand(HCI_OP_READ_REMOTE_VERSION_INFORMATION, sizeof(connection_data), connection_data); |
|
|
|
} |
|
|
|
|
|
|
@@ -1296,30 +1334,30 @@ void BluetoothController::tx_data(const Transfer_t *transfer) |
|
|
|
switch (pending_control_tx_) { |
|
|
|
case STATE_TX_SEND_CONNECT_INT: |
|
|
|
delay(1); |
|
|
|
connection_rxid_++; |
|
|
|
sendl2cap_ConnectionRequest(device_connection_handle_, connection_rxid_, interrupt_dcid_, HID_INTR_PSM); |
|
|
|
connections_[current_connection_].connection_rxid_++; |
|
|
|
sendl2cap_ConnectionRequest(connections_[current_connection_].device_connection_handle_, connections_[current_connection_].connection_rxid_, connections_[current_connection_].interrupt_dcid_, HID_INTR_PSM); |
|
|
|
pending_control_tx_ = 0; |
|
|
|
break; |
|
|
|
case STATE_TX_SEND_CONECT_RSP_SUCCESS: |
|
|
|
delay(1); |
|
|
|
// Tell the device we are ready |
|
|
|
sendl2cap_ConnectionResponse(device_connection_handle_, connection_rxid_++, control_dcid_, control_scid_, SUCCESSFUL); |
|
|
|
sendl2cap_ConnectionResponse(connections_[current_connection_].device_connection_handle_, connections_[current_connection_].connection_rxid_++, connections_[current_connection_].control_dcid_, connections_[current_connection_].control_scid_, SUCCESSFUL); |
|
|
|
pending_control_tx_ = STATE_TX_SEND_CONFIG_REQ; |
|
|
|
break; |
|
|
|
case STATE_TX_SEND_CONFIG_REQ: |
|
|
|
delay(1); |
|
|
|
sendl2cap_ConfigRequest(device_connection_handle_, connection_rxid_, control_scid_); |
|
|
|
sendl2cap_ConfigRequest(connections_[current_connection_].device_connection_handle_, connections_[current_connection_].connection_rxid_, connections_[current_connection_].control_scid_); |
|
|
|
pending_control_tx_ = 0; |
|
|
|
break; |
|
|
|
case STATE_TX_SEND_CONECT_ISR_RSP_SUCCESS: |
|
|
|
delay(1); |
|
|
|
// Tell the device we are ready |
|
|
|
sendl2cap_ConnectionResponse(device_connection_handle_, connection_rxid_++, interrupt_dcid_, interrupt_scid_, SUCCESSFUL); |
|
|
|
sendl2cap_ConnectionResponse(connections_[current_connection_].device_connection_handle_, connections_[current_connection_].connection_rxid_++, connections_[current_connection_].interrupt_dcid_, connections_[current_connection_].interrupt_scid_, SUCCESSFUL); |
|
|
|
pending_control_tx_ = STATE_TX_SEND_CONFIG_ISR_REQ; |
|
|
|
break; |
|
|
|
case STATE_TX_SEND_CONFIG_ISR_REQ: |
|
|
|
delay(1); |
|
|
|
sendl2cap_ConfigRequest(device_connection_handle_, connection_rxid_, interrupt_scid_); |
|
|
|
sendl2cap_ConfigRequest(connections_[current_connection_].device_connection_handle_, connections_[current_connection_].connection_rxid_, connections_[current_connection_].interrupt_scid_); |
|
|
|
pending_control_tx_ = 0; |
|
|
|
break; |
|
|
|
} |
|
|
@@ -1341,16 +1379,16 @@ void BluetoothController::sendL2CapCommand(uint8_t* data, uint8_t nbytes, int ch |
|
|
|
uint16_t channel_out; |
|
|
|
switch (channel) { |
|
|
|
case CONTROL_SCID: |
|
|
|
channel_out = control_scid_; |
|
|
|
channel_out = connections_[current_connection_].control_scid_; |
|
|
|
break; |
|
|
|
case INTERRUPT_SCID: |
|
|
|
channel_out = interrupt_scid_; |
|
|
|
channel_out = connections_[current_connection_].interrupt_scid_; |
|
|
|
break; |
|
|
|
default: |
|
|
|
channel_out = (uint16_t)channel; |
|
|
|
} |
|
|
|
DBGPrintf("sendL2CapCommand: %x %d %x\n", (uint32_t)data, nbytes, channel, channel_out); |
|
|
|
sendL2CapCommand (device_connection_handle_, data, nbytes, channel_out & 0xff, (channel_out >> 8) & 0xff); |
|
|
|
sendL2CapCommand (connections_[current_connection_].device_connection_handle_, data, nbytes, channel_out & 0xff, (channel_out >> 8) & 0xff); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@@ -1382,19 +1420,19 @@ void BluetoothController::process_l2cap_connection_request(uint8_t *data) { |
|
|
|
|
|
|
|
uint16_t psm = data[4]+((uint16_t)data[5] << 8); |
|
|
|
uint16_t scid = data[6]+((uint16_t)data[7] << 8); |
|
|
|
connection_rxid_ = data[1]; |
|
|
|
DBGPrintf(" L2CAP Connection Request: ID: %d, PSM: %x, SCID: %x\n",connection_rxid_, psm, scid); |
|
|
|
connections_[current_connection_].connection_rxid_ = data[1]; |
|
|
|
DBGPrintf(" L2CAP Connection Request: ID: %d, PSM: %x, SCID: %x\n",connections_[current_connection_].connection_rxid_, psm, scid); |
|
|
|
|
|
|
|
// Assuming not pair mode Send response like: |
|
|
|
// RXID Len LEN DCID DCID SCID SCID RES 0 0 0 |
|
|
|
// 0x03 0x02 0x08 0x00 0x70 0x00 0x43 0x00 0x01 0x00 0x00 0x00 |
|
|
|
if (psm == HID_CTRL_PSM) { |
|
|
|
control_scid_ = scid; |
|
|
|
sendl2cap_ConnectionResponse(device_connection_handle_, connection_rxid_, control_dcid_, control_scid_, PENDING); |
|
|
|
connections_[current_connection_].control_scid_ = scid; |
|
|
|
sendl2cap_ConnectionResponse(connections_[current_connection_].device_connection_handle_, connections_[current_connection_].connection_rxid_, connections_[current_connection_].control_dcid_, connections_[current_connection_].control_scid_, PENDING); |
|
|
|
pending_control_tx_ = STATE_TX_SEND_CONECT_RSP_SUCCESS; |
|
|
|
} else if (psm == HID_INTR_PSM) { |
|
|
|
interrupt_scid_ = scid; |
|
|
|
sendl2cap_ConnectionResponse(device_connection_handle_, connection_rxid_, interrupt_dcid_, interrupt_scid_, PENDING); |
|
|
|
connections_[current_connection_].interrupt_scid_ = scid; |
|
|
|
sendl2cap_ConnectionResponse(connections_[current_connection_].device_connection_handle_, connections_[current_connection_].connection_rxid_, connections_[current_connection_].interrupt_dcid_, connections_[current_connection_].interrupt_scid_, PENDING); |
|
|
|
pending_control_tx_ = STATE_TX_SEND_CONECT_ISR_RSP_SUCCESS; |
|
|
|
|
|
|
|
} |
|
|
@@ -1411,15 +1449,15 @@ void BluetoothController::process_l2cap_connection_response(uint8_t *data) { |
|
|
|
data[8]+((uint16_t)data[9] << 8), data[10]+((uint16_t)data[11] << 8)); |
|
|
|
|
|
|
|
//48 20 10 0 | c 0 1 0 | 3 0 8 0 44 0 70 0 0 0 0 0 |
|
|
|
if (dcid == interrupt_dcid_) { |
|
|
|
interrupt_scid_ = scid; |
|
|
|
if (dcid == connections_[current_connection_].interrupt_dcid_) { |
|
|
|
connections_[current_connection_].interrupt_scid_ = scid; |
|
|
|
DBGPrintf(" Interrupt Response\n"); |
|
|
|
connection_rxid_++; |
|
|
|
sendl2cap_ConfigRequest(device_connection_handle_, connection_rxid_, scid); |
|
|
|
} else if (dcid == control_dcid_) { |
|
|
|
control_scid_ = scid; |
|
|
|
connections_[current_connection_].connection_rxid_++; |
|
|
|
sendl2cap_ConfigRequest(connections_[current_connection_].device_connection_handle_, connections_[current_connection_].connection_rxid_, scid); |
|
|
|
} else if (dcid == connections_[current_connection_].control_dcid_) { |
|
|
|
connections_[current_connection_].control_scid_ = scid; |
|
|
|
DBGPrintf(" Control Response\n"); |
|
|
|
sendl2cap_ConfigRequest(device_connection_handle_, connection_rxid_, scid); |
|
|
|
sendl2cap_ConfigRequest(connections_[current_connection_].device_connection_handle_, connections_[current_connection_].connection_rxid_, scid); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -1430,12 +1468,12 @@ void BluetoothController::process_l2cap_config_request(uint8_t *data) { |
|
|
|
data[1], dcid, data[6]+((uint16_t)data[7] << 8), |
|
|
|
data[8], data[9], data[10], data[11]); |
|
|
|
// Now see which dest was specified |
|
|
|
if (dcid == control_dcid_) { |
|
|
|
if (dcid == connections_[current_connection_].control_dcid_) { |
|
|
|
DBGPrintf(" Control Configuration request\n"); |
|
|
|
sendl2cap_ConfigResponse(device_connection_handle_, data[1], control_scid_); |
|
|
|
} else if (dcid == interrupt_dcid_) { |
|
|
|
sendl2cap_ConfigResponse(connections_[current_connection_].device_connection_handle_, data[1], connections_[current_connection_].control_scid_); |
|
|
|
} else if (dcid == connections_[current_connection_].interrupt_dcid_) { |
|
|
|
DBGPrintf(" Interrupt Configuration request\n"); |
|
|
|
sendl2cap_ConfigResponse(device_connection_handle_, data[1], interrupt_scid_); |
|
|
|
sendl2cap_ConfigResponse(connections_[current_connection_].device_connection_handle_, data[1], connections_[current_connection_].interrupt_scid_); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -1445,25 +1483,25 @@ void BluetoothController::process_l2cap_config_response(uint8_t *data) { |
|
|
|
DBGPrintf(" L2CAP config Response: ID: %d, Source:%x, Flags:%x, Result:%x, Config: %x\n", |
|
|
|
data[1], scid, data[6]+((uint16_t)data[7] << 8), |
|
|
|
data[8]+((uint16_t)data[9] << 8), data[10]+((uint16_t)data[11] << 8)); |
|
|
|
if (scid == control_dcid_) { |
|
|
|
if (scid == connections_[current_connection_].control_dcid_) { |
|
|
|
// Set HID Boot mode |
|
|
|
// Don't do if PS3... |
|
|
|
if (!(device_driver_->special_process_required & BTHIDInput::SP_PS3_IDS)) { |
|
|
|
if (!(connections_[current_connection_].device_driver_->special_process_required & BTHIDInput::SP_PS3_IDS)) { |
|
|
|
setHIDProtocol(HID_BOOT_PROTOCOL); // |
|
|
|
} |
|
|
|
//setHIDProtocol(HID_RPT_PROTOCOL); //HID_RPT_PROTOCOL |
|
|
|
if (do_pair_device_ && !(device_driver_ && (device_driver_->special_process_required & BTHIDInput::SP_DONT_NEED_CONNECT))) { |
|
|
|
if (do_pair_device_ && !(connections_[current_connection_].device_driver_ && (connections_[current_connection_].device_driver_->special_process_required & BTHIDInput::SP_DONT_NEED_CONNECT))) { |
|
|
|
pending_control_tx_ = STATE_TX_SEND_CONNECT_INT; |
|
|
|
} else if (device_driver_ && (device_driver_->special_process_required & BTHIDInput::SP_NEED_CONNECT)) { |
|
|
|
} else if (connections_[current_connection_].device_driver_ && (connections_[current_connection_].device_driver_->special_process_required & BTHIDInput::SP_NEED_CONNECT)) { |
|
|
|
DBGPrintf(" Needs connect to device INT(PS4?)\n"); |
|
|
|
// The PS4 requires a connection request to it. |
|
|
|
pending_control_tx_ = STATE_TX_SEND_CONNECT_INT; |
|
|
|
} else { |
|
|
|
pending_control_ = 0; |
|
|
|
} |
|
|
|
} else if (scid == interrupt_dcid_) { |
|
|
|
} else if (scid == connections_[current_connection_].interrupt_dcid_) { |
|
|
|
// Enable SCan to page mode |
|
|
|
connection_complete_ = true; |
|
|
|
connections_[current_connection_].connection_complete_ = true; |
|
|
|
sendHCIWriteScanEnable(2); |
|
|
|
} |
|
|
|
} |
|
|
@@ -1488,7 +1526,7 @@ void BluetoothController::setHIDProtocol(uint8_t protocol) { |
|
|
|
uint8_t l2capbuf[1]; |
|
|
|
l2capbuf[0] = 0x70 | protocol; // Set Protocol, see Bluetooth HID specs page 33 |
|
|
|
DBGPrintf("Set HID Protocol %d (", protocol); |
|
|
|
sendL2CapCommand(device_connection_handle_, l2capbuf, sizeof(l2capbuf), control_scid_ & 0xff, control_scid_ >> 8); |
|
|
|
sendL2CapCommand(connections_[current_connection_].device_connection_handle_, l2capbuf, sizeof(l2capbuf), connections_[current_connection_].control_scid_ & 0xff, connections_[current_connection_].control_scid_ >> 8); |
|
|
|
} |
|
|
|
|
|
|
|
void BluetoothController::handleHIDTHDRData(uint8_t *data) { |
|
|
@@ -1496,11 +1534,11 @@ void BluetoothController::handleHIDTHDRData(uint8_t *data) { |
|
|
|
// T HID data |
|
|
|
//48 20 d 0 9 0 71 0 a1 3 8a cc c5 a 23 22 79 |
|
|
|
uint16_t len = data[4] + ((uint16_t)data[5] << 8); |
|
|
|
DBGPrintf("HID HDR Data: len: %d, Type: %d\n", len, data[9]); |
|
|
|
DBGPrintf("HID HDR Data: len: %d, Type: %d Con:%d\n", len, data[9], current_connection_); |
|
|
|
|
|
|
|
// ??? How to parse??? Use HID object??? |
|
|
|
if (device_driver_) { |
|
|
|
device_driver_->process_bluetooth_HID_data(&data[9], len-1); // We skip the first byte... |
|
|
|
if (connections_[current_connection_].device_driver_) { |
|
|
|
connections_[current_connection_].device_driver_->process_bluetooth_HID_data(&data[9], len-1); // We skip the first byte... |
|
|
|
} else { |
|
|
|
switch (data[9]) { |
|
|
|
case 1: |