35 control_dcid[0] = 0x70;
36 control_dcid[1] = 0x00;
37 interrupt_dcid[0] = 0x71;
38 interrupt_dcid[1] = 0x00;
45 activeConnection =
false;
76 if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_CTRL_PSM) {
79 activeConnection =
true;
87 if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) {
90 Notify(
PSTR(
"\r\nL2CAP Command Rejected - Reason: "), 0x80);
91 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
93 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
95 D_PrintHex<uint8_t > (l2capinbuf[17], 0x80);
97 D_PrintHex<uint8_t > (l2capinbuf[16], 0x80);
99 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
101 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
104 if(((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) ==
SUCCESSFUL)) {
105 if(l2capinbuf[14] == sdp_dcid[0] && l2capinbuf[15] == sdp_dcid[1]) {
107 Notify(
PSTR(
"\r\nSDP Connection Complete"), 0x80);
112 #ifdef DEBUG_USB_HOST
113 Notify(
PSTR(
"\r\nSend SDP Config Request"), 0x80);
117 }
else if(l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) {
119 Notify(
PSTR(
"\r\nHID Control Connection Complete"), 0x80);
125 }
else if(l2capinbuf[14] == interrupt_dcid[0] && l2capinbuf[15] == interrupt_dcid[1]) {
127 Notify(
PSTR(
"\r\nHID Interrupt Connection Complete"), 0x80);
137 Notify(
PSTR(
"\r\nL2CAP Connection Request - PSM: "), 0x80);
138 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
140 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
142 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
144 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
146 D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
148 if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
SDP_PSM) {
153 }
else if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_CTRL_PSM) {
158 }
else if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_INTR_PSM) {
165 if((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) {
166 if(l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
168 Notify(
PSTR(
"\r\nSDP Configuration Complete"), 0x80);
172 }
else if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
174 Notify(
PSTR(
"\r\nHID Control Configuration Complete"), 0x80);
178 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
180 Notify(
PSTR(
"\r\nHID Interrupt Configuration Complete"), 0x80);
187 if(l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
189 Notify(
PSTR(
"\r\nSDP Configuration Request"), 0x80);
192 }
else if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
194 Notify(
PSTR(
"\r\nHID Control Configuration Request"), 0x80);
197 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
199 Notify(
PSTR(
"\r\nHID Interrupt Configuration Request"), 0x80);
204 if(l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
205 #ifdef DEBUG_USB_HOST
206 Notify(
PSTR(
"\r\nDisconnect Request: SDP Channel"), 0x80);
210 }
else if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
211 #ifdef DEBUG_USB_HOST
212 Notify(
PSTR(
"\r\nDisconnect Request: Control Channel"), 0x80);
217 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
218 #ifdef DEBUG_USB_HOST
219 Notify(
PSTR(
"\r\nDisconnect Request: Interrupt Channel"), 0x80);
228 Notify(
PSTR(
"\r\nDisconnect Response: SDP Channel"), 0x80);
234 Notify(
PSTR(
"\r\nDisconnect Response: Control Channel"), 0x80);
240 Notify(
PSTR(
"\r\nDisconnect Response: Interrupt Channel"), 0x80);
246 #ifdef DEBUG_USB_HOST
247 Notify(
PSTR(
"\r\nInformation request"), 0x80);
255 Notify(
PSTR(
"\r\nL2CAP Unknown Signaling Command: "), 0x80);
256 D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
259 }
else if(l2capinbuf[6] == sdp_dcid[0] && l2capinbuf[7] == sdp_dcid[1]) {
262 Notify(
PSTR(
"\r\nSDP_SERVICE_SEARCH_REQUEST"), 0x80);
266 l2capoutbuf[1] = l2capinbuf[9];
267 l2capoutbuf[2] = l2capinbuf[10];
269 l2capoutbuf[3] = 0x00;
270 l2capoutbuf[4] = 0x05;
272 l2capoutbuf[5] = 0x00;
273 l2capoutbuf[6] = 0x00;
275 l2capoutbuf[7] = 0x00;
276 l2capoutbuf[8] = 0x00;
278 l2capoutbuf[9] = 0x00;
280 SDP_Command(l2capoutbuf, 10);
283 Notify(
PSTR(
"\r\nSDP_SERVICE_ATTRIBUTE_REQUEST"), 0x80);
287 l2capoutbuf[1] = l2capinbuf[9];
288 l2capoutbuf[2] = l2capinbuf[10];
290 l2capoutbuf[3] = 0x00;
291 l2capoutbuf[4] = 0x05;
293 l2capoutbuf[5] = 0x00;
294 l2capoutbuf[6] = 0x02;
297 l2capoutbuf[7] = 0x35;
298 l2capoutbuf[8] = 0x00;
300 l2capoutbuf[9] = 0x00;
302 SDP_Command(l2capoutbuf, 10);
305 Notify(
PSTR(
"\r\nSDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST"), 0x80);
308 if((l2capinbuf[16] << 8 | l2capinbuf[17]) == 0x0000)
309 uuid = (l2capinbuf[18] << 8 | l2capinbuf[19]);
311 uuid = (l2capinbuf[16] << 8 | l2capinbuf[17]);
312 D_PrintHex<uint16_t > (uuid, 0x80);
315 uint16_t length = l2capinbuf[11] << 8 | l2capinbuf[12];
316 D_PrintHex<uint16_t > (length, 0x80);
318 for(uint8_t i = 0; i < length; i++) {
319 D_PrintHex<uint8_t > (l2capinbuf[13 + i], 0x80);
323 serviceNotSupported(l2capinbuf[9], l2capinbuf[10]);
328 D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
331 }
else if(l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) {
334 for(uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) {
335 D_PrintHex<uint8_t > (l2capinbuf[i + 8], 0x80);
339 if(l2capinbuf[8] == 0xA1) {
340 lastBtDataInputIntMillis = (uint32_t)millis();
342 uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]);
345 switch(l2capinbuf[9]) {
357 Notify(
PSTR(
"\r\nUnknown Report type: "), 0x80);
358 D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
364 Notify(
PSTR(
"\r\nUnhandled L2CAP interrupt report: "), 0x80);
365 D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
368 }
else if(l2capinbuf[6] == control_dcid[0] && l2capinbuf[7] == control_dcid[1]) {
371 for(uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) {
372 D_PrintHex<uint8_t > (l2capinbuf[i + 8], 0x80);
376 if(l2capinbuf[8] == 0xA3) {
377 uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]);
381 Notify(
PSTR(
"\r\nUnhandled L2CAP control report: "), 0x80);
382 D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
388 Notify(
PSTR(
"\r\nUnsupported L2CAP Data - Channel ID: "), 0x80);
389 D_PrintHex<uint8_t > (l2capinbuf[7], 0x80);
391 D_PrintHex<uint8_t > (l2capinbuf[6], 0x80);
395 for(uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) {
396 D_PrintHex<uint8_t > (l2capinbuf[i + 8], 0x80);
406 void BTHID::SDP_task() {
411 #ifdef DEBUG_USB_HOST
412 Notify(
PSTR(
"\r\nSDP Incoming Connection Request"), 0x80);
423 SDPConnected =
false;
424 #ifdef DEBUG_USB_HOST
425 Notify(
PSTR(
"\r\nDisconnected SDP Channel"), 0x80);
433 #ifdef DEBUG_USB_HOST
434 Notify(
PSTR(
"\r\nSDP Successfully Configured"), 0x80);
443 #ifdef DEBUG_USB_HOST
444 Notify(
PSTR(
"\r\nDisconnected L2CAP Connection"), 0x80);
454 void BTHID::L2CAP_task() {
455 switch(l2cap_state) {
459 #ifdef DEBUG_USB_HOST
460 Notify(
PSTR(
"\r\nHID Control Successfully Configured"), 0x80);
469 #ifdef DEBUG_USB_HOST
470 Notify(
PSTR(
"\r\nHID Interrupt Incoming Connection Request"), 0x80);
486 #ifdef DEBUG_USB_HOST
487 Notify(
PSTR(
"\r\nSend HID Control Config Request"), 0x80);
499 #ifdef DEBUG_USB_HOST
500 Notify(
PSTR(
"\r\nSend HID Interrupt Connection Request"), 0x80);
510 #ifdef DEBUG_USB_HOST
511 Notify(
PSTR(
"\r\nSend HID Interrupt Config Request"), 0x80);
521 #ifdef DEBUG_USB_HOST
522 Notify(
PSTR(
"\r\nHID Channels Established"), 0x80);
537 #ifdef DEBUG_USB_HOST
538 Notify(
PSTR(
"\r\nDisconnected Interrupt Channel"), 0x80);
548 #ifdef DEBUG_USB_HOST
549 Notify(
PSTR(
"\r\nDisconnected Control Channel"), 0x80);
561 switch(l2cap_state) {
565 activeConnection =
true;
566 #ifdef DEBUG_USB_HOST
567 Notify(
PSTR(
"\r\nSend HID Control Connection Request"), 0x80);
575 #ifdef DEBUG_USB_HOST
576 Notify(
PSTR(
"\r\nHID Control Incoming Connection Request"), 0x80);
590 void BTHID::SDP_Command(uint8_t* data, uint8_t nbytes) {
594 void BTHID::serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
596 l2capoutbuf[1] = transactionIDHigh;
597 l2capoutbuf[2] = transactionIDLow;
598 l2capoutbuf[3] = 0x00;
599 l2capoutbuf[4] = 0x05;
600 l2capoutbuf[5] = 0x00;
601 l2capoutbuf[6] = 0x02;
604 l2capoutbuf[7] = 0x35;
605 l2capoutbuf[8] = 0x00;
606 l2capoutbuf[9] = 0x00;
608 SDP_Command(l2capoutbuf, 10);
615 void BTHID::setProtocol() {
616 #ifdef DEBUG_USB_HOST
617 Notify(
PSTR(
"\r\nSet protocol mode: "), 0x80);
618 D_PrintHex<uint8_t > (protocolMode, 0x80);
621 #ifdef DEBUG_USB_HOST
622 Notify(
PSTR(
"\r\nNot a valid protocol mode. Using Boot protocol instead."), 0x80);
626 uint8_t command = 0x70 | protocolMode;
#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST
#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS
#define L2CAP_FLAG_CONNECTION_SDP_REQUEST
#define L2CAP_SDP_SUCCESS
#define SDP_SERVICE_ATTRIBUTE_RESPONSE
#define L2CAP_CMD_INFORMATION_REQUEST
#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE
#define SDP_SERVICE_ATTRIBUTE_REQUEST
#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS
#define L2CAP_FLAG_CONTROL_CONNECTED
#define L2CAP_CMD_DISCONNECT_REQUEST
#define L2CAP_CMD_CONFIG_REQUEST
#define L2CAP_CMD_DISCONNECT_RESPONSE
#define l2cap_check_flag(flag)
#define l2cap_set_flag(flag)
#define SDP_SERVICE_SEARCH_REQUEST
#define L2CAP_CONTROL_CONNECT_REQUEST
#define L2CAP_CMD_COMMAND_REJECT
#define L2CAP_INTERRUPT_CONFIG_REQUEST
#define L2CAP_FLAG_CONFIG_SDP_SUCCESS
#define L2CAP_CMD_CONFIG_RESPONSE
#define SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST
#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST
#define L2CAP_CONTROL_DISCONNECT
#define L2CAP_CONTROL_CONFIG_REQUEST
#define L2CAP_FLAG_DISCONNECT_SDP_REQUEST
#define L2CAP_FLAG_INTERRUPT_CONNECTED
#define L2CAP_INTERRUPT_DISCONNECT
#define l2cap_clear_flag(flag)
#define L2CAP_CONTROL_SUCCESS
#define L2CAP_CMD_CONNECTION_REQUEST
#define L2CAP_INTERRUPT_SETUP
#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE
#define SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE
#define L2CAP_DISCONNECT_RESPONSE
#define L2CAP_FLAG_DISCONNECT_RESPONSE
#define SDP_SERVICE_SEARCH_RESPONSE
#define L2CAP_CMD_CONNECTION_RESPONSE
#define L2CAP_INTERRUPT_CONNECT_REQUEST
#define KEYBOARD_PARSER_ID
bool l2capConnectionClaimed
void hci_disconnect(uint16_t handle)
void l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
void l2cap_connection_request(uint16_t handle, uint8_t rxid, uint8_t *scid, uint16_t psm)
void l2cap_config_response(uint16_t handle, uint8_t rxid, uint8_t *scid)
void l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid, uint8_t result)
void l2cap_information_response(uint16_t handle, uint8_t rxid, uint8_t infoTypeLow, uint8_t infoTypeHigh)
void L2CAP_Command(uint16_t handle, uint8_t *data, uint8_t nbytes, uint8_t channelLow=0x01, uint8_t channelHigh=0x00)
void l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t *dcid)
void l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
bool sdpConnectionClaimed
uint8_t interrupt_scid[2]
virtual void ParseBTHIDData(uint8_t len, uint8_t *buf)
BTHID(BTD *p, bool pair=false, const char *pin="0000")
void ACLData(uint8_t *ACLData)
virtual void ResetBTHID()
virtual void ParseBTHIDControlData(uint8_t len, uint8_t *buf)
void setLeds(struct KBDLEDS data)
bool checkHciHandle(uint8_t *buf, uint16_t handle)
uint32_t l2cap_event_flag
virtual void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)=0
#define USB_HID_BOOT_PROTOCOL