Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d853d4c8 authored by Andre Eisenbach's avatar Andre Eisenbach Committed by Android Git Automerger
Browse files

am 8f81173e: am 55712734: Change UHID socket to be non-blocking

* commit '8f81173e':
  Change UHID socket to be non-blocking
parents ff410fa8 8f81173e
Loading
Loading
Loading
Loading
+43 −14
Original line number Diff line number Diff line
@@ -43,11 +43,23 @@ const char *dev_path = "/dev/uhid";
static tBTA_HH_RPT_CACHE_ENTRY sReportCache[BTA_HH_NV_LOAD_MAX];
#endif

void uhid_set_non_blocking(int fd)
{
    int opts = fcntl(fd, F_GETFL);
    if (opts < 0)
        APPL_TRACE_ERROR("%s() Getting flags failed (%s)", __func__, strerror(errno));

    opts |= O_NONBLOCK;

    if (fcntl(fd, F_SETFL, opts) < 0)
        APPL_TRACE_EVENT("%s() Setting non-blocking flag failed (%s)", __func__, strerror(errno));
}

/*Internal function to perform UHID write and error checking*/
static int uhid_write(int fd, const struct uhid_event *ev)
{
    ssize_t ret;
    ret = write(fd, ev, sizeof(*ev));
    ssize_t ret = write(fd, ev, sizeof(*ev));

    if (ret < 0){
        int rtn = -errno;
        APPL_TRACE_ERROR("%s: Cannot write to uhid:%s",
@@ -57,9 +69,9 @@ static int uhid_write(int fd, const struct uhid_event *ev)
        APPL_TRACE_ERROR("%s: Wrong size written to uhid: %zd != %zu",
                         __FUNCTION__, ret, sizeof(*ev));
        return -EFAULT;
    } else {
        return 0;
    }

    return 0;
}

/* Internal function to parse the events received from UHID driver*/
@@ -82,24 +94,31 @@ static int uhid_event(btif_hh_device_t *p_dev)
        APPL_TRACE_ERROR("%s: Cannot read uhid-cdev: %s", __FUNCTION__,
                                                strerror(errno));
        return -errno;
    } else if (ret < (ssize_t)sizeof(ev.type)) {
        APPL_TRACE_ERROR("%s: Invalid size read from uhid-dev: %zd < %zu",
    } else if ((ev.type == UHID_OUTPUT) || (ev.type==UHID_OUTPUT_EV)) {
        // Only these two types havae payload,
        // ensure we read full event descriptor
        if (ret < (ssize_t)sizeof(ev)) {
            APPL_TRACE_ERROR("%s: Invalid size read from uhid-dev: %ld != %lu",
                         __FUNCTION__, ret, sizeof(ev.type));
            return -EFAULT;
        }
    }

    switch (ev.type) {
    case UHID_START:
        APPL_TRACE_DEBUG("UHID_START from uhid-dev\n");
        p_dev->ready_for_data = TRUE;
        break;
    case UHID_STOP:
        APPL_TRACE_DEBUG("UHID_STOP from uhid-dev\n");
        p_dev->ready_for_data = FALSE;
        break;
    case UHID_OPEN:
        APPL_TRACE_DEBUG("UHID_OPEN from uhid-dev\n");
        break;
    case UHID_CLOSE:
        APPL_TRACE_DEBUG("UHID_CLOSE from uhid-dev\n");
        p_dev->ready_for_data = FALSE;
        break;
    case UHID_OUTPUT:
        if (ret < (ssize_t)(sizeof(ev.type) + sizeof(ev.u.output))) {
@@ -175,14 +194,17 @@ static inline pthread_t create_thread(void *(*start_routine)(void *), void * arg
*******************************************************************************/
static void *btif_hh_poll_event_thread(void *arg)
{

    btif_hh_device_t *p_dev = arg;
    APPL_TRACE_DEBUG("%s: Thread created fd = %d", __FUNCTION__, p_dev->fd);
    struct pollfd pfds[1];
    int ret;

    pfds[0].fd = p_dev->fd;
    pfds[0].events = POLLIN;

    // Set the uhid fd as non-blocking to ensure we never block the BTU thread
    uhid_set_non_blocking(p_dev->fd);

    while(p_dev->hh_keep_polling){
        ret = poll(pfds, 1, 50);
        if (ret < 0) {
@@ -224,7 +246,8 @@ void bta_hh_co_destroy(int fd)

int bta_hh_co_write(int fd, UINT8* rpt, UINT16 len)
{
    APPL_TRACE_DEBUG("bta_hh_co_data: UHID write");
    APPL_TRACE_DEBUG("%s: UHID write %d", __func__, len);

    struct uhid_event ev;
    memset(&ev, 0, sizeof(ev));
    ev.type = UHID_INPUT;
@@ -235,6 +258,7 @@ int bta_hh_co_write(int fd, UINT8* rpt, UINT16 len)
        return -1;
    }
    memcpy(ev.u.input.data, rpt, len);

    return uhid_write(fd, &ev);

}
@@ -280,9 +304,11 @@ void bta_hh_co_open(UINT8 dev_handle, UINT8 sub_class, tBTA_HH_ATTR_MASK attr_ma
                if (p_dev->fd < 0){
                    APPL_TRACE_ERROR("%s: Error: failed to open uhid, err:%s",
                                                                    __FUNCTION__,strerror(errno));
                    return;
                }else
                    APPL_TRACE_DEBUG("%s: uhid fd = %d", __FUNCTION__, p_dev->fd);
            }

            p_dev->hh_keep_polling = 1;
            p_dev->hh_poll_thread_id = create_thread(btif_hh_poll_event_thread, p_dev);
            break;
@@ -307,6 +333,7 @@ void bta_hh_co_open(UINT8 dev_handle, UINT8 sub_class, tBTA_HH_ATTR_MASK attr_ma
                if (p_dev->fd < 0){
                    APPL_TRACE_ERROR("%s: Error: failed to open uhid, err:%s",
                                                                    __FUNCTION__,strerror(errno));
                    return;
                }else{
                    APPL_TRACE_DEBUG("%s: uhid fd = %d", __FUNCTION__, p_dev->fd);
                    p_dev->hh_keep_polling = 1;
@@ -397,11 +424,13 @@ void bta_hh_co_data(UINT8 dev_handle, UINT8 *p_rpt, UINT16 len, tBTA_HH_PROTO_MO
        APPL_TRACE_WARNING("%s: Error: unknown HID device handle %d", __FUNCTION__, dev_handle);
        return;
    }
    // Send the HID report to the kernel.
    if (p_dev->fd >= 0) {

    // Send the HID data to the kernel.
    if ((p_dev->fd >= 0) && p_dev->ready_for_data) {
        bta_hh_co_write(p_dev->fd, p_rpt, len);
    }else {
        APPL_TRACE_WARNING("%s: Error: fd = %d, len = %d", __FUNCTION__, p_dev->fd, len);
        APPL_TRACE_WARNING("%s: Error: fd = %d, ready %d, len = %d", __FUNCTION__, p_dev->fd, 
                            p_dev->ready_for_data, len);
    }
}

@@ -455,7 +484,7 @@ void bta_hh_co_send_hid_info(btif_hh_device_t *p_dev, char *dev_name, UINT16 ven
    ev.u.create.country = ctry_code;
    result = uhid_write(p_dev->fd, &ev);

    APPL_TRACE_WARNING("%s: fd = %d, dscp_len = %d, result = %d", __FUNCTION__,
    APPL_TRACE_WARNING("%s: wrote descriptor to fd = %d, dscp_len = %d, result = %d", __FUNCTION__,
                                                                    p_dev->fd, dscp_len, result);

    if (result) {
+1 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ typedef struct
    UINT8                         sub_class;
    UINT8                         app_id;
    int                           fd;
    BOOLEAN                       ready_for_data;
    pthread_t                     hh_poll_thread_id;
    UINT8                         hh_keep_polling;
    BOOLEAN                       vup_timer_active;
+2 −0
Original line number Diff line number Diff line
@@ -518,6 +518,8 @@ void btif_hh_remove_device(bt_bdaddr_t bd_addr)

    p_dev->dev_status = BTHH_CONN_STATE_UNKNOWN;
    p_dev->dev_handle = BTA_HH_INVALID_HANDLE;
    p_dev->ready_for_data = FALSE;

    if (btif_hh_cb.device_num > 0) {
        btif_hh_cb.device_num--;
    }