xref: /btstack/src/classic/hid_host.c (revision 1744e196a49a984d365d175820c0dfc1b19ce6c7)
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(&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 uint16_t bytes_needed   = 0;
395     static uint16_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_COMPLETE:
453             // ignore data for non-string item
454             bytes_received++;
455             if (bytes_received == bytes_needed) {
456                 bytes_received = 0;
457                 state = HID_DESCRIPTOR_LIST_W4_ITEM_START;
458             }
459             break;
460         case HID_DESCRIPTOR_LIST_W4_ITEM_START:
461             hid_host_sdp_attribute_value[bytes_received++] = data;
462             if (de_get_element_type(hid_host_sdp_attribute_value) == DE_STRING){
463                 bytes_needed = de_get_header_size(hid_host_sdp_attribute_value);
464                 state = HID_DESCRIPTOR_LIST_W4_STRING_HEADER;
465             } else {
466                 bytes_needed = de_get_header_size(hid_host_sdp_attribute_value);
467                 if (bytes_needed > 1){
468                     state = HID_DESCRIPTOR_LIST_W4_ITEM_HEADER;
469                 } else {
470                     bytes_needed = de_get_len(hid_host_sdp_attribute_value);
471                     state = HID_DESCRIPTOR_LIST_W4_ITEM_COMPLETE;
472                 }
473             }
474             break;
475         case HID_DESCRIPTOR_LIST_W4_ITEM_HEADER:
476             hid_host_sdp_attribute_value[bytes_received++] = data;
477             if (bytes_received == bytes_needed) {
478                 bytes_needed = de_get_len(hid_host_sdp_attribute_value);
479                 state = HID_DESCRIPTOR_LIST_W4_ITEM_COMPLETE;
480             }
481             break;
482         case HID_DESCRIPTOR_LIST_W4_STRING_HEADER:
483             hid_host_sdp_attribute_value[bytes_received++] = data;
484             if (bytes_received == bytes_needed) {
485                 bytes_received = 0;
486                 bytes_needed = de_get_data_size(hid_host_sdp_attribute_value);
487                 state = HID_DESCRIPTOR_LIST_W4_STRING_COMPLETE;
488             }
489             break;
490         case HID_DESCRIPTOR_LIST_W4_STRING_COMPLETE:
491             stored = hid_descriptor_storage_store(connection, data);
492             if (stored) {
493                 bytes_received++;
494                 if (bytes_received == bytes_needed) {
495                     connection->hid_descriptor_status = ERROR_CODE_SUCCESS;
496                     log_info_hexdump(&hid_host_descriptor_storage[connection->hid_descriptor_offset],
497                                      connection->hid_descriptor_len);
498                     state = HID_DESCRIPTOR_LIST_COMPLETE;
499                 }
500             } else {
501                 error = true;
502             }
503             break;
504         case HID_DESCRIPTOR_LIST_ERROR:
505         case HID_DESCRIPTOR_LIST_COMPLETE:
506             // ignore data
507             break;
508         default:
509             btstack_unreachable();
510             break;
511     }
512 
513     if (error){
514         log_info("Descriptor List invalid, state %u", (int) state);
515         bytes_received = 0;
516         bytes_needed   = 0;
517         state = HID_DESCRIPTOR_LIST_ERROR;
518         connection->hid_descriptor_status = ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
519     }
520 }
521 
522 static void hid_host_handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
523     UNUSED(packet_type);
524     UNUSED(channel);
525     UNUSED(size);
526 
527     des_iterator_t attribute_list_it;
528     des_iterator_t additional_des_it;
529     des_iterator_t prot_it;
530     uint8_t       *des_element;
531     uint8_t       *element;
532     uint32_t       uuid;
533     uint8_t        status = ERROR_CODE_SUCCESS;
534     bool try_fallback_to_boot;
535     bool finalize_connection;
536 
537 
538     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_host_sdp_context_control_cid);
539     if (!connection) {
540         log_error("SDP query, connection with 0x%02x cid not found", hid_host_sdp_context_control_cid);
541         return;
542     }
543 
544     btstack_assert(connection->state == HID_HOST_W4_SDP_QUERY_RESULT);
545 
546     uint16_t  attribute_id;
547     uint16_t  attribute_offset;
548     uint8_t   attribute_data;
549     switch (hci_event_packet_get_type(packet)){
550         case SDP_EVENT_QUERY_ATTRIBUTE_VALUE:
551 
552             attribute_id = sdp_event_query_attribute_byte_get_attribute_id(packet);
553             attribute_offset = sdp_event_query_attribute_byte_get_data_offset(packet);
554             attribute_data = sdp_event_query_attribute_byte_get_data(packet);
555 
556             // process BLUETOOTH_ATTRIBUTE_HID_DESCRIPTOR_LIST with state machine
557             if (attribute_id == BLUETOOTH_ATTRIBUTE_HID_DESCRIPTOR_LIST){
558                 hid_host_handle_sdp_hid_descriptor_list(connection, attribute_offset, attribute_data);
559                 break;
560             }
561 
562             if (sdp_event_query_attribute_byte_get_attribute_length(packet) <= hid_host_sdp_attribute_value_buffer_size) {
563 
564                 hid_host_sdp_attribute_value[attribute_offset] = attribute_data;
565 
566                 if ((uint16_t)(attribute_offset + 1) == sdp_event_query_attribute_byte_get_attribute_length(packet)) {
567                     switch(attribute_id) {
568 
569                         case BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST:
570                             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)) {
571                                 if (des_iterator_get_type(&attribute_list_it) != DE_DES) continue;
572                                 des_element = des_iterator_get_element(&attribute_list_it);
573                                 des_iterator_init(&prot_it, des_element);
574                                 element = des_iterator_get_element(&prot_it);
575                                 if (de_get_element_type(element) != DE_UUID) continue;
576                                 uuid = de_get_uuid32(element);
577                                 switch (uuid){
578                                     case BLUETOOTH_PROTOCOL_L2CAP:
579                                         if (!des_iterator_has_more(&prot_it)) continue;
580                                         des_iterator_next(&prot_it);
581                                         de_element_get_uint16(des_iterator_get_element(&prot_it), &connection->control_psm);
582                                         log_info("HID Control PSM: 0x%04x", connection->control_psm);
583                                         break;
584                                     default:
585                                         break;
586                                 }
587                             }
588                             break;
589                         case BLUETOOTH_ATTRIBUTE_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS:
590                             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)) {
591                                 if (des_iterator_get_type(&attribute_list_it) != DE_DES) continue;
592                                 des_element = des_iterator_get_element(&attribute_list_it);
593                                 for (des_iterator_init(&additional_des_it, des_element); des_iterator_has_more(&additional_des_it); des_iterator_next(&additional_des_it)) {
594                                     if (des_iterator_get_type(&additional_des_it) != DE_DES) continue;
595                                     des_element = des_iterator_get_element(&additional_des_it);
596                                     des_iterator_init(&prot_it, des_element);
597                                     element = des_iterator_get_element(&prot_it);
598                                     if (de_get_element_type(element) != DE_UUID) continue;
599                                     uuid = de_get_uuid32(element);
600                                     switch (uuid){
601                                         case BLUETOOTH_PROTOCOL_L2CAP:
602                                             if (!des_iterator_has_more(&prot_it)) continue;
603                                             des_iterator_next(&prot_it);
604                                             de_element_get_uint16(des_iterator_get_element(&prot_it), &connection->interrupt_psm);
605                                             log_info("HID Interrupt PSM: 0x%04x", connection->interrupt_psm);
606                                             break;
607                                         default:
608                                             break;
609                                     }
610                                 }
611                             }
612                             break;
613 
614                         case BLUETOOTH_ATTRIBUTE_HIDSSR_HOST_MAX_LATENCY:
615                             if (de_get_element_type(hid_host_sdp_attribute_value) == DE_UINT) {
616                                 uint16_t host_max_latency;
617                                 if (de_element_get_uint16(hid_host_sdp_attribute_value, &host_max_latency) == 1){
618                                     connection->host_max_latency = host_max_latency;
619                                 } else {
620                                     connection->host_max_latency = 0xFFFF;
621                                 }
622                             }
623                             break;
624 
625                         case BLUETOOTH_ATTRIBUTE_HIDSSR_HOST_MIN_TIMEOUT:
626                             if (de_get_element_type(hid_host_sdp_attribute_value) == DE_UINT) {
627                                 uint16_t host_min_timeout;
628                                 if (de_element_get_uint16(hid_host_sdp_attribute_value, &host_min_timeout) == 1){
629                                     connection->host_min_timeout = host_min_timeout;
630                                 } else {
631                                     connection->host_min_timeout = 0xFFFF;
632                                 }
633                             }
634                             break;
635 
636                         default:
637                             break;
638                     }
639                 }
640             } else {
641                 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));
642             }
643             break;
644 
645         case SDP_EVENT_QUERY_COMPLETE:
646             status = sdp_event_query_complete_get_status(packet);
647             try_fallback_to_boot = false;
648             finalize_connection = false;
649 
650             switch (status){
651                 // remote has SDP server
652                 case ERROR_CODE_SUCCESS:
653                     //  but no HID record
654                     if (!connection->control_psm || !connection->interrupt_psm) {
655                         status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
656                         if (connection->requested_protocol_mode == HID_PROTOCOL_MODE_REPORT_WITH_FALLBACK_TO_BOOT){
657                             try_fallback_to_boot = true;
658                         } else {
659                             finalize_connection = true;
660                         }
661                         break;
662                     }
663                     // report mode possible
664                     break;
665 
666                 // SDP connection failed or remote does not have SDP server
667                 default:
668                     if (connection->requested_protocol_mode == HID_PROTOCOL_MODE_REPORT_WITH_FALLBACK_TO_BOOT){
669                         try_fallback_to_boot = true;
670                     } else {
671                         finalize_connection = true;
672                     }
673                     break;
674             }
675 
676             if (finalize_connection){
677                 hid_host_sdp_context_control_cid = 0;
678                 hid_emit_connected_event(connection, status);
679                 hid_host_finalize_connection(connection);
680                 break;
681             }
682 
683             hid_emit_sniff_params_event(connection);
684 
685             if (try_fallback_to_boot){
686                 if (connection->incoming){
687                     connection->set_protocol = true;
688                     connection->state = HID_HOST_CONNECTION_ESTABLISHED;
689                     connection->requested_protocol_mode = HID_PROTOCOL_MODE_BOOT;
690                     hid_emit_descriptor_available_event(connection);
691                     l2cap_request_can_send_now_event(connection->control_cid);
692                 } else {
693                     connection->state = HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED;
694                     status = l2cap_create_channel(hid_host_packet_handler, connection->remote_addr, BLUETOOTH_PSM_HID_CONTROL, 0xffff, &connection->control_cid);
695                     if (status != ERROR_CODE_SUCCESS){
696                         hid_host_sdp_context_control_cid = 0;
697                         hid_emit_connected_event(connection, status);
698                         hid_host_finalize_connection(connection);
699                     }
700                 }
701                 break;
702             }
703 
704             // report mode possible
705             if (connection->incoming) {
706                 connection->set_protocol = true;
707                 connection->state = HID_HOST_CONNECTION_ESTABLISHED;
708                 connection->requested_protocol_mode = HID_PROTOCOL_MODE_REPORT;
709                 hid_emit_descriptor_available_event(connection);
710                 l2cap_request_can_send_now_event(connection->control_cid);
711             } else {
712                 connection->state = HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED;
713                 status = l2cap_create_channel(hid_host_packet_handler, connection->remote_addr, connection->control_psm, 0xffff, &connection->control_cid);
714                 if (status != ERROR_CODE_SUCCESS){
715                     hid_emit_connected_event(connection, status);
716                     hid_host_finalize_connection(connection);
717                 }
718             }
719             break;
720 
721         default:
722             break;
723     }
724 
725 }
726 
727 
728 static void hid_host_handle_control_packet(hid_host_connection_t * connection, uint8_t *packet, uint16_t size){
729     UNUSED(size);
730     uint8_t param;
731     hid_message_type_t         message_type;
732     hid_handshake_param_type_t message_status;
733     hid_protocol_mode_t        protocol_mode;
734 
735     uint8_t * in_place_event;
736     uint8_t status;
737 
738     message_type   = (hid_message_type_t)(packet[0] >> 4);
739     if (message_type == HID_MESSAGE_TYPE_HID_CONTROL){
740         param = packet[0] & 0x0F;
741         switch ((hid_control_param_t)param){
742             case HID_CONTROL_PARAM_VIRTUAL_CABLE_UNPLUG:
743                 hid_emit_event(connection, HID_SUBEVENT_VIRTUAL_CABLE_UNPLUG);
744                 hid_host_disconnect(connection->hid_cid);
745                 return;
746             default:
747                 break;
748         }
749     }
750 
751     message_status = (hid_handshake_param_type_t)(packet[0] & 0x0F);
752 
753     switch (connection->state){
754         case HID_HOST_CONNECTION_ESTABLISHED:
755             if (!connection->w4_set_protocol_response) break;
756             connection->w4_set_protocol_response = false;
757 
758             switch (message_status){
759                 case HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL:
760                     connection->protocol_mode = connection->requested_protocol_mode;
761                     break;
762                 default:
763                     break;
764             }
765             hid_emit_set_protocol_response_event(connection, message_status);
766             break;
767 
768         case HID_HOST_CONTROL_CONNECTION_ESTABLISHED:           // outgoing
769         case HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED:      // outgoing
770             if (!connection->w4_set_protocol_response) break;
771             connection->w4_set_protocol_response = false;
772 
773             switch (message_status){
774                 case HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL:
775                     // we are already connected, here it is only confirmed that we are in required protocol
776                     btstack_assert(connection->incoming == false);
777                     status = l2cap_create_channel(hid_host_packet_handler, connection->remote_addr, connection->interrupt_psm, 0xffff, &connection->interrupt_cid);
778                     if (status != ERROR_CODE_SUCCESS){
779                         log_info("HID Interrupt Connection failed: 0x%02x\n", status);
780                         hid_emit_connected_event(connection, status);
781                         hid_host_finalize_connection(connection);
782                         break;
783                     }
784                     connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED;
785                     break;
786                 default:
787                     hid_emit_connected_event(connection, ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
788                     hid_host_finalize_connection(connection);
789                     break;
790             }
791             break;
792 
793         case HID_HOST_W4_GET_REPORT_RESPONSE:
794             switch (message_type){
795                 case HID_MESSAGE_TYPE_HANDSHAKE:{
796                     uint8_t event[8];
797                     hid_setup_get_report_event(connection, message_status, event, 0);
798                     hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, event, sizeof(event));
799                     break;
800                 }
801                 case HID_MESSAGE_TYPE_DATA:
802                     // reuse hci+l2cap header - max 8 byte (7 bytes + 1 bytes overwriting hid header)
803                     in_place_event = packet - 7;
804                     hid_setup_get_report_event(connection, HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL, in_place_event, size-1);
805                     hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, in_place_event, size + 7);
806                     break;
807                 default:
808                     break;
809             }
810             connection->state =  HID_HOST_CONNECTION_ESTABLISHED;
811             break;
812 
813         case HID_HOST_W4_SET_REPORT_RESPONSE:
814             hid_emit_event_with_status(connection, HID_SUBEVENT_SET_REPORT_RESPONSE, message_status);
815             connection->state =  HID_HOST_CONNECTION_ESTABLISHED;
816             break;
817 
818         case HID_HOST_W4_GET_PROTOCOL_RESPONSE:
819             protocol_mode = connection->protocol_mode;
820 
821             switch (message_type){
822                 case HID_MESSAGE_TYPE_DATA:
823                     protocol_mode = (hid_protocol_mode_t)packet[1];
824                     switch (protocol_mode){
825                         case HID_PROTOCOL_MODE_BOOT:
826                         case HID_PROTOCOL_MODE_REPORT:
827                             message_status = HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL;
828                             break;
829                         default:
830                             message_status = HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER;
831                             break;
832                     }
833                     break;
834                 default:
835                     break;
836             }
837             hid_emit_get_protocol_event(connection, message_status, protocol_mode);
838             connection->state =  HID_HOST_CONNECTION_ESTABLISHED;
839             break;
840 
841         default:
842             log_info("ignore invalid HID Control message");
843             connection->state =  HID_HOST_CONNECTION_ESTABLISHED;
844             break;
845     }
846 
847 }
848 
849 static void hid_host_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
850     UNUSED(channel);
851     UNUSED(size);
852 
853     uint8_t   event;
854     bd_addr_t address;
855     uint8_t   status;
856     uint16_t  l2cap_cid;
857     hid_host_connection_t * connection;
858 
859     switch (packet_type) {
860 
861         case L2CAP_DATA_PACKET:
862             connection = hid_host_get_connection_for_l2cap_cid(channel);
863             if (!connection) break;
864 
865             if (channel == connection->interrupt_cid){
866                 uint8_t * in_place_event = packet - 7;
867                 hid_setup_report_event(connection, in_place_event, size-1);
868                 hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, in_place_event, size + 7);
869                 break;
870             }
871 
872             if (channel == connection->control_cid){
873                 hid_host_handle_control_packet(connection, packet, size);
874                 break;
875             }
876             break;
877 
878         case HCI_EVENT_PACKET:
879             event = hci_event_packet_get_type(packet);
880             switch (event) {
881                 case L2CAP_EVENT_INCOMING_CONNECTION:
882                     l2cap_event_incoming_connection_get_address(packet, address);
883                     // connection should exist if psm == PSM_HID_INTERRUPT
884                     connection = hid_host_get_connection_for_bd_addr(address);
885 
886                     switch (l2cap_event_incoming_connection_get_psm(packet)){
887                         case PSM_HID_CONTROL:
888                             if (connection){
889                                 l2cap_decline_connection(channel);
890                                 break;
891                             }
892 
893                             connection = hid_host_create_connection(address);
894                             if (!connection){
895                                 log_error("Cannot create connection for %s", bd_addr_to_str(address));
896                                 l2cap_decline_connection(channel);
897                                 break;
898                             }
899 
900                             connection->state = HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED;
901                             connection->hid_descriptor_status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
902                             connection->con_handle = l2cap_event_incoming_connection_get_handle(packet);
903                             connection->control_cid = l2cap_event_incoming_connection_get_local_cid(packet);
904                             connection->incoming = true;
905 
906                             // emit connection request
907                             // user calls either hid_host_accept_connection or hid_host_decline_connection
908                             hid_emit_incoming_connection_event(connection);
909                             break;
910 
911                         case PSM_HID_INTERRUPT:
912                             if (!connection || (connection->state != HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED)){
913                                 log_error("Decline connection for %s", bd_addr_to_str(address));
914                                 l2cap_decline_connection(channel);
915                                 break;
916                             }
917 
918                             connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED;
919                             connection->interrupt_cid = l2cap_event_incoming_connection_get_local_cid(packet);
920                             log_info("Accept connection on Interrupt channel %s", bd_addr_to_str(address));
921                             l2cap_accept_connection(channel);
922                             break;
923 
924                         default:
925                             log_info("Decline connection for %s", bd_addr_to_str(address));
926                             l2cap_decline_connection(channel);
927                             break;
928                     }
929                     break;
930 
931                 case L2CAP_EVENT_CHANNEL_OPENED:
932                     l2cap_event_channel_opened_get_address(packet, address);
933 
934                     connection = hid_host_get_connection_for_bd_addr(address);
935                     if (!connection){
936                         log_error("Connection does not exist %s", bd_addr_to_str(address));
937                         break;
938                     }
939 
940                     status = l2cap_event_channel_opened_get_status(packet);
941                     if (status != ERROR_CODE_SUCCESS){
942                         log_info("L2CAP connection %s failed: 0x%02xn", bd_addr_to_str(address), status);
943                         hid_emit_connected_event(connection, status);
944                         hid_host_finalize_connection(connection);
945                         break;
946                     }
947 
948                     // handle incoming connection:
949                     if (connection->incoming){
950                         switch (connection->state){
951                             case HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED:
952                                 // 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)
953                                 // We expect incomming interrupt connection from remote HID device
954                                 connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED;
955                                 log_info("Incoming control connection opened: w4 interrupt");
956                                 break;
957 
958                             case HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED:
959                                 hid_emit_connected_event(connection, ERROR_CODE_SUCCESS);
960                                 connection->state = HID_HOST_CONNECTION_ESTABLISHED;
961 
962                                 switch (connection->requested_protocol_mode){
963                                     case HID_PROTOCOL_MODE_BOOT:
964                                         hid_emit_descriptor_available_event(connection);
965                                         connection->set_protocol = true;
966                                         l2cap_request_can_send_now_event(connection->control_cid);
967                                         log_info("Incoming interrupt connection opened: set boot mode");
968                                         break;
969                                     default:
970                                         // SDP query
971                                         log_info("Incoming interrupt connection opened: start SDP query");
972                                         connection->state = HID_HOST_W2_SEND_SDP_QUERY;
973                                         hid_host_handle_sdp_client_query_request.callback = &hid_host_handle_start_sdp_client_query;
974                                         (void) sdp_client_register_query_callback(&hid_host_handle_sdp_client_query_request);
975                                         break;
976                                 }
977                                 break;
978 
979                             default:
980                                 btstack_assert(false);
981                                 break;
982                         }
983                         break;
984                     }
985 
986                     // handle outgoing connection
987                     switch (connection->state){
988                         case HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED:
989                             log_info("Opened control connection, requested protocol mode %d\n", connection->requested_protocol_mode);
990                             connection->con_handle = l2cap_event_channel_opened_get_handle(packet);
991                             connection->state = HID_HOST_CONTROL_CONNECTION_ESTABLISHED;
992 
993                             switch (connection->requested_protocol_mode){
994                                 case HID_PROTOCOL_MODE_BOOT:
995                                 case HID_PROTOCOL_MODE_REPORT_WITH_FALLBACK_TO_BOOT:
996                                     connection->set_protocol = true;
997                                     connection->interrupt_psm = BLUETOOTH_PSM_HID_INTERRUPT;
998                                     l2cap_request_can_send_now_event(connection->control_cid);
999                                     break;
1000                                 default:
1001                                     status = l2cap_create_channel(hid_host_packet_handler, address, connection->interrupt_psm, 0xffff, &connection->interrupt_cid);
1002                                     if (status){
1003                                         log_info("Connecting to HID Interrupt failed: 0x%02x", status);
1004                                         hid_emit_connected_event(connection, status);
1005                                         break;
1006                                     }
1007                                     connection->protocol_mode = connection->requested_protocol_mode;
1008                                     connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED;
1009                                     break;
1010                             }
1011                             break;
1012 
1013                         case HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED:
1014                             connection->state = HID_HOST_CONNECTION_ESTABLISHED;
1015                             log_info("HID host connection established, cids: control 0x%02x, interrupt 0x%02x interrupt, hid 0x%02x",
1016                                 connection->control_cid, connection->interrupt_cid, connection->hid_cid);
1017                             hid_emit_connected_event(connection, ERROR_CODE_SUCCESS);
1018                             hid_emit_descriptor_available_event(connection);
1019                             break;
1020 
1021                         default:
1022                             btstack_assert(false);
1023                             break;
1024                     }
1025                     break;
1026 
1027                 case L2CAP_EVENT_CHANNEL_CLOSED:
1028                     l2cap_cid  = l2cap_event_channel_closed_get_local_cid(packet);
1029                     connection = hid_host_get_connection_for_l2cap_cid(l2cap_cid);
1030                     if (!connection) return;
1031 
1032                     if (l2cap_cid == connection->interrupt_cid){
1033                         connection->interrupt_cid = 0;
1034                         if (connection->state == HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED){
1035                             connection->state = HID_HOST_W4_CONTROL_CONNECTION_DISCONNECTED;
1036                             l2cap_disconnect(connection->control_cid);
1037                         }
1038                         break;
1039                     }
1040 
1041                     if (l2cap_cid == connection->control_cid){
1042                         connection->control_cid = 0;
1043                         hid_emit_event(connection, HID_SUBEVENT_CONNECTION_CLOSED);
1044                         hid_descriptor_storage_delete(connection);
1045                         hid_host_finalize_connection(connection);
1046                         break;
1047                     }
1048                     break;
1049 
1050                 case L2CAP_EVENT_CAN_SEND_NOW:
1051                     l2cap_cid  = l2cap_event_can_send_now_get_local_cid(packet);
1052                     connection = hid_host_get_connection_for_l2cap_cid(l2cap_cid);
1053                     if (!connection) return;
1054 
1055 
1056 
1057                     if (connection->control_cid == l2cap_cid){
1058                         switch(connection->state){
1059                             case HID_HOST_CONTROL_CONNECTION_ESTABLISHED:
1060                             case HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED:
1061                                 if (connection->set_protocol){
1062                                     connection->set_protocol = false;
1063                                     uint8_t protocol_mode = connection->requested_protocol_mode == HID_PROTOCOL_MODE_BOOT ? 0 : 1;
1064                                     uint8_t header = (HID_MESSAGE_TYPE_SET_PROTOCOL << 4) | protocol_mode;
1065                                     uint8_t report[] = {header};
1066                                     connection->w4_set_protocol_response = true;
1067                                     l2cap_send(connection->control_cid, (uint8_t*) report, sizeof(report));
1068                                     break;
1069                                 }
1070                                 break;
1071 
1072                             case HID_HOST_CONNECTION_ESTABLISHED:
1073                                 if ((connection->control_tasks & CONTROL_MESSAGE_BITMASK_SUSPEND) != 0){
1074                                     connection->control_tasks &= ~CONTROL_MESSAGE_BITMASK_SUSPEND;
1075                                     uint8_t report[] = { (HID_MESSAGE_TYPE_HID_CONTROL << 4) | HID_CONTROL_PARAM_SUSPEND };
1076                                     l2cap_send(connection->control_cid, (uint8_t*) report, 1);
1077                                     break;
1078                                 }
1079                                 if ((connection->control_tasks & CONTROL_MESSAGE_BITMASK_EXIT_SUSPEND) != 0){
1080                                     connection->control_tasks &= ~CONTROL_MESSAGE_BITMASK_EXIT_SUSPEND;
1081                                     uint8_t report[] = { (HID_MESSAGE_TYPE_HID_CONTROL << 4) | HID_CONTROL_PARAM_EXIT_SUSPEND };
1082                                     l2cap_send(connection->control_cid, (uint8_t*) report, 1);
1083                                     break;
1084                                 }
1085                                 if ((connection->control_tasks & CONTROL_MESSAGE_BITMASK_VIRTUAL_CABLE_UNPLUG) != 0){
1086                                     connection->control_tasks &= ~CONTROL_MESSAGE_BITMASK_VIRTUAL_CABLE_UNPLUG;
1087                                     uint8_t report[] = { (HID_MESSAGE_TYPE_HID_CONTROL << 4) | HID_CONTROL_PARAM_VIRTUAL_CABLE_UNPLUG };
1088                                     l2cap_send(connection->control_cid, (uint8_t*) report, 1);
1089                                     break;
1090                                 }
1091 
1092                                 if (connection->set_protocol){
1093                                     connection->set_protocol = false;
1094                                     uint8_t header = (HID_MESSAGE_TYPE_SET_PROTOCOL << 4) | connection->requested_protocol_mode;
1095                                     uint8_t report[] = {header};
1096 
1097                                     connection->w4_set_protocol_response = true;
1098                                     l2cap_send(connection->control_cid, (uint8_t*) report, sizeof(report));
1099                                     break;
1100                                 }
1101                                 break;
1102 
1103                             case HID_HOST_W2_SEND_GET_REPORT:{
1104                                 uint8_t header = (HID_MESSAGE_TYPE_GET_REPORT << 4) | connection->report_type;
1105                                 uint8_t report[] = {header, connection->report_id};
1106 
1107                                 connection->state = HID_HOST_W4_GET_REPORT_RESPONSE;
1108                                 l2cap_send(connection->control_cid, (uint8_t*) report, sizeof(report));
1109                                 break;
1110                             }
1111 
1112                             case HID_HOST_W2_SEND_SET_REPORT:{
1113                                 uint8_t header = (HID_MESSAGE_TYPE_SET_REPORT << 4) | connection->report_type;
1114                                 connection->state = HID_HOST_W4_SET_REPORT_RESPONSE;
1115 
1116                                 l2cap_reserve_packet_buffer();
1117                                 uint8_t * out_buffer = l2cap_get_outgoing_buffer();
1118                                 out_buffer[0] = header;
1119                                 out_buffer[1] = connection->report_id;
1120                                 (void)memcpy(out_buffer + 2, connection->report, connection->report_len);
1121                                 l2cap_send_prepared(connection->control_cid, connection->report_len + 2);
1122                                 break;
1123                             }
1124 
1125                             case HID_HOST_W2_SEND_GET_PROTOCOL:{
1126                                 uint8_t header = (HID_MESSAGE_TYPE_GET_PROTOCOL << 4);
1127                                 uint8_t report[] = {header};
1128                                 connection->state = HID_HOST_W4_GET_PROTOCOL_RESPONSE;
1129                                 l2cap_send(connection->control_cid, (uint8_t*) report, sizeof(report));
1130                                 break;
1131                             }
1132 
1133                             default:
1134                                 break;
1135                         }
1136                     }
1137 
1138                     if (connection->interrupt_cid == l2cap_cid && connection->state == HID_HOST_W2_SEND_REPORT){
1139                         connection->state = HID_HOST_CONNECTION_ESTABLISHED;
1140                         // there is no response for this type of message
1141                         uint8_t header = (HID_MESSAGE_TYPE_DATA << 4) | connection->report_type;
1142 
1143                         l2cap_reserve_packet_buffer();
1144                         uint8_t * out_buffer = l2cap_get_outgoing_buffer();
1145                         out_buffer[0] = header;
1146                         out_buffer[1] = connection->report_id;
1147                         (void)memcpy(out_buffer + 2, connection->report, connection->report_len);
1148                         l2cap_send_prepared(connection->interrupt_cid, connection->report_len + 2);
1149                         break;
1150                     }
1151 
1152                     if (connection->control_tasks != 0){
1153                         l2cap_request_can_send_now_event(connection->control_cid);
1154                     }
1155                     break;
1156                 default:
1157                     break;
1158             }
1159         default:
1160             break;
1161     }
1162 }
1163 
1164 
1165 void hid_host_init(uint8_t * hid_descriptor_storage, uint16_t hid_descriptor_storage_len){
1166     hid_host_descriptor_storage = hid_descriptor_storage;
1167     hid_host_descriptor_storage_len = hid_descriptor_storage_len;
1168 
1169     // register L2CAP Services for reconnections
1170     l2cap_register_service(hid_host_packet_handler, PSM_HID_INTERRUPT, 0xffff, gap_get_security_level());
1171     l2cap_register_service(hid_host_packet_handler, PSM_HID_CONTROL, 0xffff, gap_get_security_level());
1172 }
1173 
1174 void hid_host_deinit(void){
1175     hid_host_callback = NULL;
1176     hid_host_descriptor_storage = NULL;
1177     hid_host_sdp_context_control_cid = 0;
1178     hid_host_connections = NULL;
1179     hid_host_cid_counter = 0;
1180     (void) memset(&hid_host_handle_sdp_client_query_request, 0, sizeof(hid_host_handle_sdp_client_query_request));
1181 }
1182 
1183 void hid_host_register_packet_handler(btstack_packet_handler_t callback){
1184     hid_host_callback = callback;
1185 }
1186 
1187 static void hid_host_handle_start_sdp_client_query(void * context){
1188     UNUSED(context);
1189     btstack_linked_list_iterator_t it;
1190     btstack_linked_list_iterator_init(&it, &hid_host_connections);
1191 
1192     while (btstack_linked_list_iterator_has_next(&it)){
1193         hid_host_connection_t * connection = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it);
1194 
1195         switch (connection->state){
1196             case HID_HOST_W2_SEND_SDP_QUERY:
1197                 connection->state = HID_HOST_W4_SDP_QUERY_RESULT;
1198                 connection->hid_descriptor_status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1199                 break;
1200             default:
1201                 continue;
1202         }
1203 
1204         hid_descriptor_storage_init(connection);
1205         hid_host_sdp_context_control_cid = connection->hid_cid;
1206         sdp_client_query_uuid16(&hid_host_handle_sdp_client_query_result, (uint8_t *) connection->remote_addr, BLUETOOTH_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE_SERVICE);
1207         return;
1208     }
1209 }
1210 
1211 uint8_t hid_host_accept_connection(uint16_t hid_cid, hid_protocol_mode_t protocol_mode){
1212     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1213     if (!connection){
1214         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1215     }
1216     if (connection->state != HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED){
1217         return ERROR_CODE_COMMAND_DISALLOWED;
1218     }
1219 
1220     connection->requested_protocol_mode = protocol_mode;
1221     l2cap_accept_connection(connection->control_cid);
1222     return ERROR_CODE_SUCCESS;
1223 }
1224 
1225 uint8_t hid_host_decline_connection(uint16_t hid_cid){
1226     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1227     if (!connection){
1228         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1229     }
1230     if (connection->state != HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED){
1231         return ERROR_CODE_COMMAND_DISALLOWED;
1232     }
1233 
1234     l2cap_decline_connection(connection->control_cid);
1235     hid_host_finalize_connection(connection);
1236     return ERROR_CODE_SUCCESS;
1237 }
1238 
1239 uint8_t hid_host_connect(bd_addr_t remote_addr, hid_protocol_mode_t protocol_mode, uint16_t * hid_cid){
1240     if (hid_cid == NULL) {
1241         return ERROR_CODE_COMMAND_DISALLOWED;
1242     }
1243 
1244     hid_host_connection_t * connection = hid_host_get_connection_for_bd_addr(remote_addr);
1245     if (connection){
1246         return ERROR_CODE_COMMAND_DISALLOWED;
1247     }
1248 
1249     connection = hid_host_create_connection(remote_addr);
1250     if (!connection) return BTSTACK_MEMORY_ALLOC_FAILED;
1251 
1252     *hid_cid = connection->hid_cid;
1253 
1254     connection->state = HID_HOST_W2_SEND_SDP_QUERY;
1255     connection->incoming = false;
1256     connection->requested_protocol_mode = protocol_mode;
1257     connection->hid_descriptor_status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1258 
1259     uint8_t status = ERROR_CODE_SUCCESS;
1260 
1261     switch (connection->requested_protocol_mode){
1262         case HID_PROTOCOL_MODE_BOOT:
1263             connection->state = HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED;
1264             status = l2cap_create_channel(hid_host_packet_handler, connection->remote_addr, BLUETOOTH_PSM_HID_CONTROL, 0xffff, &connection->control_cid);
1265             break;
1266         default:
1267             hid_host_handle_sdp_client_query_request.callback = &hid_host_handle_start_sdp_client_query;
1268             // ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback
1269             (void) sdp_client_register_query_callback(&hid_host_handle_sdp_client_query_request);
1270             break;
1271     }
1272     return status;
1273 }
1274 
1275 
1276 void hid_host_disconnect(uint16_t hid_cid){
1277     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1278     if (!connection) return;
1279 
1280     switch (connection->state){
1281         case HID_HOST_IDLE:
1282         case HID_HOST_W4_CONTROL_CONNECTION_DISCONNECTED:
1283         case HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED:
1284             return;
1285         default:
1286             break;
1287     }
1288 
1289     if (connection->interrupt_cid){
1290         connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED;
1291         l2cap_disconnect(connection->interrupt_cid);
1292         return;
1293     }
1294 
1295     if (connection->control_cid){
1296         connection->state = HID_HOST_W4_CONTROL_CONNECTION_DISCONNECTED;
1297         l2cap_disconnect(connection->control_cid);
1298         return;
1299     }
1300 }
1301 
1302 
1303 static inline uint8_t hid_host_send_control_message(uint16_t hid_cid, uint8_t control_message_bitmask){
1304     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1305     if (!connection || !connection->control_cid) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1306 
1307     if (connection->state < HID_HOST_CONTROL_CONNECTION_ESTABLISHED) {
1308         return ERROR_CODE_COMMAND_DISALLOWED;
1309     }
1310     if (connection->state >= HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED){
1311         return ERROR_CODE_COMMAND_DISALLOWED;
1312     }
1313 
1314     connection->control_tasks |= control_message_bitmask;
1315     l2cap_request_can_send_now_event(connection->control_cid);
1316     return ERROR_CODE_SUCCESS;
1317 }
1318 
1319 uint8_t hid_host_send_suspend(uint16_t hid_cid){
1320     return hid_host_send_control_message(hid_cid, CONTROL_MESSAGE_BITMASK_SUSPEND);
1321 }
1322 
1323 uint8_t hid_host_send_exit_suspend(uint16_t hid_cid){
1324     return hid_host_send_control_message(hid_cid, CONTROL_MESSAGE_BITMASK_EXIT_SUSPEND);
1325 }
1326 
1327 uint8_t hid_host_send_virtual_cable_unplug(uint16_t hid_cid){
1328     return hid_host_send_control_message(hid_cid, CONTROL_MESSAGE_BITMASK_VIRTUAL_CABLE_UNPLUG);
1329 }
1330 
1331 uint8_t hid_host_send_get_report(uint16_t hid_cid,  hid_report_type_t report_type, uint8_t report_id){
1332     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1333 
1334     if (!connection || !connection->control_cid){
1335         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1336     }
1337     if (connection->state != HID_HOST_CONNECTION_ESTABLISHED){
1338         return ERROR_CODE_COMMAND_DISALLOWED;
1339     }
1340 
1341     connection->state = HID_HOST_W2_SEND_GET_REPORT;
1342     connection->report_type = report_type;
1343     connection->report_id = report_id;
1344 
1345     l2cap_request_can_send_now_event(connection->control_cid);
1346     return ERROR_CODE_SUCCESS;
1347 }
1348 
1349 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){
1350     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1351 
1352     if (!connection || !connection->control_cid){
1353         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1354     }
1355 
1356     if (connection->state != HID_HOST_CONNECTION_ESTABLISHED){
1357         return ERROR_CODE_COMMAND_DISALLOWED;
1358     }
1359 
1360     if ((l2cap_max_mtu() - 2) < report_len ){
1361         return ERROR_CODE_COMMAND_DISALLOWED;
1362     }
1363 
1364     connection->state = HID_HOST_W2_SEND_SET_REPORT;
1365     connection->report_type = report_type;
1366     connection->report_id = report_id;
1367     connection->report = report;
1368     connection->report_len = report_len;
1369 
1370     l2cap_request_can_send_now_event(connection->control_cid);
1371     return ERROR_CODE_SUCCESS;
1372 }
1373 
1374 uint8_t hid_host_send_get_protocol(uint16_t hid_cid){
1375     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1376     if (!connection || !connection->control_cid){
1377         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1378     }
1379     if (connection->state != HID_HOST_CONNECTION_ESTABLISHED){
1380         return ERROR_CODE_COMMAND_DISALLOWED;
1381     }
1382 
1383     connection->state = HID_HOST_W2_SEND_GET_PROTOCOL;
1384     l2cap_request_can_send_now_event(connection->control_cid);
1385     return ERROR_CODE_SUCCESS;
1386 }
1387 
1388 uint8_t hid_host_send_set_protocol_mode(uint16_t hid_cid, hid_protocol_mode_t protocol_mode){
1389     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1390     if (!connection || !connection->control_cid){
1391         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1392     }
1393     if (connection->state != HID_HOST_CONNECTION_ESTABLISHED || connection->set_protocol || connection->w4_set_protocol_response){
1394         return ERROR_CODE_COMMAND_DISALLOWED;
1395     }
1396 
1397     connection->set_protocol = true;
1398     connection->requested_protocol_mode = protocol_mode;
1399 
1400     l2cap_request_can_send_now_event(connection->control_cid);
1401     return ERROR_CODE_SUCCESS;
1402 }
1403 
1404 
1405 uint8_t hid_host_send_report(uint16_t hid_cid, uint8_t report_id, const uint8_t * report, uint8_t report_len){
1406     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1407     if (!connection || !connection->control_cid || !connection->interrupt_cid) {
1408         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1409     }
1410 
1411     if (connection->state < HID_HOST_CONNECTION_ESTABLISHED) {
1412         return ERROR_CODE_COMMAND_DISALLOWED;
1413     }
1414     if (connection->state >= HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED){
1415         return ERROR_CODE_COMMAND_DISALLOWED;
1416     }
1417 
1418     if ((l2cap_max_mtu() - 2) < report_len ){
1419         return ERROR_CODE_COMMAND_DISALLOWED;
1420     }
1421 
1422     connection->state = HID_HOST_W2_SEND_REPORT;
1423     connection->report_type = HID_REPORT_TYPE_OUTPUT;
1424     connection->report_id = report_id;
1425     connection->report = report;
1426     connection->report_len = report_len;
1427 
1428     l2cap_request_can_send_now_event(connection->interrupt_cid);
1429     return ERROR_CODE_SUCCESS;
1430 }
1431