1 /******************************************************************************
2  *
3  *  Copyright 2009-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 #include "bta_hh_co.h"
20 
21 #include <bluetooth/log.h>
22 #include <com_android_bluetooth_flags.h>
23 #include <fcntl.h>
24 #include <linux/hid.h>
25 #include <linux/input.h>
26 #include <linux/uhid.h>
27 #include <poll.h>
28 #include <pthread.h>
29 #include <sched.h>
30 #include <string.h>
31 #include <sys/socket.h>
32 #include <sys/types.h>
33 #include <unistd.h>
34 
35 #include <array>
36 #include <cerrno>
37 #include <cstdint>
38 #include <cstdio>
39 #include <cstring>
40 
41 #include "bta_hh_api.h"
42 #include "btif_config.h"
43 #include "btif_hh.h"
44 #include "hardware/bt_hh.h"
45 #include "hci/controller_interface.h"
46 #include "main/shim/entry.h"
47 #include "osi/include/alarm.h"
48 #include "osi/include/allocator.h"
49 #include "osi/include/compat.h"
50 #include "osi/include/fixed_queue.h"
51 #include "osi/include/osi.h"
52 #include "osi/include/properties.h"
53 #include "storage/config_keys.h"
54 #include "types/raw_address.h"
55 
56 #define BTA_HH_NV_LOAD_MAX 16
57 static tBTA_HH_RPT_CACHE_ENTRY sReportCache[BTA_HH_NV_LOAD_MAX];
58 #define BTA_HH_CACHE_REPORT_VERSION 1
59 #define THREAD_NORMAL_PRIORITY 0
60 #define BT_HH_THREAD_PREFIX "bt_hh_"
61 /* poll timeout without the aflags hid_report_queuing */
62 #define BTA_HH_UHID_POLL_PERIOD_MS 50
63 /* poll timeout with the aflags hid_report_queuing. -1 indicates no timeout. */
64 #define BTA_HH_UHID_POLL_PERIOD2_MS -1
65 /* Max number of polling interrupt allowed */
66 #define BTA_HH_UHID_INTERRUPT_COUNT_MAX 100
67 /* Disconnect if UHID isn't ready after this many milliseconds. */
68 #define BTA_HH_UHID_READY_DISCONN_TIMEOUT_MS 10000
69 #define BTA_HH_UHID_READY_SHORT_DISCONN_TIMEOUT_MS 2000
70 
71 using namespace bluetooth;
72 
73 static constexpr char kDevPath[] = "/dev/uhid";
74 static constexpr char kPropertyWaitMsAfterUhidOpen[] = "bluetooth.hid.wait_ms_after_uhid_open";
75 
76 static constexpr bthh_report_type_t map_rtype_uhid_hh[] = {BTHH_FEATURE_REPORT, BTHH_OUTPUT_REPORT,
77                                                            BTHH_INPUT_REPORT};
78 
79 static void* btif_hh_poll_event_thread(void* arg);
80 static bool to_uhid_thread(int fd, const tBTA_HH_TO_UHID_EVT* ev, size_t data_len);
81 
uhid_set_non_blocking(int fd)82 static void uhid_set_non_blocking(int fd) {
83   int opts = fcntl(fd, F_GETFL);
84   if (opts < 0) {
85     log::error("Getting flags failed ({})", strerror(errno));
86   }
87 
88   opts |= O_NONBLOCK;
89 
90   if (fcntl(fd, F_SETFL, opts) < 0) {
91     log::verbose("Setting non-blocking flag failed ({})", strerror(errno));
92   }
93 }
94 
uhid_get_report_req_handler(btif_hh_uhid_t * p_uhid,struct uhid_get_report_req & req)95 static bool uhid_get_report_req_handler(btif_hh_uhid_t* p_uhid, struct uhid_get_report_req& req) {
96   log::debug("Report type = {}, id = {}", req.rtype, req.rnum);
97 
98   if (req.rtype > UHID_INPUT_REPORT) {
99     log::error("Invalid report type {}", req.rtype);
100     return false;
101   }
102 
103   if (p_uhid->get_rpt_id_queue == nullptr) {
104     log::error("Queue is not initialized");
105     return false;
106   }
107 
108   uint32_t* context = (uint32_t*)osi_malloc(sizeof(uint32_t));
109   *context = req.id;
110 
111   if (!fixed_queue_try_enqueue(p_uhid->get_rpt_id_queue, (void*)context)) {
112     osi_free(context);
113     log::error("Queue is full, dropping event {}", req.id);
114     return false;
115   }
116 
117   btif_hh_getreport(p_uhid, map_rtype_uhid_hh[req.rtype], req.rnum, 0);
118   return true;
119 }
120 
121 #if ENABLE_UHID_SET_REPORT
uhid_set_report_req_handler(btif_hh_uhid_t * p_uhid,struct uhid_set_report_req & req)122 static bool uhid_set_report_req_handler(btif_hh_uhid_t* p_uhid, struct uhid_set_report_req& req) {
123   log::debug("Report type = {}, id = {}", req.rtype, req.rnum);
124 
125   if (req.rtype > UHID_INPUT_REPORT) {
126     log::error("Invalid report type {}", req.rtype);
127     return false;
128   }
129 
130   if (p_uhid->set_rpt_id_queue == nullptr) {
131     log::error("Queue is not initialized");
132     return false;
133   }
134 
135   uint32_t* context = (uint32_t*)osi_malloc(sizeof(uint32_t));
136   *context = req.id;
137 
138   if (!fixed_queue_try_enqueue(p_uhid->set_rpt_id_queue, (void*)context)) {
139     osi_free(context);
140     log::error("Queue is full, dropping event {}", req.id);
141     return false;
142   }
143 
144   btif_hh_setreport(p_uhid, map_rtype_uhid_hh[req.rtype], req.size, req.data);
145   return true;
146 }
147 #endif  // ENABLE_UHID_SET_REPORT
148 
149 /* Calculate the minimum length required to send message to UHID */
uhid_calc_msg_len(const struct uhid_event * ev,size_t var_len)150 static size_t uhid_calc_msg_len(const struct uhid_event* ev, size_t var_len) {
151   switch (ev->type) {
152     // these messages don't have data following them, so just 4 bytes of type.
153     case UHID_DESTROY:
154     case UHID_STOP:
155     case UHID_OPEN:
156     case UHID_CLOSE:
157       return sizeof(ev->type);
158     // these messages has static length of data.
159     case UHID_START:
160       return sizeof(ev->type) + sizeof(ev->u.start);
161     case UHID_OUTPUT:
162       return sizeof(ev->type) + sizeof(ev->u.output);
163     case UHID_GET_REPORT:
164       return sizeof(ev->type) + sizeof(ev->u.get_report);
165     case UHID_SET_REPORT_REPLY:
166       return sizeof(ev->type) + sizeof(ev->u.set_report_reply);
167     // these messages has variable amount of data. We only need to write the
168     // necessary length.
169     case UHID_CREATE2:
170       return sizeof(ev->type) + sizeof(ev->u.create2) - HID_MAX_DESCRIPTOR_SIZE + var_len;
171     case UHID_INPUT2:
172       return sizeof(ev->type) + sizeof(ev->u.input2) - UHID_DATA_MAX + var_len;
173     case UHID_GET_REPORT_REPLY:
174       return sizeof(ev->type) + sizeof(ev->u.get_report_reply) - UHID_DATA_MAX + var_len;
175     case UHID_SET_REPORT:
176       return sizeof(ev->type) + sizeof(ev->u.set_report) - UHID_DATA_MAX + var_len;
177     default:
178       log::error("unknown uhid event type {}", ev->type);
179       return 0;
180   }
181 }
182 
183 /*Internal function to perform UHID write and error checking*/
uhid_write(int fd,const struct uhid_event * ev,size_t len)184 static int uhid_write(int fd, const struct uhid_event* ev, size_t len) {
185   ssize_t ret;
186   OSI_NO_INTR(ret = write(fd, ev, len));
187 
188   if (ret < 0) {
189     int rtn = -errno;
190     log::error("Cannot write to uhid:{}", strerror(errno));
191     return rtn;
192   } else if (ret != (ssize_t)len) {
193     log::error("Wrong size written to uhid: {} != {}", ret, len);
194     return -EFAULT;
195   }
196 
197   return 0;
198 }
199 
uhid_flush_input_queue(btif_hh_uhid_t * p_uhid)200 static void uhid_flush_input_queue(btif_hh_uhid_t* p_uhid) {
201   struct uhid_event* p_ev = nullptr;
202   while (true) {
203     p_ev = (struct uhid_event*)fixed_queue_try_dequeue(p_uhid->input_queue);
204     if (p_ev == nullptr) {
205       break;
206     }
207     uhid_write(p_uhid->fd, p_ev, uhid_calc_msg_len(p_ev, p_ev->u.input2.size));
208     osi_free(p_ev);
209   }
210 }
211 
uhid_set_ready(btif_hh_uhid_t * p_uhid)212 static void uhid_set_ready(btif_hh_uhid_t* p_uhid) {
213   if (p_uhid->ready_for_data) {
214     return;
215   }
216   p_uhid->ready_for_data = true;
217   uhid_flush_input_queue(p_uhid);
218 }
219 
220 // This runs on main thread.
uhid_delayed_ready_cback(void * data)221 static void uhid_delayed_ready_cback(void* data) {
222   int send_fd = PTR_TO_INT(data);
223   tBTA_HH_TO_UHID_EVT ev = {};
224 
225   // Notify the UHID thread that the timer has expired.
226   log::verbose("UHID delayed ready evt");
227   ev.type = BTA_HH_UHID_INBOUND_READY_EVT;
228   to_uhid_thread(send_fd, &ev, 0);
229 }
230 
231 // This runs on main thread.
uhid_ready_disconn_timeout(void * data)232 static void uhid_ready_disconn_timeout(void* data) {
233   int dev_handle = PTR_TO_INT(data);
234 
235   log::verbose("UHID ready disconn timeout evt");
236   BTA_HhClose(dev_handle);
237 }
238 
uhid_on_open(btif_hh_uhid_t * p_uhid)239 static void uhid_on_open(btif_hh_uhid_t* p_uhid) {
240   if (p_uhid->ready_for_data || alarm_is_scheduled(p_uhid->delayed_ready_timer)) {
241     return;
242   }
243 
244   if (com::android::bluetooth::flags::close_hid_if_uhid_ready_too_slow()) {
245     if (alarm_is_scheduled(p_uhid->ready_disconn_timer)) {
246       alarm_cancel(p_uhid->ready_disconn_timer);
247     }
248   }
249 
250   // On some platforms delay is required, because even though UHID has indicated
251   // ready, the input events might still not be processed, and therefore lost.
252   // If it's not required, immediately set UHID as ready.
253   int ready_delay_ms = osi_property_get_int32(kPropertyWaitMsAfterUhidOpen, 0);
254   if (ready_delay_ms == 0) {
255     uhid_set_ready(p_uhid);
256     return;
257   }
258 
259   alarm_set_on_mloop(p_uhid->delayed_ready_timer, ready_delay_ms, uhid_delayed_ready_cback,
260                      INT_TO_PTR(p_uhid->internal_send_fd));
261 }
262 
uhid_queue_input(btif_hh_uhid_t * p_uhid,struct uhid_event * ev,size_t len)263 static void uhid_queue_input(btif_hh_uhid_t* p_uhid, struct uhid_event* ev, size_t len) {
264   struct uhid_event* p_ev = (struct uhid_event*)osi_malloc(len);
265   if (!p_ev) {
266     log::error("allocate uhid_event failed");
267     return;
268   }
269   memcpy(p_ev, ev, len);
270 
271   if (!fixed_queue_try_enqueue(p_uhid->input_queue, (void*)p_ev)) {
272     osi_free(p_ev);
273     log::error("uhid_event_queue is full, dropping event");
274   }
275 }
276 
277 /* Parse the events received from UHID driver*/
uhid_read_outbound_event(btif_hh_uhid_t * p_uhid)278 static int uhid_read_outbound_event(btif_hh_uhid_t* p_uhid) {
279   log::assert_that(p_uhid != nullptr, "assert failed: p_uhid != nullptr");
280 
281   struct uhid_event ev = {};
282   ssize_t ret;
283   OSI_NO_INTR(ret = read(p_uhid->fd, &ev, sizeof(ev)));
284 
285   if (ret == 0) {
286     log::error("Read HUP on uhid-cdev {}", strerror(errno));
287     return -EFAULT;
288   } else if (ret < 0) {
289     log::error("Cannot read uhid-cdev: {}", strerror(errno));
290     return -errno;
291   }
292 
293   switch (ev.type) {
294     case UHID_START:
295       log::verbose("UHID_START from uhid-dev\n");
296       if (!com::android::bluetooth::flags::hid_report_queuing()) {
297         // we can ignore START event, no one is ready to listen anyway.
298         p_uhid->ready_for_data = true;
299       }
300       break;
301     case UHID_STOP:
302       log::verbose("UHID_STOP from uhid-dev\n");
303       if (!com::android::bluetooth::flags::hid_report_queuing()) {
304         // we can ignore STOP event, it needs to be closed first anyway.
305         p_uhid->ready_for_data = false;
306       }
307       break;
308     case UHID_OPEN:
309       log::verbose("UHID_OPEN from uhid-dev\n");
310       if (com::android::bluetooth::flags::hid_report_queuing()) {
311         uhid_on_open(p_uhid);
312       } else {
313         p_uhid->ready_for_data = true;
314       }
315       break;
316     case UHID_CLOSE:
317       log::verbose("UHID_CLOSE from uhid-dev\n");
318       p_uhid->ready_for_data = false;
319       if (com::android::bluetooth::flags::hid_report_queuing()) {
320         if (alarm_is_scheduled(p_uhid->delayed_ready_timer)) {
321           alarm_cancel(p_uhid->delayed_ready_timer);
322         }
323         if (com::android::bluetooth::flags::close_hid_if_uhid_ready_too_slow()) {
324           // It's possible to get OPEN->CLOSE->OPEN sequence from UHID. Therefore, instead of
325           // immediately disconnecting when receiving CLOSE, here we wait a while and will
326           // disconnect if we don't receive OPEN before it times out.
327           if (!alarm_is_scheduled(p_uhid->ready_disconn_timer)) {
328             alarm_set_on_mloop(p_uhid->ready_disconn_timer,
329                                BTA_HH_UHID_READY_SHORT_DISCONN_TIMEOUT_MS,
330                                uhid_ready_disconn_timeout, INT_TO_PTR(p_uhid->dev_handle));
331           }
332         }
333       }
334       break;
335     case UHID_OUTPUT:
336       if (ret < (ssize_t)(sizeof(ev.type) + sizeof(ev.u.output))) {
337         log::error("Invalid size read from uhid-dev: {} < {}", ret,
338                    sizeof(ev.type) + sizeof(ev.u.output));
339         return -EFAULT;
340       }
341 
342       log::verbose("UHID_OUTPUT: Report type = {}, report_size = {}", ev.u.output.rtype,
343                    ev.u.output.size);
344       // Send SET_REPORT with feature report if the report type in output event
345       // is FEATURE
346       if (ev.u.output.rtype == UHID_FEATURE_REPORT) {
347         btif_hh_setreport(p_uhid, BTHH_FEATURE_REPORT, ev.u.output.size, ev.u.output.data);
348       } else if (ev.u.output.rtype == UHID_OUTPUT_REPORT) {
349         btif_hh_senddata(p_uhid, ev.u.output.size, ev.u.output.data);
350       } else {
351         log::error("UHID_OUTPUT: Invalid report type = {}", ev.u.output.rtype);
352       }
353       break;
354 
355     case UHID_GET_REPORT:
356       if (ret < (ssize_t)(sizeof(ev.type) + sizeof(ev.u.get_report))) {
357         log::error("UHID_GET_REPORT: Invalid size read from uhid-dev: {} < {}", ret,
358                    sizeof(ev.type) + sizeof(ev.u.get_report));
359         return -EFAULT;
360       }
361 
362       if (!uhid_get_report_req_handler(p_uhid, ev.u.get_report)) {
363         return -EFAULT;
364       }
365 
366       break;
367 
368 #if ENABLE_UHID_SET_REPORT
369     case UHID_SET_REPORT: {
370       if (ret < (ssize_t)(sizeof(ev.type) + sizeof(ev.u.set_report))) {
371         log::error("UHID_SET_REPORT: Invalid size read from uhid-dev: {} < {}", ret,
372                    sizeof(ev.type) + sizeof(ev.u.set_report));
373         return -EFAULT;
374       }
375 
376       if (!uhid_set_report_req_handler(p_uhid, ev.u.set_report)) {
377         return -EFAULT;
378       }
379       break;
380     }
381 #endif  // ENABLE_UHID_SET_REPORT
382 
383     default:
384       log::error("Invalid event from uhid-dev: {}\n", ev.type);
385   }
386 
387   return 0;
388 }
389 
390 // Parse the internal events received from BTIF and translate to UHID
391 // returns -errno when error, 0 when successful, 1 when receiving close event.
uhid_read_inbound_event(btif_hh_uhid_t * p_uhid)392 static int uhid_read_inbound_event(btif_hh_uhid_t* p_uhid) {
393   log::assert_that(p_uhid != nullptr, "assert failed: p_uhid != nullptr");
394 
395   tBTA_HH_TO_UHID_EVT ev = {};
396   ssize_t ret;
397   OSI_NO_INTR(ret = read(p_uhid->internal_recv_fd, &ev, sizeof(ev)));
398 
399   if (ret == 0) {
400     log::error("Read HUP on internal uhid-cdev {}", strerror(errno));
401     return -EFAULT;
402   } else if (ret < 0) {
403     log::error("Cannot read internal uhid-cdev: {}", strerror(errno));
404     return -errno;
405   }
406 
407   int res = 0;
408   uint32_t* context;
409   switch (ev.type) {
410     case BTA_HH_UHID_INBOUND_INPUT_EVT:
411       if (p_uhid->ready_for_data) {
412         res = uhid_write(p_uhid->fd, &ev.uhid, ret - 1);
413       } else {
414         uhid_queue_input(p_uhid, &ev.uhid, ret - 1);
415       }
416       break;
417     case BTA_HH_UHID_INBOUND_READY_EVT:
418       uhid_set_ready(p_uhid);
419       break;
420     case BTA_HH_UHID_INBOUND_CLOSE_EVT:
421       res = 1;  // any positive value indicates a normal close event
422       break;
423     case BTA_HH_UHID_INBOUND_DSCP_EVT:
424       res = uhid_write(p_uhid->fd, &ev.uhid, ret - 1);
425       break;
426     case BTA_HH_UHID_INBOUND_GET_REPORT_EVT:
427       context = (uint32_t*)fixed_queue_try_dequeue(p_uhid->get_rpt_id_queue);
428       if (context == nullptr) {
429         log::warn("No pending UHID_GET_REPORT");
430         break;
431       }
432       ev.uhid.u.get_report_reply.id = *context;
433       res = uhid_write(p_uhid->fd, &ev.uhid, ret - 1);
434       osi_free(context);
435       break;
436 #if ENABLE_UHID_SET_REPORT
437     case BTA_HH_UHID_INBOUND_SET_REPORT_EVT:
438       context = (uint32_t*)fixed_queue_try_dequeue(p_uhid->set_rpt_id_queue);
439       if (context == nullptr) {
440         log::warn("No pending UHID_SET_REPORT");
441         break;
442       }
443       ev.uhid.u.set_report_reply.id = *context;
444       res = uhid_write(p_uhid->fd, &ev.uhid, ret - 1);
445       osi_free(context);
446       break;
447 #endif  // ENABLE_UHID_SET_REPORT
448     default:
449       log::error("Invalid event from internal uhid-dev: {}", (uint8_t)ev.type);
450   }
451 
452   return res;
453 }
454 
455 /*******************************************************************************
456  *
457  * Function create_thread
458  *
459  * Description creat a select loop
460  *
461  * Returns pthread_t
462  *
463  ******************************************************************************/
create_thread(void * (* start_routine)(void *),void * arg)464 static inline pthread_t create_thread(void* (*start_routine)(void*), void* arg) {
465   log::verbose("create_thread: entered");
466   pthread_attr_t thread_attr;
467 
468   pthread_attr_init(&thread_attr);
469   pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
470   pthread_t thread_id = -1;
471   if (pthread_create(&thread_id, &thread_attr, start_routine, arg) != 0) {
472     log::error("pthread_create : {}", strerror(errno));
473     return -1;
474   }
475   log::verbose("create_thread: thread created successfully");
476   return thread_id;
477 }
478 
479 /* Internal function to close the UHID driver*/
uhid_fd_close(btif_hh_uhid_t * p_uhid)480 static void uhid_fd_close(btif_hh_uhid_t* p_uhid) {
481   if (p_uhid->fd >= 0) {
482     struct uhid_event ev = {};
483     ev.type = UHID_DESTROY;
484     uhid_write(p_uhid->fd, &ev, uhid_calc_msg_len(&ev, 0));
485     log::debug("Closing fd={}, addr:{}", p_uhid->fd, p_uhid->link_spec);
486     close(p_uhid->fd);
487     p_uhid->fd = -1;
488 
489     if (!com::android::bluetooth::flags::hid_report_queuing()) {
490       return;
491     }
492 
493     close(p_uhid->internal_recv_fd);
494     p_uhid->internal_recv_fd = -1;
495     /* Clear the queues */
496     fixed_queue_flush(p_uhid->get_rpt_id_queue, osi_free);
497     fixed_queue_free(p_uhid->get_rpt_id_queue, NULL);
498     p_uhid->get_rpt_id_queue = NULL;
499 #if ENABLE_UHID_SET_REPORT
500     fixed_queue_flush(p_uhid->set_rpt_id_queue, osi_free);
501     fixed_queue_free(p_uhid->set_rpt_id_queue, nullptr);
502     p_uhid->set_rpt_id_queue = nullptr;
503 #endif  // ENABLE_UHID_SET_REPORT
504     fixed_queue_flush(p_uhid->input_queue, osi_free);
505     fixed_queue_free(p_uhid->input_queue, nullptr);
506     p_uhid->input_queue = nullptr;
507 
508     alarm_free(p_uhid->delayed_ready_timer);
509     alarm_free(p_uhid->ready_disconn_timer);
510     osi_free(p_uhid);
511   }
512 }
513 
514 /* Internal function to open the UHID driver*/
uhid_fd_open(btif_hh_device_t * p_dev)515 static bool uhid_fd_open(btif_hh_device_t* p_dev) {
516   if (!com::android::bluetooth::flags::hid_report_queuing()) {
517     if (p_dev->uhid.fd < 0) {
518       p_dev->uhid.fd = open(kDevPath, O_RDWR | O_CLOEXEC);
519       if (p_dev->uhid.fd < 0) {
520         log::error("Failed to open uhid, err:{}", strerror(errno));
521         return false;
522       }
523     }
524 
525     if (p_dev->uhid.hh_keep_polling == 0) {
526       p_dev->uhid.hh_keep_polling = 1;
527       p_dev->hh_poll_thread_id = create_thread(btif_hh_poll_event_thread, &p_dev->uhid);
528     }
529     return true;
530   }
531 
532   if (p_dev->internal_send_fd < 0) {
533     int sockets[2];
534     if (socketpair(AF_LOCAL, SOCK_SEQPACKET | SOCK_NONBLOCK, 0, sockets) < 0) {
535       return false;
536     }
537 
538     btif_hh_uhid_t* uhid = (btif_hh_uhid_t*)osi_malloc(sizeof(btif_hh_uhid_t));
539     uhid->link_spec = p_dev->link_spec;
540     uhid->dev_handle = p_dev->dev_handle;
541     uhid->internal_recv_fd = sockets[0];
542     uhid->internal_send_fd = sockets[1];
543     p_dev->internal_send_fd = sockets[1];
544 
545     // UHID thread owns the uhid struct and is responsible to free it.
546     p_dev->hh_poll_thread_id = create_thread(btif_hh_poll_event_thread, uhid);
547   }
548   return true;
549 }
550 
uhid_fd_poll(btif_hh_uhid_t * p_uhid,struct pollfd * pfds,int nfds)551 static int uhid_fd_poll(btif_hh_uhid_t* p_uhid, struct pollfd* pfds, int nfds) {
552   int ret = 0;
553   int counter = 0;
554 
555   do {
556     if (com::android::bluetooth::flags::break_uhid_polling_early() &&
557         !com::android::bluetooth::flags::hid_report_queuing() && !p_uhid->hh_keep_polling) {
558       log::debug("Polling stopped");
559       return -1;
560     }
561 
562     if (counter++ > BTA_HH_UHID_INTERRUPT_COUNT_MAX) {
563       log::error("Polling interrupted consecutively {} times", BTA_HH_UHID_INTERRUPT_COUNT_MAX);
564       return -1;
565     }
566 
567     int uhid_poll_timeout = com::android::bluetooth::flags::hid_report_queuing()
568                                     ? BTA_HH_UHID_POLL_PERIOD2_MS
569                                     : BTA_HH_UHID_POLL_PERIOD_MS;
570     ret = poll(pfds, nfds, uhid_poll_timeout);
571   } while (ret == -1 && errno == EINTR);
572 
573   if (!com::android::bluetooth::flags::break_uhid_polling_early()) {
574     if (ret == 0) {
575       log::verbose("Polling timed out, attempt to read (old behavior)");
576       return 1;
577     }
578   }
579 
580   return ret;
581 }
582 
uhid_start_polling(btif_hh_uhid_t * p_uhid)583 static void uhid_start_polling(btif_hh_uhid_t* p_uhid) {
584   if (!com::android::bluetooth::flags::hid_report_queuing()) {
585     std::array<struct pollfd, 1> pfds = {};
586     pfds[0].fd = p_uhid->fd;
587     pfds[0].events = POLLIN;
588 
589     while (p_uhid->hh_keep_polling) {
590       int ret = uhid_fd_poll(p_uhid, pfds.data(), 1);
591 
592       if (ret < 0) {
593         log::error("Cannot poll for fds: {}\n", strerror(errno));
594         break;
595       } else if (ret == 0) {
596         /* Poll timeout, poll again */
597         continue;
598       }
599 
600       /* At least one of the fd is ready */
601       if (pfds[0].revents & POLLIN) {
602         log::verbose("POLLIN");
603         int result = uhid_read_outbound_event(p_uhid);
604         if (result != 0) {
605           log::error("Unhandled UHID event, error: {}", result);
606           break;
607         }
608       }
609     }
610 
611     return;
612   }
613 
614   std::array<struct pollfd, 2> pfds = {};
615   pfds[0].fd = p_uhid->fd;
616   pfds[0].events = POLLIN;
617   pfds[1].fd = p_uhid->internal_recv_fd;
618   pfds[1].events = POLLIN;
619 
620   while (true) {
621     int ret = uhid_fd_poll(p_uhid, pfds.data(), 2);
622     if (ret < 0) {
623       log::error("Cannot poll for fds: {}\n", strerror(errno));
624       break;
625     }
626 
627     if (pfds[0].revents & POLLIN) {
628       log::verbose("POLLIN");
629       int result = uhid_read_outbound_event(p_uhid);
630       if (result != 0) {
631         log::error("Unhandled UHID outbound event, error: {}", result);
632         break;
633       }
634     }
635 
636     if (pfds[1].revents & POLLIN) {
637       int result = uhid_read_inbound_event(p_uhid);
638       if (result != 0) {
639         if (result < 0) {
640           log::error("Unhandled UHID inbound event, error: {}", result);
641         }
642         break;
643       }
644     }
645 
646     if (pfds[1].revents & POLLHUP) {
647       log::error("inbound fd hangup, disconnect UHID");
648       break;
649     }
650   }
651 }
652 
uhid_configure_thread(btif_hh_uhid_t * p_uhid)653 static bool uhid_configure_thread(btif_hh_uhid_t* p_uhid) {
654   pid_t pid = gettid();
655   // This thread is created by bt_main_thread with RT priority. Lower the thread
656   // priority here since the tasks in this thread is not timing critical.
657   struct sched_param sched_params;
658   sched_params.sched_priority = THREAD_NORMAL_PRIORITY;
659   if (sched_setscheduler(pid, SCHED_OTHER, &sched_params)) {
660     log::error("Failed to set thread priority to normal: {}", strerror(errno));
661     return false;
662   }
663 
664   // Change the name of thread
665   char thread_name[16] = {};
666   sprintf(thread_name, BT_HH_THREAD_PREFIX "%02x:%02x", p_uhid->link_spec.addrt.bda.address[4],
667           p_uhid->link_spec.addrt.bda.address[5]);
668   pthread_setname_np(pthread_self(), thread_name);
669   log::debug("Host hid polling thread created name:{} pid:{} fd:{}", thread_name, pid, p_uhid->fd);
670 
671   // Set the uhid fd as non-blocking to ensure we never block the BTU thread
672   uhid_set_non_blocking(p_uhid->fd);
673 
674   return true;
675 }
676 
677 /*******************************************************************************
678  *
679  * Function btif_hh_poll_event_thread
680  *
681  * Description the polling thread which polls for event from UHID driver
682  *
683  * Returns void
684  *
685  ******************************************************************************/
btif_hh_poll_event_thread(void * arg)686 static void* btif_hh_poll_event_thread(void* arg) {
687   btif_hh_uhid_t* p_uhid = (btif_hh_uhid_t*)arg;
688 
689   if (com::android::bluetooth::flags::hid_report_queuing()) {
690     p_uhid->fd = open(kDevPath, O_RDWR | O_CLOEXEC);
691     if (p_uhid->fd < 0) {
692       log::error("Failed to open uhid, err:{}", strerror(errno));
693       close(p_uhid->internal_recv_fd);
694       p_uhid->internal_recv_fd = -1;
695       return 0;
696     }
697     p_uhid->ready_for_data = false;
698     p_uhid->delayed_ready_timer = alarm_new("uhid_delayed_ready_timer");
699     p_uhid->ready_disconn_timer = alarm_new("uhid_ready_disconn_timer");
700     if (com::android::bluetooth::flags::close_hid_if_uhid_ready_too_slow()) {
701       alarm_set_on_mloop(p_uhid->ready_disconn_timer, BTA_HH_UHID_READY_DISCONN_TIMEOUT_MS,
702                          uhid_ready_disconn_timeout, INT_TO_PTR(p_uhid->dev_handle));
703     }
704 
705     p_uhid->get_rpt_id_queue = fixed_queue_new(SIZE_MAX);
706     log::assert_that(p_uhid->get_rpt_id_queue, "assert failed: p_uhid->get_rpt_id_queue");
707 #if ENABLE_UHID_SET_REPORT
708     p_uhid->set_rpt_id_queue = fixed_queue_new(SIZE_MAX);
709     log::assert_that(p_uhid->set_rpt_id_queue, "assert failed: p_uhid->set_rpt_id_queue");
710 #endif  // ENABLE_UHID_SET_REPORT
711     p_uhid->input_queue = fixed_queue_new(SIZE_MAX);
712     log::assert_that(p_uhid->input_queue, "assert failed: p_uhid->input_queue");
713   }
714 
715   if (uhid_configure_thread(p_uhid)) {
716     uhid_start_polling(p_uhid);
717   }
718 
719   /* Todo: Disconnect if loop exited due to a failure */
720   log::info("Polling thread stopped for device {}", p_uhid->link_spec);
721   if (!com::android::bluetooth::flags::hid_report_queuing()) {
722     p_uhid->hh_keep_polling = 0;
723   }
724   uhid_fd_close(p_uhid);
725   return 0;
726 }
727 
728 /* Pass messages to be handled by uhid_read_inbound_event in the UHID thread */
to_uhid_thread(int fd,const tBTA_HH_TO_UHID_EVT * ev,size_t data_len)729 static bool to_uhid_thread(int fd, const tBTA_HH_TO_UHID_EVT* ev, size_t data_len) {
730   if (fd < 0) {
731     log::error("Cannot write to uhid thread: invalid fd");
732     return false;
733   }
734 
735   size_t len = data_len + sizeof(ev->type);
736   ssize_t ret;
737   OSI_NO_INTR(ret = write(fd, ev, len));
738 
739   if (ret < 0) {
740     log::error("Cannot write to uhid thread: {}", strerror(errno));
741     return false;
742   } else if (ret != (ssize_t)len) {
743     log::error("Wrong size written to uhid thread: {} != {}", ret, len);
744     return false;
745   }
746 
747   return true;
748 }
749 
bta_hh_co_write(int fd,uint8_t * rpt,uint16_t len)750 int bta_hh_co_write(int fd, uint8_t* rpt, uint16_t len) {
751   log::verbose("UHID write {}", len);
752 
753   tBTA_HH_TO_UHID_EVT to_uhid = {};
754   struct uhid_event& ev = to_uhid.uhid;
755   ev.type = UHID_INPUT2;
756   ev.u.input2.size = len;
757   if (len > sizeof(ev.u.input2.data)) {
758     log::warn("Report size greater than allowed size");
759     return -1;
760   }
761   memcpy(ev.u.input2.data, rpt, len);
762 
763   size_t mlen = uhid_calc_msg_len(&ev, len);
764   if (!com::android::bluetooth::flags::hid_report_queuing()) {
765     return uhid_write(fd, &ev, mlen);
766   }
767 
768   to_uhid.type = BTA_HH_UHID_INBOUND_INPUT_EVT;
769   return to_uhid_thread(fd, &to_uhid, mlen) ? 0 : -1;
770 }
771 
772 /*******************************************************************************
773  *
774  * Function      bta_hh_co_open
775  *
776  * Description   When connection is opened, this call-out function is executed
777  *               by HH to do platform specific initialization.
778  *
779  * Returns       True if platform specific initialization is successful
780  ******************************************************************************/
bta_hh_co_open(uint8_t dev_handle,uint8_t sub_class,tBTA_HH_ATTR_MASK attr_mask,uint8_t app_id,tAclLinkSpec & link_spec)781 bool bta_hh_co_open(uint8_t dev_handle, uint8_t sub_class, tBTA_HH_ATTR_MASK attr_mask,
782                     uint8_t app_id, tAclLinkSpec& link_spec) {
783   bool new_device = false;
784 
785   if (dev_handle == BTA_HH_INVALID_HANDLE) {
786     log::warn("dev_handle ({}) is invalid", dev_handle);
787     return false;
788   }
789 
790   // Reuse existing instance if possible
791   btif_hh_device_t* p_dev = btif_hh_find_dev_by_handle(dev_handle);
792   if (p_dev != nullptr) {
793     log::info(
794             "Found an existing device with the same handle dev_status={}, "
795             "device={}, attr_mask=0x{:04x}, sub_class=0x{:02x}, app_id={}, "
796             "dev_handle={}",
797             p_dev->dev_status, p_dev->link_spec, p_dev->attr_mask, p_dev->sub_class, p_dev->app_id,
798             dev_handle);
799   } else {  // Use an empty slot
800     p_dev = btif_hh_find_empty_dev();
801     if (p_dev == nullptr) {
802       log::error("Too many HID devices are connected");
803       return false;
804     }
805 
806     new_device = true;
807     log::verbose("New HID device added for handle {}", dev_handle);
808 
809     if (com::android::bluetooth::flags::hid_report_queuing()) {
810       p_dev->internal_send_fd = -1;
811     } else {
812       p_dev->uhid.fd = -1;
813       p_dev->uhid.hh_keep_polling = 0;
814     }
815     p_dev->attr_mask = attr_mask;
816     p_dev->sub_class = sub_class;
817     p_dev->app_id = app_id;
818     p_dev->local_vup = false;
819   }
820 
821   if (com::android::bluetooth::flags::hid_report_queuing()) {
822     p_dev->link_spec = link_spec;
823     p_dev->dev_handle = dev_handle;
824   } else {
825     p_dev->uhid.link_spec = link_spec;
826     p_dev->uhid.dev_handle = dev_handle;
827   }
828 
829   if (!uhid_fd_open(p_dev)) {
830     return false;
831   }
832 
833   if (new_device) {
834     btif_hh_cb.device_num++;
835   }
836 
837   p_dev->dev_status = BTHH_CONN_STATE_CONNECTED;
838 
839   if (!com::android::bluetooth::flags::hid_report_queuing()) {
840     p_dev->dev_handle = dev_handle;
841     p_dev->uhid.get_rpt_id_queue = fixed_queue_new(SIZE_MAX);
842     log::assert_that(p_dev->uhid.get_rpt_id_queue, "assert failed: p_dev->uhid.get_rpt_id_queue");
843 #if ENABLE_UHID_SET_REPORT
844     p_dev->uhid.set_rpt_id_queue = fixed_queue_new(SIZE_MAX);
845     log::assert_that(p_dev->uhid.set_rpt_id_queue, "assert failed: p_dev->uhid.set_rpt_id_queue");
846 #endif  // ENABLE_UHID_SET_REPORT
847   }
848 
849   log::debug("Return device status {}", p_dev->dev_status);
850   return true;
851 }
852 
853 /*******************************************************************************
854  *
855  * Function      bta_hh_co_close
856  *
857  * Description   When connection is closed, this call-out function is executed
858  *               by HH to do platform specific finalization.
859  *
860  * Parameters    p_dev  - device
861  *
862  * Returns       void.
863  ******************************************************************************/
bta_hh_co_close(btif_hh_device_t * p_dev)864 void bta_hh_co_close(btif_hh_device_t* p_dev) {
865   log::info("Closing device handle={}, status={}, address={}", p_dev->dev_handle, p_dev->dev_status,
866             p_dev->link_spec);
867 
868   if (!com::android::bluetooth::flags::hid_report_queuing()) {
869     /* Clear the queues */
870     fixed_queue_flush(p_dev->uhid.get_rpt_id_queue, osi_free);
871     fixed_queue_free(p_dev->uhid.get_rpt_id_queue, NULL);
872     p_dev->uhid.get_rpt_id_queue = NULL;
873 #if ENABLE_UHID_SET_REPORT
874     fixed_queue_flush(p_dev->uhid.set_rpt_id_queue, osi_free);
875     fixed_queue_free(p_dev->uhid.set_rpt_id_queue, nullptr);
876     p_dev->uhid.set_rpt_id_queue = nullptr;
877 #endif  // ENABLE_UHID_SET_REPORT
878 
879     /* Stop the polling thread */
880     if (p_dev->uhid.hh_keep_polling) {
881       p_dev->uhid.hh_keep_polling = 0;
882       pthread_join(p_dev->hh_poll_thread_id, NULL);
883       p_dev->hh_poll_thread_id = -1;
884     }
885     /* UHID file descriptor is closed by the polling thread */
886 
887     return;
888   }
889 
890   if (p_dev->internal_send_fd >= 0) {
891     tBTA_HH_TO_UHID_EVT to_uhid = {};
892     to_uhid.type = BTA_HH_UHID_INBOUND_CLOSE_EVT;
893     to_uhid_thread(p_dev->internal_send_fd, &to_uhid, 0);
894     pthread_join(p_dev->hh_poll_thread_id, NULL);
895     p_dev->hh_poll_thread_id = -1;
896 
897     close(p_dev->internal_send_fd);
898     p_dev->internal_send_fd = -1;
899   }
900 }
901 
902 /*******************************************************************************
903  *
904  * Function         bta_hh_co_data
905  *
906  * Description      This function is executed by BTA when HID host receive a
907  *                  data report.
908  *
909  * Parameters       dev_handle  - device handle
910  *                  *p_rpt      - pointer to the report data
911  *                  len         - length of report data
912  *
913  * Returns          void
914  ******************************************************************************/
bta_hh_co_data(uint8_t dev_handle,uint8_t * p_rpt,uint16_t len)915 void bta_hh_co_data(uint8_t dev_handle, uint8_t* p_rpt, uint16_t len) {
916   btif_hh_device_t* p_dev;
917 
918   log::verbose("dev_handle = {}", dev_handle);
919 
920   p_dev = btif_hh_find_connected_dev_by_handle(dev_handle);
921   if (p_dev == NULL) {
922     log::warn("Error: unknown HID device handle {}", dev_handle);
923     return;
924   }
925 
926   if (com::android::bluetooth::flags::hid_report_queuing()) {
927     bta_hh_co_write(p_dev->internal_send_fd, p_rpt, len);
928     return;
929   }
930 
931   // Wait a maximum of MAX_POLLING_ATTEMPTS x POLLING_SLEEP_DURATION in case
932   // device creation is pending.
933   if (p_dev->uhid.fd >= 0) {
934     uint32_t polling_attempts = 0;
935     while (!p_dev->uhid.ready_for_data && polling_attempts++ < BTIF_HH_MAX_POLLING_ATTEMPTS) {
936       usleep(BTIF_HH_POLLING_SLEEP_DURATION_US);
937     }
938   }
939 
940   // Send the HID data to the kernel.
941   if ((p_dev->uhid.fd >= 0) && p_dev->uhid.ready_for_data) {
942     bta_hh_co_write(p_dev->uhid.fd, p_rpt, len);
943   } else {
944     log::warn("Error: fd = {}, ready {}, len = {}", p_dev->uhid.fd, p_dev->uhid.ready_for_data,
945               len);
946   }
947 }
948 
949 /*******************************************************************************
950  *
951  * Function         bta_hh_co_send_hid_info
952  *
953  * Description      This function is called in btif_hh.c to process DSCP
954  *                  received.
955  *
956  * Parameters       dev_handle  - device handle
957  *                  dscp_len    - report descriptor length
958  *                  *p_dscp     - report descriptor
959  *
960  * Returns          void
961  ******************************************************************************/
bta_hh_co_send_hid_info(btif_hh_device_t * p_dev,const char * dev_name,uint16_t vendor_id,uint16_t product_id,uint16_t version,uint8_t ctry_code,uint16_t dscp_len,uint8_t * p_dscp)962 void bta_hh_co_send_hid_info(btif_hh_device_t* p_dev, const char* dev_name, uint16_t vendor_id,
963                              uint16_t product_id, uint16_t version, uint8_t ctry_code,
964                              uint16_t dscp_len, uint8_t* p_dscp) {
965   int result;
966   tBTA_HH_TO_UHID_EVT to_uhid = {};
967   struct uhid_event& ev = to_uhid.uhid;
968 
969   if (!com::android::bluetooth::flags::hid_report_queuing()) {
970     if (p_dev->uhid.fd < 0) {
971       log::warn("Error: fd = {}, dscp_len = {}", p_dev->uhid.fd, dscp_len);
972       return;
973     }
974 
975     log::warn("fd = {}, name = [{}], dscp_len = {}", p_dev->uhid.fd, dev_name, dscp_len);
976   }
977   if (dscp_len > sizeof(ev.u.create2.rd_data)) {
978     log::error("HID descriptor is too long: {}", dscp_len);
979     return;
980   }
981 
982   log::info(
983           "vendor_id = 0x{:04x}, product_id = 0x{:04x}, version= "
984           "0x{:04x},ctry_code=0x{:02x}",
985           vendor_id, product_id, version, ctry_code);
986 
987   // Create and send hid descriptor to kernel
988   ev.type = UHID_CREATE2;
989   osi_strlcpy((char*)ev.u.create2.name, dev_name, sizeof(ev.u.create2.name));
990   // TODO (b/258090765) fix: ToString -> ToColonSepHexString
991   snprintf((char*)ev.u.create2.uniq, sizeof(ev.u.create2.uniq), "%s",
992            p_dev->link_spec.addrt.bda.ToString().c_str());
993 
994   // Write controller address to phys field to correlate the hid device with a
995   // specific bluetooth controller.
996   auto controller = bluetooth::shim::GetController();
997   // TODO (b/258090765) fix: ToString -> ToColonSepHexString
998   snprintf((char*)ev.u.create2.phys, sizeof(ev.u.create2.phys), "%s",
999            controller->GetMacAddress().ToString().c_str());
1000 
1001   ev.u.create2.rd_size = dscp_len;
1002   memcpy(ev.u.create2.rd_data, p_dscp, dscp_len);
1003   ev.u.create2.bus = BUS_BLUETOOTH;
1004   ev.u.create2.vendor = vendor_id;
1005   ev.u.create2.product = product_id;
1006   ev.u.create2.version = version;
1007   ev.u.create2.country = ctry_code;
1008 
1009   size_t mlen = uhid_calc_msg_len(&ev, dscp_len);
1010   if (!com::android::bluetooth::flags::hid_report_queuing()) {
1011     result = uhid_write(p_dev->uhid.fd, &ev, mlen);
1012 
1013     log::warn("wrote descriptor to fd = {}, dscp_len = {}, result = {}", p_dev->uhid.fd, dscp_len,
1014               result);
1015 
1016     if (result) {
1017       log::warn("Error: failed to send DSCP, result = {}", result);
1018 
1019       /* The HID report descriptor is corrupted. Close the driver. */
1020       close(p_dev->uhid.fd);
1021       p_dev->uhid.fd = -1;
1022     }
1023 
1024     return;
1025   }
1026 
1027   to_uhid.type = BTA_HH_UHID_INBOUND_DSCP_EVT;
1028   if (!to_uhid_thread(p_dev->internal_send_fd, &to_uhid, mlen)) {
1029     log::warn("Error: failed to send DSCP");
1030     if (p_dev->internal_send_fd >= 0) {
1031       // Detach the uhid thread. It will exit by itself upon receiving hangup.
1032       pthread_detach(p_dev->hh_poll_thread_id);
1033       p_dev->hh_poll_thread_id = -1;
1034       close(p_dev->internal_send_fd);
1035       p_dev->internal_send_fd = -1;
1036     }
1037   }
1038 
1039   return;
1040 }
1041 
1042 /*******************************************************************************
1043  *
1044  * Function         bta_hh_co_set_rpt_rsp
1045  *
1046  * Description      This callout function is executed by HH when Set Report
1047  *                  Response is received on Control Channel.
1048  *
1049  * Returns          void.
1050  *
1051  ******************************************************************************/
bta_hh_co_set_rpt_rsp(uint8_t dev_handle,uint8_t status)1052 void bta_hh_co_set_rpt_rsp([[maybe_unused]] uint8_t dev_handle, [[maybe_unused]] uint8_t status) {
1053 #if ENABLE_UHID_SET_REPORT
1054   log::verbose("dev_handle = {}", dev_handle);
1055 
1056   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_handle(dev_handle);
1057   if (p_dev == nullptr) {
1058     log::warn("Unknown HID device handle {}", dev_handle);
1059     return;
1060   }
1061 
1062   if (com::android::bluetooth::flags::hid_report_queuing()) {
1063     tBTA_HH_TO_UHID_EVT to_uhid = {};
1064     to_uhid.type = BTA_HH_UHID_INBOUND_SET_REPORT_EVT;
1065     to_uhid.uhid.type = UHID_SET_REPORT_REPLY;
1066     to_uhid.uhid.u.set_report_reply.err = status;
1067 
1068     to_uhid_thread(p_dev->internal_send_fd, &to_uhid, uhid_calc_msg_len(&to_uhid.uhid, 0));
1069     return;
1070   }
1071 
1072   if (!p_dev->uhid.set_rpt_id_queue) {
1073     log::warn("Missing UHID_SET_REPORT id queue");
1074     return;
1075   }
1076 
1077   // Send the HID set report reply to the kernel.
1078   if (p_dev->uhid.fd < 0) {
1079     log::error("Unexpected Set Report response");
1080     return;
1081   }
1082 
1083   uint32_t* context = (uint32_t*)fixed_queue_try_dequeue(p_dev->uhid.set_rpt_id_queue);
1084 
1085   if (context == nullptr) {
1086     log::warn("No pending UHID_SET_REPORT");
1087     return;
1088   }
1089 
1090   struct uhid_event ev = {
1091           .type = UHID_SET_REPORT_REPLY,
1092           .u =
1093                   {
1094                           .set_report_reply =
1095                                   {
1096                                           .id = *context,
1097                                           .err = status,
1098                                   },
1099                   },
1100   };
1101   uhid_write(p_dev->uhid.fd, &ev, uhid_calc_msg_len(&ev, 0));
1102   osi_free(context);
1103 
1104 #else
1105   log::error("UHID_SET_REPORT_REPLY not supported");
1106 #endif  // ENABLE_UHID_SET_REPORT
1107 }
1108 
1109 /*******************************************************************************
1110  *
1111  * Function         bta_hh_co_get_rpt_rsp
1112  *
1113  * Description      This callout function is executed by HH when Get Report
1114  *                  Response is received on Control Channel.
1115  *
1116  * Returns          void.
1117  *
1118  ******************************************************************************/
bta_hh_co_get_rpt_rsp(uint8_t dev_handle,uint8_t status,const uint8_t * p_rpt,uint16_t len)1119 void bta_hh_co_get_rpt_rsp(uint8_t dev_handle, uint8_t status, const uint8_t* p_rpt, uint16_t len) {
1120   btif_hh_device_t* p_dev;
1121 
1122   log::verbose("dev_handle = {}, status = {}", dev_handle, status);
1123 
1124   p_dev = btif_hh_find_connected_dev_by_handle(dev_handle);
1125   if (p_dev == nullptr) {
1126     log::warn("Unknown HID device handle {}", dev_handle);
1127     return;
1128   }
1129 
1130   // len of zero is allowed, it's possible on failure case.
1131   if (len > UHID_DATA_MAX) {
1132     log::warn("Invalid report size = {}", len);
1133     return;
1134   }
1135 
1136   if (com::android::bluetooth::flags::hid_report_queuing()) {
1137     tBTA_HH_TO_UHID_EVT to_uhid = {};
1138     to_uhid.type = BTA_HH_UHID_INBOUND_GET_REPORT_EVT;
1139     to_uhid.uhid.type = UHID_GET_REPORT_REPLY;
1140     to_uhid.uhid.u.get_report_reply.err = status;
1141     to_uhid.uhid.u.get_report_reply.size = len;
1142     if (len > 0) {
1143       memcpy(to_uhid.uhid.u.get_report_reply.data, p_rpt, len);
1144     }
1145 
1146     to_uhid_thread(p_dev->internal_send_fd, &to_uhid, uhid_calc_msg_len(&to_uhid.uhid, len));
1147     return;
1148   }
1149 
1150   if (!p_dev->uhid.get_rpt_id_queue) {
1151     log::warn("Missing UHID_GET_REPORT id queue");
1152     return;
1153   }
1154 
1155   // Send the HID report to the kernel.
1156   if (p_dev->uhid.fd < 0) {
1157     log::warn("Unexpected Get Report response");
1158     return;
1159   }
1160 
1161   uint32_t* context = (uint32_t*)fixed_queue_try_dequeue(p_dev->uhid.get_rpt_id_queue);
1162 
1163   if (context == nullptr) {
1164     log::warn("No pending UHID_GET_REPORT");
1165     return;
1166   }
1167 
1168   struct uhid_event ev = {
1169           .type = UHID_GET_REPORT_REPLY,
1170           .u =
1171                   {
1172                           .get_report_reply =
1173                                   {
1174                                           .id = *context,
1175                                           .err = status,
1176                                           .size = len,
1177                                   },
1178                   },
1179   };
1180   if (len > 0) {
1181     memcpy(ev.u.get_report_reply.data, p_rpt, len);
1182   }
1183 
1184   uhid_write(p_dev->uhid.fd, &ev, uhid_calc_msg_len(&ev, len));
1185   osi_free(context);
1186 }
1187 
1188 /*******************************************************************************
1189  *
1190  * Function         bta_hh_le_co_rpt_info
1191  *
1192  * Description      This callout function is to convey the report information on
1193  *                  a HOGP device to the application. Application can save this
1194  *                  information in NV if device is bonded and load it back when
1195  *                  stack reboot.
1196  *
1197  * Parameters       link_spec   - ACL link specification
1198  *                  p_entry     - report entry pointer
1199  *                  app_id      - application id
1200  *
1201  * Returns          void.
1202  *
1203  ******************************************************************************/
bta_hh_le_co_rpt_info(const tAclLinkSpec & link_spec,tBTA_HH_RPT_CACHE_ENTRY * p_entry,uint8_t)1204 void bta_hh_le_co_rpt_info(const tAclLinkSpec& link_spec, tBTA_HH_RPT_CACHE_ENTRY* p_entry,
1205                            uint8_t /* app_id */) {
1206   unsigned idx = 0;
1207 
1208   std::string addrstr = link_spec.addrt.bda.ToString();
1209   const char* bdstr = addrstr.c_str();
1210 
1211   size_t len = btif_config_get_bin_length(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT);
1212   if (len >= sizeof(tBTA_HH_RPT_CACHE_ENTRY) && len <= sizeof(sReportCache)) {
1213     btif_config_get_bin(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT, (uint8_t*)sReportCache, &len);
1214     idx = len / sizeof(tBTA_HH_RPT_CACHE_ENTRY);
1215   }
1216 
1217   if (idx < BTA_HH_NV_LOAD_MAX) {
1218     memcpy(&sReportCache[idx++], p_entry, sizeof(tBTA_HH_RPT_CACHE_ENTRY));
1219     btif_config_set_bin(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT, (const uint8_t*)sReportCache,
1220                         idx * sizeof(tBTA_HH_RPT_CACHE_ENTRY));
1221     btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT_VERSION, BTA_HH_CACHE_REPORT_VERSION);
1222     log::verbose("Saving report; dev={}, idx={}", link_spec, idx);
1223   }
1224 }
1225 
1226 /*******************************************************************************
1227  *
1228  * Function         bta_hh_le_co_cache_load
1229  *
1230  * Description      This callout function is to request the application to load
1231  *                  the cached HOGP report if there is any. When cache reading
1232  *                  is completed, bta_hh_le_co_cache_load() is called by the
1233  *                  application.
1234  *
1235  * Parameters       link_spec   - ACL link specification
1236  *                  p_num_rpt   - number of cached report
1237  *                  app_id      - application id
1238  *
1239  * Returns          the cached report array
1240  *
1241  ******************************************************************************/
bta_hh_le_co_cache_load(const tAclLinkSpec & link_spec,uint8_t * p_num_rpt,uint8_t app_id)1242 tBTA_HH_RPT_CACHE_ENTRY* bta_hh_le_co_cache_load(const tAclLinkSpec& link_spec, uint8_t* p_num_rpt,
1243                                                  uint8_t app_id) {
1244   std::string addrstr = link_spec.addrt.bda.ToString();
1245   const char* bdstr = addrstr.c_str();
1246 
1247   size_t len = btif_config_get_bin_length(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT);
1248   if (!p_num_rpt || len < sizeof(tBTA_HH_RPT_CACHE_ENTRY)) {
1249     return NULL;
1250   }
1251 
1252   if (len > sizeof(sReportCache)) {
1253     len = sizeof(sReportCache);
1254   }
1255   btif_config_get_bin(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT, (uint8_t*)sReportCache, &len);
1256 
1257   int cache_version = -1;
1258   btif_config_get_int(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT_VERSION, &cache_version);
1259 
1260   if (cache_version != BTA_HH_CACHE_REPORT_VERSION) {
1261     bta_hh_le_co_reset_rpt_cache(link_spec, app_id);
1262     return NULL;
1263   }
1264 
1265   *p_num_rpt = len / sizeof(tBTA_HH_RPT_CACHE_ENTRY);
1266 
1267   log::verbose("Loaded {} reports; dev={}", *p_num_rpt, link_spec);
1268 
1269   return sReportCache;
1270 }
1271 
1272 /*******************************************************************************
1273  *
1274  * Function         bta_hh_le_co_reset_rpt_cache
1275  *
1276  * Description      This callout function is to reset the HOGP device cache.
1277  *
1278  * Parameters       link_spec  - ACL link specification
1279  *
1280  * Returns          none
1281  *
1282  ******************************************************************************/
bta_hh_le_co_reset_rpt_cache(const tAclLinkSpec & link_spec,uint8_t)1283 void bta_hh_le_co_reset_rpt_cache(const tAclLinkSpec& link_spec, uint8_t /* app_id */) {
1284   std::string addrstr = link_spec.addrt.bda.ToString();
1285   const char* bdstr = addrstr.c_str();
1286 
1287   btif_config_remove(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT);
1288   btif_config_remove(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT_VERSION);
1289   log::verbose("Reset cache for bda {}", link_spec);
1290 }
1291