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