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