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