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  for(uint8_t i = 0; i < NUM_PARSERS; i++)
27  pRptParser[i] = NULL;
28 
29  if(pBtd)
30  pBtd->registerServiceClass(this); // Register it as a Bluetooth service
31 
33  pBtd->btdPin = pin;
34 
35  /* Set device cid for the control and intterrupt channelse - LSB */
36  control_dcid[0] = 0x70; // 0x0070
37  control_dcid[1] = 0x00;
38  interrupt_dcid[0] = 0x71; // 0x0071
39  interrupt_dcid[1] = 0x00;
40 
41  Reset();
42 }
43 
44 void BTHID::Reset() {
45  connected = false;
46  activeConnection = false;
47  l2cap_event_flag = 0; // Reset flags
48  l2cap_state = L2CAP_WAIT;
49  ResetBTHID();
50 }
51 
52 void BTHID::disconnect() { // Use this void to disconnect the device
53  // First the HID interrupt channel has to be disconnected, then the HID control channel and finally the HCI connection
54  pBtd->l2cap_disconnection_request(hci_handle, ++identifier, interrupt_scid, interrupt_dcid);
55  Reset();
56  l2cap_state = L2CAP_INTERRUPT_DISCONNECT;
57 }
58 
59 void BTHID::ACLData(uint8_t* l2capinbuf) {
60  if(!pBtd->l2capConnectionClaimed && pBtd->incomingHIDDevice && !connected && !activeConnection) {
61  if(l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
62  if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
63  pBtd->incomingHIDDevice = false;
64  pBtd->l2capConnectionClaimed = true; // Claim that the incoming connection belongs to this service
65  activeConnection = true;
66  hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
67  l2cap_state = L2CAP_WAIT;
68  }
69  }
70  }
71  //if((l2capinbuf[0] | (uint16_t)l2capinbuf[1] << 8) == (hci_handle | 0x2000U)) { // acl_handle_ok or it's a new connection
72  if(UHS_ACL_HANDLE_OK(l2capinbuf, hci_handle)) { // acl_handle_ok or it's a new connection
73  if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { // l2cap_control - Channel ID for ACL-U
74  if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
75 #ifdef DEBUG_USB_HOST
76  Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
77  D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
78  Notify(PSTR(" "), 0x80);
79  D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
80  Notify(PSTR(" "), 0x80);
81  D_PrintHex<uint8_t > (l2capinbuf[17], 0x80);
82  Notify(PSTR(" "), 0x80);
83  D_PrintHex<uint8_t > (l2capinbuf[16], 0x80);
84  Notify(PSTR(" "), 0x80);
85  D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
86  Notify(PSTR(" "), 0x80);
87  D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
88 #endif
89  } else if(l2capinbuf[8] == L2CAP_CMD_CONNECTION_RESPONSE) {
90  if(((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) == SUCCESSFUL)) { // Success
91  if(l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) {
92  //Notify(PSTR("\r\nHID Control Connection Complete"), 0x80);
93  identifier = l2capinbuf[9];
94  control_scid[0] = l2capinbuf[12];
95  control_scid[1] = l2capinbuf[13];
97  } else if(l2capinbuf[14] == interrupt_dcid[0] && l2capinbuf[15] == interrupt_dcid[1]) {
98  //Notify(PSTR("\r\nHID Interrupt Connection Complete"), 0x80);
99  identifier = l2capinbuf[9];
100  interrupt_scid[0] = l2capinbuf[12];
101  interrupt_scid[1] = l2capinbuf[13];
103  }
104  }
105  } else if(l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
106 #ifdef EXTRADEBUG
107  Notify(PSTR("\r\nL2CAP Connection Request - PSM: "), 0x80);
108  D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
109  Notify(PSTR(" "), 0x80);
110  D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
111  Notify(PSTR(" SCID: "), 0x80);
112  D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
113  Notify(PSTR(" "), 0x80);
114  D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
115  Notify(PSTR(" Identifier: "), 0x80);
116  D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
117 #endif
118  if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
119  identifier = l2capinbuf[9];
120  control_scid[0] = l2capinbuf[14];
121  control_scid[1] = l2capinbuf[15];
123  } else if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_INTR_PSM) {
124  identifier = l2capinbuf[9];
125  interrupt_scid[0] = l2capinbuf[14];
126  interrupt_scid[1] = l2capinbuf[15];
128  }
129  } else if(l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
130  if((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success
131  if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
132  //Notify(PSTR("\r\nHID Control Configuration Complete"), 0x80);
133  identifier = l2capinbuf[9];
135  } else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
136  //Notify(PSTR("\r\nHID Interrupt Configuration Complete"), 0x80);
137  identifier = l2capinbuf[9];
139  }
140  }
141  } else if(l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
142  if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
143  //Notify(PSTR("\r\nHID Control Configuration Request"), 0x80);
145  } else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
146  //Notify(PSTR("\r\nHID Interrupt Configuration Request"), 0x80);
148  }
149  } else if(l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
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);
153 #endif
154  identifier = l2capinbuf[9];
155  pBtd->l2cap_disconnection_response(hci_handle, identifier, control_dcid, control_scid);
156  Reset();
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);
160 #endif
161  identifier = l2capinbuf[9];
162  pBtd->l2cap_disconnection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid);
163  Reset();
164  }
165  } else if(l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
166  if(l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
167  //Notify(PSTR("\r\nDisconnect Response: Control Channel"), 0x80);
168  identifier = l2capinbuf[9];
170  } else if(l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
171  //Notify(PSTR("\r\nDisconnect Response: Interrupt Channel"), 0x80);
172  identifier = l2capinbuf[9];
174  }
175  }
176 #ifdef EXTRADEBUG
177  else {
178  identifier = l2capinbuf[9];
179  Notify(PSTR("\r\nL2CAP Unknown Signaling Command: "), 0x80);
180  D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
181  }
182 #endif
183  } else if(l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) { // l2cap_interrupt
184 #ifdef PRINTREPORT
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);
188  Notify(PSTR(" "), 0x80);
189  }
190 #endif
191  if(l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT
192  uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]);
193  ParseBTHIDData((uint8_t)(length - 1), &l2capinbuf[9]);
194 
195  switch(l2capinbuf[9]) {
196  case 0x01: // Keyboard or Joystick events
197  if(pRptParser[KEYBOARD_PARSER_ID])
198  pRptParser[KEYBOARD_PARSER_ID]->Parse(reinterpret_cast<HID *>(this), 0, (uint8_t)(length - 2), &l2capinbuf[10]); // Use reinterpret_cast again to extract the instance
199  break;
200 
201  case 0x02: // Mouse events
202  if(pRptParser[MOUSE_PARSER_ID])
203  pRptParser[MOUSE_PARSER_ID]->Parse(reinterpret_cast<HID *>(this), 0, (uint8_t)(length - 2), &l2capinbuf[10]); // Use reinterpret_cast again to extract the instance
204  break;
205 #ifdef EXTRADEBUG
206  default:
207  Notify(PSTR("\r\nUnknown Report type: "), 0x80);
208  D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
209  break;
210 #endif
211  }
212  }
213  } else if(l2capinbuf[6] == control_dcid[0] && l2capinbuf[7] == control_dcid[1]) { // l2cap_control
214 #ifdef PRINTREPORT
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);
218  Notify(PSTR(" "), 0x80);
219  }
220 #endif
221  }
222 #ifdef EXTRADEBUG
223  else {
224  Notify(PSTR("\r\nUnsupported L2CAP Data - Channel ID: "), 0x80);
225  D_PrintHex<uint8_t > (l2capinbuf[7], 0x80);
226  Notify(PSTR(" "), 0x80);
227  D_PrintHex<uint8_t > (l2capinbuf[6], 0x80);
228 
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);
233  Notify(PSTR(" "), 0x80);
234  }
235  }
236 #endif
237  L2CAP_task();
238  }
239 }
240 
241 void BTHID::L2CAP_task() {
242  switch(l2cap_state) {
243  /* These states are used if the HID device is the host */
246 #ifdef DEBUG_USB_HOST
247  Notify(PSTR("\r\nHID Control Successfully Configured"), 0x80);
248 #endif
249  setProtocol(); // Set protocol before establishing HID interrupt channel
250  l2cap_state = L2CAP_INTERRUPT_SETUP;
251  }
252  break;
253 
256 #ifdef DEBUG_USB_HOST
257  Notify(PSTR("\r\nHID Interrupt Incoming Connection Request"), 0x80);
258 #endif
259  pBtd->l2cap_connection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid, PENDING);
260  delay(1);
261  pBtd->l2cap_connection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid, SUCCESSFUL);
262  identifier++;
263  delay(1);
265 
266  l2cap_state = L2CAP_INTERRUPT_CONFIG_REQUEST;
267  }
268  break;
269 
270  /* These states are used if the Arduino is the host */
273 #ifdef DEBUG_USB_HOST
274  Notify(PSTR("\r\nSend HID Control Config Request"), 0x80);
275 #endif
276  identifier++;
278  l2cap_state = L2CAP_CONTROL_CONFIG_REQUEST;
279  }
280  break;
281 
284  setProtocol(); // Set protocol before establishing HID interrupt channel
285  delay(1); // Short delay between commands - just to be sure
286 #ifdef DEBUG_USB_HOST
287  Notify(PSTR("\r\nSend HID Interrupt Connection Request"), 0x80);
288 #endif
289  identifier++;
290  pBtd->l2cap_connection_request(hci_handle, identifier, interrupt_dcid, HID_INTR_PSM);
291  l2cap_state = L2CAP_INTERRUPT_CONNECT_REQUEST;
292  }
293  break;
294 
297 #ifdef DEBUG_USB_HOST
298  Notify(PSTR("\r\nSend HID Interrupt Config Request"), 0x80);
299 #endif
300  identifier++;
302  l2cap_state = L2CAP_INTERRUPT_CONFIG_REQUEST;
303  }
304  break;
305 
307  if(l2cap_check_flag(L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS)) { // Now the HID channels is established
308 #ifdef DEBUG_USB_HOST
309  Notify(PSTR("\r\nHID Channels Established"), 0x80);
310 #endif
311  pBtd->connectToHIDDevice = false;
312  pBtd->pairWithHIDDevice = false;
313  connected = true;
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
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) {
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);
371  l2cap_state = L2CAP_CONTROL_SUCCESS;
372  }
373  break;
374  }
375 }
376 
377 /************************************************************/
378 /* HID Commands */
379 
380 /************************************************************/
381 void BTHID::setProtocol() {
382 #ifdef DEBUG_USB_HOST
383  Notify(PSTR("\r\nSet protocol mode: "), 0x80);
384  D_PrintHex<uint8_t > (protocolMode, 0x80);
385 #endif
386  if (protocolMode != HID_BOOT_PROTOCOL && protocolMode != HID_RPT_PROTOCOL) {
387 #ifdef DEBUG_USB_HOST
388  Notify(PSTR("\r\nNot a valid protocol mode. Using Boot protocol instead."), 0x80);
389 #endif
390  protocolMode = HID_BOOT_PROTOCOL; // Use Boot Protocol by default
391  }
392  uint8_t command = 0x70 | protocolMode; // Set Protocol, see Bluetooth HID specs page 33
393  pBtd->L2CAP_Command(hci_handle, &command, 1, control_scid[0], control_scid[1]);
394 }
395 
396 void BTHID::setLeds(uint8_t data) {
397  uint8_t buf[3];
398  buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
399  buf[1] = 0x01; // Report ID
400  buf[2] = data;
402 }
#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE
Definition: BTD.h:139
#define UHS_ACL_HANDLE_OK(x, y)
Definition: BTD.h:207
#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS
Definition: BTD.h:143
#define L2CAP_INTERRUPT_CONFIG_REQUEST
Definition: BTD.h:115
#define L2CAP_INTERRUPT_SETUP
Definition: BTD.h:113
void l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid, uint8_t result)
Definition: BTD.cpp:1231
#define SUCCESSFUL
Definition: BTD.h:177
virtual void ACLData(uint8_t *ACLData)
Definition: BTHID.cpp:59
void l2cap_connection_request(uint16_t handle, uint8_t rxid, uint8_t *scid, uint16_t psm)
Definition: BTD.cpp:1218
#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST
Definition: BTD.h:142
#define HID_RPT_PROTOCOL
Definition: hid.h:83
Definition: BTD.h:230
void l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
Definition: BTD.cpp:1284
uint8_t interrupt_scid[2]
Definition: BTHID.h:139
bool connected
Definition: BTHID.h:92
virtual void Run()
Definition: BTHID.cpp:347
const char * btdPin
Definition: BTD.h:482
#define L2CAP_DONE
Definition: BTD.h:104
#define L2CAP_CONTROL_SUCCESS
Definition: BTD.h:109
#define L2CAP_WAIT
Definition: BTD.h:103
virtual void ResetBTHID()
Definition: BTHID.h:123
virtual void Reset()
Definition: BTHID.cpp:44
#define L2CAP_CONTROL_CONFIG_REQUEST
Definition: BTD.h:108
void l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
Definition: BTD.cpp:1297
uint8_t control_scid[2]
Definition: BTHID.h:136
#define Notify(...)
Definition: message.h:44
bool connectToHIDDevice
Definition: BTD.h:519
#define HID_BOOT_PROTOCOL
Definition: hid.h:82
#define L2CAP_CONTROL_CONNECT_REQUEST
Definition: BTD.h:107
#define HID_CTRL_PSM
Definition: BTD.h:182
bool incomingHIDDevice
Definition: BTD.h:523
bool pairWithHIDDevice
Definition: BTD.h:525
#define MOUSE_PARSER_ID
Definition: BTHID.h:25
uint16_t hci_handle
Definition: BTD.h:487
void hci_disconnect(uint16_t handle)
Definition: BTD.cpp:1142
#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE
Definition: BTD.h:145
virtual void disconnect()
Definition: BTHID.cpp:52
void setLeds(uint8_t data)
Definition: BTHID.cpp:396
virtual void ParseBTHIDData(uint8_t len, uint8_t *buf)
Definition: BTHID.h:115
BTD * pBtd
Definition: BTHID.h:129
#define l2cap_check_flag(flag)
Definition: BTD.h:160
#define L2CAP_CMD_CONFIG_REQUEST
Definition: BTD.h:168
#define L2CAP_FLAG_CONTROL_CONNECTED
Definition: BTD.h:138
#define L2CAP_CMD_DISCONNECT_REQUEST
Definition: BTD.h:170
#define L2CAP_CONTROL_DISCONNECT
Definition: BTD.h:110
#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST
Definition: BTD.h:136
uint16_t hci_handle
Definition: BTHID.h:132
#define HID_INTR_PSM
Definition: BTD.h:183
int8_t registerServiceClass(BluetoothService *pService)
Definition: BTD.h:333
bool l2capConnectionClaimed
Definition: BTD.h:473
virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)=0
#define L2CAP_CMD_DISCONNECT_RESPONSE
Definition: BTD.h:171
#define L2CAP_CMD_CONNECTION_RESPONSE
Definition: BTD.h:167
#define L2CAP_CMD_CONFIG_RESPONSE
Definition: BTD.h:169
#define NUM_PARSERS
Definition: BTHID.h:26
#define KEYBOARD_PARSER_ID
Definition: BTHID.h:24
void L2CAP_Command(uint16_t handle, uint8_t *data, uint8_t nbytes, uint8_t channelLow=0x01, uint8_t channelHigh=0x00)
Definition: BTD.cpp:1190
void l2cap_config_response(uint16_t handle, uint8_t rxid, uint8_t *scid)
Definition: BTD.cpp:1265
#define PENDING
Definition: BTD.h:176
#define L2CAP_FLAG_INTERRUPT_CONNECTED
Definition: BTD.h:144
#define l2cap_set_flag(flag)
Definition: BTD.h:161
void l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t *dcid)
Definition: BTD.cpp:1248
#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS
Definition: BTD.h:137
#define L2CAP_CMD_CONNECTION_REQUEST
Definition: BTD.h:166
BTHID(BTD *p, bool pair=false, const char *pin="0000")
Definition: BTHID.cpp:23
#define L2CAP_INTERRUPT_CONNECT_REQUEST
Definition: BTD.h:114
void pair(void)
Definition: BTHID.h:95
#define L2CAP_INTERRUPT_DISCONNECT
Definition: BTD.h:116
#define L2CAP_CMD_COMMAND_REJECT
Definition: BTD.h:165