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