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