xref: /btstack/src/classic/hid_host.c (revision 98f1394d9d4c33f501ec5dcff54d145a92013c5e)
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 #define MAX_ATTRIBUTE_VALUE_SIZE 300
57 
58 #define CONTROL_MESSAGE_BITMASK_SUSPEND             1
59 #define CONTROL_MESSAGE_BITMASK_EXIT_SUSPEND        2
60 #define CONTROL_MESSAGE_BITMASK_VIRTUAL_CABLE_UNPLUG 4
61 
62 // globals
63 
64 // higher-layer callbacks
65 static btstack_packet_handler_t hid_host_callback;
66 
67 // descriptor storage
68 static uint8_t * hid_host_descriptor_storage;
69 static uint16_t  hid_host_descriptor_storage_len;
70 
71 // SDP
72 static uint8_t            hid_host_sdp_attribute_value[MAX_ATTRIBUTE_VALUE_SIZE];
73 static const unsigned int hid_host_sdp_attribute_value_buffer_size = MAX_ATTRIBUTE_VALUE_SIZE;
74 static uint16_t           hid_host_sdp_context_control_cid = 0;
75 
76 // connections
77 static btstack_linked_list_t hid_host_connections;
78 static uint16_t              hid_host_cid_counter = 0;
79 
80 // lower layer callbacks
81 static btstack_context_callback_registration_t hid_host_handle_sdp_client_query_request;
82 
83 // prototypes
84 
85 static void hid_host_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
86 static void hid_host_handle_start_sdp_client_query(void * context);
87 
88 static uint16_t hid_descriptor_storage_get_available_space(void){
89     // assumes all descriptors are back to back
90     uint16_t free_space = hid_host_descriptor_storage_len;
91 
92     btstack_linked_list_iterator_t it;
93     btstack_linked_list_iterator_init(&it, &hid_host_connections);
94     while (btstack_linked_list_iterator_has_next(&it)){
95         hid_host_connection_t * connection = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it);
96         free_space -= connection->hid_descriptor_len;
97     }
98     return free_space;
99 }
100 
101 static hid_host_connection_t * hid_host_get_connection_for_hid_cid(uint16_t hid_cid){
102     btstack_linked_list_iterator_t it;
103     btstack_linked_list_iterator_init(&it, &hid_host_connections);
104     while (btstack_linked_list_iterator_has_next(&it)){
105         hid_host_connection_t * connection = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it);
106         if (connection->hid_cid != hid_cid) continue;
107         return connection;
108     }
109     return NULL;
110 }
111 
112 static hid_host_connection_t * hid_host_get_connection_for_l2cap_cid(uint16_t l2cap_cid){
113     btstack_linked_list_iterator_t it;
114     btstack_linked_list_iterator_init(&it, &hid_host_connections);
115     while (btstack_linked_list_iterator_has_next(&it)){
116         hid_host_connection_t * connection = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it);
117         if ((connection->interrupt_cid != l2cap_cid) && (connection->control_cid != l2cap_cid)) continue;
118         return connection;
119     }
120     return NULL;
121 }
122 
123 static void hid_descriptor_storage_init(hid_host_connection_t * connection){
124     connection->hid_descriptor_len = 0;
125     connection->hid_descriptor_max_len = hid_descriptor_storage_get_available_space();
126     connection->hid_descriptor_offset = hid_host_descriptor_storage_len - connection->hid_descriptor_max_len;
127 }
128 
129 static bool hid_descriptor_storage_store(hid_host_connection_t * connection, uint8_t byte){
130     if (connection->hid_descriptor_len >= connection->hid_descriptor_max_len) return false;
131 
132     hid_host_descriptor_storage[connection->hid_descriptor_offset + connection->hid_descriptor_len] = byte;
133     connection->hid_descriptor_len++;
134     return true;
135 }
136 
137 static void hid_descriptor_storage_delete(hid_host_connection_t * connection){
138     uint16_t next_offset = connection->hid_descriptor_offset + connection->hid_descriptor_len;
139 
140     memmove(&hid_host_descriptor_storage[connection->hid_descriptor_offset],
141             &hid_host_descriptor_storage[next_offset],
142             hid_host_descriptor_storage_len - next_offset);
143 
144     connection->hid_descriptor_len = 0;
145     connection->hid_descriptor_offset = 0;
146 
147     btstack_linked_list_iterator_t it;
148     btstack_linked_list_iterator_init(&it, &hid_host_connections);
149     while (btstack_linked_list_iterator_has_next(&it)){
150         hid_host_connection_t * conn = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it);
151         if (conn->hid_descriptor_offset >= next_offset){
152             conn->hid_descriptor_offset = next_offset;
153             next_offset += conn->hid_descriptor_len;
154         }
155     }
156 }
157 
158 const uint8_t * hid_descriptor_storage_get_descriptor_data(uint16_t hid_cid){
159     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
160     if (!connection){
161         return NULL;
162     }
163     return &hid_host_descriptor_storage[connection->hid_descriptor_offset];
164 }
165 
166 uint16_t hid_descriptor_storage_get_descriptor_len(uint16_t hid_cid){
167     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
168     if (!connection){
169         return 0;
170     }
171     return connection->hid_descriptor_len;
172 }
173 
174 
175 // HID Util
176 static void hid_emit_connected_event(hid_host_connection_t * connection, uint8_t status){
177     uint8_t event[15];
178     uint16_t pos = 0;
179     event[pos++] = HCI_EVENT_HID_META;
180     pos++;  // skip len
181     event[pos++] = HID_SUBEVENT_CONNECTION_OPENED;
182     little_endian_store_16(event, pos, connection->hid_cid);
183     pos+=2;
184     event[pos++] = status;
185     reverse_bd_addr(connection->remote_addr, &event[pos]);
186     pos += 6;
187     little_endian_store_16(event,pos,connection->con_handle);
188     pos += 2;
189     event[pos++] = connection->incoming;
190     event[1] = pos - 2;
191     hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos);
192 }
193 
194 static void hid_emit_descriptor_available_event(hid_host_connection_t * connection){
195     uint8_t event[6];
196     uint16_t pos = 0;
197     event[pos++] = HCI_EVENT_HID_META;
198     pos++;  // skip len
199     event[pos++] = HID_SUBEVENT_DESCRIPTOR_AVAILABLE;
200     little_endian_store_16(event,pos,connection->hid_cid);
201     pos += 2;
202     event[pos++] = connection->hid_descriptor_status;
203     event[1] = pos - 2;
204     hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos);
205 }
206 
207 static void hid_emit_sniff_params_event(hid_host_connection_t * connection){
208     uint8_t event[9];
209     uint16_t pos = 0;
210     event[pos++] = HCI_EVENT_HID_META;
211     pos++;  // skip len
212     event[pos++] = HID_SUBEVENT_SNIFF_SUBRATING_PARAMS;
213     little_endian_store_16(event,pos,connection->hid_cid);
214     pos += 2;
215     little_endian_store_16(event,pos,connection->host_max_latency);
216     pos += 2;
217     little_endian_store_16(event,pos,connection->host_min_timeout);
218     pos += 2;
219 
220     event[1] = pos - 2;
221     hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos);
222 }
223 
224 static void hid_emit_event(hid_host_connection_t * connection, uint8_t subevent_type){
225     uint8_t event[5];
226     uint16_t pos = 0;
227     event[pos++] = HCI_EVENT_HID_META;
228     pos++;  // skip len
229     event[pos++] = subevent_type;
230     little_endian_store_16(event,pos,connection->hid_cid);
231     pos += 2;
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_with_status(hid_host_connection_t * connection, uint8_t subevent_type, hid_handshake_param_type_t status){
237     uint8_t event[6];
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[pos++] = status;
245     event[1] = pos - 2;
246     hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos);
247 }
248 
249 static void hid_emit_set_protocol_response_event(hid_host_connection_t * connection, hid_handshake_param_type_t status){
250     uint8_t event[7];
251     uint16_t pos = 0;
252     event[pos++] = HCI_EVENT_HID_META;
253     pos++;  // skip len
254     event[pos++] = HID_SUBEVENT_SET_PROTOCOL_RESPONSE;
255     little_endian_store_16(event,pos,connection->hid_cid);
256     pos += 2;
257     event[pos++] = status;
258     event[pos++] = connection->protocol_mode;
259     event[1] = pos - 2;
260     hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos);
261 }
262 
263 static void hid_emit_incoming_connection_event(hid_host_connection_t * connection){
264     uint8_t event[13];
265     uint16_t pos = 0;
266     event[pos++] = HCI_EVENT_HID_META;
267     pos++;  // skip len
268     event[pos++] = HID_SUBEVENT_INCOMING_CONNECTION;
269     little_endian_store_16(event, pos, connection->hid_cid);
270     pos += 2;
271     reverse_bd_addr(connection->remote_addr, &event[pos]);
272     pos += 6;
273     little_endian_store_16(event,pos,connection->con_handle);
274     pos += 2;
275     event[1] = pos - 2;
276     hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos);
277 }
278 
279 // setup get report response event - potentially in-place of original l2cap packet
280 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){
281     uint16_t pos = 0;
282     buffer[pos++] = HCI_EVENT_HID_META;
283     pos++;  // skip len
284     buffer[pos++] = HID_SUBEVENT_GET_REPORT_RESPONSE;
285     little_endian_store_16(buffer, pos, connection->hid_cid);
286     pos += 2;
287     buffer[pos++] = (uint8_t) status;
288     little_endian_store_16(buffer, pos, report_len);
289     pos += 2;
290     buffer[1] = pos + report_len - 2;
291 }
292 
293 // setup report event - potentially in-place of original l2cap packet
294 static void hid_setup_report_event(hid_host_connection_t * connection, uint8_t *buffer, uint16_t report_len){
295     uint16_t pos = 0;
296     buffer[pos++] = HCI_EVENT_HID_META;
297     pos++;  // skip len
298     buffer[pos++] = HID_SUBEVENT_REPORT;
299     little_endian_store_16(buffer, pos, connection->hid_cid);
300     pos += 2;
301     little_endian_store_16(buffer, pos, report_len);
302     pos += 2;
303     buffer[1] = pos + report_len - 2;
304 }
305 
306 
307 static void hid_emit_get_protocol_event(hid_host_connection_t * connection, hid_handshake_param_type_t status, hid_protocol_mode_t protocol_mode){
308     uint8_t event[7];
309     uint16_t pos = 0;
310     event[pos++] = HCI_EVENT_HID_META;
311     pos++;  // skip len
312     event[pos++] = HID_SUBEVENT_GET_PROTOCOL_RESPONSE;
313     little_endian_store_16(event,pos,connection->hid_cid);
314     pos += 2;
315     event[pos++] = status;
316     event[pos++] = protocol_mode;
317     event[1] = pos - 2;
318     hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos);
319 }
320 
321 // HID Host
322 
323 static uint16_t hid_host_get_next_cid(void){
324     if (hid_host_cid_counter == 0xffff) {
325         hid_host_cid_counter = 1;
326     } else {
327         hid_host_cid_counter++;
328     }
329     return hid_host_cid_counter;
330 }
331 
332 static hid_host_connection_t * hid_host_create_connection(bd_addr_t remote_addr){
333     hid_host_connection_t * connection = btstack_memory_hid_host_connection_get();
334     if (!connection){
335         log_error("Not enough memory to create connection");
336         return NULL;
337     }
338     connection->state = HID_HOST_IDLE;
339     connection->hid_cid = hid_host_get_next_cid();
340     connection->control_cid = 0;
341     connection->control_psm = 0;
342     connection->interrupt_cid = 0;
343     connection->interrupt_psm = 0;
344     connection->con_handle = HCI_CON_HANDLE_INVALID;
345 
346     (void)memcpy(connection->remote_addr, remote_addr, 6);
347     btstack_linked_list_add(&hid_host_connections, (btstack_linked_item_t *) connection);
348     return connection;
349 }
350 
351 static hid_host_connection_t * hid_host_get_connection_for_bd_addr(bd_addr_t addr){
352     btstack_linked_list_iterator_t it;
353     btstack_linked_list_iterator_init(&it, &hid_host_connections);
354     while (btstack_linked_list_iterator_has_next(&it)){
355         hid_host_connection_t * connection = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it);
356         if (memcmp(addr, connection->remote_addr, 6) != 0) continue;
357         return connection;
358     }
359     return NULL;
360 }
361 
362 
363 static void hid_host_finalize_connection(hid_host_connection_t * connection){
364     uint16_t interrupt_cid = connection->interrupt_cid;
365     uint16_t control_cid = connection->control_cid;
366 
367     connection->interrupt_cid = 0;
368     connection->control_cid = 0;
369 
370     if (interrupt_cid != 0){
371         l2cap_disconnect(interrupt_cid);
372     }
373     if (control_cid != 0){
374         l2cap_disconnect(control_cid);
375     }
376     btstack_linked_list_remove(&hid_host_connections, (btstack_linked_item_t*) connection);
377     btstack_memory_hid_host_connection_free(connection);
378 }
379 
380 static void hid_host_handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
381     UNUSED(packet_type);
382     UNUSED(channel);
383     UNUSED(size);
384 
385     des_iterator_t attribute_list_it;
386     des_iterator_t additional_des_it;
387     des_iterator_t prot_it;
388     uint8_t       *des_element;
389     uint8_t       *element;
390     uint32_t       uuid;
391     uint8_t        status = ERROR_CODE_SUCCESS;
392     bool try_fallback_to_boot;
393     bool finalize_connection;
394 
395 
396     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_host_sdp_context_control_cid);
397     if (!connection) {
398         log_error("SDP query, connection with 0x%02x cid not found", hid_host_sdp_context_control_cid);
399         return;
400     }
401 
402     btstack_assert(connection->state == HID_HOST_W4_SDP_QUERY_RESULT);
403 
404     switch (hci_event_packet_get_type(packet)){
405         case SDP_EVENT_QUERY_ATTRIBUTE_VALUE:
406 
407             if (sdp_event_query_attribute_byte_get_attribute_length(packet) <= hid_host_sdp_attribute_value_buffer_size) {
408 
409                 hid_host_sdp_attribute_value[sdp_event_query_attribute_byte_get_data_offset(packet)] = sdp_event_query_attribute_byte_get_data(packet);
410 
411                 if ((uint16_t)(sdp_event_query_attribute_byte_get_data_offset(packet)+1) == sdp_event_query_attribute_byte_get_attribute_length(packet)) {
412                     switch(sdp_event_query_attribute_byte_get_attribute_id(packet)) {
413 
414                         case BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST:
415                             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)) {
416                                 if (des_iterator_get_type(&attribute_list_it) != DE_DES) continue;
417                                 des_element = des_iterator_get_element(&attribute_list_it);
418                                 des_iterator_init(&prot_it, des_element);
419                                 element = des_iterator_get_element(&prot_it);
420                                 if (de_get_element_type(element) != DE_UUID) continue;
421                                 uuid = de_get_uuid32(element);
422                                 switch (uuid){
423                                     case BLUETOOTH_PROTOCOL_L2CAP:
424                                         if (!des_iterator_has_more(&prot_it)) continue;
425                                         des_iterator_next(&prot_it);
426                                         de_element_get_uint16(des_iterator_get_element(&prot_it), &connection->control_psm);
427                                         log_info("HID Control PSM: 0x%04x", connection->control_psm);
428                                         break;
429                                     default:
430                                         break;
431                                 }
432                             }
433                             break;
434                         case BLUETOOTH_ATTRIBUTE_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS:
435                             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)) {
436                                 if (des_iterator_get_type(&attribute_list_it) != DE_DES) continue;
437                                 des_element = des_iterator_get_element(&attribute_list_it);
438                                 for (des_iterator_init(&additional_des_it, des_element); des_iterator_has_more(&additional_des_it); des_iterator_next(&additional_des_it)) {
439                                     if (des_iterator_get_type(&additional_des_it) != DE_DES) continue;
440                                     des_element = des_iterator_get_element(&additional_des_it);
441                                     des_iterator_init(&prot_it, des_element);
442                                     element = des_iterator_get_element(&prot_it);
443                                     if (de_get_element_type(element) != DE_UUID) continue;
444                                     uuid = de_get_uuid32(element);
445                                     switch (uuid){
446                                         case BLUETOOTH_PROTOCOL_L2CAP:
447                                             if (!des_iterator_has_more(&prot_it)) continue;
448                                             des_iterator_next(&prot_it);
449                                             de_element_get_uint16(des_iterator_get_element(&prot_it), &connection->interrupt_psm);
450                                             log_info("HID Interrupt PSM: 0x%04x", connection->interrupt_psm);
451                                             break;
452                                         default:
453                                             break;
454                                     }
455                                 }
456                             }
457                             break;
458 
459                         case BLUETOOTH_ATTRIBUTE_HID_DESCRIPTOR_LIST:
460                             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)) {
461                                 if (des_iterator_get_type(&attribute_list_it) != DE_DES) continue;
462                                 des_element = des_iterator_get_element(&attribute_list_it);
463                                 for (des_iterator_init(&additional_des_it, des_element); des_iterator_has_more(&additional_des_it); des_iterator_next(&additional_des_it)) {
464                                     if (des_iterator_get_type(&additional_des_it) != DE_STRING) continue;
465                                     element = des_iterator_get_element(&additional_des_it);
466 
467                                     const uint8_t * descriptor = de_get_string(element);
468                                     uint16_t descriptor_len = de_get_data_size(element);
469 
470                                     uint16_t i;
471                                     bool stored = false;
472 
473                                     connection->hid_descriptor_status = ERROR_CODE_SUCCESS;
474                                     for (i = 0; i < descriptor_len; i++){
475                                         stored = hid_descriptor_storage_store(connection, descriptor[i]);
476                                         if (!stored){
477                                             connection->hid_descriptor_status = ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
478                                             break;
479                                         }
480                                     }
481                                 }
482                             }
483                             break;
484 
485                         case BLUETOOTH_ATTRIBUTE_HIDSSR_HOST_MAX_LATENCY:
486                             if (de_get_element_type(hid_host_sdp_attribute_value) == DE_UINT) {
487                                 uint16_t host_max_latency;
488                                 if (de_element_get_uint16(hid_host_sdp_attribute_value, &host_max_latency) == 1){
489                                     connection->host_max_latency = host_max_latency;
490                                 } else {
491                                     connection->host_max_latency = 0xFFFF;
492                                 }
493                             }
494                             break;
495 
496                         case BLUETOOTH_ATTRIBUTE_HIDSSR_HOST_MIN_TIMEOUT:
497                             if (de_get_element_type(hid_host_sdp_attribute_value) == DE_UINT) {
498                                 uint16_t host_min_timeout;
499                                 if (de_element_get_uint16(hid_host_sdp_attribute_value, &host_min_timeout) == 1){
500                                     connection->host_min_timeout = host_min_timeout;
501                                 } else {
502                                     connection->host_min_timeout = 0xFFFF;
503                                 }
504                             }
505                             break;
506 
507                         default:
508                             break;
509                     }
510                 }
511             } else {
512                 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));
513             }
514             break;
515 
516         case SDP_EVENT_QUERY_COMPLETE:
517             status = sdp_event_query_complete_get_status(packet);
518             try_fallback_to_boot = false;
519             finalize_connection = false;
520 
521             switch (status){
522                 // remote has SDP server
523                 case ERROR_CODE_SUCCESS:
524                     //  but no HID record
525                     if (!connection->control_psm || !connection->interrupt_psm) {
526                         status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
527                         if (connection->requested_protocol_mode == HID_PROTOCOL_MODE_REPORT_WITH_FALLBACK_TO_BOOT){
528                             try_fallback_to_boot = true;
529                         } else {
530                             finalize_connection = true;
531                         }
532                         break;
533                     }
534                     // report mode possible
535                     break;
536 
537                 // SDP connection failed or remote does not have SDP server
538                 default:
539                     if (connection->requested_protocol_mode == HID_PROTOCOL_MODE_REPORT_WITH_FALLBACK_TO_BOOT){
540                         try_fallback_to_boot = true;
541                     } else {
542                         finalize_connection = true;
543                     }
544                     break;
545             }
546 
547             if (finalize_connection){
548                 hid_host_sdp_context_control_cid = 0;
549                 hid_emit_connected_event(connection, status);
550                 hid_host_finalize_connection(connection);
551                 break;
552             }
553 
554             hid_emit_sniff_params_event(connection);
555 
556             if (try_fallback_to_boot){
557                 if (connection->incoming){
558                     connection->set_protocol = true;
559                     connection->state = HID_HOST_CONNECTION_ESTABLISHED;
560                     connection->requested_protocol_mode = HID_PROTOCOL_MODE_BOOT;
561                     hid_emit_descriptor_available_event(connection);
562                     l2cap_request_can_send_now_event(connection->control_cid);
563                 } else {
564                     connection->state = HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED;
565                     status = l2cap_create_channel(hid_host_packet_handler, connection->remote_addr, BLUETOOTH_PSM_HID_CONTROL, 0xffff, &connection->control_cid);
566                     if (status != ERROR_CODE_SUCCESS){
567                         hid_host_sdp_context_control_cid = 0;
568                         hid_emit_connected_event(connection, status);
569                         hid_host_finalize_connection(connection);
570                     }
571                 }
572                 break;
573             }
574 
575             // report mode possible
576             if (connection->incoming) {
577                 connection->set_protocol = true;
578                 connection->state = HID_HOST_CONNECTION_ESTABLISHED;
579                 connection->requested_protocol_mode = HID_PROTOCOL_MODE_REPORT;
580                 hid_emit_descriptor_available_event(connection);
581                 l2cap_request_can_send_now_event(connection->control_cid);
582             } else {
583                 connection->state = HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED;
584                 status = l2cap_create_channel(hid_host_packet_handler, connection->remote_addr, connection->control_psm, 0xffff, &connection->control_cid);
585                 if (status != ERROR_CODE_SUCCESS){
586                     hid_emit_connected_event(connection, status);
587                     hid_host_finalize_connection(connection);
588                 }
589             }
590             break;
591 
592         default:
593             break;
594     }
595 
596 }
597 
598 
599 static void hid_host_handle_control_packet(hid_host_connection_t * connection, uint8_t *packet, uint16_t size){
600     UNUSED(size);
601     uint8_t param;
602     hid_message_type_t         message_type;
603     hid_handshake_param_type_t message_status;
604     hid_protocol_mode_t        protocol_mode;
605 
606     uint8_t * in_place_event;
607     uint8_t status;
608 
609     message_type   = (hid_message_type_t)(packet[0] >> 4);
610     if (message_type == HID_MESSAGE_TYPE_HID_CONTROL){
611         param = packet[0] & 0x0F;
612         switch ((hid_control_param_t)param){
613             case HID_CONTROL_PARAM_VIRTUAL_CABLE_UNPLUG:
614                 hid_emit_event(connection, HID_SUBEVENT_VIRTUAL_CABLE_UNPLUG);
615                 hid_host_disconnect(connection->hid_cid);
616                 return;
617             default:
618                 break;
619         }
620     }
621 
622     message_status = (hid_handshake_param_type_t)(packet[0] & 0x0F);
623 
624     switch (connection->state){
625         case HID_HOST_CONNECTION_ESTABLISHED:
626             if (!connection->w4_set_protocol_response) break;
627             connection->w4_set_protocol_response = false;
628 
629             switch (message_status){
630                 case HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL:
631                     connection->protocol_mode = connection->requested_protocol_mode;
632                     break;
633                 default:
634                     break;
635             }
636             hid_emit_set_protocol_response_event(connection, message_status);
637             break;
638 
639         case HID_HOST_CONTROL_CONNECTION_ESTABLISHED:           // outgoing
640         case HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED:      // outgoing
641             if (!connection->w4_set_protocol_response) break;
642             connection->w4_set_protocol_response = false;
643 
644             switch (message_status){
645                 case HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL:
646                     // we are already connected, here it is only confirmed that we are in required protocol
647                     btstack_assert(connection->incoming == false);
648                     status = l2cap_create_channel(hid_host_packet_handler, connection->remote_addr, connection->interrupt_psm, 0xffff, &connection->interrupt_cid);
649                     if (status != ERROR_CODE_SUCCESS){
650                         log_info("HID Interrupt Connection failed: 0x%02x\n", status);
651                         hid_emit_connected_event(connection, status);
652                         hid_host_finalize_connection(connection);
653                         break;
654                     }
655                     connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED;
656                     break;
657                 default:
658                     hid_emit_connected_event(connection, ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
659                     hid_host_finalize_connection(connection);
660                     break;
661             }
662             break;
663 
664         case HID_HOST_W4_GET_REPORT_RESPONSE:
665             switch (message_type){
666                 case HID_MESSAGE_TYPE_HANDSHAKE:{
667                     uint8_t event[8];
668                     hid_setup_get_report_event(connection, message_status, event, 0);
669                     hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, event, sizeof(event));
670                     break;
671                 }
672                 case HID_MESSAGE_TYPE_DATA:
673                     // reuse hci+l2cap header - max 8 byte (7 bytes + 1 bytes overwriting hid header)
674                     in_place_event = packet - 7;
675                     hid_setup_get_report_event(connection, HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL, in_place_event, size-1);
676                     hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, in_place_event, size + 7);
677                     break;
678                 default:
679                     break;
680             }
681             connection->state =  HID_HOST_CONNECTION_ESTABLISHED;
682             break;
683 
684         case HID_HOST_W4_SET_REPORT_RESPONSE:
685             hid_emit_event_with_status(connection, HID_SUBEVENT_SET_REPORT_RESPONSE, message_status);
686             connection->state =  HID_HOST_CONNECTION_ESTABLISHED;
687             break;
688 
689         case HID_HOST_W4_GET_PROTOCOL_RESPONSE:
690             protocol_mode = connection->protocol_mode;
691 
692             switch (message_type){
693                 case HID_MESSAGE_TYPE_DATA:
694                     protocol_mode = (hid_protocol_mode_t)packet[1];
695                     switch (protocol_mode){
696                         case HID_PROTOCOL_MODE_BOOT:
697                         case HID_PROTOCOL_MODE_REPORT:
698                             message_status = HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL;
699                             break;
700                         default:
701                             message_status = HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER;
702                             break;
703                     }
704                     break;
705                 default:
706                     break;
707             }
708             hid_emit_get_protocol_event(connection, message_status, protocol_mode);
709             connection->state =  HID_HOST_CONNECTION_ESTABLISHED;
710             break;
711 
712         default:
713             log_info("ignore invalid HID Control message");
714             connection->state =  HID_HOST_CONNECTION_ESTABLISHED;
715             break;
716     }
717 
718 }
719 
720 static void hid_host_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
721     UNUSED(channel);
722     UNUSED(size);
723 
724     uint8_t   event;
725     bd_addr_t address;
726     uint8_t   status;
727     uint16_t  l2cap_cid;
728     hid_host_connection_t * connection;
729 
730     switch (packet_type) {
731 
732         case L2CAP_DATA_PACKET:
733             connection = hid_host_get_connection_for_l2cap_cid(channel);
734             if (!connection) break;
735 
736             if (channel == connection->interrupt_cid){
737                 uint8_t * in_place_event = packet - 7;
738                 hid_setup_report_event(connection, in_place_event, size-1);
739                 hid_host_callback(HCI_EVENT_PACKET, connection->hid_cid, in_place_event, size + 7);
740                 break;
741             }
742 
743             if (channel == connection->control_cid){
744                 hid_host_handle_control_packet(connection, packet, size);
745                 break;
746             }
747             break;
748 
749         case HCI_EVENT_PACKET:
750             event = hci_event_packet_get_type(packet);
751             switch (event) {
752                 case L2CAP_EVENT_INCOMING_CONNECTION:
753                     l2cap_event_incoming_connection_get_address(packet, address);
754                     // connection should exist if psm == PSM_HID_INTERRUPT
755                     connection = hid_host_get_connection_for_bd_addr(address);
756 
757                     switch (l2cap_event_incoming_connection_get_psm(packet)){
758                         case PSM_HID_CONTROL:
759                             if (connection){
760                                 l2cap_decline_connection(channel);
761                                 break;
762                             }
763 
764                             connection = hid_host_create_connection(address);
765                             if (!connection){
766                                 log_error("Cannot create connection for %s", bd_addr_to_str(address));
767                                 l2cap_decline_connection(channel);
768                                 break;
769                             }
770 
771                             connection->state = HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED;
772                             connection->hid_descriptor_status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
773                             connection->con_handle = l2cap_event_incoming_connection_get_handle(packet);
774                             connection->control_cid = l2cap_event_incoming_connection_get_local_cid(packet);
775                             connection->incoming = true;
776 
777                             // emit connection request
778                             // user calls either hid_host_accept_connection or hid_host_decline_connection
779                             hid_emit_incoming_connection_event(connection);
780                             break;
781 
782                         case PSM_HID_INTERRUPT:
783                             if (!connection || (connection->state != HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED)){
784                                 log_error("Decline connection for %s", bd_addr_to_str(address));
785                                 l2cap_decline_connection(channel);
786                                 break;
787                             }
788 
789                             connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED;
790                             connection->interrupt_cid = l2cap_event_incoming_connection_get_local_cid(packet);
791                             log_info("Accept connection on Interrupt channel %s", bd_addr_to_str(address));
792                             l2cap_accept_connection(channel);
793                             break;
794 
795                         default:
796                             log_info("Decline connection for %s", bd_addr_to_str(address));
797                             l2cap_decline_connection(channel);
798                             break;
799                     }
800                     break;
801 
802                 case L2CAP_EVENT_CHANNEL_OPENED:
803                     l2cap_event_channel_opened_get_address(packet, address);
804 
805                     connection = hid_host_get_connection_for_bd_addr(address);
806                     if (!connection){
807                         log_error("Connection does not exist %s", bd_addr_to_str(address));
808                         break;
809                     }
810 
811                     status = l2cap_event_channel_opened_get_status(packet);
812                     if (status != ERROR_CODE_SUCCESS){
813                         log_info("L2CAP connection %s failed: 0x%02xn", bd_addr_to_str(address), status);
814                         hid_emit_connected_event(connection, status);
815                         hid_host_finalize_connection(connection);
816                         break;
817                     }
818 
819                     // handle incoming connection:
820                     if (connection->incoming){
821                         switch (connection->state){
822                             case HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED:
823                                 // 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)
824                                 // We expect incomming interrupt connection from remote HID device
825                                 connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED;
826                                 log_info("Incoming control connection opened: w4 interrupt");
827                                 break;
828 
829                             case HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED:
830                                 hid_emit_connected_event(connection, ERROR_CODE_SUCCESS);
831                                 connection->state = HID_HOST_CONNECTION_ESTABLISHED;
832 
833                                 switch (connection->requested_protocol_mode){
834                                     case HID_PROTOCOL_MODE_BOOT:
835                                         hid_emit_descriptor_available_event(connection);
836                                         connection->set_protocol = true;
837                                         l2cap_request_can_send_now_event(connection->control_cid);
838                                         log_info("Incoming interrupt connection opened: set boot mode");
839                                         break;
840                                     default:
841                                         // SDP query
842                                         log_info("Incoming interrupt connection opened: start SDP query");
843                                         connection->state = HID_HOST_W2_SEND_SDP_QUERY;
844                                         hid_host_handle_sdp_client_query_request.callback = &hid_host_handle_start_sdp_client_query;
845                                         (void) sdp_client_register_query_callback(&hid_host_handle_sdp_client_query_request);
846                                         break;
847                                 }
848                                 break;
849 
850                             default:
851                                 btstack_assert(false);
852                                 break;
853                         }
854                         break;
855                     }
856 
857                     // handle outgoing connection
858                     switch (connection->state){
859                         case HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED:
860                             log_info("Opened control connection, requested protocol mode %d\n", connection->requested_protocol_mode);
861                             connection->con_handle = l2cap_event_channel_opened_get_handle(packet);
862                             connection->state = HID_HOST_CONTROL_CONNECTION_ESTABLISHED;
863 
864                             switch (connection->requested_protocol_mode){
865                                 case HID_PROTOCOL_MODE_BOOT:
866                                 case HID_PROTOCOL_MODE_REPORT_WITH_FALLBACK_TO_BOOT:
867                                     connection->set_protocol = true;
868                                     connection->interrupt_psm = BLUETOOTH_PSM_HID_INTERRUPT;
869                                     l2cap_request_can_send_now_event(connection->control_cid);
870                                     break;
871                                 default:
872                                     status = l2cap_create_channel(hid_host_packet_handler, address, connection->interrupt_psm, 0xffff, &connection->interrupt_cid);
873                                     if (status){
874                                         log_info("Connecting to HID Interrupt failed: 0x%02x", status);
875                                         hid_emit_connected_event(connection, status);
876                                         break;
877                                     }
878                                     connection->protocol_mode = connection->requested_protocol_mode;
879                                     connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED;
880                                     break;
881                             }
882                             break;
883 
884                         case HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED:
885                             connection->state = HID_HOST_CONNECTION_ESTABLISHED;
886                             log_info("HID host connection established, cids: control 0x%02x, interrupt 0x%02x interrupt, hid 0x%02x",
887                                 connection->control_cid, connection->interrupt_cid, connection->hid_cid);
888                             hid_emit_connected_event(connection, ERROR_CODE_SUCCESS);
889                             hid_emit_descriptor_available_event(connection);
890                             break;
891 
892                         default:
893                             btstack_assert(false);
894                             break;
895                     }
896                     break;
897 
898                 case L2CAP_EVENT_CHANNEL_CLOSED:
899                     l2cap_cid  = l2cap_event_channel_closed_get_local_cid(packet);
900                     connection = hid_host_get_connection_for_l2cap_cid(l2cap_cid);
901                     if (!connection) return;
902 
903                     if (l2cap_cid == connection->interrupt_cid){
904                         connection->interrupt_cid = 0;
905                         if (connection->state == HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED){
906                             connection->state = HID_HOST_W4_CONTROL_CONNECTION_DISCONNECTED;
907                             l2cap_disconnect(connection->control_cid);
908                         }
909                         break;
910                     }
911 
912                     if (l2cap_cid == connection->control_cid){
913                         connection->control_cid = 0;
914                         hid_emit_event(connection, HID_SUBEVENT_CONNECTION_CLOSED);
915                         hid_descriptor_storage_delete(connection);
916                         hid_host_finalize_connection(connection);
917                         break;
918                     }
919                     break;
920 
921                 case L2CAP_EVENT_CAN_SEND_NOW:
922                     l2cap_cid  = l2cap_event_can_send_now_get_local_cid(packet);
923                     connection = hid_host_get_connection_for_l2cap_cid(l2cap_cid);
924                     if (!connection) return;
925 
926 
927 
928                     if (connection->control_cid == l2cap_cid){
929                         switch(connection->state){
930                             case HID_HOST_CONTROL_CONNECTION_ESTABLISHED:
931                             case HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED:
932                                 if (connection->set_protocol){
933                                     connection->set_protocol = false;
934                                     uint8_t header = (HID_MESSAGE_TYPE_SET_PROTOCOL << 4) | connection->requested_protocol_mode;
935                                     uint8_t report[] = {header};
936                                     connection->w4_set_protocol_response = true;
937                                     l2cap_send(connection->control_cid, (uint8_t*) report, sizeof(report));
938                                     break;
939                                 }
940                                 break;
941 
942                             case HID_HOST_CONNECTION_ESTABLISHED:
943                                 if ((connection->control_tasks & CONTROL_MESSAGE_BITMASK_SUSPEND) != 0){
944                                     connection->control_tasks &= ~CONTROL_MESSAGE_BITMASK_SUSPEND;
945                                     uint8_t report[] = { (HID_MESSAGE_TYPE_HID_CONTROL << 4) | HID_CONTROL_PARAM_SUSPEND };
946                                     l2cap_send(connection->control_cid, (uint8_t*) report, 1);
947                                     break;
948                                 }
949                                 if ((connection->control_tasks & CONTROL_MESSAGE_BITMASK_EXIT_SUSPEND) != 0){
950                                     connection->control_tasks &= ~CONTROL_MESSAGE_BITMASK_EXIT_SUSPEND;
951                                     uint8_t report[] = { (HID_MESSAGE_TYPE_HID_CONTROL << 4) | HID_CONTROL_PARAM_EXIT_SUSPEND };
952                                     l2cap_send(connection->control_cid, (uint8_t*) report, 1);
953                                     break;
954                                 }
955                                 if ((connection->control_tasks & CONTROL_MESSAGE_BITMASK_VIRTUAL_CABLE_UNPLUG) != 0){
956                                     connection->control_tasks &= ~CONTROL_MESSAGE_BITMASK_VIRTUAL_CABLE_UNPLUG;
957                                     uint8_t report[] = { (HID_MESSAGE_TYPE_HID_CONTROL << 4) | HID_CONTROL_PARAM_VIRTUAL_CABLE_UNPLUG };
958                                     l2cap_send(connection->control_cid, (uint8_t*) report, 1);
959                                     break;
960                                 }
961 
962                                 if (connection->set_protocol){
963                                     connection->set_protocol = false;
964                                     uint8_t header = (HID_MESSAGE_TYPE_SET_PROTOCOL << 4) | connection->requested_protocol_mode;
965                                     uint8_t report[] = {header};
966 
967                                     connection->w4_set_protocol_response = true;
968                                     l2cap_send(connection->control_cid, (uint8_t*) report, sizeof(report));
969                                     break;
970                                 }
971                                 break;
972 
973                             case HID_HOST_W2_SEND_GET_REPORT:{
974                                 uint8_t header = (HID_MESSAGE_TYPE_GET_REPORT << 4) | connection->report_type;
975                                 uint8_t report[] = {header, connection->report_id};
976 
977                                 connection->state = HID_HOST_W4_GET_REPORT_RESPONSE;
978                                 l2cap_send(connection->control_cid, (uint8_t*) report, sizeof(report));
979                                 break;
980                             }
981 
982                             case HID_HOST_W2_SEND_SET_REPORT:{
983                                 uint8_t header = (HID_MESSAGE_TYPE_SET_REPORT << 4) | connection->report_type;
984                                 connection->state = HID_HOST_W4_SET_REPORT_RESPONSE;
985 
986                                 l2cap_reserve_packet_buffer();
987                                 uint8_t * out_buffer = l2cap_get_outgoing_buffer();
988                                 out_buffer[0] = header;
989                                 out_buffer[1] = connection->report_id;
990                                 (void)memcpy(out_buffer + 2, connection->report, connection->report_len);
991                                 l2cap_send_prepared(connection->control_cid, connection->report_len + 2);
992                                 break;
993                             }
994 
995                             case HID_HOST_W2_SEND_GET_PROTOCOL:{
996                                 uint8_t header = (HID_MESSAGE_TYPE_GET_PROTOCOL << 4);
997                                 uint8_t report[] = {header};
998                                 connection->state = HID_HOST_W4_GET_PROTOCOL_RESPONSE;
999                                 l2cap_send(connection->control_cid, (uint8_t*) report, sizeof(report));
1000                                 break;
1001                             }
1002 
1003                             default:
1004                                 break;
1005                         }
1006                     }
1007 
1008                     if (connection->interrupt_cid == l2cap_cid && connection->state == HID_HOST_W2_SEND_REPORT){
1009                         connection->state = HID_HOST_CONNECTION_ESTABLISHED;
1010                         // there is no response for this type of message
1011                         uint8_t header = (HID_MESSAGE_TYPE_DATA << 4) | connection->report_type;
1012 
1013                         l2cap_reserve_packet_buffer();
1014                         uint8_t * out_buffer = l2cap_get_outgoing_buffer();
1015                         out_buffer[0] = header;
1016                         out_buffer[1] = connection->report_id;
1017                         (void)memcpy(out_buffer + 2, connection->report, connection->report_len);
1018                         l2cap_send_prepared(connection->interrupt_cid, connection->report_len + 2);
1019                         break;
1020                     }
1021 
1022                     if (connection->control_tasks != 0){
1023                         l2cap_request_can_send_now_event(connection->control_cid);
1024                     }
1025                     break;
1026                 default:
1027                     break;
1028             }
1029         default:
1030             break;
1031     }
1032 }
1033 
1034 
1035 void hid_host_init(uint8_t * hid_descriptor_storage, uint16_t hid_descriptor_storage_len){
1036     hid_host_descriptor_storage = hid_descriptor_storage;
1037     hid_host_descriptor_storage_len = hid_descriptor_storage_len;
1038 
1039     // register L2CAP Services for reconnections
1040     l2cap_register_service(hid_host_packet_handler, PSM_HID_INTERRUPT, 0xffff, gap_get_security_level());
1041     l2cap_register_service(hid_host_packet_handler, PSM_HID_CONTROL, 0xffff, gap_get_security_level());
1042 }
1043 
1044 void hid_host_deinit(void){
1045     hid_host_callback = NULL;
1046     hid_host_descriptor_storage = NULL;
1047     hid_host_sdp_context_control_cid = 0;
1048     hid_host_connections = NULL;
1049     hid_host_cid_counter = 0;
1050     (void) memset(&hid_host_handle_sdp_client_query_request, 0, sizeof(hid_host_handle_sdp_client_query_request));
1051 }
1052 
1053 void hid_host_register_packet_handler(btstack_packet_handler_t callback){
1054     hid_host_callback = callback;
1055 }
1056 
1057 static void hid_host_handle_start_sdp_client_query(void * context){
1058     UNUSED(context);
1059     btstack_linked_list_iterator_t it;
1060     btstack_linked_list_iterator_init(&it, &hid_host_connections);
1061 
1062     while (btstack_linked_list_iterator_has_next(&it)){
1063         hid_host_connection_t * connection = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it);
1064 
1065         switch (connection->state){
1066             case HID_HOST_W2_SEND_SDP_QUERY:
1067                 connection->state = HID_HOST_W4_SDP_QUERY_RESULT;
1068                 connection->hid_descriptor_status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1069                 break;
1070             default:
1071                 continue;
1072         }
1073 
1074         hid_descriptor_storage_init(connection);
1075         hid_host_sdp_context_control_cid = connection->hid_cid;
1076         sdp_client_query_uuid16(&hid_host_handle_sdp_client_query_result, (uint8_t *) connection->remote_addr, BLUETOOTH_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE_SERVICE);
1077         return;
1078     }
1079 }
1080 
1081 uint8_t hid_host_accept_connection(uint16_t hid_cid, hid_protocol_mode_t protocol_mode){
1082     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1083     if (!connection){
1084         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1085     }
1086     if (connection->state != HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED){
1087         return ERROR_CODE_COMMAND_DISALLOWED;
1088     }
1089 
1090     connection->requested_protocol_mode = protocol_mode;
1091     l2cap_accept_connection(connection->control_cid);
1092     return ERROR_CODE_SUCCESS;
1093 }
1094 
1095 uint8_t hid_host_decline_connection(uint16_t hid_cid){
1096     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1097     if (!connection){
1098         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1099     }
1100     if (connection->state != HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED){
1101         return ERROR_CODE_COMMAND_DISALLOWED;
1102     }
1103 
1104     l2cap_decline_connection(connection->control_cid);
1105     hid_host_finalize_connection(connection);
1106     return ERROR_CODE_SUCCESS;
1107 }
1108 
1109 uint8_t hid_host_connect(bd_addr_t remote_addr, hid_protocol_mode_t protocol_mode, uint16_t * hid_cid){
1110     if (hid_cid == NULL) {
1111         return ERROR_CODE_COMMAND_DISALLOWED;
1112     }
1113 
1114     hid_host_connection_t * connection = hid_host_get_connection_for_bd_addr(remote_addr);
1115     if (connection){
1116         return ERROR_CODE_COMMAND_DISALLOWED;
1117     }
1118 
1119     connection = hid_host_create_connection(remote_addr);
1120     if (!connection) return BTSTACK_MEMORY_ALLOC_FAILED;
1121 
1122     *hid_cid = connection->hid_cid;
1123 
1124     connection->state = HID_HOST_W2_SEND_SDP_QUERY;
1125     connection->incoming = false;
1126     connection->requested_protocol_mode = protocol_mode;
1127     connection->hid_descriptor_status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1128 
1129     uint8_t status = ERROR_CODE_SUCCESS;
1130 
1131     switch (connection->requested_protocol_mode){
1132         case HID_PROTOCOL_MODE_BOOT:
1133             connection->state = HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED;
1134             status = l2cap_create_channel(hid_host_packet_handler, connection->remote_addr, BLUETOOTH_PSM_HID_CONTROL, 0xffff, &connection->control_cid);
1135             break;
1136         default:
1137             hid_host_handle_sdp_client_query_request.callback = &hid_host_handle_start_sdp_client_query;
1138             // ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback
1139             (void) sdp_client_register_query_callback(&hid_host_handle_sdp_client_query_request);
1140             break;
1141     }
1142     return status;
1143 }
1144 
1145 
1146 void hid_host_disconnect(uint16_t hid_cid){
1147     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1148     if (!connection) return;
1149 
1150     switch (connection->state){
1151         case HID_HOST_IDLE:
1152         case HID_HOST_W4_CONTROL_CONNECTION_DISCONNECTED:
1153         case HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED:
1154             return;
1155         default:
1156             break;
1157     }
1158 
1159     if (connection->interrupt_cid){
1160         connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED;
1161         l2cap_disconnect(connection->interrupt_cid);
1162         return;
1163     }
1164 
1165     if (connection->control_cid){
1166         connection->state = HID_HOST_W4_CONTROL_CONNECTION_DISCONNECTED;
1167         l2cap_disconnect(connection->control_cid);
1168         return;
1169     }
1170 }
1171 
1172 
1173 static inline uint8_t hid_host_send_control_message(uint16_t hid_cid, uint8_t control_message_bitmask){
1174     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1175     if (!connection || !connection->control_cid) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1176 
1177     if (connection->state < HID_HOST_CONTROL_CONNECTION_ESTABLISHED) {
1178         return ERROR_CODE_COMMAND_DISALLOWED;
1179     }
1180     if (connection->state >= HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED){
1181         return ERROR_CODE_COMMAND_DISALLOWED;
1182     }
1183 
1184     connection->control_tasks |= control_message_bitmask;
1185     l2cap_request_can_send_now_event(connection->control_cid);
1186     return ERROR_CODE_SUCCESS;
1187 }
1188 
1189 uint8_t hid_host_send_suspend(uint16_t hid_cid){
1190     return hid_host_send_control_message(hid_cid, CONTROL_MESSAGE_BITMASK_SUSPEND);
1191 }
1192 
1193 uint8_t hid_host_send_exit_suspend(uint16_t hid_cid){
1194     return hid_host_send_control_message(hid_cid, CONTROL_MESSAGE_BITMASK_EXIT_SUSPEND);
1195 }
1196 
1197 uint8_t hid_host_send_virtual_cable_unplug(uint16_t hid_cid){
1198     return hid_host_send_control_message(hid_cid, CONTROL_MESSAGE_BITMASK_VIRTUAL_CABLE_UNPLUG);
1199 }
1200 
1201 uint8_t hid_host_send_get_report(uint16_t hid_cid,  hid_report_type_t report_type, uint8_t report_id){
1202     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1203 
1204     if (!connection || !connection->control_cid){
1205         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1206     }
1207     if (connection->state != HID_HOST_CONNECTION_ESTABLISHED){
1208         return ERROR_CODE_COMMAND_DISALLOWED;
1209     }
1210 
1211     connection->state = HID_HOST_W2_SEND_GET_REPORT;
1212     connection->report_type = report_type;
1213     connection->report_id = report_id;
1214 
1215     l2cap_request_can_send_now_event(connection->control_cid);
1216     return ERROR_CODE_SUCCESS;
1217 }
1218 
1219 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){
1220     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1221 
1222     if (!connection || !connection->control_cid){
1223         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1224     }
1225 
1226     if (connection->state != HID_HOST_CONNECTION_ESTABLISHED){
1227         return ERROR_CODE_COMMAND_DISALLOWED;
1228     }
1229 
1230     if ((l2cap_max_mtu() - 2) < report_len ){
1231         return ERROR_CODE_COMMAND_DISALLOWED;
1232     }
1233 
1234     connection->state = HID_HOST_W2_SEND_SET_REPORT;
1235     connection->report_type = report_type;
1236     connection->report_id = report_id;
1237     connection->report = report;
1238     connection->report_len = report_len;
1239 
1240     l2cap_request_can_send_now_event(connection->control_cid);
1241     return ERROR_CODE_SUCCESS;
1242 }
1243 
1244 uint8_t hid_host_send_get_protocol(uint16_t hid_cid){
1245     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1246     if (!connection || !connection->control_cid){
1247         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1248     }
1249     if (connection->state != HID_HOST_CONNECTION_ESTABLISHED){
1250         return ERROR_CODE_COMMAND_DISALLOWED;
1251     }
1252 
1253     connection->state = HID_HOST_W2_SEND_GET_PROTOCOL;
1254     l2cap_request_can_send_now_event(connection->control_cid);
1255     return ERROR_CODE_SUCCESS;
1256 }
1257 
1258 uint8_t hid_host_send_set_protocol_mode(uint16_t hid_cid, hid_protocol_mode_t protocol_mode){
1259     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1260     if (!connection || !connection->control_cid){
1261         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1262     }
1263     if (connection->state != HID_HOST_CONNECTION_ESTABLISHED || connection->set_protocol || connection->w4_set_protocol_response){
1264         return ERROR_CODE_COMMAND_DISALLOWED;
1265     }
1266 
1267     connection->set_protocol = true;
1268     connection->requested_protocol_mode = protocol_mode;
1269 
1270     l2cap_request_can_send_now_event(connection->control_cid);
1271     return ERROR_CODE_SUCCESS;
1272 }
1273 
1274 
1275 uint8_t hid_host_send_report(uint16_t hid_cid, uint8_t report_id, const uint8_t * report, uint8_t report_len){
1276     hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
1277     if (!connection || !connection->control_cid || !connection->interrupt_cid) {
1278         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1279     }
1280 
1281     if (connection->state < HID_HOST_CONNECTION_ESTABLISHED) {
1282         return ERROR_CODE_COMMAND_DISALLOWED;
1283     }
1284     if (connection->state >= HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED){
1285         return ERROR_CODE_COMMAND_DISALLOWED;
1286     }
1287 
1288     if ((l2cap_max_mtu() - 2) < report_len ){
1289         return ERROR_CODE_COMMAND_DISALLOWED;
1290     }
1291 
1292     connection->state = HID_HOST_W2_SEND_REPORT;
1293     connection->report_type = HID_REPORT_TYPE_OUTPUT;
1294     connection->report_id = report_id;
1295     connection->report = report;
1296     connection->report_len = report_len;
1297 
1298     l2cap_request_can_send_now_event(connection->interrupt_cid);
1299     return ERROR_CODE_SUCCESS;
1300 }
1301