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 #define LOG_TAG "bt_btif_sock" 20 21 #include "btif_sock_util.h" 22 23 #include <arpa/inet.h> 24 #include <errno.h> 25 #include <netinet/in.h> 26 #include <netinet/tcp.h> 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 #include <sys/ioctl.h> 31 #include <sys/socket.h> 32 #include <sys/types.h> 33 #include <sys/un.h> 34 #include <unistd.h> 35 36 #include <hardware/bluetooth.h> 37 #include <hardware/bt_sock.h> 38 39 #include "bt_target.h" 40 #include "bta_api.h" 41 #include "bta_jv_api.h" 42 #include "bta_jv_co.h" 43 #include "btif_common.h" 44 #include "btif_sock_sdp.h" 45 #include "btif_sock_thread.h" 46 #include "btif_util.h" 47 #include "btm_api.h" 48 #include "btm_int.h" 49 #include "btu.h" 50 #include "bt_common.h" 51 #include "hcimsgs.h" 52 #include "osi/include/log.h" 53 #include "port_api.h" 54 #include "sdp_api.h" 55 56 #define asrt(s) if(!(s)) BTIF_TRACE_ERROR("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__) 57 58 int sock_send_all(int sock_fd, const uint8_t* buf, int len) 59 { 60 int s = len; 61 62 while(s) 63 { 64 ssize_t ret; 65 OSI_NO_INTR(ret = send(sock_fd, buf, s, 0)); 66 if(ret <= 0) 67 { 68 BTIF_TRACE_ERROR("sock fd:%d send errno:%d, ret:%d", sock_fd, errno, ret); 69 return -1; 70 } 71 buf += ret; 72 s -= ret; 73 } 74 return len; 75 } 76 int sock_recv_all(int sock_fd, uint8_t* buf, int len) 77 { 78 int r = len; 79 80 while(r) 81 { 82 ssize_t ret; 83 OSI_NO_INTR(ret = recv(sock_fd, buf, r, MSG_WAITALL)); 84 if(ret <= 0) 85 { 86 BTIF_TRACE_ERROR("sock fd:%d recv errno:%d, ret:%d", sock_fd, errno, ret); 87 return -1; 88 } 89 buf += ret; 90 r -= ret; 91 } 92 return len; 93 } 94 95 int sock_send_fd(int sock_fd, const uint8_t* buf, int len, int send_fd) 96 { 97 struct msghdr msg; 98 unsigned char *buffer = (unsigned char *)buf; 99 memset(&msg, 0, sizeof(msg)); 100 101 struct cmsghdr *cmsg; 102 char msgbuf[CMSG_SPACE(1)]; 103 asrt(send_fd != -1); 104 if(sock_fd == -1 || send_fd == -1) 105 return -1; 106 // Add any pending outbound file descriptors to the message 107 // See "man cmsg" really 108 msg.msg_control = msgbuf; 109 msg.msg_controllen = sizeof msgbuf; 110 cmsg = CMSG_FIRSTHDR(&msg); 111 cmsg->cmsg_level = SOL_SOCKET; 112 cmsg->cmsg_type = SCM_RIGHTS; 113 cmsg->cmsg_len = CMSG_LEN(sizeof send_fd); 114 memcpy(CMSG_DATA(cmsg), &send_fd, sizeof send_fd); 115 116 // We only write our msg_control during the first write 117 int ret_len = len; 118 while (len > 0) { 119 struct iovec iv; 120 memset(&iv, 0, sizeof(iv)); 121 122 iv.iov_base = buffer; 123 iv.iov_len = len; 124 125 msg.msg_iov = &iv; 126 msg.msg_iovlen = 1; 127 128 ssize_t ret; 129 OSI_NO_INTR(ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL)); 130 if (ret < 0) { 131 BTIF_TRACE_ERROR("fd:%d, send_fd:%d, sendmsg ret:%d, errno:%d, %s", 132 sock_fd, send_fd, (int)ret, errno, strerror(errno)); 133 ret_len = -1; 134 break; 135 } 136 137 buffer += ret; 138 len -= ret; 139 140 // Wipes out any msg_control too 141 memset(&msg, 0, sizeof(msg)); 142 } 143 BTIF_TRACE_DEBUG("close fd:%d after sent", send_fd); 144 // TODO: This seems wrong - if the FD is not opened in JAVA before this is called 145 // we get a "socket closed" exception in java, when reading from the socket... 146 close(send_fd); 147 return ret_len; 148 } 149 150 static const char* hex_table = "0123456789abcdef"; 151 static inline void byte2hex(const char* data, char** str) 152 { 153 **str = hex_table[(*data >> 4) & 0xf]; 154 ++*str; 155 **str = hex_table[*data & 0xf]; 156 ++*str; 157 } 158 static inline void byte2char(const char* data, char** str) 159 { 160 **str = *data < ' ' ? '.' : *data > '~' ? '.' : *data; 161 ++(*str); 162 } 163 static inline void word2hex(const char* data, char** hex) 164 { 165 byte2hex(&data[1], hex); 166 byte2hex(&data[0], hex); 167 } 168 void dump_bin(const char* title, const char* data, int size) 169 { 170 char line_buff[256]; 171 char *line; 172 int i, j, addr; 173 const int width = 16; 174 LOG_DEBUG(LOG_TAG, "%s, size:%d, dump started {", title, size); 175 if(size <= 0) 176 return; 177 //write offset 178 line = line_buff; 179 *line++ = ' '; 180 *line++ = ' '; 181 *line++ = ' '; 182 *line++ = ' '; 183 *line++ = ' '; 184 *line++ = ' '; 185 for(j = 0; j < width; j++) 186 { 187 byte2hex((const char*)&j, &line); 188 *line++ = ' '; 189 } 190 *line = 0; 191 LOG_DEBUG(LOG_TAG, "%s", line_buff); 192 193 for(i = 0; i < size / width; i++) 194 { 195 line = line_buff; 196 //write address: 197 addr = i*width; 198 word2hex((const char*)&addr, &line); 199 *line++ = ':'; *line++ = ' '; 200 //write hex of data 201 for(j = 0; j < width; j++) 202 { 203 byte2hex(&data[j], &line); 204 *line++ = ' '; 205 } 206 //write char of data 207 for(j = 0; j < width; j++) 208 byte2char(data++, &line); 209 //wirte the end of line 210 *line = 0; 211 //output the line 212 LOG_DEBUG(LOG_TAG, "%s", line_buff); 213 } 214 //last line of left over if any 215 int leftover = size % width; 216 if(leftover > 0) 217 { 218 line = line_buff; 219 //write address: 220 addr = i*width; 221 word2hex((const char*)&addr, &line); 222 *line++ = ':'; *line++ = ' '; 223 //write hex of data 224 for(j = 0; j < leftover; j++) { 225 byte2hex(&data[j], &line); 226 *line++ = ' '; 227 } 228 //write hex padding 229 for(; j < width; j++) { 230 *line++ = ' '; 231 *line++ = ' '; 232 *line++ = ' '; 233 } 234 //write char of data 235 for(j = 0; j < leftover; j++) 236 byte2char(data++, &line); 237 //write the end of line 238 *line = 0; 239 //output the line 240 LOG_DEBUG(LOG_TAG, "%s", line_buff); 241 } 242 LOG_DEBUG(LOG_TAG, "%s, size:%d, dump ended }", title, size); 243 } 244 245