USB Host Shield 2.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
BTHID.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2013 Kristian Lauszus, TKJ Electronics. All rights reserved.
2 
3  This software may be distributed and modified under the terms of the GNU
4  General Public License version 2 (GPL2) as published by the Free Software
5  Foundation and appearing in the file GPL2.TXT included in the packaging of
6  this file. Please note that GPL2 Section 2[b] requires that all works based
7  on this software must also be made publicly available under the terms of
8  the GPL2 ("Copyleft").
9 
10  Contact information
11  -------------------
12 
13  Kristian Lauszus, TKJ Electronics
14  Web : http://www.tkjelectronics.com
15  e-mail : kristianl@tkjelectronics.com
16  */
17 
18 #include "BTHID.h"
19 // To enable serial debugging see "settings.h"
20 //#define EXTRADEBUG // Uncomment to get even more debugging data
21 //#define PRINTREPORT // Uncomment to print the report send by the HID device
22 
23 BTHID::BTHID(BTD *p, bool pair, const char *pin) :
24 pBtd(p), // pointer to USB class instance - mandatory
25 protocolMode(HID_BOOT_PROTOCOL)
26 {
27  for(uint8_t i = 0; i < epMUL; i++)
28  pRptParser[i] = NULL;
29 
30  if (pBtd)
31  pBtd->registerServiceClass(this); // Register it as a Bluetooth service
32 
33  pBtd->pairWithHIDDevice = pair;
34 
35  if (pair)
36  pBtd->btdPin= pin;
37 
38  /* Set device cid for the control and intterrupt channelse - LSB */
39  control_dcid[0] = 0x70; // 0x0070
40  control_dcid[1] = 0x00;
41  interrupt_dcid[0] = 0x71; // 0x0071
42  interrupt_dcid[1] = 0x00;
43 
44  Reset();
45 }
46 
47 void BTHID::Reset() {
48  connected = false;
49  activeConnection = false;
50  l2cap_event_flag = 0; // Reset flags
51  l2cap_state = L2CAP_WAIT;
52 }
53 
54 void BTHID::disconnect() { // Use this void to disconnect any of the controllers
55  // First the HID interrupt channel has to be disconnected, then the HID control channel and finally the HCI connection
56  pBtd->l2cap_disconnection_request(hci_handle, 0x0A, interrupt_scid, interrupt_dcid);
57  Reset();
58  l2cap_state = L2CAP_INTERRUPT_DISCONNECT;
59 }
60 
61 void BTHID::ACLData(uint8_t* l2capinbuf) {
62  if (!pBtd->l2capConnectionClaimed && pBtd->incomingHIDDevice && !connected && !activeConnection) {
63  if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
64  if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
65  pBtd->incomingHIDDevice = false;
66  pBtd->l2capConnectionClaimed = true; // Claim that the incoming connection belongs to this service
67  activeConnection = true;
68  hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
69  l2cap_state = L2CAP_WAIT;
70  }
71  }
72  }
73  if ((l2capinbuf[0] | (l2capinbuf[1] << 8)) == (hci_handle | 0x2000)) { // acl_handle_ok or it's a new connection
74  if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) { //l2cap_control - Channel ID for ACL-U
75  if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
76 #ifdef DEBUG_USB_HOST
77  Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
78  D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
79  Notify(PSTR(" "), 0x80);
80  D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
81  Notify(PSTR(" "), 0x80);
82  D_PrintHex<uint8_t > (l2capinbuf[17], 0x80);
83  Notify(PSTR(" "), 0x80);
84  D_PrintHex<uint8_t > (l2capinbuf[16], 0x80);
85  Notify(PSTR(" "), 0x80);
86  D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
87  Notify(PSTR(" "), 0x80);
88  D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
89 #endif
90  } else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_RESPONSE) {
91  if (((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) == SUCCESSFUL)) { // Success
92  if (l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) { // Success
93  //Notify(PSTR("\r\nHID Control Connection Complete"), 0x80);
94  identifier = l2capinbuf[9];
95  control_scid[0] = l2capinbuf[12];
96  control_scid[1] = l2capinbuf[13];
97  l2cap_event_flag |= L2CAP_FLAG_CONTROL_CONNECTED;
98  } else if (l2capinbuf[14] == interrupt_dcid[0] && l2capinbuf[15] == interrupt_dcid[1]) {
99  //Notify(PSTR("\r\nHID Interrupt Connection Complete"), 0x80);
100  identifier = l2capinbuf[9];
101  interrupt_scid[0] = l2capinbuf[12];
102  interrupt_scid[1] = l2capinbuf[13];
103  l2cap_event_flag |= L2CAP_FLAG_INTERRUPT_CONNECTED;
104  }
105  }
106  } else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
107 #ifdef EXTRADEBUG
108  Notify(PSTR("\r\nL2CAP Connection Request - PSM: "), 0x80);
109  D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
110  Notify(PSTR(" "), 0x80);
111  D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
112  Notify(PSTR(" SCID: "), 0x80);
113  D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
114  Notify(PSTR(" "), 0x80);
115  D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
116  Notify(PSTR(" Identifier: "), 0x80);
117  D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
118 #endif
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];
123  l2cap_event_flag |= L2CAP_FLAG_CONNECTION_CONTROL_REQUEST;
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];
128  l2cap_event_flag |= L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST;
129  }
130  } else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
131  if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success
132  if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
133  //Notify(PSTR("\r\nHID Control Configuration Complete"), 0x80);
134  identifier = l2capinbuf[9];
135  l2cap_event_flag |= L2CAP_FLAG_CONFIG_CONTROL_SUCCESS;
136  } else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
137  //Notify(PSTR("\r\nHID Interrupt Configuration Complete"), 0x80);
138  identifier = l2capinbuf[9];
139  l2cap_event_flag |= L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS;
140  }
141  }
142  } else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
143  if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
144  //Notify(PSTR("\r\nHID Control Configuration Request"), 0x80);
145  pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], control_scid);
146  } else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
147  //Notify(PSTR("\r\nHID Interrupt Configuration Request"), 0x80);
148  pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], interrupt_scid);
149  }
150  } else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
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);
154 #endif
155  identifier = l2capinbuf[9];
156  pBtd->l2cap_disconnection_response(hci_handle, identifier, control_dcid, control_scid);
157  Reset();
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);
161 #endif
162  identifier = l2capinbuf[9];
163  pBtd->l2cap_disconnection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid);
164  Reset();
165  }
166  } else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
167  if (l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
168  //Notify(PSTR("\r\nDisconnect Response: Control Channel"), 0x80);
169  identifier = l2capinbuf[9];
170  l2cap_event_flag |= L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE;
171  } else if (l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
172  //Notify(PSTR("\r\nDisconnect Response: Interrupt Channel"), 0x80);
173  identifier = l2capinbuf[9];
174  l2cap_event_flag |= L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE;
175  }
176  }
177 #ifdef EXTRADEBUG
178  else {
179  identifier = l2capinbuf[9];
180  Notify(PSTR("\r\nL2CAP Unknown Signaling Command: "), 0x80);
181  D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
182  }
183 #endif
184  } else if (l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) { // l2cap_interrupt
185  //Notify(PSTR("\r\n\r\nL2CAP Interrupt: "), 0x80);
186 #ifdef PRINTREPORT
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);
190  Notifyc(' ', 0x80);
191  }
192 #endif
193  if (l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT
194  switch (l2capinbuf[9]) {
195  case 0x01: // Keyboard events
196  if (pRptParser[KEYBOARD_PARSER_ID]) {
197  uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]);
198  pRptParser[KEYBOARD_PARSER_ID]->Parse((HID*)this, 0, (uint8_t) length, &l2capinbuf[10]);
199  }
200  break;
201 
202  case 0x02: // Mouse events
203  case 0x1A:
204  if (pRptParser[MOUSE_PARSER_ID]) {
205  uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]);
206  pRptParser[MOUSE_PARSER_ID]->Parse((HID*)this, 0, (uint8_t) length, &l2capinbuf[10]);
207  }
208  break;
209  case 0x03:
210 #ifdef EXTRADEBUG
211  Notify(PSTR("\r\nChange mode event: "), 0x80);
212  D_PrintHex<uint8_t > (l2capinbuf[11], 0x80);
213 #endif
214  break;
215 #ifdef DEBUG_USB_HOST
216  default:
217  Notify(PSTR("\r\nUnknown Report type: "), 0x80);
218  D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
219  break;
220 #endif
221  }
222  }
223  }
224 #ifdef EXTRADEBUG
225  else {
226  Notify(PSTR("\r\nUnsupported L2CAP Data - Channel ID: "), 0x80);
227  D_PrintHex<uint8_t > (l2capinbuf[7], 0x80);
228  Notify(PSTR(" "), 0x80);
229  D_PrintHex<uint8_t > (l2capinbuf[6], 0x80);
230 
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);
235  Notifyc(' ', 0x80);
236  }
237  }
238 #endif
239  L2CAP_task();
240  }
241 }
242 
243 void BTHID::L2CAP_task() {
244  switch (l2cap_state) {
245  /* These states are used if the HID device is the host */
248 #ifdef DEBUG_USB_HOST
249  Notify(PSTR("\r\nHID Control Successfully Configured"), 0x80);
250 #endif
251  l2cap_state = L2CAP_INTERRUPT_SETUP;
252  }
253  break;
254 
257 #ifdef DEBUG_USB_HOST
258  Notify(PSTR("\r\nHID Interrupt Incoming Connection Request"), 0x80);
259 #endif
260  pBtd->l2cap_connection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid, PENDING);
261  delay(1);
262  pBtd->l2cap_connection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid, SUCCESSFUL);
263  identifier++;
264  delay(1);
265  pBtd->l2cap_config_request(hci_handle, identifier, interrupt_scid);
266 
267  l2cap_state = L2CAP_INTERRUPT_CONFIG_REQUEST;
268  }
269  break;
270 
271  /* These states are used if the Arduino is the host */
274 #ifdef DEBUG_USB_HOST
275  Notify(PSTR("\r\nSend HID Control Config Request"), 0x80);
276 #endif
277  identifier++;
278  pBtd->l2cap_config_request(hci_handle, identifier, control_scid);
279  l2cap_state = L2CAP_CONTROL_CONFIG_REQUEST;
280  }
281  break;
282 
285 #ifdef DEBUG_USB_HOST
286  Notify(PSTR("\r\nSend HID Interrupt Connection Request"), 0x80);
287 #endif
288  identifier++;
289  pBtd->l2cap_connection_request(hci_handle, identifier, interrupt_dcid, HID_INTR_PSM);
290  l2cap_state = L2CAP_INTERRUPT_CONNECT_REQUEST;
291  }
292  break;
293 
296 #ifdef DEBUG_USB_HOST
297  Notify(PSTR("\r\nSend HID Interrupt Config Request"), 0x80);
298 #endif
299  identifier++;
300  pBtd->l2cap_config_request(hci_handle, identifier, interrupt_scid);
301  l2cap_state = L2CAP_INTERRUPT_CONFIG_REQUEST;
302  }
303  break;
304 
306  if (l2cap_config_success_interrupt_flag) { // Now the HID channels is established
307 #ifdef DEBUG_USB_HOST
308  Notify(PSTR("\r\nHID Channels Established"), 0x80);
309 #endif
310  pBtd->connectToHIDDevice = false;
311  pBtd->pairWithHIDDevice = false;
312  connected = true;
313  setProtocol();
314  onInit();
315  l2cap_state = L2CAP_DONE;
316  }
317  break;
318 
319  case L2CAP_DONE:
320  break;
321 
324 #ifdef DEBUG_USB_HOST
325  Notify(PSTR("\r\nDisconnected Interrupt Channel"), 0x80);
326 #endif
327  identifier++;
328  pBtd->l2cap_disconnection_request(hci_handle, identifier, control_scid, control_dcid);
329  l2cap_state = L2CAP_CONTROL_DISCONNECT;
330  }
331  break;
332 
335 #ifdef DEBUG_USB_HOST
336  Notify(PSTR("\r\nDisconnected Control Channel"), 0x80);
337 #endif
338  pBtd->hci_disconnect(hci_handle);
339  hci_handle = -1; // Reset handle
340  l2cap_event_flag = 0; // Reset flags
341  l2cap_state = L2CAP_WAIT;
342  }
343  break;
344  }
345 }
346 
347 void BTHID::Run() {
348  switch (l2cap_state) {
349  case L2CAP_WAIT:
350  if (pBtd->connectToHIDDevice && !pBtd->l2capConnectionClaimed && !connected && !activeConnection) {
351  pBtd->l2capConnectionClaimed = true;
352  activeConnection = true;
353 #ifdef DEBUG_USB_HOST
354  Notify(PSTR("\r\nSend HID Control Connection Request"), 0x80);
355 #endif
356  hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
357  l2cap_event_flag = 0; // Reset flags
358  identifier = 0;
359  pBtd->l2cap_connection_request(hci_handle, identifier, control_dcid, HID_CTRL_PSM);
360  l2cap_state = L2CAP_CONTROL_CONNECT_REQUEST;
362 #ifdef DEBUG_USB_HOST
363  Notify(PSTR("\r\nHID Control Incoming Connection Request"), 0x80);
364 #endif
365  pBtd->l2cap_connection_response(hci_handle, identifier, control_dcid, control_scid, PENDING);
366  delay(1);
367  pBtd->l2cap_connection_response(hci_handle, identifier, control_dcid, control_scid, SUCCESSFUL);
368  identifier++;
369  delay(1);
370  pBtd->l2cap_config_request(hci_handle, identifier, control_scid);
371  l2cap_state = L2CAP_CONTROL_SUCCESS;
372  }
373  break;
374  }
375 }
376 
377 /************************************************************/
378 /* HID Commands */
379 /************************************************************/
380 void BTHID::setProtocol() {
381  uint8_t command = 0x70 | protocolMode; // Set Protocol, see HID specs page 33
382  pBtd->L2CAP_Command(hci_handle, &command, 1, control_scid[0], control_scid[1]);
383 }
void l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid, uint8_t result)
Definition: BTD.cpp:1222
#define SUCCESSFUL
Definition: BTD.h:121
virtual void ACLData(uint8_t *ACLData)
Definition: BTHID.cpp:61
void l2cap_connection_request(uint16_t handle, uint8_t rxid, uint8_t *scid, uint16_t psm)
Definition: BTD.cpp:1209
#define L2CAP_CONTROL_CONFIG_REQUEST
Definition: BTHID.h:34
Definition: BTD.h:158
void l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
Definition: BTD.cpp:1275
#define l2cap_disconnect_response_interrupt_flag
Definition: BTHID.h:59
bool connected
Definition: BTHID.h:103
virtual void Run()
Definition: BTHID.cpp:347
const char * btdPin
Definition: BTD.h:407
virtual void Reset()
Definition: BTHID.cpp:47
#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS
Definition: BTHID.h:47
#define l2cap_connection_request_control_flag
Definition: BTHID.h:60
void l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
Definition: BTD.cpp:1288
#define L2CAP_FLAG_INTERRUPT_CONNECTED
Definition: BTHID.h:45
#define Notify(...)
Definition: message.h:44
#define L2CAP_WAIT
Definition: BTHID.h:26
bool connectToHIDDevice
Definition: BTD.h:444
#define HID_BOOT_PROTOCOL
Definition: hid.h:79
#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE
Definition: BTHID.h:49
#define l2cap_connection_request_interrupt_flag
Definition: BTHID.h:61
#define HID_CTRL_PSM
Definition: BTD.h:126
bool incomingHIDDevice
Definition: BTD.h:448
bool pairWithHIDDevice
Definition: BTD.h:450
#define L2CAP_INTERRUPT_DISCONNECT
Definition: BTHID.h:40
#define MOUSE_PARSER_ID
Definition: BTHID.h:64
uint16_t hci_handle
Definition: BTD.h:412
#define Notifyc(...)
Definition: message.h:46
void hci_disconnect(uint16_t handle)
Definition: BTD.cpp:1133
virtual void disconnect()
Definition: BTHID.cpp:54
#define L2CAP_CONTROL_CONNECT_REQUEST
Definition: BTHID.h:33
Definition: hid.h:143
#define L2CAP_DONE
Definition: BTHID.h:38
#define L2CAP_INTERRUPT_SETUP
Definition: BTHID.h:30
#define l2cap_disconnect_response_control_flag
Definition: BTHID.h:58
#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST
Definition: BTHID.h:51
#define epMUL
Definition: BTHID.h:65
#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST
Definition: BTHID.h:50
#define L2CAP_CMD_CONFIG_REQUEST
Definition: BTD.h:112
#define L2CAP_CMD_DISCONNECT_REQUEST
Definition: BTD.h:114
#define HID_INTR_PSM
Definition: BTD.h:127
#define L2CAP_INTERRUPT_CONNECT_REQUEST
Definition: BTHID.h:35
int8_t registerServiceClass(BluetoothService *pService)
Definition: BTD.h:258
bool l2capConnectionClaimed
Definition: BTD.h:398
virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)=0
#define L2CAP_CMD_DISCONNECT_RESPONSE
Definition: BTD.h:115
#define L2CAP_CMD_CONNECTION_RESPONSE
Definition: BTD.h:111
#define l2cap_connected_interrupt_flag
Definition: BTHID.h:55
#define L2CAP_CMD_CONFIG_RESPONSE
Definition: BTD.h:113
#define L2CAP_FLAG_CONTROL_CONNECTED
Definition: BTHID.h:44
#define l2cap_config_success_control_flag
Definition: BTHID.h:56
#define l2cap_config_success_interrupt_flag
Definition: BTHID.h:57
#define KEYBOARD_PARSER_ID
Definition: BTHID.h:63
#define l2cap_connected_control_flag
Definition: BTHID.h:54
#define L2CAP_CONTROL_SUCCESS
Definition: BTHID.h:29
BTHID(BTD *p, bool pair=false, const char *pin="1234")
Definition: BTHID.cpp:23
void L2CAP_Command(uint16_t handle, uint8_t *data, uint8_t nbytes, uint8_t channelLow=0x01, uint8_t channelHigh=0x00)
Definition: BTD.cpp:1181
void l2cap_config_response(uint16_t handle, uint8_t rxid, uint8_t *scid)
Definition: BTD.cpp:1256
#define PENDING
Definition: BTD.h:120
void l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t *dcid)
Definition: BTD.cpp:1239
#define L2CAP_INTERRUPT_CONFIG_REQUEST
Definition: BTHID.h:37
#define L2CAP_CMD_CONNECTION_REQUEST
Definition: BTD.h:110
#define L2CAP_CONTROL_DISCONNECT
Definition: BTHID.h:41
#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE
Definition: BTHID.h:48
void pair(void)
Definition: BTHID.h:109
#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS
Definition: BTHID.h:46
#define L2CAP_CMD_COMMAND_REJECT
Definition: BTD.h:109