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