36 control_dcid[0] = 0x70;
37 control_dcid[1] = 0x00;
38 interrupt_dcid[0] = 0x71;
39 interrupt_dcid[1] = 0x00;
46 activeConnection =
false;
62 if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_CTRL_PSM) {
65 activeConnection =
true;
73 if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) {
76 Notify(PSTR(
"\r\nL2CAP Command Rejected - Reason: "), 0x80);
77 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
79 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
81 D_PrintHex<uint8_t > (l2capinbuf[17], 0x80);
83 D_PrintHex<uint8_t > (l2capinbuf[16], 0x80);
85 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
87 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
90 if(((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) ==
SUCCESSFUL)) {
91 if(l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) {
93 identifier = l2capinbuf[9];
97 }
else if(l2capinbuf[14] == interrupt_dcid[0] && l2capinbuf[15] == interrupt_dcid[1]) {
99 identifier = l2capinbuf[9];
107 Notify(PSTR(
"\r\nL2CAP Connection Request - PSM: "), 0x80);
108 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
110 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
111 Notify(PSTR(
" SCID: "), 0x80);
112 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
114 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
115 Notify(PSTR(
" Identifier: "), 0x80);
116 D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
118 if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_CTRL_PSM) {
119 identifier = l2capinbuf[9];
123 }
else if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_INTR_PSM) {
124 identifier = l2capinbuf[9];
130 if((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) {
131 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
133 identifier = l2capinbuf[9];
135 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
137 identifier = l2capinbuf[9];
142 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
145 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
150 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
151 #ifdef DEBUG_USB_HOST
152 Notify(PSTR(
"\r\nDisconnect Request: Control Channel"), 0x80);
154 identifier = l2capinbuf[9];
157 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
158 #ifdef DEBUG_USB_HOST
159 Notify(PSTR(
"\r\nDisconnect Request: Interrupt Channel"), 0x80);
161 identifier = l2capinbuf[9];
168 identifier = l2capinbuf[9];
172 identifier = l2capinbuf[9];
178 identifier = l2capinbuf[9];
179 Notify(PSTR(
"\r\nL2CAP Unknown Signaling Command: "), 0x80);
180 D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
183 }
else if(l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) {
185 Notify(PSTR(
"\r\nL2CAP Interrupt: "), 0x80);
186 for(uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) {
187 D_PrintHex<uint8_t > (l2capinbuf[i + 8], 0x80);
191 if(l2capinbuf[8] == 0xA1) {
192 uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]);
195 switch(l2capinbuf[9]) {
198 pRptParser[
KEYBOARD_PARSER_ID]->
Parse(reinterpret_cast<HID *>(
this), 0, (uint8_t)(length - 2), &l2capinbuf[10]);
203 pRptParser[
MOUSE_PARSER_ID]->
Parse(reinterpret_cast<HID *>(
this), 0, (uint8_t)(length - 2), &l2capinbuf[10]);
207 Notify(PSTR(
"\r\nUnknown Report type: "), 0x80);
208 D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
213 }
else if(l2capinbuf[6] == control_dcid[0] && l2capinbuf[7] == control_dcid[1]) {
215 Notify(PSTR(
"\r\nL2CAP Control: "), 0x80);
216 for(uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) {
217 D_PrintHex<uint8_t > (l2capinbuf[i + 8], 0x80);
224 Notify(PSTR(
"\r\nUnsupported L2CAP Data - Channel ID: "), 0x80);
225 D_PrintHex<uint8_t > (l2capinbuf[7], 0x80);
227 D_PrintHex<uint8_t > (l2capinbuf[6], 0x80);
229 Notify(PSTR(
"\r\nData: "), 0x80);
230 Notify(PSTR(
"\r\n"), 0x80);
231 for(uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) {
232 D_PrintHex<uint8_t > (l2capinbuf[i + 8], 0x80);
241 void BTHID::L2CAP_task() {
242 switch(l2cap_state) {
246 #ifdef DEBUG_USB_HOST
247 Notify(PSTR(
"\r\nHID Control Successfully Configured"), 0x80);
256 #ifdef DEBUG_USB_HOST
257 Notify(PSTR(
"\r\nHID Interrupt Incoming Connection Request"), 0x80);
273 #ifdef DEBUG_USB_HOST
274 Notify(PSTR(
"\r\nSend HID Control Config Request"), 0x80);
286 #ifdef DEBUG_USB_HOST
287 Notify(PSTR(
"\r\nSend HID Interrupt Connection Request"), 0x80);
297 #ifdef DEBUG_USB_HOST
298 Notify(PSTR(
"\r\nSend HID Interrupt Config Request"), 0x80);
308 #ifdef DEBUG_USB_HOST
309 Notify(PSTR(
"\r\nHID Channels Established"), 0x80);
324 #ifdef DEBUG_USB_HOST
325 Notify(PSTR(
"\r\nDisconnected Interrupt Channel"), 0x80);
335 #ifdef DEBUG_USB_HOST
336 Notify(PSTR(
"\r\nDisconnected Control Channel"), 0x80);
340 l2cap_event_flag = 0;
348 switch(l2cap_state) {
352 activeConnection =
true;
353 #ifdef DEBUG_USB_HOST
354 Notify(PSTR(
"\r\nSend HID Control Connection Request"), 0x80);
357 l2cap_event_flag = 0;
362 #ifdef DEBUG_USB_HOST
363 Notify(PSTR(
"\r\nHID Control Incoming Connection Request"), 0x80);
381 void BTHID::setProtocol() {
382 #ifdef DEBUG_USB_HOST
383 Notify(PSTR(
"\r\nSet protocol mode: "), 0x80);
384 D_PrintHex<uint8_t > (protocolMode, 0x80);
387 #ifdef DEBUG_USB_HOST
388 Notify(PSTR(
"\r\nNot a valid protocol mode. Using Boot protocol instead."), 0x80);
392 uint8_t command = 0x70 | protocolMode;
#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE
#define UHS_ACL_HANDLE_OK(x, y)
#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS
#define L2CAP_INTERRUPT_CONFIG_REQUEST
#define L2CAP_INTERRUPT_SETUP
void l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid, uint8_t result)
virtual void ACLData(uint8_t *ACLData)
void l2cap_connection_request(uint16_t handle, uint8_t rxid, uint8_t *scid, uint16_t psm)
#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST
void l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
uint8_t interrupt_scid[2]
#define L2CAP_CONTROL_SUCCESS
virtual void ResetBTHID()
#define L2CAP_CONTROL_CONFIG_REQUEST
void l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
#define HID_BOOT_PROTOCOL
#define L2CAP_CONTROL_CONNECT_REQUEST
void hci_disconnect(uint16_t handle)
#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE
virtual void disconnect()
void setLeds(uint8_t data)
virtual void ParseBTHIDData(uint8_t len, uint8_t *buf)
#define l2cap_check_flag(flag)
#define L2CAP_CMD_CONFIG_REQUEST
#define L2CAP_FLAG_CONTROL_CONNECTED
#define L2CAP_CMD_DISCONNECT_REQUEST
#define L2CAP_CONTROL_DISCONNECT
#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST
int8_t registerServiceClass(BluetoothService *pService)
bool l2capConnectionClaimed
virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)=0
#define L2CAP_CMD_DISCONNECT_RESPONSE
#define L2CAP_CMD_CONNECTION_RESPONSE
#define L2CAP_CMD_CONFIG_RESPONSE
#define KEYBOARD_PARSER_ID
void L2CAP_Command(uint16_t handle, uint8_t *data, uint8_t nbytes, uint8_t channelLow=0x01, uint8_t channelHigh=0x00)
void l2cap_config_response(uint16_t handle, uint8_t rxid, uint8_t *scid)
#define L2CAP_FLAG_INTERRUPT_CONNECTED
#define l2cap_set_flag(flag)
void l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t *dcid)
#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS
#define L2CAP_CMD_CONNECTION_REQUEST
BTHID(BTD *p, bool pair=false, const char *pin="0000")
#define L2CAP_INTERRUPT_CONNECT_REQUEST
#define L2CAP_INTERRUPT_DISCONNECT
#define L2CAP_CMD_COMMAND_REJECT