27 for(uint8_t i = 0; i <
epMUL; i++)
39 control_dcid[0] = 0x70;
40 control_dcid[1] = 0x00;
41 interrupt_dcid[0] = 0x71;
42 interrupt_dcid[1] = 0x00;
49 activeConnection =
false;
64 if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_CTRL_PSM) {
67 activeConnection =
true;
73 if ((l2capinbuf[0] | (l2capinbuf[1] << 8)) == (hci_handle | 0x2000)) {
74 if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) {
77 Notify(PSTR(
"\r\nL2CAP Command Rejected - Reason: "), 0x80);
78 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
80 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
82 D_PrintHex<uint8_t > (l2capinbuf[17], 0x80);
84 D_PrintHex<uint8_t > (l2capinbuf[16], 0x80);
86 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
88 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
91 if (((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) ==
SUCCESSFUL)) {
92 if (l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) {
94 identifier = l2capinbuf[9];
95 control_scid[0] = l2capinbuf[12];
96 control_scid[1] = l2capinbuf[13];
98 }
else if (l2capinbuf[14] == interrupt_dcid[0] && l2capinbuf[15] == interrupt_dcid[1]) {
100 identifier = l2capinbuf[9];
101 interrupt_scid[0] = l2capinbuf[12];
102 interrupt_scid[1] = l2capinbuf[13];
108 Notify(PSTR(
"\r\nL2CAP Connection Request - PSM: "), 0x80);
109 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
111 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
112 Notify(PSTR(
" SCID: "), 0x80);
113 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
115 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
116 Notify(PSTR(
" Identifier: "), 0x80);
117 D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
119 if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_CTRL_PSM) {
120 identifier = l2capinbuf[9];
121 control_scid[0] = l2capinbuf[14];
122 control_scid[1] = l2capinbuf[15];
124 }
else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_INTR_PSM) {
125 identifier = l2capinbuf[9];
126 interrupt_scid[0] = l2capinbuf[14];
127 interrupt_scid[1] = l2capinbuf[15];
131 if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) {
132 if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
134 identifier = l2capinbuf[9];
136 }
else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
138 identifier = l2capinbuf[9];
143 if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
146 }
else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
151 if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
152 #ifdef DEBUG_USB_HOST
153 Notify(PSTR(
"\r\nDisconnect Request: Control Channel"), 0x80);
155 identifier = l2capinbuf[9];
158 }
else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
159 #ifdef DEBUG_USB_HOST
160 Notify(PSTR(
"\r\nDisconnect Request: Interrupt Channel"), 0x80);
162 identifier = l2capinbuf[9];
167 if (l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
169 identifier = l2capinbuf[9];
171 }
else if (l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
173 identifier = l2capinbuf[9];
179 identifier = l2capinbuf[9];
180 Notify(PSTR(
"\r\nL2CAP Unknown Signaling Command: "), 0x80);
181 D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
184 }
else if (l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) {
187 Notify(PSTR(
"\r\n"), 0x80);
188 for (uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) {
189 D_PrintHex<uint8_t > (l2capinbuf[i + 8], 0x80);
193 if (l2capinbuf[8] == 0xA1) {
194 switch (l2capinbuf[9]) {
197 uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]);
205 uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]);
211 Notify(PSTR(
"\r\nChange mode event: "), 0x80);
212 D_PrintHex<uint8_t > (l2capinbuf[11], 0x80);
215 #ifdef DEBUG_USB_HOST
217 Notify(PSTR(
"\r\nUnknown Report type: "), 0x80);
218 D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
226 Notify(PSTR(
"\r\nUnsupported L2CAP Data - Channel ID: "), 0x80);
227 D_PrintHex<uint8_t > (l2capinbuf[7], 0x80);
229 D_PrintHex<uint8_t > (l2capinbuf[6], 0x80);
231 Notify(PSTR(
"\r\nData: "), 0x80);
232 Notify(PSTR(
"\r\n"), 0x80);
233 for (uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) {
234 D_PrintHex<uint8_t > (l2capinbuf[i + 8], 0x80);
243 void BTHID::L2CAP_task() {
244 switch (l2cap_state) {
248 #ifdef DEBUG_USB_HOST
249 Notify(PSTR(
"\r\nHID Control Successfully Configured"), 0x80);
257 #ifdef DEBUG_USB_HOST
258 Notify(PSTR(
"\r\nHID Interrupt Incoming Connection Request"), 0x80);
274 #ifdef DEBUG_USB_HOST
275 Notify(PSTR(
"\r\nSend HID Control Config Request"), 0x80);
285 #ifdef DEBUG_USB_HOST
286 Notify(PSTR(
"\r\nSend HID Interrupt Connection Request"), 0x80);
296 #ifdef DEBUG_USB_HOST
297 Notify(PSTR(
"\r\nSend HID Interrupt Config Request"), 0x80);
307 #ifdef DEBUG_USB_HOST
308 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);
380 void BTHID::setProtocol() {
381 uint8_t command = 0x70 | protocolMode;
382 pBtd->
L2CAP_Command(hci_handle, &command, 1, control_scid[0], control_scid[1]);
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_CONTROL_CONFIG_REQUEST
void l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
#define l2cap_disconnect_response_interrupt_flag
#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS
#define l2cap_connection_request_control_flag
void l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
#define L2CAP_FLAG_INTERRUPT_CONNECTED
#define HID_BOOT_PROTOCOL
#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE
#define l2cap_connection_request_interrupt_flag
#define L2CAP_INTERRUPT_DISCONNECT
void hci_disconnect(uint16_t handle)
virtual void disconnect()
#define L2CAP_CONTROL_CONNECT_REQUEST
#define L2CAP_INTERRUPT_SETUP
#define l2cap_disconnect_response_control_flag
#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST
#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST
#define L2CAP_CMD_CONFIG_REQUEST
#define L2CAP_CMD_DISCONNECT_REQUEST
#define L2CAP_INTERRUPT_CONNECT_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_connected_interrupt_flag
#define L2CAP_CMD_CONFIG_RESPONSE
#define L2CAP_FLAG_CONTROL_CONNECTED
#define l2cap_config_success_control_flag
#define l2cap_config_success_interrupt_flag
#define KEYBOARD_PARSER_ID
#define l2cap_connected_control_flag
#define L2CAP_CONTROL_SUCCESS
BTHID(BTD *p, bool pair=false, const char *pin="1234")
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)
void l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t *dcid)
#define L2CAP_INTERRUPT_CONFIG_REQUEST
#define L2CAP_CMD_CONNECTION_REQUEST
#define L2CAP_CONTROL_DISCONNECT
#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE
#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS
#define L2CAP_CMD_COMMAND_REJECT