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