1 /*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holders nor the names of
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * 4. Any redistribution, use, or modification is done solely for
17 * personal benefit and not for any commercial purpose or for
18 * monetary gain.
19 *
20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Please inquire about commercial licensing options at
34 * [email protected]
35 *
36 */
37
38 #define BTSTACK_FILE__ "hid_host.c"
39
40 #include <string.h>
41
42 #include "bluetooth.h"
43 #include "bluetooth_psm.h"
44 #include "bluetooth_sdp.h"
45 #include "btstack_debug.h"
46 #include "btstack_event.h"
47 #include "btstack_hid.h"
48 #include "btstack_hid_parser.h"
49 #include "btstack_memory.h"
50 #include "l2cap.h"
51
52 #include "classic/hid_host.h"
53 #include "classic/sdp_util.h"
54 #include "classic/sdp_client.h"
55
56 #ifndef HID_HOST_SDP_MAX_ATTRIBUTE_VALUE_SIZE
57 #define HID_HOST_SDP_MAX_ATTRIBUTE_VALUE_SIZE 32
58 #endif
59
60 #define CONTROL_MESSAGE_BITMASK_SUSPEND 1
61 #define CONTROL_MESSAGE_BITMASK_EXIT_SUSPEND 2
62 #define CONTROL_MESSAGE_BITMASK_VIRTUAL_CABLE_UNPLUG 4
63
64 // globals
65
66 // higher-layer callbacks
67 static btstack_packet_handler_t hid_host_callback;
68
69 // descriptor storage
70 static uint8_t * hid_host_descriptor_storage;
71 static uint16_t hid_host_descriptor_storage_len;
72
73 // SDP
74 static uint8_t hid_host_sdp_attribute_value[HID_HOST_SDP_MAX_ATTRIBUTE_VALUE_SIZE];
75 static const unsigned int hid_host_sdp_attribute_value_buffer_size = HID_HOST_SDP_MAX_ATTRIBUTE_VALUE_SIZE;
76 static uint16_t hid_host_sdp_context_control_cid = 0;
77
78 // connections
79 static btstack_linked_list_t hid_host_connections;
80 static uint16_t hid_host_cid_counter = 0;
81
82 // lower layer callbacks
83 static btstack_context_callback_registration_t hid_host_handle_sdp_client_query_request;
84
85 // prototypes
86
87 static void hid_host_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
88 static void hid_host_handle_start_sdp_client_query(void * context);
89
hid_descriptor_storage_get_available_space(void)90 static uint16_t hid_descriptor_storage_get_available_space(void){
91 // assumes all descriptors are back to back
92 uint16_t free_space = hid_host_descriptor_storage_len;
93
94 btstack_linked_list_iterator_t it;
95 btstack_linked_list_iterator_init(&it, &hid_host_connections);
96 while (btstack_linked_list_iterator_has_next(&it)){
97 hid_host_connection_t * connection = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it);
98 free_space -= connection->hid_descriptor_len;
99 }
100 return free_space;
101 }
102
hid_host_get_connection_for_hid_cid(uint16_t hid_cid)103 static hid_host_connection_t * hid_host_get_connection_for_hid_cid(uint16_t hid_cid){
104 btstack_linked_list_iterator_t it;
105 btstack_linked_list_iterator_init(&it, &hid_host_connections);
106 while (btstack_linked_list_iterator_has_next(&it)){
107 hid_host_connection_t * connection = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it);
108 if (connection->hid_cid != hid_cid) continue;
109 return connection;
110 }
111 return NULL;
112 }
113
hid_host_get_connection_for_l2cap_cid(uint16_t l2cap_cid)114 static hid_host_connection_t * hid_host_get_connection_for_l2cap_cid(uint16_t l2cap_cid){
115 btstack_linked_list_iterator_t it;
116 btstack_linked_list_iterator_init(&it, &hid_host_connections);
117 while (btstack_linked_list_iterator_has_next(&it)){
118 hid_host_connection_t * connection = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it);
119 if ((connection->interrupt_cid != l2cap_cid) && (connection->control_cid != l2cap_cid)) continue;
120 return connection;
121 }
122 return NULL;
123 }
124
hid_descriptor_storage_init(hid_host_connection_t * connection)125 static void hid_descriptor_storage_init(hid_host_connection_t * connection){
126 // reserve remaining space for this connection
127 uint16_t available_space = hid_descriptor_storage_get_available_space();
128 connection->hid_descriptor_len = 0;
129 connection->hid_descriptor_max_len = available_space;
130 connection->hid_descriptor_offset = hid_host_descriptor_storage_len - available_space;
131 }
132
hid_descriptor_storage_store(hid_host_connection_t * connection,uint8_t byte)133 static bool hid_descriptor_storage_store(hid_host_connection_t * connection, uint8_t byte){
134 // store single hid descriptor byte
135 if (connection->hid_descriptor_len >= connection->hid_descriptor_max_len) return false;
136
137 hid_host_descriptor_storage[connection->hid_descriptor_offset + connection->hid_descriptor_len] = byte;
138 connection->hid_descriptor_len++;
139 return true;
140 }
141
hid_descriptor_storage_delete(hid_host_connection_t * connection)142 static void hid_descriptor_storage_delete(hid_host_connection_t * connection){
143 uint16_t descriptor_len = connection->hid_descriptor_len;
144
145 if (descriptor_len > 0){
146 uint16_t next_offset = connection->hid_descriptor_offset + connection->hid_descriptor_len;
147
148 // move higher descriptors down
149 memmove(&hid_host_descriptor_storage[connection->hid_descriptor_offset],
150 &hid_host_descriptor_storage[next_offset],
151 hid_host_descriptor_storage_len - next_offset);
152
153 // fix descriptor offset of higher descriptors
154 btstack_linked_list_iterator_t it;
155 btstack_linked_list_iterator_init(&it, &hid_host_connections);
156 while (btstack_linked_list_iterator_has_next(&it)){
157 hid_host_connection_t * conn = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it);
158 if (conn == connection) continue;
159 if (conn->hid_descriptor_offset >= next_offset){
160 conn->hid_descriptor_offset -= descriptor_len;
161 }
162 }
163 }
164
165 // clear descriptor
166 connection->hid_descriptor_len = 0;
167 connection->hid_descriptor_offset = 0;
168 }
169
hid_descriptor_storage_get_descriptor_data(uint16_t hid_cid)170 const uint8_t * hid_descriptor_storage_get_descriptor_data(uint16_t hid_cid){
171 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
172 if (!connection){
173 return NULL;
174 }
175 return &hid_host_descriptor_storage[connection->hid_descriptor_offset];
176 }
177
hid_descriptor_storage_get_descriptor_len(uint16_t hid_cid)178 uint16_t hid_descriptor_storage_get_descriptor_len(uint16_t hid_cid){
179 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
180 if (!connection){
181 return 0;
182 }
183 return connection->hid_descriptor_len;
184 }
185
186
187 // HID Util
hid_emit_connected_event(hid_host_connection_t * connection,uint8_t status)188 static void hid_emit_connected_event(hid_host_connection_t * connection, uint8_t status){
189 uint8_t event[15];
190 uint16_t pos = 0;
191 event[pos++] = HCI_EVENT_HID_META;
192 pos++; // skip len
193 event[pos++] = HID_SUBEVENT_CONNECTION_OPENED;
194 little_endian_store_16(event, pos, connection->hid_cid);
195 pos+=2;
196 event[pos++] = status;
197 reverse_bd_addr(connection->remote_addr, &event[pos]);
198 pos += 6;
199 little_endian_store_16(event,pos,connection->con_handle);
200 pos += 2;
201 event[pos++] = connection->incoming;
202 event[1] = pos - 2;
203 hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos);
204 }
205
hid_emit_descriptor_available_event(hid_host_connection_t * connection)206 static void hid_emit_descriptor_available_event(hid_host_connection_t * connection){
207 uint8_t event[6];
208 uint16_t pos = 0;
209 event[pos++] = HCI_EVENT_HID_META;
210 pos++; // skip len
211 event[pos++] = HID_SUBEVENT_DESCRIPTOR_AVAILABLE;
212 little_endian_store_16(event,pos,connection->hid_cid);
213 pos += 2;
214 event[pos++] = connection->hid_descriptor_status;
215 event[1] = pos - 2;
216 hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos);
217 }
218
hid_emit_sniff_params_event(hid_host_connection_t * connection)219 static void hid_emit_sniff_params_event(hid_host_connection_t * connection){
220 uint8_t event[9];
221 uint16_t pos = 0;
222 event[pos++] = HCI_EVENT_HID_META;
223 pos++; // skip len
224 event[pos++] = HID_SUBEVENT_SNIFF_SUBRATING_PARAMS;
225 little_endian_store_16(event,pos,connection->hid_cid);
226 pos += 2;
227 little_endian_store_16(event,pos,connection->host_max_latency);
228 pos += 2;
229 little_endian_store_16(event,pos,connection->host_min_timeout);
230 pos += 2;
231
232 event[1] = pos - 2;
233 hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos);
234 }
235
hid_emit_event(hid_host_connection_t * connection,uint8_t subevent_type)236 static void hid_emit_event(hid_host_connection_t * connection, uint8_t subevent_type){
237 uint8_t event[5];
238 uint16_t pos = 0;
239 event[pos++] = HCI_EVENT_HID_META;
240 pos++; // skip len
241 event[pos++] = subevent_type;
242 little_endian_store_16(event,pos,connection->hid_cid);
243 pos += 2;
244 event[1] = pos - 2;
245 hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos);
246 }
247
hid_emit_event_with_status(hid_host_connection_t * connection,uint8_t subevent_type,hid_handshake_param_type_t status)248 static void hid_emit_event_with_status(hid_host_connection_t * connection, uint8_t subevent_type, hid_handshake_param_type_t status){
249 uint8_t event[6];
250 uint16_t pos = 0;
251 event[pos++] = HCI_EVENT_HID_META;
252 pos++; // skip len
253 event[pos++] = subevent_type;
254 little_endian_store_16(event,pos,connection->hid_cid);
255 pos += 2;
256 event[pos++] = status;
257 event[1] = pos - 2;
258 hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos);
259 }
260
hid_emit_set_protocol_response_event(hid_host_connection_t * connection,hid_handshake_param_type_t status)261 static void hid_emit_set_protocol_response_event(hid_host_connection_t * connection, hid_handshake_param_type_t status){
262 uint8_t event[7];
263 uint16_t pos = 0;
264 event[pos++] = HCI_EVENT_HID_META;
265 pos++; // skip len
266 event[pos++] = HID_SUBEVENT_SET_PROTOCOL_RESPONSE;
267 little_endian_store_16(event,pos,connection->hid_cid);
268 pos += 2;
269 event[pos++] = status;
270 event[pos++] = connection->protocol_mode;
271 event[1] = pos - 2;
272 hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos);
273 }
274
hid_emit_incoming_connection_event(hid_host_connection_t * connection)275 static void hid_emit_incoming_connection_event(hid_host_connection_t * connection){
276 uint8_t event[13];
277 uint16_t pos = 0;
278 event[pos++] = HCI_EVENT_HID_META;
279 pos++; // skip len
280 event[pos++] = HID_SUBEVENT_INCOMING_CONNECTION;
281 little_endian_store_16(event, pos, connection->hid_cid);
282 pos += 2;
283 reverse_bd_addr(connection->remote_addr, &event[pos]);
284 pos += 6;
285 little_endian_store_16(event,pos,connection->con_handle);
286 pos += 2;
287 event[1] = pos - 2;
288 hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos);
289 }
290
291 // setup get report response event - potentially in-place of original l2cap packet
hid_setup_get_report_event(hid_host_connection_t * connection,hid_handshake_param_type_t status,uint8_t * buffer,uint16_t report_len)292 static void hid_setup_get_report_event(hid_host_connection_t * connection, hid_handshake_param_type_t status, uint8_t *buffer, uint16_t report_len){
293 uint16_t pos = 0;
294 buffer[pos++] = HCI_EVENT_HID_META;
295 pos++; // skip len
296 buffer[pos++] = HID_SUBEVENT_GET_REPORT_RESPONSE;
297 little_endian_store_16(buffer, pos, connection->hid_cid);
298 pos += 2;
299 buffer[pos++] = (uint8_t) status;
300 little_endian_store_16(buffer, pos, report_len);
301 pos += 2;
302 buffer[1] = pos + report_len - 2;
303 }
304
305 // setup report event - potentially in-place of original l2cap packet
hid_setup_report_event(hid_host_connection_t * connection,uint8_t * buffer,uint16_t report_len)306 static void hid_setup_report_event(hid_host_connection_t * connection, uint8_t *buffer, uint16_t report_len){
307 uint16_t pos = 0;
308 buffer[pos++] = HCI_EVENT_HID_META;
309 pos++; // skip len
310 buffer[pos++] = HID_SUBEVENT_REPORT;
311 little_endian_store_16(buffer, pos, connection->hid_cid);
312 pos += 2;
313 little_endian_store_16(buffer, pos, report_len);
314 pos += 2;
315 buffer[1] = pos + report_len - 2;
316 }
317
318
hid_emit_get_protocol_event(hid_host_connection_t * connection,hid_handshake_param_type_t status,hid_protocol_mode_t protocol_mode)319 static void hid_emit_get_protocol_event(hid_host_connection_t * connection, hid_handshake_param_type_t status, hid_protocol_mode_t protocol_mode){
320 uint8_t event[7];
321 uint16_t pos = 0;
322 event[pos++] = HCI_EVENT_HID_META;
323 pos++; // skip len
324 event[pos++] = HID_SUBEVENT_GET_PROTOCOL_RESPONSE;
325 little_endian_store_16(event,pos,connection->hid_cid);
326 pos += 2;
327 event[pos++] = status;
328 event[pos++] = protocol_mode;
329 event[1] = pos - 2;
330 hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos);
331 }
332
333 // HID Host
334
hid_host_get_next_cid(void)335 static uint16_t hid_host_get_next_cid(void){
336 if (hid_host_cid_counter == 0xffff) {
337 hid_host_cid_counter = 1;
338 } else {
339 hid_host_cid_counter++;
340 }
341 return hid_host_cid_counter;
342 }
343
hid_host_create_connection(bd_addr_t remote_addr)344 static hid_host_connection_t * hid_host_create_connection(bd_addr_t remote_addr){
345 hid_host_connection_t * connection = btstack_memory_hid_host_connection_get();
346 if (!connection){
347 log_error("Not enough memory to create connection");
348 return NULL;
349 }
350 connection->state = HID_HOST_IDLE;
351 connection->hid_cid = hid_host_get_next_cid();
352 connection->control_cid = 0;
353 connection->control_psm = 0;
354 connection->interrupt_cid = 0;
355 connection->interrupt_psm = 0;
356 connection->con_handle = HCI_CON_HANDLE_INVALID;
357
358 (void)memcpy(connection->remote_addr, remote_addr, 6);
359 btstack_linked_list_add_tail(&hid_host_connections, (btstack_linked_item_t *) connection);
360 return connection;
361 }
362
hid_host_get_connection_for_bd_addr(bd_addr_t addr)363 static hid_host_connection_t * hid_host_get_connection_for_bd_addr(bd_addr_t addr){
364 btstack_linked_list_iterator_t it;
365 btstack_linked_list_iterator_init(&it, &hid_host_connections);
366 while (btstack_linked_list_iterator_has_next(&it)){
367 hid_host_connection_t * connection = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it);
368 if (memcmp(addr, connection->remote_addr, 6) != 0) continue;
369 return connection;
370 }
371 return NULL;
372 }
373
374
hid_host_finalize_connection(hid_host_connection_t * connection)375 static void hid_host_finalize_connection(hid_host_connection_t * connection){
376 uint16_t interrupt_cid = connection->interrupt_cid;
377 uint16_t control_cid = connection->control_cid;
378
379 connection->interrupt_cid = 0;
380 connection->control_cid = 0;
381
382 if (interrupt_cid != 0){
383 l2cap_disconnect(interrupt_cid);
384 }
385 if (control_cid != 0){
386 l2cap_disconnect(control_cid);
387 }
388 btstack_linked_list_remove(&hid_host_connections, (btstack_linked_item_t*) connection);
389 btstack_memory_hid_host_connection_free(connection);
390 }
391
hid_host_handle_sdp_hid_descriptor_list(hid_host_connection_t * connection,uint16_t attribute_offset,uint8_t data)392 static void hid_host_handle_sdp_hid_descriptor_list(hid_host_connection_t * connection, uint16_t attribute_offset, uint8_t data){
393 // state machine
394 static uint32_t bytes_needed = 0;
395 static uint32_t bytes_received = 0;
396 static enum {
397 HID_DESCRIPTOR_LIST_ERROR,
398 HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_LIST_START,
399 HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_LIST_HEADER,
400 HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_START,
401 HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_HEADER,
402 HID_DESCRIPTOR_LIST_W4_ITEM_START,
403 HID_DESCRIPTOR_LIST_W4_ITEM_HEADER,
404 HID_DESCRIPTOR_LIST_W4_ITEM_COMPLETE,
405 HID_DESCRIPTOR_LIST_W4_STRING_HEADER,
406 HID_DESCRIPTOR_LIST_W4_STRING_COMPLETE,
407 HID_DESCRIPTOR_LIST_COMPLETE,
408 } state = HID_DESCRIPTOR_LIST_ERROR;
409
410 // init state machine
411 if (attribute_offset == 0){
412 state = HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_LIST_START;
413 bytes_received = 0;
414 }
415
416 // next step
417 bool stored;
418 bool error = false;
419 switch (state){
420 case HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_LIST_START:
421 hid_host_sdp_attribute_value[bytes_received++] = data;
422 if (de_get_element_type(hid_host_sdp_attribute_value) == DE_DES){
423 bytes_needed = de_get_header_size(hid_host_sdp_attribute_value);
424 state = HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_LIST_HEADER;
425 } else {
426 error = true;
427 }
428 break;
429 case HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_LIST_HEADER:
430 hid_host_sdp_attribute_value[bytes_received++] = data;
431 if (bytes_received >= bytes_needed) {
432 bytes_received = 0;
433 state = HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_START;
434 }
435 break;
436 case HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_START:
437 hid_host_sdp_attribute_value[bytes_received++] = data;
438 if (de_get_element_type(hid_host_sdp_attribute_value) == DE_DES){
439 bytes_needed = de_get_header_size(hid_host_sdp_attribute_value);
440 state = HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_HEADER;
441 } else {
442 error = true;
443 }
444 break;
445 case HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_HEADER:
446 hid_host_sdp_attribute_value[bytes_received++] = data;
447 if (bytes_received >= bytes_needed) {
448 bytes_received = 0;
449 state = HID_DESCRIPTOR_LIST_W4_ITEM_START;
450 }
451 break;
452 case HID_DESCRIPTOR_LIST_W4_ITEM_START:
453 hid_host_sdp_attribute_value[bytes_received++] = data;
454 bytes_needed = de_get_header_size(hid_host_sdp_attribute_value);
455 if (de_get_element_type(hid_host_sdp_attribute_value) == DE_STRING){
456 state = HID_DESCRIPTOR_LIST_W4_STRING_HEADER;
457 } else {
458 if (bytes_needed > 1){
459 state = HID_DESCRIPTOR_LIST_W4_ITEM_HEADER;
460 } else {
461 bytes_needed = de_get_len(hid_host_sdp_attribute_value);
462 state = HID_DESCRIPTOR_LIST_W4_ITEM_COMPLETE;
463 }
464 }
465 break;
466 case HID_DESCRIPTOR_LIST_W4_ITEM_HEADER:
467 hid_host_sdp_attribute_value[bytes_received++] = data;
468 if (bytes_received >= bytes_needed) {
469 bytes_needed = de_get_len(hid_host_sdp_attribute_value);
470 state = HID_DESCRIPTOR_LIST_W4_ITEM_COMPLETE;
471 }
472 break;
473 case HID_DESCRIPTOR_LIST_W4_ITEM_COMPLETE:
474 // ignore data for non-string item
475 bytes_received++;
476 if (bytes_received >= bytes_needed) {
477 bytes_received = 0;
478 state = HID_DESCRIPTOR_LIST_W4_ITEM_START;
479 }
480 break;
481 case HID_DESCRIPTOR_LIST_W4_STRING_HEADER:
482 hid_host_sdp_attribute_value[bytes_received++] = data;
483 if (bytes_received >= bytes_needed) {
484 bytes_received = 0;
485 bytes_needed = de_get_data_size(hid_host_sdp_attribute_value);
486 state = HID_DESCRIPTOR_LIST_W4_STRING_COMPLETE;
487 }
488 break;
489 case HID_DESCRIPTOR_LIST_W4_STRING_COMPLETE:
490 stored = hid_descriptor_storage_store(connection, data);
491 if (stored) {
492 bytes_received++;
493 if (bytes_received >= bytes_needed) {
494 connection->hid_descriptor_status = ERROR_CODE_SUCCESS;
495 log_info_hexdump(&hid_host_descriptor_storage[connection->hid_descriptor_offset],
496 connection->hid_descriptor_len);
497 state = HID_DESCRIPTOR_LIST_COMPLETE;
498 }
499 } else {
500 error = true;
501 }
502 break;
503 case HID_DESCRIPTOR_LIST_ERROR:
504 case HID_DESCRIPTOR_LIST_COMPLETE:
505 // ignore data
506 break;
507 default:
508 btstack_unreachable();
509 break;
510 }
511
512 if (error){
513 log_info("Descriptor List invalid, state %u", (int) state);
514 state = HID_DESCRIPTOR_LIST_ERROR;
515 connection->hid_descriptor_status = ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
516 }
517 }
518
hid_host_handle_sdp_client_query_result(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)519 static void hid_host_handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
520 UNUSED(packet_type);
521 UNUSED(channel);
522 UNUSED(size);
523
524 des_iterator_t attribute_list_it;
525 des_iterator_t additional_des_it;
526 des_iterator_t prot_it;
527 uint8_t *des_element;
528 uint8_t *element;
529 uint32_t uuid;
530 uint8_t status = ERROR_CODE_SUCCESS;
531 bool try_fallback_to_boot;
532 bool finalize_connection;
533
534
535 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_host_sdp_context_control_cid);
536 if (!connection) {
537 log_error("SDP query, connection with 0x%02x cid not found", hid_host_sdp_context_control_cid);
538 return;
539 }
540
541 btstack_assert(connection->state == HID_HOST_W4_SDP_QUERY_RESULT);
542
543 uint16_t attribute_id;
544 uint16_t attribute_offset;
545 uint8_t attribute_data;
546 switch (hci_event_packet_get_type(packet)){
547 case SDP_EVENT_QUERY_ATTRIBUTE_VALUE:
548
549 attribute_id = sdp_event_query_attribute_byte_get_attribute_id(packet);
550 attribute_offset = sdp_event_query_attribute_byte_get_data_offset(packet);
551 attribute_data = sdp_event_query_attribute_byte_get_data(packet);
552
553 // filter attributes
554 bool process_data = false;
555 switch (attribute_id){
556 case BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST:
557 case BLUETOOTH_ATTRIBUTE_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS:
558 case BLUETOOTH_ATTRIBUTE_HIDSSR_HOST_MAX_LATENCY:
559 case BLUETOOTH_ATTRIBUTE_HIDSSR_HOST_MIN_TIMEOUT:
560 process_data = true;
561 break;
562 case BLUETOOTH_ATTRIBUTE_HID_DESCRIPTOR_LIST:
563 // directly process BLUETOOTH_ATTRIBUTE_HID_DESCRIPTOR_LIST with state machine
564 hid_host_handle_sdp_hid_descriptor_list(connection, attribute_offset, attribute_data);
565 break;
566 default:
567 break;
568 }
569 if (process_data == false){
570 break;
571 }
572
573 if (sdp_event_query_attribute_byte_get_attribute_length(packet) <= hid_host_sdp_attribute_value_buffer_size) {
574
575 hid_host_sdp_attribute_value[attribute_offset] = attribute_data;
576
577 if ((uint16_t)(attribute_offset + 1) == sdp_event_query_attribute_byte_get_attribute_length(packet)) {
578 switch(attribute_id) {
579
580 case BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST:
581 for (des_iterator_init(&attribute_list_it, hid_host_sdp_attribute_value); des_iterator_has_more(&attribute_list_it); des_iterator_next(&attribute_list_it)) {
582 if (des_iterator_get_type(&attribute_list_it) != DE_DES) continue;
583 des_element = des_iterator_get_element(&attribute_list_it);
584 des_iterator_init(&prot_it, des_element);
585 element = des_iterator_get_element(&prot_it);
586 if (de_get_element_type(element) != DE_UUID) continue;
587 uuid = de_get_uuid32(element);
588 switch (uuid){
589 case BLUETOOTH_PROTOCOL_L2CAP:
590 if (!des_iterator_has_more(&prot_it)) continue;
591 des_iterator_next(&prot_it);
592 de_element_get_uint16(des_iterator_get_element(&prot_it), &connection->control_psm);
593 log_info("HID Control PSM: 0x%04x", connection->control_psm);
594 break;
595 default:
596 break;
597 }
598 }
599 break;
600 case BLUETOOTH_ATTRIBUTE_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS:
601 for (des_iterator_init(&attribute_list_it, hid_host_sdp_attribute_value); des_iterator_has_more(&attribute_list_it); des_iterator_next(&attribute_list_it)) {
602 if (des_iterator_get_type(&attribute_list_it) != DE_DES) continue;
603 des_element = des_iterator_get_element(&attribute_list_it);
604 for (des_iterator_init(&additional_des_it, des_element); des_iterator_has_more(&additional_des_it); des_iterator_next(&additional_des_it)) {
605 if (des_iterator_get_type(&additional_des_it) != DE_DES) continue;
606 des_element = des_iterator_get_element(&additional_des_it);
607 des_iterator_init(&prot_it, des_element);
608 element = des_iterator_get_element(&prot_it);
609 if (de_get_element_type(element) != DE_UUID) continue;
610 uuid = de_get_uuid32(element);
611 switch (uuid){
612 case BLUETOOTH_PROTOCOL_L2CAP:
613 if (!des_iterator_has_more(&prot_it)) continue;
614 des_iterator_next(&prot_it);
615 de_element_get_uint16(des_iterator_get_element(&prot_it), &connection->interrupt_psm);
616 log_info("HID Interrupt PSM: 0x%04x", connection->interrupt_psm);
617 break;
618 default:
619 break;
620 }
621 }
622 }
623 break;
624
625 case BLUETOOTH_ATTRIBUTE_HIDSSR_HOST_MAX_LATENCY:
626 if (de_get_element_type(hid_host_sdp_attribute_value) == DE_UINT) {
627 uint16_t host_max_latency;
628 if (de_element_get_uint16(hid_host_sdp_attribute_value, &host_max_latency) == 1){
629 connection->host_max_latency = host_max_latency;
630 } else {
631 connection->host_max_latency = 0xFFFF;
632 }
633 }
634 break;
635
636 case BLUETOOTH_ATTRIBUTE_HIDSSR_HOST_MIN_TIMEOUT:
637 if (de_get_element_type(hid_host_sdp_attribute_value) == DE_UINT) {
638 uint16_t host_min_timeout;
639 if (de_element_get_uint16(hid_host_sdp_attribute_value, &host_min_timeout) == 1){
640 connection->host_min_timeout = host_min_timeout;
641 } else {
642 connection->host_min_timeout = 0xFFFF;
643 }
644 }
645 break;
646
647 default:
648 break;
649 }
650 }
651 } else {
652 log_error("SDP attribute value buffer size exceeded: available %d, required %d", hid_host_sdp_attribute_value_buffer_size, sdp_event_query_attribute_byte_get_attribute_length(packet));
653 }
654 break;
655
656 case SDP_EVENT_QUERY_COMPLETE:
657 status = sdp_event_query_complete_get_status(packet);
658 try_fallback_to_boot = false;
659 finalize_connection = false;
660
661 switch (status){
662 // remote has SDP server
663 case ERROR_CODE_SUCCESS:
664 // but no HID record
665 if (!connection->control_psm || !connection->interrupt_psm) {
666 status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
667 if (connection->requested_protocol_mode == HID_PROTOCOL_MODE_REPORT_WITH_FALLBACK_TO_BOOT){
668 try_fallback_to_boot = true;
669 } else {
670 finalize_connection = true;
671 }
672 break;
673 }
674 // report mode possible
675 break;
676
677 // SDP query incomplete (e.g. disconnect)
678 case SDP_QUERY_INCOMPLETE:
679 finalize_connection = true;
680 break;
681
682 // SDP connection failed or remote does not have SDP server
683 default:
684 if (connection->requested_protocol_mode == HID_PROTOCOL_MODE_REPORT_WITH_FALLBACK_TO_BOOT){
685 try_fallback_to_boot = true;
686 } else {
687 finalize_connection = true;
688 }
689 break;
690 }
691
692 if (finalize_connection){
693 hid_host_sdp_context_control_cid = 0;
694 hid_emit_connected_event(connection, status);
695 hid_host_finalize_connection(connection);
696 break;
697 }
698
699 hid_emit_sniff_params_event(connection);
700
701 if (try_fallback_to_boot){
702 if (connection->incoming){
703 connection->set_protocol = true;
704 connection->state = HID_HOST_CONNECTION_ESTABLISHED;
705 connection->requested_protocol_mode = HID_PROTOCOL_MODE_BOOT;
706 hid_emit_descriptor_available_event(connection);
707 l2cap_request_can_send_now_event(connection->control_cid);
708 } else {
709 connection->state = HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED;
710 status = l2cap_create_channel(hid_host_packet_handler, connection->remote_addr, BLUETOOTH_PSM_HID_CONTROL, 0xffff, &connection->control_cid);
711 if (status != ERROR_CODE_SUCCESS){
712 hid_host_sdp_context_control_cid = 0;
713 hid_emit_connected_event(connection, status);
714 hid_host_finalize_connection(connection);
715 }
716 }
717 break;
718 }
719
720 // report mode possible
721 if (connection->incoming) {
722 connection->set_protocol = true;
723 connection->state = HID_HOST_CONNECTION_ESTABLISHED;
724 connection->requested_protocol_mode = HID_PROTOCOL_MODE_REPORT;
725 hid_emit_descriptor_available_event(connection);
726 l2cap_request_can_send_now_event(connection->control_cid);
727 } else {
728 connection->state = HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED;
729 status = l2cap_create_channel(hid_host_packet_handler, connection->remote_addr, connection->control_psm, 0xffff, &connection->control_cid);
730 if (status != ERROR_CODE_SUCCESS){
731 hid_emit_connected_event(connection, status);
732 hid_host_finalize_connection(connection);
733 }
734 }
735 break;
736
737 default:
738 break;
739 }
740
741 }
742
743
hid_host_handle_control_packet(hid_host_connection_t * connection,uint8_t * packet,uint16_t size)744 static void hid_host_handle_control_packet(hid_host_connection_t * connection, uint8_t *packet, uint16_t size){
745 UNUSED(size);
746 uint8_t param;
747 hid_message_type_t message_type;
748 hid_handshake_param_type_t message_status;
749 hid_protocol_mode_t protocol_mode;
750
751 uint8_t * in_place_event;
752 uint8_t status;
753
754 message_type = (hid_message_type_t)(packet[0] >> 4);
755 if (message_type == HID_MESSAGE_TYPE_HID_CONTROL){
756 param = packet[0] & 0x0F;
757 switch ((hid_control_param_t)param){
758 case HID_CONTROL_PARAM_VIRTUAL_CABLE_UNPLUG:
759 hid_emit_event(connection, HID_SUBEVENT_VIRTUAL_CABLE_UNPLUG);
760 hid_host_disconnect(connection->hid_cid);
761 return;
762 default:
763 break;
764 }
765 }
766
767 message_status = (hid_handshake_param_type_t)(packet[0] & 0x0F);
768
769 switch (connection->state){
770 case HID_HOST_CONNECTION_ESTABLISHED:
771 if (!connection->w4_set_protocol_response) break;
772 connection->w4_set_protocol_response = false;
773
774 switch (message_status){
775 case HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL:
776 connection->protocol_mode = connection->requested_protocol_mode;
777 break;
778 default:
779 break;
780 }
781 hid_emit_set_protocol_response_event(connection, message_status);
782 break;
783
784 case HID_HOST_CONTROL_CONNECTION_ESTABLISHED: // outgoing
785 case HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED: // outgoing
786 if (!connection->w4_set_protocol_response) break;
787 connection->w4_set_protocol_response = false;
788
789 switch (message_status){
790 case HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL:
791 // we are already connected, here it is only confirmed that we are in required protocol
792 btstack_assert(connection->incoming == false);
793 status = l2cap_create_channel(hid_host_packet_handler, connection->remote_addr, connection->interrupt_psm, 0xffff, &connection->interrupt_cid);
794 if (status != ERROR_CODE_SUCCESS){
795 log_info("HID Interrupt Connection failed: 0x%02x\n", status);
796 hid_emit_connected_event(connection, status);
797 hid_host_finalize_connection(connection);
798 break;
799 }
800 connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED;
801 break;
802 default:
803 hid_emit_connected_event(connection, ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
804 hid_host_finalize_connection(connection);
805 break;
806 }
807 break;
808
809 case HID_HOST_W4_GET_REPORT_RESPONSE:
810 switch (message_type){
811 case HID_MESSAGE_TYPE_HANDSHAKE:{
812 uint8_t event[8];
813 hid_setup_get_report_event(connection, message_status, event, 0);
814 hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, event, sizeof(event));
815 break;
816 }
817 case HID_MESSAGE_TYPE_DATA:
818 // reuse hci+l2cap header - max 8 byte (7 bytes + 1 bytes overwriting hid header)
819 in_place_event = packet - 7;
820 hid_setup_get_report_event(connection, HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL, in_place_event, size-1);
821 hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, in_place_event, size + 7);
822 break;
823 default:
824 break;
825 }
826 connection->state = HID_HOST_CONNECTION_ESTABLISHED;
827 break;
828
829 case HID_HOST_W4_SET_REPORT_RESPONSE:
830 hid_emit_event_with_status(connection, HID_SUBEVENT_SET_REPORT_RESPONSE, message_status);
831 connection->state = HID_HOST_CONNECTION_ESTABLISHED;
832 break;
833
834 case HID_HOST_W4_GET_PROTOCOL_RESPONSE:
835 protocol_mode = connection->protocol_mode;
836
837 switch (message_type){
838 case HID_MESSAGE_TYPE_DATA:
839 protocol_mode = (hid_protocol_mode_t)packet[1];
840 switch (protocol_mode){
841 case HID_PROTOCOL_MODE_BOOT:
842 case HID_PROTOCOL_MODE_REPORT:
843 message_status = HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL;
844 break;
845 default:
846 message_status = HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER;
847 break;
848 }
849 break;
850 default:
851 break;
852 }
853 hid_emit_get_protocol_event(connection, message_status, protocol_mode);
854 connection->state = HID_HOST_CONNECTION_ESTABLISHED;
855 break;
856
857 default:
858 log_info("ignore invalid HID Control message");
859 connection->state = HID_HOST_CONNECTION_ESTABLISHED;
860 break;
861 }
862
863 }
864
hid_host_packet_handler(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)865 static void hid_host_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
866 UNUSED(channel);
867 UNUSED(size);
868
869 uint8_t event;
870 bd_addr_t address;
871 uint8_t status;
872 uint16_t l2cap_cid;
873 hid_host_connection_t * connection;
874
875 switch (packet_type) {
876
877 case L2CAP_DATA_PACKET:
878 connection = hid_host_get_connection_for_l2cap_cid(channel);
879 if (!connection) break;
880
881 if (channel == connection->interrupt_cid){
882 uint8_t * in_place_event = packet - 7;
883 hid_setup_report_event(connection, in_place_event, size);
884 hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, in_place_event, size + 7);
885 break;
886 }
887
888 if (channel == connection->control_cid){
889 hid_host_handle_control_packet(connection, packet, size);
890 break;
891 }
892 break;
893
894 case HCI_EVENT_PACKET:
895 event = hci_event_packet_get_type(packet);
896 switch (event) {
897 case L2CAP_EVENT_INCOMING_CONNECTION:
898 l2cap_event_incoming_connection_get_address(packet, address);
899 // connection should exist if psm == PSM_HID_INTERRUPT
900 connection = hid_host_get_connection_for_bd_addr(address);
901
902 switch (l2cap_event_incoming_connection_get_psm(packet)){
903 case PSM_HID_CONTROL:
904 if (connection){
905 l2cap_decline_connection(channel);
906 break;
907 }
908
909 connection = hid_host_create_connection(address);
910 if (!connection){
911 log_error("Cannot create connection for %s", bd_addr_to_str(address));
912 l2cap_decline_connection(channel);
913 break;
914 }
915
916 connection->state = HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED;
917 connection->hid_descriptor_status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
918 connection->con_handle = l2cap_event_incoming_connection_get_handle(packet);
919 connection->control_cid = l2cap_event_incoming_connection_get_local_cid(packet);
920 connection->incoming = true;
921
922 // emit connection request
923 // user calls either hid_host_accept_connection or hid_host_decline_connection
924 hid_emit_incoming_connection_event(connection);
925 break;
926
927 case PSM_HID_INTERRUPT:
928 if (!connection || (connection->state != HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED)){
929 log_error("Decline connection for %s", bd_addr_to_str(address));
930 l2cap_decline_connection(channel);
931 break;
932 }
933
934 connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED;
935 connection->interrupt_cid = l2cap_event_incoming_connection_get_local_cid(packet);
936 log_info("Accept connection on Interrupt channel %s", bd_addr_to_str(address));
937 l2cap_accept_connection(channel);
938 break;
939
940 default:
941 log_info("Decline connection for %s", bd_addr_to_str(address));
942 l2cap_decline_connection(channel);
943 break;
944 }
945 break;
946
947 case L2CAP_EVENT_CHANNEL_OPENED:
948 l2cap_event_channel_opened_get_address(packet, address);
949
950 connection = hid_host_get_connection_for_bd_addr(address);
951 if (!connection){
952 log_error("Connection does not exist %s", bd_addr_to_str(address));
953 break;
954 }
955
956 status = l2cap_event_channel_opened_get_status(packet);
957 if (status != ERROR_CODE_SUCCESS){
958 log_info("L2CAP connection %s failed: 0x%02xn", bd_addr_to_str(address), status);
959 hid_emit_connected_event(connection, status);
960 hid_host_finalize_connection(connection);
961 break;
962 }
963
964 // handle incoming connection:
965 if (connection->incoming){
966 switch (connection->state){
967 case HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED:
968 // A Bluetooth HID Host or Bluetooth HID device shall always open both the control and Interrupt channels. (HID_v1.1.1, Chapter 5.2.2)
969 // We expect incomming interrupt connection from remote HID device
970 connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED;
971 log_info("Incoming control connection opened: w4 interrupt");
972 break;
973
974 case HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED:
975 hid_emit_connected_event(connection, ERROR_CODE_SUCCESS);
976 connection->state = HID_HOST_CONNECTION_ESTABLISHED;
977
978 switch (connection->requested_protocol_mode){
979 case HID_PROTOCOL_MODE_BOOT:
980 hid_emit_descriptor_available_event(connection);
981 connection->set_protocol = true;
982 l2cap_request_can_send_now_event(connection->control_cid);
983 log_info("Incoming interrupt connection opened: set boot mode");
984 break;
985 default:
986 // SDP query
987 log_info("Incoming interrupt connection opened: start SDP query");
988 connection->state = HID_HOST_W2_SEND_SDP_QUERY;
989 hid_host_handle_sdp_client_query_request.callback = &hid_host_handle_start_sdp_client_query;
990 (void) sdp_client_register_query_callback(&hid_host_handle_sdp_client_query_request);
991 break;
992 }
993 break;
994
995 default:
996 btstack_assert(false);
997 break;
998 }
999 break;
1000 }
1001
1002 // handle outgoing connection
1003 switch (connection->state){
1004 case HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED:
1005 log_info("Opened control connection, requested protocol mode %d\n", connection->requested_protocol_mode);
1006 connection->con_handle = l2cap_event_channel_opened_get_handle(packet);
1007 connection->state = HID_HOST_CONTROL_CONNECTION_ESTABLISHED;
1008
1009 switch (connection->requested_protocol_mode){
1010 case HID_PROTOCOL_MODE_BOOT:
1011 case HID_PROTOCOL_MODE_REPORT_WITH_FALLBACK_TO_BOOT:
1012 connection->set_protocol = true;
1013 connection->interrupt_psm = BLUETOOTH_PSM_HID_INTERRUPT;
1014 l2cap_request_can_send_now_event(connection->control_cid);
1015 break;
1016 default:
1017 status = l2cap_create_channel(hid_host_packet_handler, address, connection->interrupt_psm, 0xffff, &connection->interrupt_cid);
1018 if (status){
1019 log_info("Connecting to HID Interrupt failed: 0x%02x", status);
1020 hid_emit_connected_event(connection, status);
1021 break;
1022 }
1023 connection->protocol_mode = connection->requested_protocol_mode;
1024 connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED;
1025 break;
1026 }
1027 break;
1028
1029 case HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED:
1030 connection->state = HID_HOST_CONNECTION_ESTABLISHED;
1031 log_info("HID host connection established, cids: control 0x%02x, interrupt 0x%02x interrupt, hid 0x%02x",
1032 connection->control_cid, connection->interrupt_cid, connection->hid_cid);
1033 hid_emit_connected_event(connection, ERROR_CODE_SUCCESS);
1034 hid_emit_descriptor_available_event(connection);
1035 break;
1036
1037 default:
1038 btstack_assert(false);
1039 break;
1040 }
1041 break;
1042
1043 case L2CAP_EVENT_CHANNEL_CLOSED:
1044 l2cap_cid = l2cap_event_channel_closed_get_local_cid(packet);
1045 connection = hid_host_get_connection_for_l2cap_cid(l2cap_cid);
1046 if (!connection) return;
1047
1048 if (l2cap_cid == connection->interrupt_cid){
1049 connection->interrupt_cid = 0;
1050 if (connection->state == HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED){
1051 connection->state = HID_HOST_W4_CONTROL_CONNECTION_DISCONNECTED;
1052 l2cap_disconnect(connection->control_cid);
1053 }
1054 break;
1055 }
1056
1057 if (l2cap_cid == connection->control_cid){
1058 connection->control_cid = 0;
1059 hid_emit_event(connection, HID_SUBEVENT_CONNECTION_CLOSED);
1060 hid_descriptor_storage_delete(connection);
1061 hid_host_finalize_connection(connection);
1062 break;
1063 }
1064 break;
1065
1066 case L2CAP_EVENT_CAN_SEND_NOW:
1067 l2cap_cid = l2cap_event_can_send_now_get_local_cid(packet);
1068 connection = hid_host_get_connection_for_l2cap_cid(l2cap_cid);
1069 if (!connection) return;
1070
1071
1072
1073 if (connection->control_cid == l2cap_cid){
1074 switch(connection->state){
1075 case HID_HOST_CONTROL_CONNECTION_ESTABLISHED:
1076 case HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED:
1077 if (connection->set_protocol){
1078 connection->set_protocol = false;
1079 uint8_t protocol_mode = connection->requested_protocol_mode == HID_PROTOCOL_MODE_BOOT ? 0 : 1;
1080 uint8_t header = (HID_MESSAGE_TYPE_SET_PROTOCOL << 4) | protocol_mode;
1081 uint8_t report[] = {header};
1082 connection->w4_set_protocol_response = true;
1083 l2cap_send(connection->control_cid, (uint8_t*) report, sizeof(report));
1084 break;
1085 }
1086 break;
1087
1088 case HID_HOST_CONNECTION_ESTABLISHED:
1089 if ((connection->control_tasks & CONTROL_MESSAGE_BITMASK_SUSPEND) != 0){
1090 connection->control_tasks &= ~CONTROL_MESSAGE_BITMASK_SUSPEND;
1091 uint8_t report[] = { (HID_MESSAGE_TYPE_HID_CONTROL << 4) | HID_CONTROL_PARAM_SUSPEND };
1092 l2cap_send(connection->control_cid, (uint8_t*) report, 1);
1093 break;
1094 }
1095 if ((connection->control_tasks & CONTROL_MESSAGE_BITMASK_EXIT_SUSPEND) != 0){
1096 connection->control_tasks &= ~CONTROL_MESSAGE_BITMASK_EXIT_SUSPEND;
1097 uint8_t report[] = { (HID_MESSAGE_TYPE_HID_CONTROL << 4) | HID_CONTROL_PARAM_EXIT_SUSPEND };
1098 l2cap_send(connection->control_cid, (uint8_t*) report, 1);
1099 break;
1100 }
1101 if ((connection->control_tasks & CONTROL_MESSAGE_BITMASK_VIRTUAL_CABLE_UNPLUG) != 0){
1102 connection->control_tasks &= ~CONTROL_MESSAGE_BITMASK_VIRTUAL_CABLE_UNPLUG;
1103 uint8_t report[] = { (HID_MESSAGE_TYPE_HID_CONTROL << 4) | HID_CONTROL_PARAM_VIRTUAL_CABLE_UNPLUG };
1104 l2cap_send(connection->control_cid, (uint8_t*) report, 1);
1105 break;
1106 }
1107
1108 if (connection->set_protocol){
1109 connection->set_protocol = false;
1110 uint8_t header = (HID_MESSAGE_TYPE_SET_PROTOCOL << 4) | connection->requested_protocol_mode;
1111 uint8_t report[] = {header};
1112
1113 connection->w4_set_protocol_response = true;
1114 l2cap_send(connection->control_cid, (uint8_t*) report, sizeof(report));
1115 break;
1116 }
1117 break;
1118
1119 case HID_HOST_W2_SEND_GET_REPORT:{
1120 uint8_t header = (HID_MESSAGE_TYPE_GET_REPORT << 4) | connection->report_type;
1121 uint8_t report[2];
1122 uint16_t pos = 0;
1123 report[pos++] = header;
1124 if (connection->report_id != HID_REPORT_ID_UNDEFINED){
1125 report[pos++] = (uint8_t) connection->report_id;
1126 }
1127
1128 connection->state = HID_HOST_W4_GET_REPORT_RESPONSE;
1129 l2cap_send(connection->control_cid, (uint8_t*) report, pos);
1130 break;
1131 }
1132
1133 case HID_HOST_W2_SEND_SET_REPORT:{
1134 uint8_t header = (HID_MESSAGE_TYPE_SET_REPORT << 4) | connection->report_type;
1135 connection->state = HID_HOST_W4_SET_REPORT_RESPONSE;
1136
1137 l2cap_reserve_packet_buffer();
1138 uint8_t * out_buffer = l2cap_get_outgoing_buffer();
1139 uint16_t pos = 0;
1140 out_buffer[pos++] = header;
1141 if (connection->report_id != HID_REPORT_ID_UNDEFINED){
1142 out_buffer[pos++] = (uint8_t) connection->report_id;
1143 }
1144 (void)memcpy(&out_buffer[pos], connection->report, connection->report_len);
1145 pos += connection->report_len;
1146 l2cap_send_prepared(connection->control_cid, pos);
1147 break;
1148 }
1149
1150 case HID_HOST_W2_SEND_GET_PROTOCOL:{
1151 uint8_t header = (HID_MESSAGE_TYPE_GET_PROTOCOL << 4);
1152 uint8_t report[] = {header};
1153 connection->state = HID_HOST_W4_GET_PROTOCOL_RESPONSE;
1154 l2cap_send(connection->control_cid, (uint8_t*) report, sizeof(report));
1155 break;
1156 }
1157
1158 default:
1159 break;
1160 }
1161 }
1162
1163 if (connection->interrupt_cid == l2cap_cid && connection->state == HID_HOST_W2_SEND_REPORT){
1164 connection->state = HID_HOST_CONNECTION_ESTABLISHED;
1165 // there is no response for this type of message
1166 uint8_t header = (HID_MESSAGE_TYPE_DATA << 4) | connection->report_type;
1167
1168 l2cap_reserve_packet_buffer();
1169 uint8_t * out_buffer = l2cap_get_outgoing_buffer();
1170 uint16_t pos = 0;
1171 out_buffer[pos++] = header;
1172 if (connection->report_id != HID_REPORT_ID_UNDEFINED){
1173 out_buffer[pos++] = (uint8_t) connection->report_id;
1174 }
1175 (void)memcpy(&out_buffer[pos], connection->report, connection->report_len);
1176 pos += connection->report_len;
1177 l2cap_send_prepared(connection->interrupt_cid, pos);
1178 break;
1179 }
1180
1181 if (connection->control_tasks != 0){
1182 l2cap_request_can_send_now_event(connection->control_cid);
1183 }
1184 break;
1185 default:
1186 break;
1187 }
1188 default:
1189 break;
1190 }
1191 }
1192
1193
hid_host_init(uint8_t * hid_descriptor_storage,uint16_t hid_descriptor_storage_len)1194 void hid_host_init(uint8_t * hid_descriptor_storage, uint16_t hid_descriptor_storage_len){
1195 hid_host_descriptor_storage = hid_descriptor_storage;
1196 hid_host_descriptor_storage_len = hid_descriptor_storage_len;
1197
1198 // register L2CAP Services for reconnections
1199 l2cap_register_service(hid_host_packet_handler, PSM_HID_INTERRUPT, 0xffff, gap_get_security_level());
1200 l2cap_register_service(hid_host_packet_handler, PSM_HID_CONTROL, 0xffff, gap_get_security_level());
1201 }
1202
hid_host_deinit(void)1203 void hid_host_deinit(void){
1204 hid_host_callback = NULL;
1205 hid_host_descriptor_storage = NULL;
1206 hid_host_sdp_context_control_cid = 0;
1207 hid_host_connections = NULL;
1208 hid_host_cid_counter = 0;
1209 (void) memset(&hid_host_handle_sdp_client_query_request, 0, sizeof(hid_host_handle_sdp_client_query_request));
1210 }
1211
hid_host_register_packet_handler(btstack_packet_handler_t callback)1212 void hid_host_register_packet_handler(btstack_packet_handler_t callback){
1213 hid_host_callback = callback;
1214 }
1215
hid_host_handle_start_sdp_client_query(void * context)1216 static void hid_host_handle_start_sdp_client_query(void * context){
1217 UNUSED(context);
1218 btstack_linked_list_iterator_t it;
1219 btstack_linked_list_iterator_init(&it, &hid_host_connections);
1220
1221 while (btstack_linked_list_iterator_has_next(&it)){
1222 hid_host_connection_t * connection = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it);
1223
1224 switch (connection->state){
1225 case HID_HOST_W2_SEND_SDP_QUERY:
1226 connection->state = HID_HOST_W4_SDP_QUERY_RESULT;
1227 connection->hid_descriptor_status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1228 break;
1229 default:
1230 continue;
1231 }
1232
1233 hid_descriptor_storage_init(connection);
1234 hid_host_sdp_context_control_cid = connection->hid_cid;
1235 sdp_client_query_uuid16(&hid_host_handle_sdp_client_query_result, (uint8_t *) connection->remote_addr, BLUETOOTH_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE_SERVICE);
1236 return;
1237 }
1238 }
1239
hid_host_accept_connection(uint16_t hid_cid,hid_protocol_mode_t protocol_mode)1240 uint8_t hid_host_accept_connection(uint16_t hid_cid, hid_protocol_mode_t protocol_mode){
1241 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1242 if (!connection){
1243 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1244 }
1245 if (connection->state != HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED){
1246 return ERROR_CODE_COMMAND_DISALLOWED;
1247 }
1248
1249 connection->requested_protocol_mode = protocol_mode;
1250 l2cap_accept_connection(connection->control_cid);
1251 return ERROR_CODE_SUCCESS;
1252 }
1253
hid_host_decline_connection(uint16_t hid_cid)1254 uint8_t hid_host_decline_connection(uint16_t hid_cid){
1255 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1256 if (!connection){
1257 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1258 }
1259 if (connection->state != HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED){
1260 return ERROR_CODE_COMMAND_DISALLOWED;
1261 }
1262
1263 l2cap_decline_connection(connection->control_cid);
1264 hid_host_finalize_connection(connection);
1265 return ERROR_CODE_SUCCESS;
1266 }
1267
hid_host_connect(bd_addr_t remote_addr,hid_protocol_mode_t protocol_mode,uint16_t * hid_cid)1268 uint8_t hid_host_connect(bd_addr_t remote_addr, hid_protocol_mode_t protocol_mode, uint16_t * hid_cid){
1269 if (hid_cid == NULL) {
1270 return ERROR_CODE_COMMAND_DISALLOWED;
1271 }
1272
1273 hid_host_connection_t * connection = hid_host_get_connection_for_bd_addr(remote_addr);
1274 if (connection){
1275 return ERROR_CODE_COMMAND_DISALLOWED;
1276 }
1277
1278 connection = hid_host_create_connection(remote_addr);
1279 if (!connection) return BTSTACK_MEMORY_ALLOC_FAILED;
1280
1281 *hid_cid = connection->hid_cid;
1282
1283 connection->state = HID_HOST_W2_SEND_SDP_QUERY;
1284 connection->incoming = false;
1285 connection->requested_protocol_mode = protocol_mode;
1286 connection->hid_descriptor_status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1287
1288 uint8_t status = ERROR_CODE_SUCCESS;
1289
1290 switch (connection->requested_protocol_mode){
1291 case HID_PROTOCOL_MODE_BOOT:
1292 connection->state = HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED;
1293 status = l2cap_create_channel(hid_host_packet_handler, connection->remote_addr, BLUETOOTH_PSM_HID_CONTROL, 0xffff, &connection->control_cid);
1294 break;
1295 default:
1296 hid_host_handle_sdp_client_query_request.callback = &hid_host_handle_start_sdp_client_query;
1297 // ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback
1298 (void) sdp_client_register_query_callback(&hid_host_handle_sdp_client_query_request);
1299 break;
1300 }
1301 return status;
1302 }
1303
1304
hid_host_disconnect(uint16_t hid_cid)1305 void hid_host_disconnect(uint16_t hid_cid){
1306 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1307 if (!connection) return;
1308
1309 switch (connection->state){
1310 case HID_HOST_IDLE:
1311 case HID_HOST_W4_CONTROL_CONNECTION_DISCONNECTED:
1312 case HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED:
1313 return;
1314 default:
1315 break;
1316 }
1317
1318 if (connection->interrupt_cid){
1319 connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED;
1320 l2cap_disconnect(connection->interrupt_cid);
1321 return;
1322 }
1323
1324 if (connection->control_cid){
1325 connection->state = HID_HOST_W4_CONTROL_CONNECTION_DISCONNECTED;
1326 l2cap_disconnect(connection->control_cid);
1327 return;
1328 }
1329 }
1330
1331
hid_host_send_control_message(uint16_t hid_cid,uint8_t control_message_bitmask)1332 static inline uint8_t hid_host_send_control_message(uint16_t hid_cid, uint8_t control_message_bitmask){
1333 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1334 if (!connection || !connection->control_cid) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1335
1336 if (connection->state < HID_HOST_CONTROL_CONNECTION_ESTABLISHED) {
1337 return ERROR_CODE_COMMAND_DISALLOWED;
1338 }
1339 if (connection->state >= HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED){
1340 return ERROR_CODE_COMMAND_DISALLOWED;
1341 }
1342
1343 connection->control_tasks |= control_message_bitmask;
1344 l2cap_request_can_send_now_event(connection->control_cid);
1345 return ERROR_CODE_SUCCESS;
1346 }
1347
hid_host_send_suspend(uint16_t hid_cid)1348 uint8_t hid_host_send_suspend(uint16_t hid_cid){
1349 return hid_host_send_control_message(hid_cid, CONTROL_MESSAGE_BITMASK_SUSPEND);
1350 }
1351
hid_host_send_exit_suspend(uint16_t hid_cid)1352 uint8_t hid_host_send_exit_suspend(uint16_t hid_cid){
1353 return hid_host_send_control_message(hid_cid, CONTROL_MESSAGE_BITMASK_EXIT_SUSPEND);
1354 }
1355
hid_host_send_virtual_cable_unplug(uint16_t hid_cid)1356 uint8_t hid_host_send_virtual_cable_unplug(uint16_t hid_cid){
1357 return hid_host_send_control_message(hid_cid, CONTROL_MESSAGE_BITMASK_VIRTUAL_CABLE_UNPLUG);
1358 }
1359
hid_host_send_get_report(uint16_t hid_cid,hid_report_type_t report_type,uint16_t report_id)1360 uint8_t hid_host_send_get_report(uint16_t hid_cid, hid_report_type_t report_type, uint16_t report_id){
1361 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1362
1363 if (!connection || !connection->control_cid){
1364 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1365 }
1366 if (connection->state != HID_HOST_CONNECTION_ESTABLISHED){
1367 return ERROR_CODE_COMMAND_DISALLOWED;
1368 }
1369
1370 connection->state = HID_HOST_W2_SEND_GET_REPORT;
1371 connection->report_type = report_type;
1372 connection->report_id = report_id;
1373
1374 l2cap_request_can_send_now_event(connection->control_cid);
1375 return ERROR_CODE_SUCCESS;
1376 }
1377
hid_host_send_set_report(uint16_t hid_cid,hid_report_type_t report_type,uint16_t report_id,const uint8_t * report,uint8_t report_len)1378 uint8_t hid_host_send_set_report(uint16_t hid_cid, hid_report_type_t report_type, uint16_t report_id, const uint8_t * report, uint8_t report_len){
1379 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1380
1381 if (!connection || !connection->control_cid){
1382 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1383 }
1384
1385 if (connection->state != HID_HOST_CONNECTION_ESTABLISHED){
1386 return ERROR_CODE_COMMAND_DISALLOWED;
1387 }
1388
1389 if ((l2cap_max_mtu() - 2) < report_len ){
1390 return ERROR_CODE_COMMAND_DISALLOWED;
1391 }
1392
1393 connection->state = HID_HOST_W2_SEND_SET_REPORT;
1394 connection->report_type = report_type;
1395 connection->report_id = report_id;
1396 connection->report = report;
1397 connection->report_len = report_len;
1398
1399 l2cap_request_can_send_now_event(connection->control_cid);
1400 return ERROR_CODE_SUCCESS;
1401 }
1402
hid_host_send_get_protocol(uint16_t hid_cid)1403 uint8_t hid_host_send_get_protocol(uint16_t hid_cid){
1404 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1405 if (!connection || !connection->control_cid){
1406 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1407 }
1408 if (connection->state != HID_HOST_CONNECTION_ESTABLISHED){
1409 return ERROR_CODE_COMMAND_DISALLOWED;
1410 }
1411
1412 connection->state = HID_HOST_W2_SEND_GET_PROTOCOL;
1413 l2cap_request_can_send_now_event(connection->control_cid);
1414 return ERROR_CODE_SUCCESS;
1415 }
1416
hid_host_send_set_protocol_mode(uint16_t hid_cid,hid_protocol_mode_t protocol_mode)1417 uint8_t hid_host_send_set_protocol_mode(uint16_t hid_cid, hid_protocol_mode_t protocol_mode){
1418 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1419 if (!connection || !connection->control_cid){
1420 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1421 }
1422 if (connection->state != HID_HOST_CONNECTION_ESTABLISHED || connection->set_protocol || connection->w4_set_protocol_response){
1423 return ERROR_CODE_COMMAND_DISALLOWED;
1424 }
1425
1426 connection->set_protocol = true;
1427 connection->requested_protocol_mode = protocol_mode;
1428
1429 l2cap_request_can_send_now_event(connection->control_cid);
1430 return ERROR_CODE_SUCCESS;
1431 }
1432
1433
hid_host_send_report(uint16_t hid_cid,uint16_t report_id,const uint8_t * report,uint8_t report_len)1434 uint8_t hid_host_send_report(uint16_t hid_cid, uint16_t report_id, const uint8_t * report, uint8_t report_len){
1435 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1436 if (!connection || !connection->control_cid || !connection->interrupt_cid) {
1437 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1438 }
1439
1440 if (connection->state < HID_HOST_CONNECTION_ESTABLISHED) {
1441 return ERROR_CODE_COMMAND_DISALLOWED;
1442 }
1443 if (connection->state >= HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED){
1444 return ERROR_CODE_COMMAND_DISALLOWED;
1445 }
1446
1447 if ((l2cap_max_mtu() - 2) < report_len ){
1448 return ERROR_CODE_COMMAND_DISALLOWED;
1449 }
1450
1451 connection->state = HID_HOST_W2_SEND_REPORT;
1452 connection->report_type = HID_REPORT_TYPE_OUTPUT;
1453 connection->report_id = report_id;
1454 connection->report = report;
1455 connection->report_len = report_len;
1456
1457 l2cap_request_can_send_now_event(connection->interrupt_cid);
1458 return ERROR_CODE_SUCCESS;
1459 }
1460