• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /* Max number of polling interrupt allowed */
62 #define BTA_HH_UHID_INTERRUPT_COUNT_MAX 100
63 /* Disconnect if UHID isn't ready after this many milliseconds. */
64 #define BTA_HH_UHID_READY_DISCONN_TIMEOUT_MS 10000
65 #define BTA_HH_UHID_READY_SHORT_DISCONN_TIMEOUT_MS 2000
66 
67 using namespace bluetooth;
68 
69 static constexpr char kDevPath[] = "/dev/uhid";
70 static constexpr char kPropertyWaitMsAfterUhidOpen[] = "bluetooth.hid.wait_ms_after_uhid_open";
71 
72 static constexpr bthh_report_type_t map_rtype_uhid_hh[] = {BTHH_FEATURE_REPORT, BTHH_OUTPUT_REPORT,
73                                                            BTHH_INPUT_REPORT};
74 
75 static void* btif_hh_poll_event_thread(void* arg);
76 static bool to_uhid_thread(int fd, const tBTA_HH_TO_UHID_EVT* ev, size_t data_len);
77 
uhid_set_non_blocking(int fd)78 static void uhid_set_non_blocking(int fd) {
79   int opts = fcntl(fd, F_GETFL);
80   if (opts < 0) {
81     log::error("Getting flags failed ({})", strerror(errno));
82   }
83 
84   opts |= O_NONBLOCK;
85 
86   if (fcntl(fd, F_SETFL, opts) < 0) {
87     log::verbose("Setting non-blocking flag failed ({})", strerror(errno));
88   }
89 }
90 
uhid_get_report_req_handler(btif_hh_uhid_t * p_uhid,struct uhid_get_report_req & req)91 static bool uhid_get_report_req_handler(btif_hh_uhid_t* p_uhid, struct uhid_get_report_req& req) {
92   log::debug("Report type = {}, id = {}", req.rtype, req.rnum);
93 
94   if (req.rtype > UHID_INPUT_REPORT) {
95     log::error("Invalid report type {}", req.rtype);
96     return false;
97   }
98 
99   if (p_uhid->get_rpt_id_queue == nullptr) {
100     log::error("Queue is not initialized");
101     return false;
102   }
103 
104   uint32_t* context = (uint32_t*)osi_malloc(sizeof(uint32_t));
105   *context = req.id;
106 
107   if (!fixed_queue_try_enqueue(p_uhid->get_rpt_id_queue, (void*)context)) {
108     osi_free(context);
109     log::error("Queue is full, dropping event {}", req.id);
110     return false;
111   }
112 
113   btif_hh_getreport(p_uhid, map_rtype_uhid_hh[req.rtype], req.rnum, 0);
114   return true;
115 }
116 
117 #if ENABLE_UHID_SET_REPORT
uhid_set_report_req_handler(btif_hh_uhid_t * p_uhid,struct uhid_set_report_req & req)118 static bool uhid_set_report_req_handler(btif_hh_uhid_t* p_uhid, struct uhid_set_report_req& req) {
119   log::debug("Report type = {}, id = {}", req.rtype, req.rnum);
120 
121   if (req.rtype > UHID_INPUT_REPORT) {
122     log::error("Invalid report type {}", req.rtype);
123     return false;
124   }
125 
126   if (p_uhid->set_rpt_id_queue == nullptr) {
127     log::error("Queue is not initialized");
128     return false;
129   }
130 
131   uint32_t* context = (uint32_t*)osi_malloc(sizeof(uint32_t));
132   *context = req.id;
133 
134   if (!fixed_queue_try_enqueue(p_uhid->set_rpt_id_queue, (void*)context)) {
135     osi_free(context);
136     log::error("Queue is full, dropping event {}", req.id);
137     return false;
138   }
139 
140   btif_hh_setreport(p_uhid, map_rtype_uhid_hh[req.rtype], req.size, req.data);
141   return true;
142 }
143 #endif  // ENABLE_UHID_SET_REPORT
144 
145 /* Calculate the minimum length required to send message to UHID */
uhid_calc_msg_len(const struct uhid_event * ev,size_t var_len)146 static size_t uhid_calc_msg_len(const struct uhid_event* ev, size_t var_len) {
147   switch (ev->type) {
148     // these messages don't have data following them, so just 4 bytes of type.
149     case UHID_DESTROY:
150     case UHID_STOP:
151     case UHID_OPEN:
152     case UHID_CLOSE:
153       return sizeof(ev->type);
154     // these messages has static length of data.
155     case UHID_START:
156       return sizeof(ev->type) + sizeof(ev->u.start);
157     case UHID_OUTPUT:
158       return sizeof(ev->type) + sizeof(ev->u.output);
159     case UHID_GET_REPORT:
160       return sizeof(ev->type) + sizeof(ev->u.get_report);
161     case UHID_SET_REPORT_REPLY:
162       return sizeof(ev->type) + sizeof(ev->u.set_report_reply);
163     // these messages has variable amount of data. We only need to write the
164     // necessary length.
165     case UHID_CREATE2:
166       return sizeof(ev->type) + sizeof(ev->u.create2) - HID_MAX_DESCRIPTOR_SIZE + var_len;
167     case UHID_INPUT2:
168       return sizeof(ev->type) + sizeof(ev->u.input2) - UHID_DATA_MAX + var_len;
169     case UHID_GET_REPORT_REPLY:
170       return sizeof(ev->type) + sizeof(ev->u.get_report_reply) - UHID_DATA_MAX + var_len;
171     case UHID_SET_REPORT:
172       return sizeof(ev->type) + sizeof(ev->u.set_report) - UHID_DATA_MAX + var_len;
173     default:
174       log::error("unknown uhid event type {}", ev->type);
175       return 0;
176   }
177 }
178 
179 /*Internal function to perform UHID write and error checking*/
uhid_write(int fd,const struct uhid_event * ev,size_t len)180 static int uhid_write(int fd, const struct uhid_event* ev, size_t len) {
181   ssize_t ret;
182   OSI_NO_INTR(ret = write(fd, ev, len));
183 
184   if (ret < 0) {
185     int rtn = -errno;
186     log::error("Cannot write to uhid:{}", strerror(errno));
187     return rtn;
188   } else if (ret != (ssize_t)len) {
189     log::error("Wrong size written to uhid: {} != {}", ret, len);
190     return -EFAULT;
191   }
192 
193   return 0;
194 }
195 
uhid_flush_input_queue(btif_hh_uhid_t * p_uhid)196 static void uhid_flush_input_queue(btif_hh_uhid_t* p_uhid) {
197   struct uhid_event* p_ev = nullptr;
198   while (true) {
199     p_ev = (struct uhid_event*)fixed_queue_try_dequeue(p_uhid->input_queue);
200     if (p_ev == nullptr) {
201       break;
202     }
203     uhid_write(p_uhid->fd, p_ev, uhid_calc_msg_len(p_ev, p_ev->u.input2.size));
204     osi_free(p_ev);
205   }
206 }
207 
uhid_set_ready(btif_hh_uhid_t * p_uhid)208 static void uhid_set_ready(btif_hh_uhid_t* p_uhid) {
209   if (p_uhid->ready_for_data) {
210     return;
211   }
212   p_uhid->ready_for_data = true;
213   uhid_flush_input_queue(p_uhid);
214 }
215 
216 // This runs on main thread.
uhid_delayed_ready_cback(void * data)217 static void uhid_delayed_ready_cback(void* data) {
218   int send_fd = PTR_TO_INT(data);
219   tBTA_HH_TO_UHID_EVT ev = {};
220 
221   // Notify the UHID thread that the timer has expired.
222   log::verbose("UHID delayed ready evt");
223   ev.type = BTA_HH_UHID_INBOUND_READY_EVT;
224   to_uhid_thread(send_fd, &ev, 0);
225 }
226 
227 // This runs on main thread.
uhid_ready_disconn_timeout(void * data)228 static void uhid_ready_disconn_timeout(void* data) {
229   int dev_handle = PTR_TO_INT(data);
230 
231   log::verbose("UHID ready disconn timeout evt");
232   BTA_HhClose(dev_handle);
233 }
234 
uhid_on_open(btif_hh_uhid_t * p_uhid)235 static void uhid_on_open(btif_hh_uhid_t* p_uhid) {
236   if (p_uhid->ready_for_data || alarm_is_scheduled(p_uhid->delayed_ready_timer)) {
237     return;
238   }
239 
240   if (com::android::bluetooth::flags::close_hid_if_uhid_ready_too_slow()) {
241     if (alarm_is_scheduled(p_uhid->ready_disconn_timer)) {
242       alarm_cancel(p_uhid->ready_disconn_timer);
243     }
244   }
245 
246   // On some platforms delay is required, because even though UHID has indicated
247   // ready, the input events might still not be processed, and therefore lost.
248   // If it's not required, immediately set UHID as ready.
249   int ready_delay_ms = osi_property_get_int32(kPropertyWaitMsAfterUhidOpen, 0);
250   if (ready_delay_ms == 0) {
251     uhid_set_ready(p_uhid);
252     return;
253   }
254 
255   alarm_set_on_mloop(p_uhid->delayed_ready_timer, ready_delay_ms, uhid_delayed_ready_cback,
256                      INT_TO_PTR(p_uhid->internal_send_fd));
257 }
258 
uhid_queue_input(btif_hh_uhid_t * p_uhid,struct uhid_event * ev,size_t len)259 static void uhid_queue_input(btif_hh_uhid_t* p_uhid, struct uhid_event* ev, size_t len) {
260   struct uhid_event* p_ev = (struct uhid_event*)osi_malloc(len);
261   if (!p_ev) {
262     log::error("allocate uhid_event failed");
263     return;
264   }
265   memcpy(p_ev, ev, len);
266 
267   if (!fixed_queue_try_enqueue(p_uhid->input_queue, (void*)p_ev)) {
268     osi_free(p_ev);
269     log::error("uhid_event_queue is full, dropping event");
270   }
271 }
272 
273 /* Parse the events received from UHID driver*/
uhid_read_outbound_event(btif_hh_uhid_t * p_uhid)274 static int uhid_read_outbound_event(btif_hh_uhid_t* p_uhid) {
275   log::assert_that(p_uhid != nullptr, "assert failed: p_uhid != nullptr");
276 
277   struct uhid_event ev = {};
278   ssize_t ret;
279   OSI_NO_INTR(ret = read(p_uhid->fd, &ev, sizeof(ev)));
280 
281   if (ret == 0) {
282     log::error("Read HUP on uhid-cdev {}", strerror(errno));
283     return -EFAULT;
284   } else if (ret < 0) {
285     log::error("Cannot read uhid-cdev: {}", strerror(errno));
286     return -errno;
287   }
288 
289   switch (ev.type) {
290     case UHID_START:
291       log::verbose("UHID_START from uhid-dev\n");
292       break;
293     case UHID_STOP:
294       log::verbose("UHID_STOP from uhid-dev\n");
295       break;
296     case UHID_OPEN:
297       log::verbose("UHID_OPEN from uhid-dev\n");
298       uhid_on_open(p_uhid);
299       break;
300     case UHID_CLOSE:
301       log::verbose("UHID_CLOSE from uhid-dev\n");
302       p_uhid->ready_for_data = false;
303       if (alarm_is_scheduled(p_uhid->delayed_ready_timer)) {
304         alarm_cancel(p_uhid->delayed_ready_timer);
305       }
306       if (com::android::bluetooth::flags::close_hid_if_uhid_ready_too_slow()) {
307         // It's possible to get OPEN->CLOSE->OPEN sequence from UHID. Therefore, instead of
308         // immediately disconnecting when receiving CLOSE, here we wait a while and will
309         // disconnect if we don't receive OPEN before it times out.
310         if (!alarm_is_scheduled(p_uhid->ready_disconn_timer)) {
311           alarm_set_on_mloop(p_uhid->ready_disconn_timer,
312                              BTA_HH_UHID_READY_SHORT_DISCONN_TIMEOUT_MS, uhid_ready_disconn_timeout,
313                              INT_TO_PTR(p_uhid->dev_handle));
314         }
315       }
316       break;
317     case UHID_OUTPUT:
318       if (ret < (ssize_t)(sizeof(ev.type) + sizeof(ev.u.output))) {
319         log::error("Invalid size read from uhid-dev: {} < {}", ret,
320                    sizeof(ev.type) + sizeof(ev.u.output));
321         return -EFAULT;
322       }
323 
324       log::verbose("UHID_OUTPUT: Report type = {}, report_size = {}", ev.u.output.rtype,
325                    ev.u.output.size);
326       // Send SET_REPORT with feature report if the report type in output event
327       // is FEATURE
328       if (ev.u.output.rtype == UHID_FEATURE_REPORT) {
329         btif_hh_setreport(p_uhid, BTHH_FEATURE_REPORT, ev.u.output.size, ev.u.output.data);
330       } else if (ev.u.output.rtype == UHID_OUTPUT_REPORT) {
331         btif_hh_senddata(p_uhid, ev.u.output.size, ev.u.output.data);
332       } else {
333         log::error("UHID_OUTPUT: Invalid report type = {}", ev.u.output.rtype);
334       }
335       break;
336 
337     case UHID_GET_REPORT:
338       if (ret < (ssize_t)(sizeof(ev.type) + sizeof(ev.u.get_report))) {
339         log::error("UHID_GET_REPORT: Invalid size read from uhid-dev: {} < {}", ret,
340                    sizeof(ev.type) + sizeof(ev.u.get_report));
341         return -EFAULT;
342       }
343 
344       if (!uhid_get_report_req_handler(p_uhid, ev.u.get_report)) {
345         return -EFAULT;
346       }
347 
348       break;
349 
350 #if ENABLE_UHID_SET_REPORT
351     case UHID_SET_REPORT: {
352       if (ret < (ssize_t)(sizeof(ev.type) + sizeof(ev.u.set_report))) {
353         log::error("UHID_SET_REPORT: Invalid size read from uhid-dev: {} < {}", ret,
354                    sizeof(ev.type) + sizeof(ev.u.set_report));
355         return -EFAULT;
356       }
357 
358       if (!uhid_set_report_req_handler(p_uhid, ev.u.set_report)) {
359         return -EFAULT;
360       }
361       break;
362     }
363 #endif  // ENABLE_UHID_SET_REPORT
364 
365     default:
366       log::error("Invalid event from uhid-dev: {}\n", ev.type);
367   }
368 
369   return 0;
370 }
371 
372 // Parse the internal events received from BTIF and translate to UHID
373 // returns -errno when error, 0 when successful, 1 when receiving close event.
uhid_read_inbound_event(btif_hh_uhid_t * p_uhid)374 static int uhid_read_inbound_event(btif_hh_uhid_t* p_uhid) {
375   log::assert_that(p_uhid != nullptr, "assert failed: p_uhid != nullptr");
376 
377   tBTA_HH_TO_UHID_EVT ev = {};
378   ssize_t ret;
379   OSI_NO_INTR(ret = read(p_uhid->internal_recv_fd, &ev, sizeof(ev)));
380 
381   if (ret == 0) {
382     log::error("Read HUP on internal uhid-cdev {}", strerror(errno));
383     return -EFAULT;
384   } else if (ret < 0) {
385     log::error("Cannot read internal uhid-cdev: {}", strerror(errno));
386     return -errno;
387   }
388 
389   int res = 0;
390   uint32_t* context;
391   switch (ev.type) {
392     case BTA_HH_UHID_INBOUND_INPUT_EVT:
393       if (p_uhid->ready_for_data) {
394         res = uhid_write(p_uhid->fd, &ev.uhid, ret - 1);
395       } else {
396         uhid_queue_input(p_uhid, &ev.uhid, ret - 1);
397       }
398       break;
399     case BTA_HH_UHID_INBOUND_READY_EVT:
400       uhid_set_ready(p_uhid);
401       break;
402     case BTA_HH_UHID_INBOUND_CLOSE_EVT:
403       res = 1;  // any positive value indicates a normal close event
404       break;
405     case BTA_HH_UHID_INBOUND_DSCP_EVT:
406       res = uhid_write(p_uhid->fd, &ev.uhid, ret - 1);
407       break;
408     case BTA_HH_UHID_INBOUND_GET_REPORT_EVT:
409       context = (uint32_t*)fixed_queue_try_dequeue(p_uhid->get_rpt_id_queue);
410       if (context == nullptr) {
411         log::warn("No pending UHID_GET_REPORT");
412         break;
413       }
414       ev.uhid.u.get_report_reply.id = *context;
415       res = uhid_write(p_uhid->fd, &ev.uhid, ret - 1);
416       osi_free(context);
417       break;
418 #if ENABLE_UHID_SET_REPORT
419     case BTA_HH_UHID_INBOUND_SET_REPORT_EVT:
420       context = (uint32_t*)fixed_queue_try_dequeue(p_uhid->set_rpt_id_queue);
421       if (context == nullptr) {
422         log::warn("No pending UHID_SET_REPORT");
423         break;
424       }
425       ev.uhid.u.set_report_reply.id = *context;
426       res = uhid_write(p_uhid->fd, &ev.uhid, ret - 1);
427       osi_free(context);
428       break;
429 #endif  // ENABLE_UHID_SET_REPORT
430     default:
431       log::error("Invalid event from internal uhid-dev: {}", (uint8_t)ev.type);
432   }
433 
434   return res;
435 }
436 
437 /*******************************************************************************
438  *
439  * Function create_thread
440  *
441  * Description creat a select loop
442  *
443  * Returns pthread_t
444  *
445  ******************************************************************************/
create_thread(void * (* start_routine)(void *),void * arg)446 static inline pthread_t create_thread(void* (*start_routine)(void*), void* arg) {
447   log::verbose("create_thread: entered");
448   pthread_attr_t thread_attr;
449 
450   pthread_attr_init(&thread_attr);
451   pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
452   pthread_t thread_id = -1;
453   if (pthread_create(&thread_id, &thread_attr, start_routine, arg) != 0) {
454     log::error("pthread_create : {}", strerror(errno));
455     return -1;
456   }
457   log::verbose("create_thread: thread created successfully");
458   return thread_id;
459 }
460 
461 /* Internal function to close the UHID driver*/
uhid_fd_close(btif_hh_uhid_t * p_uhid)462 static void uhid_fd_close(btif_hh_uhid_t* p_uhid) {
463   if (p_uhid->fd >= 0) {
464     struct uhid_event ev = {};
465     ev.type = UHID_DESTROY;
466     uhid_write(p_uhid->fd, &ev, uhid_calc_msg_len(&ev, 0));
467     log::debug("Closing fd={}, addr:{}", p_uhid->fd, p_uhid->link_spec);
468     close(p_uhid->fd);
469     p_uhid->fd = -1;
470     close(p_uhid->internal_recv_fd);
471     p_uhid->internal_recv_fd = -1;
472     /* Clear the queues */
473     fixed_queue_flush(p_uhid->get_rpt_id_queue, osi_free);
474     fixed_queue_free(p_uhid->get_rpt_id_queue, NULL);
475     p_uhid->get_rpt_id_queue = NULL;
476 #if ENABLE_UHID_SET_REPORT
477     fixed_queue_flush(p_uhid->set_rpt_id_queue, osi_free);
478     fixed_queue_free(p_uhid->set_rpt_id_queue, nullptr);
479     p_uhid->set_rpt_id_queue = nullptr;
480 #endif  // ENABLE_UHID_SET_REPORT
481     fixed_queue_flush(p_uhid->input_queue, osi_free);
482     fixed_queue_free(p_uhid->input_queue, nullptr);
483     p_uhid->input_queue = nullptr;
484 
485     alarm_free(p_uhid->delayed_ready_timer);
486     alarm_free(p_uhid->ready_disconn_timer);
487     osi_free(p_uhid);
488   }
489 }
490 
491 /* Internal function to open the UHID driver*/
uhid_fd_open(btif_hh_device_t * p_dev)492 static bool uhid_fd_open(btif_hh_device_t* p_dev) {
493   if (p_dev->internal_send_fd < 0) {
494     int sockets[2];
495     if (socketpair(AF_LOCAL, SOCK_SEQPACKET | SOCK_NONBLOCK, 0, sockets) < 0) {
496       return false;
497     }
498 
499     btif_hh_uhid_t* uhid = (btif_hh_uhid_t*)osi_malloc(sizeof(btif_hh_uhid_t));
500     uhid->link_spec = p_dev->link_spec;
501     uhid->dev_handle = p_dev->dev_handle;
502     uhid->internal_recv_fd = sockets[0];
503     uhid->internal_send_fd = sockets[1];
504     p_dev->internal_send_fd = sockets[1];
505 
506     // UHID thread owns the uhid struct and is responsible to free it.
507     p_dev->hh_poll_thread_id = create_thread(btif_hh_poll_event_thread, uhid);
508   }
509   return true;
510 }
511 
uhid_fd_poll(struct pollfd * pfds,int nfds)512 static int uhid_fd_poll(struct pollfd* pfds, int nfds) {
513   int ret = 0;
514   int counter = 0;
515 
516   do {
517     if (counter++ > BTA_HH_UHID_INTERRUPT_COUNT_MAX) {
518       log::error("Polling interrupted consecutively {} times", BTA_HH_UHID_INTERRUPT_COUNT_MAX);
519       return -1;
520     }
521     ret = poll(pfds, nfds, -1);
522   } while (ret == -1 && errno == EINTR);
523 
524   return ret;
525 }
526 
uhid_start_polling(btif_hh_uhid_t * p_uhid)527 static void uhid_start_polling(btif_hh_uhid_t* p_uhid) {
528   std::array<struct pollfd, 2> pfds = {};
529   pfds[0].fd = p_uhid->fd;
530   pfds[0].events = POLLIN;
531   pfds[1].fd = p_uhid->internal_recv_fd;
532   pfds[1].events = POLLIN;
533 
534   while (true) {
535     int ret = uhid_fd_poll(pfds.data(), 2);
536     if (ret < 0) {
537       log::error("Cannot poll for fds: {}\n", strerror(errno));
538       break;
539     }
540 
541     if (pfds[0].revents & POLLIN) {
542       log::verbose("POLLIN");
543       int result = uhid_read_outbound_event(p_uhid);
544       if (result != 0) {
545         log::error("Unhandled UHID outbound event, error: {}", result);
546         break;
547       }
548     }
549 
550     if (pfds[1].revents & POLLIN) {
551       int result = uhid_read_inbound_event(p_uhid);
552       if (result != 0) {
553         if (result < 0) {
554           log::error("Unhandled UHID inbound event, error: {}", result);
555         }
556         break;
557       }
558     }
559 
560     if (pfds[1].revents & POLLHUP) {
561       log::error("inbound fd hangup, disconnect UHID");
562       break;
563     }
564   }
565 }
566 
uhid_configure_thread(btif_hh_uhid_t * p_uhid)567 static bool uhid_configure_thread(btif_hh_uhid_t* p_uhid) {
568   pid_t pid = gettid();
569   // This thread is created by bt_main_thread with RT priority. Lower the thread
570   // priority here since the tasks in this thread is not timing critical.
571   struct sched_param sched_params;
572   sched_params.sched_priority = THREAD_NORMAL_PRIORITY;
573   if (sched_setscheduler(pid, SCHED_OTHER, &sched_params)) {
574     log::error("Failed to set thread priority to normal: {}", strerror(errno));
575     return false;
576   }
577 
578   // Change the name of thread
579   char thread_name[16] = {};
580   sprintf(thread_name, BT_HH_THREAD_PREFIX "%02x:%02x", p_uhid->link_spec.addrt.bda.address[4],
581           p_uhid->link_spec.addrt.bda.address[5]);
582   pthread_setname_np(pthread_self(), thread_name);
583   log::debug("Host hid polling thread created name:{} pid:{} fd:{}", thread_name, pid, p_uhid->fd);
584 
585   // Set the uhid fd as non-blocking to ensure we never block the BTU thread
586   uhid_set_non_blocking(p_uhid->fd);
587 
588   return true;
589 }
590 
591 /*******************************************************************************
592  *
593  * Function btif_hh_poll_event_thread
594  *
595  * Description the polling thread which polls for event from UHID driver
596  *
597  * Returns void
598  *
599  ******************************************************************************/
btif_hh_poll_event_thread(void * arg)600 static void* btif_hh_poll_event_thread(void* arg) {
601   btif_hh_uhid_t* p_uhid = (btif_hh_uhid_t*)arg;
602 
603   p_uhid->fd = open(kDevPath, O_RDWR | O_CLOEXEC);
604   if (p_uhid->fd < 0) {
605     log::error("Failed to open uhid, err:{}", strerror(errno));
606     close(p_uhid->internal_recv_fd);
607     p_uhid->internal_recv_fd = -1;
608     return 0;
609   }
610   p_uhid->ready_for_data = false;
611   p_uhid->delayed_ready_timer = alarm_new("uhid_delayed_ready_timer");
612   p_uhid->ready_disconn_timer = alarm_new("uhid_ready_disconn_timer");
613   if (com::android::bluetooth::flags::close_hid_if_uhid_ready_too_slow()) {
614     alarm_set_on_mloop(p_uhid->ready_disconn_timer, BTA_HH_UHID_READY_DISCONN_TIMEOUT_MS,
615                        uhid_ready_disconn_timeout, INT_TO_PTR(p_uhid->dev_handle));
616   }
617 
618   p_uhid->get_rpt_id_queue = fixed_queue_new(SIZE_MAX);
619   log::assert_that(p_uhid->get_rpt_id_queue, "assert failed: p_uhid->get_rpt_id_queue");
620 #if ENABLE_UHID_SET_REPORT
621   p_uhid->set_rpt_id_queue = fixed_queue_new(SIZE_MAX);
622   log::assert_that(p_uhid->set_rpt_id_queue, "assert failed: p_uhid->set_rpt_id_queue");
623 #endif  // ENABLE_UHID_SET_REPORT
624   p_uhid->input_queue = fixed_queue_new(SIZE_MAX);
625   log::assert_that(p_uhid->input_queue, "assert failed: p_uhid->input_queue");
626 
627   if (uhid_configure_thread(p_uhid)) {
628     uhid_start_polling(p_uhid);
629   }
630 
631   /* Todo: Disconnect if loop exited due to a failure */
632   log::info("Polling thread stopped for device {}", p_uhid->link_spec);
633   uhid_fd_close(p_uhid);
634   return 0;
635 }
636 
637 /* 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)638 static bool to_uhid_thread(int fd, const tBTA_HH_TO_UHID_EVT* ev, size_t data_len) {
639   if (fd < 0) {
640     log::error("Cannot write to uhid thread: invalid fd");
641     return false;
642   }
643 
644   size_t len = data_len + sizeof(ev->type);
645   ssize_t ret;
646   OSI_NO_INTR(ret = write(fd, ev, len));
647 
648   if (ret < 0) {
649     log::error("Cannot write to uhid thread: {}", strerror(errno));
650     return false;
651   } else if (ret != (ssize_t)len) {
652     log::error("Wrong size written to uhid thread: {} != {}", ret, len);
653     return false;
654   }
655 
656   return true;
657 }
658 
bta_hh_co_write(int fd,uint8_t * rpt,uint16_t len)659 int bta_hh_co_write(int fd, uint8_t* rpt, uint16_t len) {
660   log::verbose("UHID write {}", len);
661 
662   tBTA_HH_TO_UHID_EVT to_uhid = {};
663   struct uhid_event& ev = to_uhid.uhid;
664   ev.type = UHID_INPUT2;
665   ev.u.input2.size = len;
666   if (len > sizeof(ev.u.input2.data)) {
667     log::warn("Report size greater than allowed size");
668     return -1;
669   }
670   memcpy(ev.u.input2.data, rpt, len);
671 
672   size_t mlen = uhid_calc_msg_len(&ev, len);
673   to_uhid.type = BTA_HH_UHID_INBOUND_INPUT_EVT;
674   return to_uhid_thread(fd, &to_uhid, mlen) ? 0 : -1;
675 }
676 
677 /*******************************************************************************
678  *
679  * Function      bta_hh_co_open
680  *
681  * Description   When connection is opened, this call-out function is executed
682  *               by HH to do platform specific initialization.
683  *
684  * Returns       True if platform specific initialization is successful
685  ******************************************************************************/
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)686 bool bta_hh_co_open(uint8_t dev_handle, uint8_t sub_class, tBTA_HH_ATTR_MASK attr_mask,
687                     uint8_t app_id, tAclLinkSpec& link_spec) {
688   bool new_device = false;
689 
690   if (dev_handle == BTA_HH_INVALID_HANDLE) {
691     log::warn("dev_handle ({}) is invalid", dev_handle);
692     return false;
693   }
694 
695   // Reuse existing instance if possible
696   btif_hh_device_t* p_dev = btif_hh_find_dev_by_handle(dev_handle);
697   if (p_dev != nullptr) {
698     log::info(
699             "Found an existing device with the same handle dev_status={}, "
700             "device={}, attr_mask=0x{:04x}, sub_class=0x{:02x}, app_id={}, "
701             "dev_handle={}",
702             p_dev->dev_status, p_dev->link_spec, p_dev->attr_mask, p_dev->sub_class, p_dev->app_id,
703             dev_handle);
704   } else {  // Use an empty slot
705     p_dev = btif_hh_find_empty_dev();
706     if (p_dev == nullptr) {
707       log::error("Too many HID devices are connected");
708       return false;
709     }
710 
711     new_device = true;
712     log::verbose("New HID device added for handle {}", dev_handle);
713 
714     p_dev->internal_send_fd = -1;
715     p_dev->attr_mask = attr_mask;
716     p_dev->sub_class = sub_class;
717     p_dev->app_id = app_id;
718     p_dev->local_vup = false;
719   }
720 
721   p_dev->link_spec = link_spec;
722   p_dev->dev_handle = dev_handle;
723 
724   if (!uhid_fd_open(p_dev)) {
725     return false;
726   }
727 
728   if (new_device) {
729     btif_hh_cb.device_num++;
730   }
731 
732   p_dev->dev_status = BTHH_CONN_STATE_CONNECTED;
733   log::debug("Return device status {}", p_dev->dev_status);
734   return true;
735 }
736 
737 /*******************************************************************************
738  *
739  * Function      bta_hh_co_close
740  *
741  * Description   When connection is closed, this call-out function is executed
742  *               by HH to do platform specific finalization.
743  *
744  * Parameters    p_dev  - device
745  *
746  * Returns       void.
747  ******************************************************************************/
bta_hh_co_close(btif_hh_device_t * p_dev)748 void bta_hh_co_close(btif_hh_device_t* p_dev) {
749   log::info("Closing device handle={}, status={}, address={}", p_dev->dev_handle, p_dev->dev_status,
750             p_dev->link_spec);
751 
752   if (p_dev->internal_send_fd >= 0) {
753     tBTA_HH_TO_UHID_EVT to_uhid = {};
754     to_uhid.type = BTA_HH_UHID_INBOUND_CLOSE_EVT;
755     to_uhid_thread(p_dev->internal_send_fd, &to_uhid, 0);
756     pthread_join(p_dev->hh_poll_thread_id, NULL);
757     p_dev->hh_poll_thread_id = -1;
758 
759     close(p_dev->internal_send_fd);
760     p_dev->internal_send_fd = -1;
761   }
762 }
763 
764 /*******************************************************************************
765  *
766  * Function         bta_hh_co_data
767  *
768  * Description      This function is executed by BTA when HID host receive a
769  *                  data report.
770  *
771  * Parameters       dev_handle  - device handle
772  *                  *p_rpt      - pointer to the report data
773  *                  len         - length of report data
774  *
775  * Returns          void
776  ******************************************************************************/
bta_hh_co_data(uint8_t dev_handle,uint8_t * p_rpt,uint16_t len)777 void bta_hh_co_data(uint8_t dev_handle, uint8_t* p_rpt, uint16_t len) {
778   btif_hh_device_t* p_dev;
779 
780   log::verbose("dev_handle = {}", dev_handle);
781 
782   p_dev = btif_hh_find_connected_dev_by_handle(dev_handle);
783   if (p_dev == NULL) {
784     log::warn("Error: unknown HID device handle {}", dev_handle);
785     return;
786   }
787 
788   bta_hh_co_write(p_dev->internal_send_fd, p_rpt, len);
789 }
790 
791 /*******************************************************************************
792  *
793  * Function         bta_hh_co_send_hid_info
794  *
795  * Description      This function is called in btif_hh.c to process DSCP
796  *                  received.
797  *
798  * Parameters       dev_handle  - device handle
799  *                  dscp_len    - report descriptor length
800  *                  *p_dscp     - report descriptor
801  *
802  * Returns          void
803  ******************************************************************************/
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)804 void bta_hh_co_send_hid_info(btif_hh_device_t* p_dev, const char* dev_name, uint16_t vendor_id,
805                              uint16_t product_id, uint16_t version, uint8_t ctry_code,
806                              uint16_t dscp_len, uint8_t* p_dscp) {
807   int result;
808   tBTA_HH_TO_UHID_EVT to_uhid = {};
809   struct uhid_event& ev = to_uhid.uhid;
810 
811   if (dscp_len > sizeof(ev.u.create2.rd_data)) {
812     log::error("HID descriptor is too long: {}", dscp_len);
813     return;
814   }
815 
816   log::info(
817           "vendor_id = 0x{:04x}, product_id = 0x{:04x}, version= "
818           "0x{:04x},ctry_code=0x{:02x}",
819           vendor_id, product_id, version, ctry_code);
820 
821   // Create and send hid descriptor to kernel
822   ev.type = UHID_CREATE2;
823   osi_strlcpy((char*)ev.u.create2.name, dev_name, sizeof(ev.u.create2.name));
824   // TODO (b/258090765) fix: ToString -> ToColonSepHexString
825   snprintf((char*)ev.u.create2.uniq, sizeof(ev.u.create2.uniq), "%s",
826            p_dev->link_spec.addrt.bda.ToString().c_str());
827 
828   // Write controller address to phys field to correlate the hid device with a
829   // specific bluetooth controller.
830   auto controller = bluetooth::shim::GetController();
831   // TODO (b/258090765) fix: ToString -> ToColonSepHexString
832   snprintf((char*)ev.u.create2.phys, sizeof(ev.u.create2.phys), "%s",
833            controller->GetMacAddress().ToString().c_str());
834 
835   ev.u.create2.rd_size = dscp_len;
836   memcpy(ev.u.create2.rd_data, p_dscp, dscp_len);
837   ev.u.create2.bus = BUS_BLUETOOTH;
838   ev.u.create2.vendor = vendor_id;
839   ev.u.create2.product = product_id;
840   ev.u.create2.version = version;
841   ev.u.create2.country = ctry_code;
842 
843   size_t mlen = uhid_calc_msg_len(&ev, dscp_len);
844   to_uhid.type = BTA_HH_UHID_INBOUND_DSCP_EVT;
845   if (!to_uhid_thread(p_dev->internal_send_fd, &to_uhid, mlen)) {
846     log::warn("Error: failed to send DSCP");
847     if (p_dev->internal_send_fd >= 0) {
848       // Detach the uhid thread. It will exit by itself upon receiving hangup.
849       pthread_detach(p_dev->hh_poll_thread_id);
850       p_dev->hh_poll_thread_id = -1;
851       close(p_dev->internal_send_fd);
852       p_dev->internal_send_fd = -1;
853     }
854   }
855 
856   return;
857 }
858 
859 /*******************************************************************************
860  *
861  * Function         bta_hh_co_set_rpt_rsp
862  *
863  * Description      This callout function is executed by HH when Set Report
864  *                  Response is received on Control Channel.
865  *
866  * Returns          void.
867  *
868  ******************************************************************************/
bta_hh_co_set_rpt_rsp(uint8_t dev_handle,uint8_t status)869 void bta_hh_co_set_rpt_rsp([[maybe_unused]] uint8_t dev_handle, [[maybe_unused]] uint8_t status) {
870 #if ENABLE_UHID_SET_REPORT
871   log::verbose("dev_handle = {}", dev_handle);
872 
873   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_handle(dev_handle);
874   if (p_dev == nullptr) {
875     log::warn("Unknown HID device handle {}", dev_handle);
876     return;
877   }
878 
879   tBTA_HH_TO_UHID_EVT to_uhid = {};
880   to_uhid.type = BTA_HH_UHID_INBOUND_SET_REPORT_EVT;
881   to_uhid.uhid.type = UHID_SET_REPORT_REPLY;
882   to_uhid.uhid.u.set_report_reply.err = status;
883 
884   to_uhid_thread(p_dev->internal_send_fd, &to_uhid, uhid_calc_msg_len(&to_uhid.uhid, 0));
885   return;
886 #else
887   log::error("UHID_SET_REPORT_REPLY not supported");
888 #endif  // ENABLE_UHID_SET_REPORT
889 }
890 
891 /*******************************************************************************
892  *
893  * Function         bta_hh_co_get_rpt_rsp
894  *
895  * Description      This callout function is executed by HH when Get Report
896  *                  Response is received on Control Channel.
897  *
898  * Returns          void.
899  *
900  ******************************************************************************/
bta_hh_co_get_rpt_rsp(uint8_t dev_handle,uint8_t status,const uint8_t * p_rpt,uint16_t len)901 void bta_hh_co_get_rpt_rsp(uint8_t dev_handle, uint8_t status, const uint8_t* p_rpt, uint16_t len) {
902   btif_hh_device_t* p_dev;
903 
904   log::verbose("dev_handle = {}, status = {}", dev_handle, status);
905 
906   p_dev = btif_hh_find_connected_dev_by_handle(dev_handle);
907   if (p_dev == nullptr) {
908     log::warn("Unknown HID device handle {}", dev_handle);
909     return;
910   }
911 
912   // len of zero is allowed, it's possible on failure case.
913   if (len > UHID_DATA_MAX) {
914     log::warn("Invalid report size = {}", len);
915     return;
916   }
917 
918   tBTA_HH_TO_UHID_EVT to_uhid = {};
919   to_uhid.type = BTA_HH_UHID_INBOUND_GET_REPORT_EVT;
920   to_uhid.uhid.type = UHID_GET_REPORT_REPLY;
921   to_uhid.uhid.u.get_report_reply.err = status;
922   to_uhid.uhid.u.get_report_reply.size = len;
923   if (len > 0) {
924     memcpy(to_uhid.uhid.u.get_report_reply.data, p_rpt, len);
925   }
926 
927   to_uhid_thread(p_dev->internal_send_fd, &to_uhid, uhid_calc_msg_len(&to_uhid.uhid, len));
928 }
929 
930 /*******************************************************************************
931  *
932  * Function         bta_hh_le_co_rpt_info
933  *
934  * Description      This callout function is to convey the report information on
935  *                  a HOGP device to the application. Application can save this
936  *                  information in NV if device is bonded and load it back when
937  *                  stack reboot.
938  *
939  * Parameters       link_spec   - ACL link specification
940  *                  p_entry     - report entry pointer
941  *                  app_id      - application id
942  *
943  * Returns          void.
944  *
945  ******************************************************************************/
bta_hh_le_co_rpt_info(const tAclLinkSpec & link_spec,tBTA_HH_RPT_CACHE_ENTRY * p_entry,uint8_t)946 void bta_hh_le_co_rpt_info(const tAclLinkSpec& link_spec, tBTA_HH_RPT_CACHE_ENTRY* p_entry,
947                            uint8_t /* app_id */) {
948   unsigned idx = 0;
949 
950   std::string addrstr = link_spec.addrt.bda.ToString();
951   const char* bdstr = addrstr.c_str();
952 
953   size_t len = btif_config_get_bin_length(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT);
954   if (len >= sizeof(tBTA_HH_RPT_CACHE_ENTRY) && len <= sizeof(sReportCache)) {
955     btif_config_get_bin(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT, (uint8_t*)sReportCache, &len);
956     idx = len / sizeof(tBTA_HH_RPT_CACHE_ENTRY);
957   }
958 
959   if (idx < BTA_HH_NV_LOAD_MAX) {
960     memcpy(&sReportCache[idx++], p_entry, sizeof(tBTA_HH_RPT_CACHE_ENTRY));
961     btif_config_set_bin(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT, (const uint8_t*)sReportCache,
962                         idx * sizeof(tBTA_HH_RPT_CACHE_ENTRY));
963     btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT_VERSION, BTA_HH_CACHE_REPORT_VERSION);
964     log::verbose("Saving report; dev={}, idx={}", link_spec, idx);
965   }
966 }
967 
968 /*******************************************************************************
969  *
970  * Function         bta_hh_le_co_cache_load
971  *
972  * Description      This callout function is to request the application to load
973  *                  the cached HOGP report if there is any. When cache reading
974  *                  is completed, bta_hh_le_co_cache_load() is called by the
975  *                  application.
976  *
977  * Parameters       link_spec   - ACL link specification
978  *                  p_num_rpt   - number of cached report
979  *                  app_id      - application id
980  *
981  * Returns          the cached report array
982  *
983  ******************************************************************************/
bta_hh_le_co_cache_load(const tAclLinkSpec & link_spec,uint8_t * p_num_rpt,uint8_t app_id)984 tBTA_HH_RPT_CACHE_ENTRY* bta_hh_le_co_cache_load(const tAclLinkSpec& link_spec, uint8_t* p_num_rpt,
985                                                  uint8_t app_id) {
986   std::string addrstr = link_spec.addrt.bda.ToString();
987   const char* bdstr = addrstr.c_str();
988 
989   size_t len = btif_config_get_bin_length(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT);
990   if (!p_num_rpt || len < sizeof(tBTA_HH_RPT_CACHE_ENTRY)) {
991     return NULL;
992   }
993 
994   if (len > sizeof(sReportCache)) {
995     len = sizeof(sReportCache);
996   }
997   btif_config_get_bin(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT, (uint8_t*)sReportCache, &len);
998 
999   int cache_version = -1;
1000   btif_config_get_int(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT_VERSION, &cache_version);
1001 
1002   if (cache_version != BTA_HH_CACHE_REPORT_VERSION) {
1003     bta_hh_le_co_reset_rpt_cache(link_spec, app_id);
1004     return NULL;
1005   }
1006 
1007   *p_num_rpt = len / sizeof(tBTA_HH_RPT_CACHE_ENTRY);
1008 
1009   log::verbose("Loaded {} reports; dev={}", *p_num_rpt, link_spec);
1010 
1011   return sReportCache;
1012 }
1013 
1014 /*******************************************************************************
1015  *
1016  * Function         bta_hh_le_co_reset_rpt_cache
1017  *
1018  * Description      This callout function is to reset the HOGP device cache.
1019  *
1020  * Parameters       link_spec  - ACL link specification
1021  *
1022  * Returns          none
1023  *
1024  ******************************************************************************/
bta_hh_le_co_reset_rpt_cache(const tAclLinkSpec & link_spec,uint8_t)1025 void bta_hh_le_co_reset_rpt_cache(const tAclLinkSpec& link_spec, uint8_t /* app_id */) {
1026   std::string addrstr = link_spec.addrt.bda.ToString();
1027   const char* bdstr = addrstr.c_str();
1028 
1029   btif_config_remove(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT);
1030   btif_config_remove(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT_VERSION);
1031   log::verbose("Reset cache for bda {}", link_spec);
1032 }
1033