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