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