1/****************************************************************************** 2 * 3 * Copyright (C) 2009-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 20/************************************************************************************ 21 * 22 * Filename: btif_hf.c 23 * 24 * Description: Handsfree Profile Bluetooth Interface 25 * 26 * 27 ***********************************************************************************/ 28#include <hardware/bluetooth.h> 29#include <hardware/bt_sock.h> 30#include <errno.h> 31#include <sys/ioctl.h> 32#include <stdio.h> 33#include <string.h> 34#include <sys/types.h> 35#include <sys/socket.h> 36#include <sys/un.h> 37#include <arpa/inet.h> 38#include <netinet/in.h> 39#include <stdlib.h> 40#include <errno.h> 41#include <unistd.h> 42#include <sys/ioctl.h> 43 44#include <cutils/sockets.h> 45#include <netinet/tcp.h> 46 47 48#define LOG_TAG "BTIF_SOCK" 49#include "btif_common.h" 50#include "btif_util.h" 51 52#include "bta_api.h" 53#include "btif_sock_thread.h" 54#include "btif_sock_sdp.h" 55 56#include "bt_target.h" 57#include "gki.h" 58#include "hcimsgs.h" 59#include "sdp_api.h" 60#include "btu.h" 61#include "btm_api.h" 62#include "btm_int.h" 63#include "bta_jv_api.h" 64#include "bta_jv_co.h" 65#include "port_api.h" 66 67#define asrt(s) if(!(s)) BTIF_TRACE_ERROR("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__) 68 69 70int sock_send_all(int sock_fd, const uint8_t* buf, int len) 71{ 72 int s = len; 73 int ret; 74 while(s) 75 { 76 do ret = send(sock_fd, buf, s, 0); 77 while(ret < 0 && errno == EINTR); 78 if(ret <= 0) 79 { 80 BTIF_TRACE_ERROR("sock fd:%d send errno:%d, ret:%d", sock_fd, errno, ret); 81 return -1; 82 } 83 buf += ret; 84 s -= ret; 85 } 86 return len; 87} 88int sock_recv_all(int sock_fd, uint8_t* buf, int len) 89{ 90 int r = len; 91 int ret = -1; 92 while(r) 93 { 94 do ret = recv(sock_fd, buf, r, MSG_WAITALL); 95 while(ret < 0 && errno == EINTR); 96 if(ret <= 0) 97 { 98 BTIF_TRACE_ERROR("sock fd:%d recv errno:%d, ret:%d", sock_fd, errno, ret); 99 return -1; 100 } 101 buf += ret; 102 r -= ret; 103 } 104 return len; 105} 106 107int sock_send_fd(int sock_fd, const uint8_t* buf, int len, int send_fd) 108{ 109 ssize_t ret; 110 struct msghdr msg; 111 unsigned char *buffer = (unsigned char *)buf; 112 memset(&msg, 0, sizeof(msg)); 113 114 struct cmsghdr *cmsg; 115 char msgbuf[CMSG_SPACE(1)]; 116 asrt(send_fd != -1); 117 if(sock_fd == -1 || send_fd == -1) 118 return -1; 119 // Add any pending outbound file descriptors to the message 120 // See "man cmsg" really 121 msg.msg_control = msgbuf; 122 msg.msg_controllen = sizeof msgbuf; 123 cmsg = CMSG_FIRSTHDR(&msg); 124 cmsg->cmsg_level = SOL_SOCKET; 125 cmsg->cmsg_type = SCM_RIGHTS; 126 cmsg->cmsg_len = CMSG_LEN(sizeof send_fd); 127 memcpy(CMSG_DATA(cmsg), &send_fd, sizeof send_fd); 128 129 // We only write our msg_control during the first write 130 int ret_len = len; 131 while (len > 0) { 132 struct iovec iv; 133 memset(&iv, 0, sizeof(iv)); 134 135 iv.iov_base = buffer; 136 iv.iov_len = len; 137 138 msg.msg_iov = &iv; 139 msg.msg_iovlen = 1; 140 141 do { 142 ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL); 143 } while (ret < 0 && errno == EINTR); 144 145 if (ret < 0) { 146 BTIF_TRACE_ERROR("fd:%d, send_fd:%d, sendmsg ret:%d, errno:%d, %s", 147 sock_fd, send_fd, (int)ret, errno, strerror(errno)); 148 ret_len = -1; 149 break; 150 } 151 152 buffer += ret; 153 len -= ret; 154 155 // Wipes out any msg_control too 156 memset(&msg, 0, sizeof(msg)); 157 } 158 BTIF_TRACE_DEBUG("close fd:%d after sent", send_fd); 159 close(send_fd); 160 return ret_len; 161} 162 163 164#define PRINT(s) __android_log_write(ANDROID_LOG_DEBUG, NULL, s) 165static const char* hex_table = "0123456789abcdef"; 166static inline void byte2hex(const char* data, char** str) 167{ 168 **str = hex_table[(*data >> 4) & 0xf]; 169 ++*str; 170 **str = hex_table[*data & 0xf]; 171 ++*str; 172} 173static inline void byte2char(const char* data, char** str) 174{ 175 **str = *data < ' ' ? '.' : *data > '~' ? '.' : *data; 176 ++(*str); 177} 178static inline void word2hex(const char* data, char** hex) 179{ 180 byte2hex(&data[1], hex); 181 byte2hex(&data[0], hex); 182} 183void dump_bin(const char* title, const char* data, int size) 184{ 185 char line_buff[256]; 186 char *line; 187 int i, j, addr; 188 const int width = 16; 189 ALOGD("%s, size:%d, dump started {", title, size); 190 if(size <= 0) 191 return; 192 //write offset 193 line = line_buff; 194 *line++ = ' '; 195 *line++ = ' '; 196 *line++ = ' '; 197 *line++ = ' '; 198 *line++ = ' '; 199 *line++ = ' '; 200 for(j = 0; j < width; j++) 201 { 202 byte2hex((const char*)&j, &line); 203 *line++ = ' '; 204 } 205 *line = 0; 206 PRINT(line_buff); 207 208 for(i = 0; i < size / width; i++) 209 { 210 line = line_buff; 211 //write address: 212 addr = i*width; 213 word2hex((const char*)&addr, &line); 214 *line++ = ':'; *line++ = ' '; 215 //write hex of data 216 for(j = 0; j < width; j++) 217 { 218 byte2hex(&data[j], &line); 219 *line++ = ' '; 220 } 221 //write char of data 222 for(j = 0; j < width; j++) 223 byte2char(data++, &line); 224 //wirte the end of line 225 *line = 0; 226 //output the line 227 PRINT(line_buff); 228 } 229 //last line of left over if any 230 int leftover = size % width; 231 if(leftover > 0) 232 { 233 line = line_buff; 234 //write address: 235 addr = i*width; 236 word2hex((const char*)&addr, &line); 237 *line++ = ':'; *line++ = ' '; 238 //write hex of data 239 for(j = 0; j < leftover; j++) { 240 byte2hex(&data[j], &line); 241 *line++ = ' '; 242 } 243 //write hex padding 244 for(; j < width; j++) { 245 *line++ = ' '; 246 *line++ = ' '; 247 *line++ = ' '; 248 } 249 //write char of data 250 for(j = 0; j < leftover; j++) 251 byte2char(data++, &line); 252 //write the end of line 253 *line = 0; 254 //output the line 255 PRINT(line_buff); 256 } 257 ALOGD("%s, size:%d, dump ended }", title, size); 258} 259 260