xref: /btstack/src/classic/hid_host.c (revision 6897da5c53aac5b1f90f41b5b15d0bd43d61dfff)
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 
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 
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 
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 
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 
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 
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 
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 
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
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 
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 
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 
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 
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 
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 
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
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
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
1212 void hid_host_register_packet_handler(btstack_packet_handler_t callback){
1213     hid_host_callback = callback;
1214 }
1215 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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