OSDN Git Service

resolved conflicts for b8cc54d1 to mnc-dr-dev-plus-aosp
[android-x86/system-bt.git] / btif / src / btif_sock_util.c
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 "gki.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     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 }
76 int 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
95 int 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
153 static const char* hex_table = "0123456789abcdef";
154 static 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 }
161 static inline void byte2char(const char* data, char** str)
162 {
163     **str = *data < ' ' ? '.' : *data > '~' ? '.' : *data;
164     ++(*str);
165 }
166 static inline void word2hex(const char* data, char** hex)
167 {
168     byte2hex(&data[1], hex);
169     byte2hex(&data[0], hex);
170 }
171 void 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