xref: /btstack/src/classic/hid_device.c (revision 2e1f7af07f6a4d201438589c1d8aae3edfdaa45e)
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_device.c"
39 
40 #include <string.h>
41 
42 #include "classic/hid_device.h"
43 #include "classic/sdp_util.h"
44 #include "bluetooth.h"
45 #include "bluetooth_sdp.h"
46 #include "l2cap.h"
47 #include "btstack_event.h"
48 #include "btstack_debug.h"
49 
50 // hid device state
51 typedef struct hid_device {
52     uint16_t  cid;
53     bd_addr_t bd_addr;
54     hci_con_handle_t con_handle;
55     uint16_t  control_cid;
56     uint16_t  interrupt_cid;
57     uint8_t   incoming;
58 } hid_device_t;
59 
60 static hid_device_t _hid_device;
61 static hid_device_t * hid_device = &_hid_device;
62 
63 static btstack_packet_handler_t hid_callback;
64 
65 void hid_create_sdp_record(
66     uint8_t *service,
67     uint32_t service_record_handle,
68     uint16_t hid_device_subclass,
69     uint8_t  hid_country_code,
70     uint8_t  hid_virtual_cable,
71     uint8_t  hid_reconnect_initiate,
72     uint8_t  hid_boot_device,
73     const uint8_t * hid_descriptor, uint16_t hid_descriptor_size,
74     const char *device_name){
75 
76     uint8_t * attribute;
77     de_create_sequence(service);
78 
79     de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_RECORD_HANDLE);
80     de_add_number(service, DE_UINT, DE_SIZE_32, service_record_handle);
81 
82     de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST);
83     attribute = de_push_sequence(service);
84     {
85         de_add_number(attribute,  DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE_SERVICE);
86     }
87     de_pop_sequence(service, attribute);
88 
89     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST);
90     attribute = de_push_sequence(service);
91     {
92         uint8_t * l2cpProtocol = de_push_sequence(attribute);
93         {
94             de_add_number(l2cpProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP);
95             de_add_number(l2cpProtocol,  DE_UINT, DE_SIZE_16, PSM_HID_CONTROL);
96         }
97         de_pop_sequence(attribute, l2cpProtocol);
98 
99         uint8_t * hidProtocol = de_push_sequence(attribute);
100         {
101             de_add_number(hidProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_HIDP);
102         }
103         de_pop_sequence(attribute, hidProtocol);
104     }
105     de_pop_sequence(service, attribute);
106 
107     // TODO?
108     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
109     attribute = de_push_sequence(service);
110     {
111         de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x656e);
112         de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x006a);
113         de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x0100);
114     }
115     de_pop_sequence(service, attribute);
116 
117     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS);
118     attribute = de_push_sequence(service);
119     {
120         uint8_t * additionalDescriptorAttribute = de_push_sequence(attribute);
121         {
122             uint8_t * l2cpProtocol = de_push_sequence(additionalDescriptorAttribute);
123             {
124                 de_add_number(l2cpProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP);
125                 de_add_number(l2cpProtocol,  DE_UINT, DE_SIZE_16, PSM_HID_INTERRUPT);
126             }
127             de_pop_sequence(additionalDescriptorAttribute, l2cpProtocol);
128 
129             uint8_t * hidProtocol = de_push_sequence(attribute);
130             {
131                 de_add_number(hidProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_HIDP);
132             }
133             de_pop_sequence(attribute, hidProtocol);
134         }
135         de_pop_sequence(attribute, additionalDescriptorAttribute);
136     }
137     de_pop_sequence(service, attribute);
138 
139     // 0x0100 "ServiceName"
140     de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0100);
141     de_add_data(service,  DE_STRING, strlen(device_name), (uint8_t *) device_name);
142 
143     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
144     attribute = de_push_sequence(service);
145     {
146         uint8_t * hidProfile = de_push_sequence(attribute);
147         {
148             de_add_number(hidProfile,  DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE_SERVICE);
149             de_add_number(hidProfile,  DE_UINT, DE_SIZE_16, 0x0101);    // Version 1.1
150         }
151         de_pop_sequence(attribute, hidProfile);
152     }
153     de_pop_sequence(service, attribute);
154 
155     // Deprecated in v1.1.1
156     // de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_DEVICE_RELEASE_NUMBER);
157     // de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0101);
158 
159     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_PARSER_VERSION);
160     de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0111);  // v1.1.1
161 
162     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_DEVICE_SUBCLASS);
163     de_add_number(service,  DE_UINT, DE_SIZE_16, hid_device_subclass);
164 
165     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_COUNTRY_CODE);
166     de_add_number(service,  DE_UINT, DE_SIZE_16, hid_country_code);
167 
168     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_VIRTUAL_CABLE);
169     de_add_number(service,  DE_BOOL, DE_SIZE_8,  hid_virtual_cable);
170 
171     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_RECONNECT_INITIATE);
172     de_add_number(service,  DE_BOOL, DE_SIZE_8,  hid_reconnect_initiate);
173 
174     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_DESCRIPTOR_LIST);
175     attribute = de_push_sequence(service);
176     {
177         uint8_t* hidDescriptor = de_push_sequence(attribute);
178         {
179             de_add_number(hidDescriptor,  DE_UINT, DE_SIZE_8, 0x22);    // Report Descriptor
180             de_add_data(hidDescriptor,  DE_STRING, hid_descriptor_size, (uint8_t *) hid_descriptor);
181         }
182         de_pop_sequence(attribute, hidDescriptor);
183     }
184     de_pop_sequence(service, attribute);
185 
186     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_BOOT_DEVICE);
187     de_add_number(service,  DE_BOOL, DE_SIZE_8,  hid_boot_device);
188 }
189 
190 static inline void hid_device_emit_connected_event(hid_device_t * context, uint8_t status){
191     uint8_t event[15];
192     int pos = 0;
193     event[pos++] = HCI_EVENT_HID_META;
194     pos++;  // skip len
195     event[pos++] = HID_SUBEVENT_CONNECTION_OPENED;
196     little_endian_store_16(event,pos,context->cid);
197     pos+=2;
198     event[pos++] = status;
199     memcpy(&event[pos], context->bd_addr, 6);
200     pos += 6;
201     little_endian_store_16(event,pos,context->con_handle);
202     pos += 2;
203     event[pos++] = context->incoming;
204     event[1] = pos - 2;
205     if (pos != sizeof(event)) log_error("hid_device_emit_connected_event size %u", pos);
206     hid_callback(HCI_EVENT_PACKET, context->cid, &event[0], pos);
207 }
208 
209 static inline void hid_device_emit_connection_closed_event(hid_device_t * context){
210     uint8_t event[5];
211     int pos = 0;
212     event[pos++] = HCI_EVENT_HID_META;
213     pos++;  // skip len
214     event[pos++] = HID_SUBEVENT_CONNECTION_CLOSED;
215     little_endian_store_16(event,pos,context->cid);
216     pos+=2;
217     event[1] = pos - 2;
218     if (pos != sizeof(event)) log_error("hid_device_emit_connection_closed_event size %u", pos);
219     hid_callback(HCI_EVENT_PACKET, context->cid, &event[0], pos);
220 }
221 
222 static inline void hid_device_emit_can_send_now_event(hid_device_t * context){
223     uint8_t event[5];
224     int pos = 0;
225     event[pos++] = HCI_EVENT_HID_META;
226     pos++;  // skip len
227     event[pos++] = HID_SUBEVENT_CAN_SEND_NOW;
228     little_endian_store_16(event,pos,context->cid);
229     pos+=2;
230     event[1] = pos - 2;
231     if (pos != sizeof(event)) log_error("hid_device_emit_can_send_now_event size %u", pos);
232     hid_callback(HCI_EVENT_PACKET, context->cid, &event[0], pos);
233 }
234 
235 
236 static int hid_connected(void){
237     return hid_device->control_cid && hid_device->interrupt_cid;
238 }
239 
240 static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * packet, uint16_t packet_size){
241     UNUSED(channel);
242     UNUSED(packet_size);
243     int connected_before;
244     switch (packet_type){
245         case HCI_EVENT_PACKET:
246             switch (packet[0]){
247                 case L2CAP_EVENT_INCOMING_CONNECTION:
248                     switch (l2cap_event_incoming_connection_get_psm(packet)){
249                         case PSM_HID_CONTROL:
250                         case PSM_HID_INTERRUPT:
251                             if (hid_device->con_handle == 0 || l2cap_event_incoming_connection_get_handle(packet) == hid_device->con_handle){
252                                 hid_device->con_handle = l2cap_event_incoming_connection_get_handle(packet);
253                                 l2cap_accept_connection(channel);
254                             } else {
255                                 l2cap_decline_connection(channel);
256                             }
257                             break;
258                         default:
259                             l2cap_decline_connection(channel);
260                             break;
261                     }
262                     break;
263                 case L2CAP_EVENT_CHANNEL_OPENED:
264                     if (l2cap_event_channel_opened_get_status(packet)) return;
265                     connected_before = hid_connected();
266                     switch (l2cap_event_channel_opened_get_psm(packet)){
267                         case PSM_HID_CONTROL:
268                             hid_device->control_cid = l2cap_event_channel_opened_get_local_cid(packet);
269                             log_info("HID Control opened, cid 0x%02x", hid_device->control_cid);
270                             break;
271                         case PSM_HID_INTERRUPT:
272                             hid_device->interrupt_cid = l2cap_event_channel_opened_get_local_cid(packet);
273                             log_info("HID Interrupt opened, cid 0x%02x", hid_device->interrupt_cid);
274                             break;
275                         default:
276                             break;
277                     }
278                     if (!connected_before && hid_connected()){
279                         hid_device->incoming = 1;
280                         log_info("HID Connected");
281                         hid_device_emit_connected_event(hid_device, 0);
282                     }
283                     break;
284                 case L2CAP_EVENT_CHANNEL_CLOSED:
285                     connected_before = hid_connected();
286                     if (l2cap_event_channel_closed_get_local_cid(packet) == hid_device->control_cid){
287                         log_info("HID Control closed");
288                         hid_device->control_cid = 0;
289                     }
290                     if (l2cap_event_channel_closed_get_local_cid(packet) == hid_device->interrupt_cid){
291                         log_info("HID Interrupt closed");
292                         hid_device->interrupt_cid = 0;
293                     }
294                     if (connected_before && !hid_connected()){
295                         hid_device->con_handle = 0;
296                         log_info("HID Disconnected");
297                         hid_device_emit_connection_closed_event(hid_device);
298                     }
299                     break;
300                 case L2CAP_EVENT_CAN_SEND_NOW:
301                     log_info("HID Can send now, emit event");
302                     hid_device_emit_can_send_now_event(hid_device);
303                     break;
304                 default:
305                     break;
306             }
307             break;
308         default:
309             break;
310     }
311 }
312 
313 /**
314  * @brief Set up HID Device
315  */
316 void hid_device_init(void){
317     memset(hid_device, 0, sizeof(hid_device_t));
318     hid_device->cid = 1;
319     l2cap_register_service(packet_handler, PSM_HID_INTERRUPT, 100, LEVEL_0);
320     l2cap_register_service(packet_handler, PSM_HID_CONTROL,   100, LEVEL_0);
321 }
322 
323 /**
324  * @brief Register callback for the HID Device client.
325  * @param callback
326  */
327 void hid_device_register_packet_handler(btstack_packet_handler_t callback){
328     hid_callback = callback;
329 }
330 
331 /**
332  * @brief Request can send now event to send HID Report
333  * @param hid_cid
334  */
335 void hid_device_request_can_send_now_event(uint16_t hid_cid){
336     UNUSED(hid_cid);
337     if (!hid_device->control_cid) return;
338     l2cap_request_can_send_now_event(hid_device->control_cid);
339 }
340 
341 /**
342  * @brief Send HID messageon interrupt channel
343  * @param hid_cid
344  */
345 void hid_device_send_interrupt_message(uint16_t hid_cid, const uint8_t * message, uint16_t message_len){
346     UNUSED(hid_cid);
347     if (!hid_device->interrupt_cid) return;
348     l2cap_send(hid_device->interrupt_cid, (uint8_t*) message, message_len);
349 }
350 
351 /**
352  * @brief Send HID messageon control channel
353  * @param hid_cid
354  */
355 void hid_device_send_contro_message(uint16_t hid_cid, const uint8_t * message, uint16_t message_len){
356     UNUSED(hid_cid);
357     if (!hid_device->control_cid) return;
358     l2cap_send(hid_device->control_cid, (uint8_t*) message, message_len);
359 }
360 
361