15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Copyright (C) 2009-2012 Broadcom Corporation 45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * you may not use this file except in compliance with the License. 75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * You may obtain a copy of the License at: 85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * See the License for the specific language governing permissions and 155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * limitations under the License. 165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/ 185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Filename: userial.c 225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Description: Contains open/read/write/close functions on serial port 245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/ 265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define LOG_TAG "bt_userial" 285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <utils/Log.h> 305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <pthread.h> 315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <fcntl.h> 325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <errno.h> 335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdio.h> 345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/socket.h> 355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_hci_bdroid.h" 365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "userial.h" 375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "utils.h" 385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_vendor_lib.h" 395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/prctl.h> 40690401a234619e7a836859f6e4458aabdfb7c9e0Zhihai Xu#include "bt_utils.h" 415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Constants & Macros 445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#ifndef USERIAL_DBG 475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define USERIAL_DBG FALSE 485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (USERIAL_DBG == TRUE) 515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define USERIALDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);} 525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else 535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define USERIALDBG(param, ...) {} 545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 56ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#ifndef ENABLE_USERIAL_TIMING_LOGS 57ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define ENABLE_USERIAL_TIMING_LOGS FALSE 58ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif 59ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define MAX_SERIAL_PORT (USERIAL_PORT_3 + 1) 615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define READ_LIMIT (BTHC_USERIAL_READ_MEM_SIZE - BT_HC_HDR_SIZE) 625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectenum { 645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project USERIAL_RX_EXIT, 655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project USERIAL_RX_FLOW_OFF, 665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project USERIAL_RX_FLOW_ON 675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}; 685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Externs 715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectextern bt_vendor_interface_t *bt_vnd_if; 745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Local type definitions 775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef struct 805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int fd; 825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t port; 835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pthread_t read_thread; 845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BUFFER_Q rx_q; 855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project HC_BT_HDR *p_rx_hdr; 865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} tUSERIAL_CB; 875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Static variables 905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic tUSERIAL_CB userial_cb; 935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic volatile uint8_t userial_running = 0; 945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Static functions 975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 99ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined(ENABLE_USERIAL_TIMING_LOGS) && (ENABLE_USERIAL_TIMING_LOGS==TRUE) 100ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 101ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic void log_userial_tx_timing(int len) 102ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{ 103ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta #define USEC_PER_SEC 1000000L 104ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta static struct timespec prev = {0, 0}; 105ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta struct timespec now, diff; 106ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta unsigned int diff_us = 0; 107ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta unsigned int now_us = 0; 108ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 109ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta clock_gettime(CLOCK_MONOTONIC, &now); 110ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta now_us = now.tv_sec*USEC_PER_SEC + now.tv_nsec/1000; 111ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC + (now.tv_nsec - prev.tv_nsec)/1000; 112ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 113ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta ALOGW("[userial] ts %08d diff : %08d len %d", now_us, diff_us, 114ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta len); 115ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 116ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta prev = now; 117ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta} 118ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 119ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif 120ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 121ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Socket signal functions to wake up userial_read_thread for termination 1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** creating an unnamed pair of connected sockets 1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** - signal_fds[0]: join fd_set in select call of userial_read_thread 1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** - signal_fds[1]: trigger from userial_close 1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*****************************************************************************/ 1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int signal_fds[2]={0,1}; 1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic uint8_t rx_flow_on = TRUE; 1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline int create_signal_fds(fd_set* set) 1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(signal_fds[0]==0 && socketpair(AF_UNIX, SOCK_STREAM, 0, signal_fds)<0) 1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGE("create_signal_sockets:socketpair failed, errno: %d", errno); 1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FD_SET(signal_fds[0], set); 1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return signal_fds[0]; 1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline int send_wakeup_signal(char sig_cmd) 1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return send(signal_fds[1], &sig_cmd, sizeof(sig_cmd), 0); 1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline char reset_signal() 1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project char sig_recv = -1; 1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project recv(signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL); 1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return sig_recv; 1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline int is_signaled(fd_set* set) 1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FD_ISSET(signal_fds[0], set); 1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 156ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta 1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function select_read 1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description check if fd is ready for reading and listen for termination 1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** signal. need to use select in order to avoid collision 1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** between read and close on the same fd 1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns -1: termination 1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** >=0: numbers of bytes read back from fd 1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int select_read(int fd, uint8_t *pbuf, int len) 1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project fd_set input; 1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int n = 0, ret = -1; 1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project char reason = 0; 1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while (userial_running) 1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Initialize the input fd set */ 1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FD_ZERO(&input); 1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (rx_flow_on == TRUE) 1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FD_SET(fd, &input); 1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int fd_max = create_signal_fds(&input); 1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project fd_max = fd_max > fd ? fd_max : fd; 1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Do the select */ 1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project n = select(fd_max+1, &input, NULL, NULL, NULL); 1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(is_signaled(&input)) 1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project reason = reset_signal(); 1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (reason == USERIAL_RX_EXIT) 1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project USERIALDBG("RX termination"); 1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (reason == USERIAL_RX_FLOW_OFF) 1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project USERIALDBG("RX flow OFF"); 1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project rx_flow_on = FALSE; 2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (reason == USERIAL_RX_FLOW_ON) 2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project USERIALDBG("RX flow ON"); 2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project rx_flow_on = TRUE; 2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (n > 0) 2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* We might have input */ 2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (FD_ISSET(fd, &input)) 2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ret = read(fd, pbuf, (size_t)len); 2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (0 == ret) 2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGW( "read() returned 0!" ); 2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return ret; 2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (n < 0) 2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGW( "select() Failed"); 2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (n == 0) 2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGW( "Got a select() TIMEOUT"); 2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return ret; 2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function userial_read_thread 2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description 2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns void * 2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void *userial_read_thread(void *arg) 2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int rx_length = 0; 2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project HC_BT_HDR *p_buf = NULL; 2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t *p; 2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project USERIALDBG("Entering userial_read_thread()"); 2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project prctl(PR_SET_NAME, (unsigned long)"userial_read", 0, 0, 0); 2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project rx_flow_on = TRUE; 2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project userial_running = 1; 2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 251690401a234619e7a836859f6e4458aabdfb7c9e0Zhihai Xu raise_priority_a2dp(TASK_HIGH_USERIAL_READ); 252690401a234619e7a836859f6e4458aabdfb7c9e0Zhihai Xu 2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while (userial_running) 2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (bt_hc_cbacks) 2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf = (HC_BT_HDR *) bt_hc_cbacks->alloc( \ 2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BTHC_USERIAL_READ_MEM_SIZE); 2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf = NULL; 2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_buf != NULL) 2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->offset = 0; 2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->layer_specific = 0; 2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = (uint8_t *) (p_buf + 1); 2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project rx_length = select_read(userial_cb.fd, p, READ_LIMIT); 2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project rx_length = 0; 2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project utils_delay(100); 2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGW("userial_read_thread() failed to gain buffers"); 2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project continue; 2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (rx_length > 0) 2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->len = (uint16_t)rx_length; 2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project utils_enqueue(&(userial_cb.rx_q), p_buf); 2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bthc_signal_event(HC_EVENT_RX); 2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else /* either 0 or < 0 */ 2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGW("select_read return size <=0:%d, exiting userial_read_thread",\ 2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project rx_length); 2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* if we get here, we should have a buffer */ 2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_hc_cbacks->dealloc((TRANSAC) p_buf, (char *) (p_buf + 1)); 2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* negative value means exit thread */ 2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } /* for */ 2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project userial_running = 0; 2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project USERIALDBG("Leaving userial_read_thread()"); 2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pthread_exit(NULL); 3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return NULL; // Compiler friendly 3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Userial API Functions 3075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*****************************************************************************/ 3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function userial_init 3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Initializes the userial driver 3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns TRUE/FALSE 3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectuint8_t userial_init(void) 3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project USERIALDBG("userial_init"); 3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset(&userial_cb, 0, sizeof(tUSERIAL_CB)); 3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project userial_cb.fd = -1; 3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project utils_queue_init(&(userial_cb.rx_q)); 3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return TRUE; 3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function userial_open 3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Open Bluetooth device with the port ID 3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns TRUE/FALSE 3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectuint8_t userial_open(uint8_t port) 3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct sched_param param; 3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int policy, result; 3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pthread_attr_t thread_attr; 3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int fd_array[CH_MAX]; 3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project USERIALDBG("userial_open(port:%d)", port); 3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (userial_running) 3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Userial is open; close it first */ 3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project userial_close(); 3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project utils_delay(50); 3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (port >= MAX_SERIAL_PORT) 3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGE("Port > MAX_SERIAL_PORT"); 3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Calling vendor-specific part */ 3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (bt_vnd_if) 3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project result = bt_vnd_if->op(BT_VND_OP_USERIAL_OPEN, &fd_array); 3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (result != 1) 3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGE("userial_open: wrong numbers of open fd in vendor lib [%d]!", 3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project result); 3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGE("userial_open: HCI UART expects only one open fd"); 3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_vnd_if->op(BT_VND_OP_USERIAL_CLOSE, NULL); 3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project userial_cb.fd = fd_array[0]; 3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGE("userial_open: missing vendor lib interface !!!"); 3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGE("userial_open: unable to open UART port"); 3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (userial_cb.fd == -1) 3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGE("userial_open: failed to open UART port"); 3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project USERIALDBG( "fd = %d", userial_cb.fd); 3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project userial_cb.port = port; 3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pthread_attr_init(&thread_attr); 3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (pthread_create(&(userial_cb.read_thread), &thread_attr, \ 3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project userial_read_thread, NULL) != 0 ) 3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGE("pthread_create failed!"); 3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(pthread_getschedparam(userial_cb.read_thread, &policy, ¶m)==0) 4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project policy = BTHC_LINUX_BASE_POLICY; 4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BTHC_LINUX_BASE_POLICY!=SCHED_NORMAL) 4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project param.sched_priority = BTHC_USERIAL_READ_THREAD_PRIORITY; 4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project result = pthread_setschedparam(userial_cb.read_thread, policy, ¶m); 4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (result != 0) 4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGW("userial_open: pthread_setschedparam failed (%s)", \ 4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project strerror(result)); 4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return TRUE; 4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function userial_read 4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Read data from the userial port 4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns Number of bytes actually read from the userial port and 4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** copied into p_data. This may be less than len. 4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectuint16_t userial_read(uint16_t msg_id, uint8_t *p_buffer, uint16_t len) 4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t total_len = 0; 4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t copy_len = 0; 4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t *p_data = NULL; 4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project do 4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(userial_cb.p_rx_hdr != NULL) 4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_data = ((uint8_t *)(userial_cb.p_rx_hdr + 1)) + \ 4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (userial_cb.p_rx_hdr->offset); 4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if((userial_cb.p_rx_hdr->len) <= (len - total_len)) 4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project copy_len = userial_cb.p_rx_hdr->len; 4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project copy_len = (len - total_len); 4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memcpy((p_buffer + total_len), p_data, copy_len); 4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project total_len += copy_len; 4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project userial_cb.p_rx_hdr->offset += copy_len; 4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project userial_cb.p_rx_hdr->len -= copy_len; 4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(userial_cb.p_rx_hdr->len == 0) 4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (bt_hc_cbacks) 4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_hc_cbacks->dealloc((TRANSAC) userial_cb.p_rx_hdr, \ 4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (char *) (userial_cb.p_rx_hdr+1)); 4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project userial_cb.p_rx_hdr = NULL; 4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(userial_cb.p_rx_hdr == NULL) 4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project userial_cb.p_rx_hdr=(HC_BT_HDR *)utils_dequeue(&(userial_cb.rx_q)); 4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } while ((userial_cb.p_rx_hdr != NULL) && (total_len < len)); 4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return total_len; 4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function userial_write 4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Write data to the userial port 4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns Number of bytes actually written to the userial port. This 4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** may be less than len. 4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectuint16_t userial_write(uint16_t msg_id, uint8_t *p_data, uint16_t len) 4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int ret, total = 0; 4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while(len != 0) 4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 488ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined(ENABLE_USERIAL_TIMING_LOGS) && (ENABLE_USERIAL_TIMING_LOGS==TRUE) 489ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta log_userial_tx_timing(len); 490ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif 4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ret = write(userial_cb.fd, p_data+total, len); 4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project total += ret; 4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project len -= ret; 4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return ((uint16_t)total); 4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function userial_close 5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Close the userial port 5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns None 5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid userial_close(void) 5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int result; 5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project TRANSAC p_buf; 5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project USERIALDBG("userial_close(fd:%d)", userial_cb.fd); 5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (userial_running) 5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project send_wakeup_signal(USERIAL_RX_EXIT); 5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((result=pthread_join(userial_cb.read_thread, NULL)) < 0) 5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGE( "pthread_join() FAILED result:%d", result); 5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Calling vendor-specific part */ 5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (bt_vnd_if) 5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_vnd_if->op(BT_VND_OP_USERIAL_CLOSE, NULL); 5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project userial_cb.fd = -1; 5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (bt_hc_cbacks) 5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while ((p_buf = utils_dequeue (&(userial_cb.rx_q))) != NULL) 5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_hc_cbacks->dealloc(p_buf, (char *) ((HC_BT_HDR *)p_buf+1)); 5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function userial_ioctl 5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description ioctl inteface 5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns None 5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid userial_ioctl(userial_ioctl_op_t op, void *p_data) 5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project switch(op) 5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case USERIAL_OP_RXFLOW_ON: 5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (userial_running) 5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project send_wakeup_signal(USERIAL_RX_FLOW_ON); 5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case USERIAL_OP_RXFLOW_OFF: 5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (userial_running) 5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project send_wakeup_signal(USERIAL_RX_FLOW_OFF); 5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case USERIAL_OP_INIT: 5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project default: 5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 565