/******************************************************************************* ** ** Function select_read ** ** Description check if fd is ready for reading and listen for termination ** signal. need to use select in order to avoid collision ** between read and close on the same fd ** ** Returns -1: termination ** >=0: numbers of bytes read back from fd ** *******************************************************************************/ static int select_read(int fd, uint8_t *pbuf, int len) { fd_set input; int n = 0, ret = -1; char reason = 0; while (userial_running) { /* Initialize the input fd set */ FD_ZERO(&input); if (rx_flow_on == TRUE) { FD_SET(fd, &input); } int fd_max = create_signal_fds(&input); fd_max = fd_max > fd ? fd_max : fd; /* Do the select */ n = select(fd_max+1, &input, NULL, NULL, NULL); if(is_signaled(&input)) { reason = reset_signal(); if (reason == USERIAL_RX_EXIT) { USERIALDBG("RX termination"); return -1; } else if (reason == USERIAL_RX_FLOW_OFF) { USERIALDBG("RX flow OFF"); rx_flow_on = FALSE; } else if (reason == USERIAL_RX_FLOW_ON) { USERIALDBG("RX flow ON"); rx_flow_on = TRUE; } } if (n > 0) { /* We might have input */ if (FD_ISSET(fd, &input)) { ret = read(fd, pbuf, (size_t)len); if (0 == ret) ALOGW( "read() returned 0!" ); return ret; } } else if (n < 0) ALOGW( "select() Failed"); else if (n == 0) ALOGW( "Got a select() TIMEOUT"); } return ret; }
/******************************************************************************* ** ** Function userial_evt_read_thread ** ** Description The reading thread on EVT and ACL_IN channels ** ** Returns void * ** *******************************************************************************/ static void *userial_read_thread(void *arg) { fd_set input; int n; char reason = 0; USERIALDBG("Entering userial_read_thread()"); rx_flow_on = TRUE; userial_running = 1; raise_priority_a2dp(TASK_HIGH_USERIAL_READ); while (userial_running) { /* Initialize the input fd set */ FD_ZERO(&input); if (rx_flow_on == TRUE) { FD_SET(userial_cb.fd[CH_EVT], &input); FD_SET(userial_cb.fd[CH_ACL_IN], &input); } int fd_max = create_signal_fds(&input); fd_max = (fd_max>userial_cb.fd[CH_EVT]) ? fd_max : userial_cb.fd[CH_EVT]; fd_max = (fd_max>userial_cb.fd[CH_ACL_IN]) ? fd_max : userial_cb.fd[CH_ACL_IN]; /* Do the select */ n = 0; n = select(fd_max+1, &input, NULL, NULL, NULL); if(is_signaled(&input)) { reason = reset_signal(); if (reason == USERIAL_RX_EXIT) { ALOGI("exiting userial_read_thread"); userial_running = 0; break; } else if (reason == USERIAL_RX_FLOW_OFF) { USERIALDBG("RX flow OFF"); rx_flow_on = FALSE; } else if (reason == USERIAL_RX_FLOW_ON) { USERIALDBG("RX flow ON"); rx_flow_on = TRUE; } } if (n > 0) { /* We might have input */ if (FD_ISSET(userial_cb.fd[CH_EVT], &input)) { hci_mct_receive_evt_msg(); } if (FD_ISSET(userial_cb.fd[CH_ACL_IN], &input)) { hci_mct_receive_acl_msg(); } } else if (n < 0) ALOGW( "select() Failed"); else if (n == 0) ALOGW( "Got a select() TIMEOUT"); } /* while */ userial_running = 0; USERIALDBG("Leaving userial_evt_read_thread()"); pthread_exit(NULL); return NULL; // Compiler friendly }