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 "bd.h" 53 54 #include "bta_api.h" 55 #include "btif_sock_thread.h" 56 #include "btif_sock_sdp.h" 57 58 #include "bt_target.h" 59 #include "gki.h" 60 #include "hcimsgs.h" 61 #include "sdp_api.h" 62 #include "btu.h" 63 #include "btm_api.h" 64 #include "btm_int.h" 65 #include "bta_jv_api.h" 66 #include "bta_jv_co.h" 67 #include "port_api.h" 68 69 #define asrt(s) if(!(s)) BTIF_TRACE_ERROR3("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__) 70 71 72 int sock_send_all(int sock_fd, const uint8_t* buf, int len) 73 { 74 int s = len; 75 int ret; 76 while(s) 77 { 78 do ret = send(sock_fd, buf, s, 0); 79 while(ret < 0 && errno == EINTR); 80 if(ret <= 0) 81 { 82 BTIF_TRACE_ERROR3("sock fd:%d send errno:%d, ret:%d", sock_fd, errno, ret); 83 return -1; 84 } 85 buf += ret; 86 s -= ret; 87 } 88 return len; 89 } 90 int sock_recv_all(int sock_fd, uint8_t* buf, int len) 91 { 92 int r = len; 93 int ret = -1; 94 while(r) 95 { 96 do ret = recv(sock_fd, buf, r, MSG_WAITALL); 97 while(ret < 0 && errno == EINTR); 98 if(ret <= 0) 99 { 100 BTIF_TRACE_ERROR3("sock fd:%d recv errno:%d, ret:%d", sock_fd, errno, ret); 101 return -1; 102 } 103 buf += ret; 104 r -= ret; 105 } 106 return len; 107 } 108 109 int sock_send_fd(int sock_fd, const uint8_t* buf, int len, int send_fd) 110 { 111 ssize_t ret; 112 struct msghdr msg; 113 unsigned char *buffer = (unsigned char *)buf; 114 memset(&msg, 0, sizeof(msg)); 115 116 struct cmsghdr *cmsg; 117 char msgbuf[CMSG_SPACE(1)]; 118 asrt(send_fd != -1); 119 if(sock_fd == -1 || send_fd == -1) 120 return -1; 121 // Add any pending outbound file descriptors to the message 122 // See "man cmsg" really 123 msg.msg_control = msgbuf; 124 msg.msg_controllen = sizeof msgbuf; 125 cmsg = CMSG_FIRSTHDR(&msg); 126 cmsg->cmsg_level = SOL_SOCKET; 127 cmsg->cmsg_type = SCM_RIGHTS; 128 cmsg->cmsg_len = CMSG_LEN(sizeof send_fd); 129 memcpy(CMSG_DATA(cmsg), &send_fd, sizeof send_fd); 130 131 // We only write our msg_control during the first write 132 int ret_len = len; 133 while (len > 0) { 134 struct iovec iv; 135 memset(&iv, 0, sizeof(iv)); 136 137 iv.iov_base = buffer; 138 iv.iov_len = len; 139 140 msg.msg_iov = &iv; 141 msg.msg_iovlen = 1; 142 143 do { 144 ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL); 145 } while (ret < 0 && errno == EINTR); 146 147 if (ret < 0) { 148 BTIF_TRACE_ERROR5("fd:%d, send_fd:%d, sendmsg ret:%d, errno:%d, %s", 149 sock_fd, send_fd, (int)ret, errno, strerror(errno)); 150 ret_len = -1; 151 break; 152 } 153 154 buffer += ret; 155 len -= ret; 156 157 // Wipes out any msg_control too 158 memset(&msg, 0, sizeof(msg)); 159 } 160 BTIF_TRACE_DEBUG1("close fd:%d after sent", send_fd); 161 close(send_fd); 162 return ret_len; 163 } 164 165 166 #define PRINT(s) __android_log_write(ANDROID_LOG_DEBUG, NULL, s) 167 static const char* hex_table = "0123456789abcdef"; 168 static inline void byte2hex(const char* data, char** str) 169 { 170 **str = hex_table[(*data >> 4) & 0xf]; 171 ++*str; 172 **str = hex_table[*data & 0xf]; 173 ++*str; 174 } 175 static inline void byte2char(const char* data, char** str) 176 { 177 **str = *data < ' ' ? '.' : *data > '~' ? '.' : *data; 178 ++(*str); 179 } 180 static inline void word2hex(const char* data, char** hex) 181 { 182 byte2hex(&data[1], hex); 183 byte2hex(&data[0], hex); 184 } 185 void dump_bin(const char* title, const char* data, int size) 186 { 187 char line_buff[256]; 188 char *line; 189 int i, j, addr; 190 const int width = 16; 191 ALOGD("%s, size:%d, dump started {", title, size); 192 if(size <= 0) 193 return; 194 //write offset 195 line = line_buff; 196 *line++ = ' '; 197 *line++ = ' '; 198 *line++ = ' '; 199 *line++ = ' '; 200 *line++ = ' '; 201 *line++ = ' '; 202 for(j = 0; j < width; j++) 203 { 204 byte2hex((const char*)&j, &line); 205 *line++ = ' '; 206 } 207 *line = 0; 208 PRINT(line_buff); 209 210 for(i = 0; i < size / width; i++) 211 { 212 line = line_buff; 213 //write address: 214 addr = i*width; 215 word2hex((const char*)&addr, &line); 216 *line++ = ':'; *line++ = ' '; 217 //write hex of data 218 for(j = 0; j < width; j++) 219 { 220 byte2hex(&data[j], &line); 221 *line++ = ' '; 222 } 223 //write char of data 224 for(j = 0; j < width; j++) 225 byte2char(data++, &line); 226 //wirte the end of line 227 *line = 0; 228 //output the line 229 PRINT(line_buff); 230 } 231 //last line of left over if any 232 int leftover = size % width; 233 if(leftover > 0) 234 { 235 line = line_buff; 236 //write address: 237 addr = i*width; 238 word2hex((const char*)&addr, &line); 239 *line++ = ':'; *line++ = ' '; 240 //write hex of data 241 for(j = 0; j < leftover; j++) { 242 byte2hex(&data[j], &line); 243 *line++ = ' '; 244 } 245 //write hex padding 246 for(; j < width; j++) { 247 *line++ = ' '; 248 *line++ = ' '; 249 *line++ = ' '; 250 } 251 //write char of data 252 for(j = 0; j < leftover; j++) 253 byte2char(data++, &line); 254 //write the end of line 255 *line = 0; 256 //output the line 257 PRINT(line_buff); 258 } 259 ALOGD("%s, size:%d, dump ended }", title, size); 260 } 261 262