xref: /btstack/src/classic/hid_host.c (revision b4c969508293980a60ef0b5378098d3cb8b366d0)
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[] = {header, connection->report_id};
1122 
1123                                 connection->state = HID_HOST_W4_GET_REPORT_RESPONSE;
1124                                 l2cap_send(connection->control_cid, (uint8_t*) report, sizeof(report));
1125                                 break;
1126                             }
1127 
1128                             case HID_HOST_W2_SEND_SET_REPORT:{
1129                                 uint8_t header = (HID_MESSAGE_TYPE_SET_REPORT << 4) | connection->report_type;
1130                                 connection->state = HID_HOST_W4_SET_REPORT_RESPONSE;
1131 
1132                                 l2cap_reserve_packet_buffer();
1133                                 uint8_t * out_buffer = l2cap_get_outgoing_buffer();
1134                                 out_buffer[0] = header;
1135                                 out_buffer[1] = connection->report_id;
1136                                 (void)memcpy(out_buffer + 2, connection->report, connection->report_len);
1137                                 l2cap_send_prepared(connection->control_cid, connection->report_len + 2);
1138                                 break;
1139                             }
1140 
1141                             case HID_HOST_W2_SEND_GET_PROTOCOL:{
1142                                 uint8_t header = (HID_MESSAGE_TYPE_GET_PROTOCOL << 4);
1143                                 uint8_t report[] = {header};
1144                                 connection->state = HID_HOST_W4_GET_PROTOCOL_RESPONSE;
1145                                 l2cap_send(connection->control_cid, (uint8_t*) report, sizeof(report));
1146                                 break;
1147                             }
1148 
1149                             default:
1150                                 break;
1151                         }
1152                     }
1153 
1154                     if (connection->interrupt_cid == l2cap_cid && connection->state == HID_HOST_W2_SEND_REPORT){
1155                         connection->state = HID_HOST_CONNECTION_ESTABLISHED;
1156                         // there is no response for this type of message
1157                         uint8_t header = (HID_MESSAGE_TYPE_DATA << 4) | connection->report_type;
1158 
1159                         l2cap_reserve_packet_buffer();
1160                         uint8_t * out_buffer = l2cap_get_outgoing_buffer();
1161                         out_buffer[0] = header;
1162                         out_buffer[1] = connection->report_id;
1163                         (void)memcpy(out_buffer + 2, connection->report, connection->report_len);
1164                         l2cap_send_prepared(connection->interrupt_cid, connection->report_len + 2);
1165                         break;
1166                     }
1167 
1168                     if (connection->control_tasks != 0){
1169                         l2cap_request_can_send_now_event(connection->control_cid);
1170                     }
1171                     break;
1172                 default:
1173                     break;
1174             }
1175         default:
1176             break;
1177     }
1178 }
1179 
1180 
1181 void hid_host_init(uint8_t * hid_descriptor_storage, uint16_t hid_descriptor_storage_len){
1182     hid_host_descriptor_storage = hid_descriptor_storage;
1183     hid_host_descriptor_storage_len = hid_descriptor_storage_len;
1184 
1185     // register L2CAP Services for reconnections
1186     l2cap_register_service(hid_host_packet_handler, PSM_HID_INTERRUPT, 0xffff, gap_get_security_level());
1187     l2cap_register_service(hid_host_packet_handler, PSM_HID_CONTROL, 0xffff, gap_get_security_level());
1188 }
1189 
1190 void hid_host_deinit(void){
1191     hid_host_callback = NULL;
1192     hid_host_descriptor_storage = NULL;
1193     hid_host_sdp_context_control_cid = 0;
1194     hid_host_connections = NULL;
1195     hid_host_cid_counter = 0;
1196     (void) memset(&hid_host_handle_sdp_client_query_request, 0, sizeof(hid_host_handle_sdp_client_query_request));
1197 }
1198 
1199 void hid_host_register_packet_handler(btstack_packet_handler_t callback){
1200     hid_host_callback = callback;
1201 }
1202 
1203 static void hid_host_handle_start_sdp_client_query(void * context){
1204     UNUSED(context);
1205     btstack_linked_list_iterator_t it;
1206     btstack_linked_list_iterator_init(&it, &hid_host_connections);
1207 
1208     while (btstack_linked_list_iterator_has_next(&it)){
1209         hid_host_connection_t * connection = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it);
1210 
1211         switch (connection->state){
1212             case HID_HOST_W2_SEND_SDP_QUERY:
1213                 connection->state = HID_HOST_W4_SDP_QUERY_RESULT;
1214                 connection->hid_descriptor_status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1215                 break;
1216             default:
1217                 continue;
1218         }
1219 
1220         hid_descriptor_storage_init(connection);
1221         hid_host_sdp_context_control_cid = connection->hid_cid;
1222         sdp_client_query_uuid16(&hid_host_handle_sdp_client_query_result, (uint8_t *) connection->remote_addr, BLUETOOTH_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE_SERVICE);
1223         return;
1224     }
1225 }
1226 
1227 uint8_t hid_host_accept_connection(uint16_t hid_cid, hid_protocol_mode_t protocol_mode){
1228     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1229     if (!connection){
1230         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1231     }
1232     if (connection->state != HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED){
1233         return ERROR_CODE_COMMAND_DISALLOWED;
1234     }
1235 
1236     connection->requested_protocol_mode = protocol_mode;
1237     l2cap_accept_connection(connection->control_cid);
1238     return ERROR_CODE_SUCCESS;
1239 }
1240 
1241 uint8_t hid_host_decline_connection(uint16_t hid_cid){
1242     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1243     if (!connection){
1244         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1245     }
1246     if (connection->state != HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED){
1247         return ERROR_CODE_COMMAND_DISALLOWED;
1248     }
1249 
1250     l2cap_decline_connection(connection->control_cid);
1251     hid_host_finalize_connection(connection);
1252     return ERROR_CODE_SUCCESS;
1253 }
1254 
1255 uint8_t hid_host_connect(bd_addr_t remote_addr, hid_protocol_mode_t protocol_mode, uint16_t * hid_cid){
1256     if (hid_cid == NULL) {
1257         return ERROR_CODE_COMMAND_DISALLOWED;
1258     }
1259 
1260     hid_host_connection_t * connection = hid_host_get_connection_for_bd_addr(remote_addr);
1261     if (connection){
1262         return ERROR_CODE_COMMAND_DISALLOWED;
1263     }
1264 
1265     connection = hid_host_create_connection(remote_addr);
1266     if (!connection) return BTSTACK_MEMORY_ALLOC_FAILED;
1267 
1268     *hid_cid = connection->hid_cid;
1269 
1270     connection->state = HID_HOST_W2_SEND_SDP_QUERY;
1271     connection->incoming = false;
1272     connection->requested_protocol_mode = protocol_mode;
1273     connection->hid_descriptor_status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1274 
1275     uint8_t status = ERROR_CODE_SUCCESS;
1276 
1277     switch (connection->requested_protocol_mode){
1278         case HID_PROTOCOL_MODE_BOOT:
1279             connection->state = HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED;
1280             status = l2cap_create_channel(hid_host_packet_handler, connection->remote_addr, BLUETOOTH_PSM_HID_CONTROL, 0xffff, &connection->control_cid);
1281             break;
1282         default:
1283             hid_host_handle_sdp_client_query_request.callback = &hid_host_handle_start_sdp_client_query;
1284             // ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback
1285             (void) sdp_client_register_query_callback(&hid_host_handle_sdp_client_query_request);
1286             break;
1287     }
1288     return status;
1289 }
1290 
1291 
1292 void hid_host_disconnect(uint16_t hid_cid){
1293     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1294     if (!connection) return;
1295 
1296     switch (connection->state){
1297         case HID_HOST_IDLE:
1298         case HID_HOST_W4_CONTROL_CONNECTION_DISCONNECTED:
1299         case HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED:
1300             return;
1301         default:
1302             break;
1303     }
1304 
1305     if (connection->interrupt_cid){
1306         connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED;
1307         l2cap_disconnect(connection->interrupt_cid);
1308         return;
1309     }
1310 
1311     if (connection->control_cid){
1312         connection->state = HID_HOST_W4_CONTROL_CONNECTION_DISCONNECTED;
1313         l2cap_disconnect(connection->control_cid);
1314         return;
1315     }
1316 }
1317 
1318 
1319 static inline uint8_t hid_host_send_control_message(uint16_t hid_cid, uint8_t control_message_bitmask){
1320     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1321     if (!connection || !connection->control_cid) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1322 
1323     if (connection->state < HID_HOST_CONTROL_CONNECTION_ESTABLISHED) {
1324         return ERROR_CODE_COMMAND_DISALLOWED;
1325     }
1326     if (connection->state >= HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED){
1327         return ERROR_CODE_COMMAND_DISALLOWED;
1328     }
1329 
1330     connection->control_tasks |= control_message_bitmask;
1331     l2cap_request_can_send_now_event(connection->control_cid);
1332     return ERROR_CODE_SUCCESS;
1333 }
1334 
1335 uint8_t hid_host_send_suspend(uint16_t hid_cid){
1336     return hid_host_send_control_message(hid_cid, CONTROL_MESSAGE_BITMASK_SUSPEND);
1337 }
1338 
1339 uint8_t hid_host_send_exit_suspend(uint16_t hid_cid){
1340     return hid_host_send_control_message(hid_cid, CONTROL_MESSAGE_BITMASK_EXIT_SUSPEND);
1341 }
1342 
1343 uint8_t hid_host_send_virtual_cable_unplug(uint16_t hid_cid){
1344     return hid_host_send_control_message(hid_cid, CONTROL_MESSAGE_BITMASK_VIRTUAL_CABLE_UNPLUG);
1345 }
1346 
1347 uint8_t hid_host_send_get_report(uint16_t hid_cid,  hid_report_type_t report_type, uint8_t report_id){
1348     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1349 
1350     if (!connection || !connection->control_cid){
1351         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1352     }
1353     if (connection->state != HID_HOST_CONNECTION_ESTABLISHED){
1354         return ERROR_CODE_COMMAND_DISALLOWED;
1355     }
1356 
1357     connection->state = HID_HOST_W2_SEND_GET_REPORT;
1358     connection->report_type = report_type;
1359     connection->report_id = report_id;
1360 
1361     l2cap_request_can_send_now_event(connection->control_cid);
1362     return ERROR_CODE_SUCCESS;
1363 }
1364 
1365 uint8_t hid_host_send_set_report(uint16_t hid_cid, hid_report_type_t report_type, uint8_t report_id, const uint8_t * report, uint8_t report_len){
1366     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1367 
1368     if (!connection || !connection->control_cid){
1369         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1370     }
1371 
1372     if (connection->state != HID_HOST_CONNECTION_ESTABLISHED){
1373         return ERROR_CODE_COMMAND_DISALLOWED;
1374     }
1375 
1376     if ((l2cap_max_mtu() - 2) < report_len ){
1377         return ERROR_CODE_COMMAND_DISALLOWED;
1378     }
1379 
1380     connection->state = HID_HOST_W2_SEND_SET_REPORT;
1381     connection->report_type = report_type;
1382     connection->report_id = report_id;
1383     connection->report = report;
1384     connection->report_len = report_len;
1385 
1386     l2cap_request_can_send_now_event(connection->control_cid);
1387     return ERROR_CODE_SUCCESS;
1388 }
1389 
1390 uint8_t hid_host_send_get_protocol(uint16_t hid_cid){
1391     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1392     if (!connection || !connection->control_cid){
1393         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1394     }
1395     if (connection->state != HID_HOST_CONNECTION_ESTABLISHED){
1396         return ERROR_CODE_COMMAND_DISALLOWED;
1397     }
1398 
1399     connection->state = HID_HOST_W2_SEND_GET_PROTOCOL;
1400     l2cap_request_can_send_now_event(connection->control_cid);
1401     return ERROR_CODE_SUCCESS;
1402 }
1403 
1404 uint8_t hid_host_send_set_protocol_mode(uint16_t hid_cid, hid_protocol_mode_t protocol_mode){
1405     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1406     if (!connection || !connection->control_cid){
1407         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1408     }
1409     if (connection->state != HID_HOST_CONNECTION_ESTABLISHED || connection->set_protocol || connection->w4_set_protocol_response){
1410         return ERROR_CODE_COMMAND_DISALLOWED;
1411     }
1412 
1413     connection->set_protocol = true;
1414     connection->requested_protocol_mode = protocol_mode;
1415 
1416     l2cap_request_can_send_now_event(connection->control_cid);
1417     return ERROR_CODE_SUCCESS;
1418 }
1419 
1420 
1421 uint8_t hid_host_send_report(uint16_t hid_cid, uint8_t report_id, const uint8_t * report, uint8_t report_len){
1422     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1423     if (!connection || !connection->control_cid || !connection->interrupt_cid) {
1424         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1425     }
1426 
1427     if (connection->state < HID_HOST_CONNECTION_ESTABLISHED) {
1428         return ERROR_CODE_COMMAND_DISALLOWED;
1429     }
1430     if (connection->state >= HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED){
1431         return ERROR_CODE_COMMAND_DISALLOWED;
1432     }
1433 
1434     if ((l2cap_max_mtu() - 2) < report_len ){
1435         return ERROR_CODE_COMMAND_DISALLOWED;
1436     }
1437 
1438     connection->state = HID_HOST_W2_SEND_REPORT;
1439     connection->report_type = HID_REPORT_TYPE_OUTPUT;
1440     connection->report_id = report_id;
1441     connection->report = report;
1442     connection->report_len = report_len;
1443 
1444     l2cap_request_can_send_now_event(connection->interrupt_cid);
1445     return ERROR_CODE_SUCCESS;
1446 }
1447