summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2009-04-25 06:24:05 +0200
committerGravatar Nikias Bassen2009-04-25 06:24:05 +0200
commitce4b528e203a67cbc3c8c2950b237b8fd1a41bed (patch)
treea349e15739f787bcb4c227f89004fce87f1e8383
parent25273957cbfa16dc908c4a56f48f2c847d5e7ab2 (diff)
downloadusbmuxd-ce4b528e203a67cbc3c8c2950b237b8fd1a41bed.tar.gz
usbmuxd-ce4b528e203a67cbc3c8c2950b237b8fd1a41bed.tar.bz2
indent -kr -ut
-rw-r--r--libusbmuxd.c138
-rw-r--r--main.c1875
-rw-r--r--sock_stuff.c470
-rw-r--r--sock_stuff.h15
-rw-r--r--usbmux.c325
5 files changed, 1559 insertions, 1264 deletions
diff --git a/libusbmuxd.c b/libusbmuxd.c
index edd585c..c8acbf8 100644
--- a/libusbmuxd.c
+++ b/libusbmuxd.c
@@ -14,37 +14,37 @@
14// socket utility functions 14// socket utility functions
15#include "sock_stuff.h" 15#include "sock_stuff.h"
16 16
17static int usbmuxd_get_result(int sfd, uint32_t tag, uint32_t *result) 17static int usbmuxd_get_result(int sfd, uint32_t tag, uint32_t * result)
18{ 18{
19 struct usbmuxd_result res; 19 struct usbmuxd_result res;
20 int recv_len; 20 int recv_len;
21 21
22 if (!result) { 22 if (!result) {
23 return -EINVAL; 23 return -EINVAL;
24 } 24 }
25 25
26 if ((recv_len = recv_buf(sfd, &res, sizeof(res))) <= 0) { 26 if ((recv_len = recv_buf(sfd, &res, sizeof(res))) <= 0) {
27 perror("recv"); 27 perror("recv");
28 return -errno; 28 return -errno;
29 } else { 29 } else {
30 if ((recv_len == sizeof(res)) 30 if ((recv_len == sizeof(res))
31 && (res.header.length == (uint32_t)recv_len) 31 && (res.header.length == (uint32_t) recv_len)
32 && (res.header.reserved == 0) 32 && (res.header.reserved == 0)
33 && (res.header.type == USBMUXD_RESULT) 33 && (res.header.type == USBMUXD_RESULT)
34 ) { 34 ) {
35 *result = res.result; 35 *result = res.result;
36 if (res.header.tag == tag) { 36 if (res.header.tag == tag) {
37 return 1; 37 return 1;
38 } else { 38 } else {
39 return 0; 39 return 0;
40 } 40 }
41 } 41 }
42 } 42 }
43 43
44 return -1; 44 return -1;
45} 45}
46 46
47int usbmuxd_scan(usbmuxd_scan_result **available_devices) 47int usbmuxd_scan(usbmuxd_scan_result ** available_devices)
48{ 48{
49 struct usbmuxd_scan_request s_req; 49 struct usbmuxd_scan_request s_req;
50 int sfd; 50 int sfd;
@@ -68,13 +68,16 @@ int usbmuxd_scan(usbmuxd_scan_result **available_devices)
68 s_req.header.tag = 2; 68 s_req.header.tag = 2;
69 69
70 // send scan request packet 70 // send scan request packet
71 if (send_buf(sfd, &s_req, s_req.header.length) == (int)s_req.header.length) { 71 if (send_buf(sfd, &s_req, s_req.header.length) ==
72 (int) s_req.header.length) {
72 res = -1; 73 res = -1;
73 // get response 74 // get response
74 if (usbmuxd_get_result(sfd, s_req.header.tag, &res) && (res == 0)) { 75 if (usbmuxd_get_result(sfd, s_req.header.tag, &res) && (res == 0)) {
75 scan_success = 1; 76 scan_success = 1;
76 } else { 77 } else {
77 fprintf(stderr, "%s: Did not get response to scan request (with result=0)...\n", __func__); 78 fprintf(stderr,
79 "%s: Did not get response to scan request (with result=0)...\n",
80 __func__);
78 close(sfd); 81 close(sfd);
79 return res; 82 return res;
80 } 83 }
@@ -91,29 +94,45 @@ int usbmuxd_scan(usbmuxd_scan_result **available_devices)
91 if (recv_buf_timeout(sfd, &pktlen, 4, MSG_PEEK, 1000) == 4) { 94 if (recv_buf_timeout(sfd, &pktlen, 4, MSG_PEEK, 1000) == 4) {
92 if (pktlen != sizeof(dev_info_pkt)) { 95 if (pktlen != sizeof(dev_info_pkt)) {
93 // invalid packet size received! 96 // invalid packet size received!
94 fprintf(stderr, "%s: Invalid packet size (%d) received when expecting a device info record.\n", __func__, pktlen); 97 fprintf(stderr,
98 "%s: Invalid packet size (%d) received when expecting a device info record.\n",
99 __func__, pktlen);
95 break; 100 break;
96 } 101 }
97 102
98 recv_len = recv_buf(sfd, &dev_info_pkt, pktlen); 103 recv_len = recv_buf(sfd, &dev_info_pkt, pktlen);
99 if (recv_len <= 0) { 104 if (recv_len <= 0) {
100 fprintf(stderr, "%s: Error when receiving device info record\n", __func__); 105 fprintf(stderr,
106 "%s: Error when receiving device info record\n",
107 __func__);
101 break; 108 break;
102 } else if ((uint32_t)recv_len < pktlen) { 109 } else if ((uint32_t) recv_len < pktlen) {
103 fprintf(stderr, "%s: received less data than specified in header!\n", __func__); 110 fprintf(stderr,
111 "%s: received less data than specified in header!\n",
112 __func__);
104 } else { 113 } else {
105 //fprintf(stderr, "%s: got device record with id %d, UUID=%s\n", __func__, dev_info_pkt.device_info.device_id, dev_info_pkt.device_info.serial_number); 114 //fprintf(stderr, "%s: got device record with id %d, UUID=%s\n", __func__, dev_info_pkt.device_info.device_id, dev_info_pkt.device_info.serial_number);
106 newlist = (usbmuxd_scan_result *)realloc(*available_devices, sizeof(usbmuxd_scan_result) * (dev_cnt+1)); 115 newlist =
116 (usbmuxd_scan_result *) realloc(*available_devices,
117 sizeof
118 (usbmuxd_scan_result) *
119 (dev_cnt + 1));
107 if (newlist) { 120 if (newlist) {
108 newlist[dev_cnt].handle = (int)dev_info_pkt.device.device_id; 121 newlist[dev_cnt].handle =
109 newlist[dev_cnt].product_id = dev_info_pkt.device.product_id; 122 (int) dev_info_pkt.device.device_id;
110 memset(newlist[dev_cnt].serial_number, '\0', sizeof(newlist[dev_cnt].serial_number)); 123 newlist[dev_cnt].product_id =
111 memcpy(newlist[dev_cnt].serial_number, dev_info_pkt.device.serial_number, 124 dev_info_pkt.device.product_id;
112 sizeof(dev_info_pkt.device.serial_number)); 125 memset(newlist[dev_cnt].serial_number, '\0',
126 sizeof(newlist[dev_cnt].serial_number));
127 memcpy(newlist[dev_cnt].serial_number,
128 dev_info_pkt.device.serial_number,
129 sizeof(dev_info_pkt.device.serial_number));
113 *available_devices = newlist; 130 *available_devices = newlist;
114 dev_cnt++; 131 dev_cnt++;
115 } else { 132 } else {
116 fprintf(stderr, "%s: ERROR: out of memory when trying to realloc!\n", __func__); 133 fprintf(stderr,
134 "%s: ERROR: out of memory when trying to realloc!\n",
135 __func__);
117 break; 136 break;
118 } 137 }
119 } 138 }
@@ -125,8 +144,11 @@ int usbmuxd_scan(usbmuxd_scan_result **available_devices)
125 } 144 }
126 145
127 // terminating zero record 146 // terminating zero record
128 newlist = (usbmuxd_scan_result *)realloc(*available_devices, sizeof(usbmuxd_scan_result) * (dev_cnt+1)); 147 newlist =
129 memset(newlist+dev_cnt, 0, sizeof(usbmuxd_scan_result)); 148 (usbmuxd_scan_result *) realloc(*available_devices,
149 sizeof(usbmuxd_scan_result) *
150 (dev_cnt + 1));
151 memset(newlist + dev_cnt, 0, sizeof(usbmuxd_scan_result));
130 *available_devices = newlist; 152 *available_devices = newlist;
131 153
132 return dev_cnt; 154 return dev_cnt;
@@ -141,31 +163,33 @@ int usbmuxd_connect(const int handle, const unsigned short tcp_port)
141 163
142 sfd = connect_unix_socket(USBMUXD_SOCKET_FILE); 164 sfd = connect_unix_socket(USBMUXD_SOCKET_FILE);
143 if (sfd < 0) { 165 if (sfd < 0) {
144 fprintf(stderr, "%s: Error: Connection to usbmuxd failed: %s\n", __func__, strerror(errno)); 166 fprintf(stderr, "%s: Error: Connection to usbmuxd failed: %s\n",
145 return sfd; 167 __func__, strerror(errno));
168 return sfd;
146 } 169 }
147 170
148 c_req.header.length = sizeof(c_req); 171 c_req.header.length = sizeof(c_req);
149 c_req.header.reserved = 0; 172 c_req.header.reserved = 0;
150 c_req.header.type = USBMUXD_CONNECT; 173 c_req.header.type = USBMUXD_CONNECT;
151 c_req.header.tag = 3; 174 c_req.header.tag = 3;
152 c_req.device_id = (uint32_t)handle; 175 c_req.device_id = (uint32_t) handle;
153 c_req.tcp_dport = htons(tcp_port); 176 c_req.tcp_dport = htons(tcp_port);
154 c_req.reserved = 0; 177 c_req.reserved = 0;
155 178
156 if (send_buf(sfd, &c_req, sizeof(c_req)) < 0) { 179 if (send_buf(sfd, &c_req, sizeof(c_req)) < 0) {
157 perror("send"); 180 perror("send");
158 } else { 181 } else {
159 // read ACK 182 // read ACK
160 //fprintf(stderr, "%s: Reading connect result...\n", __func__); 183 //fprintf(stderr, "%s: Reading connect result...\n", __func__);
161 if (usbmuxd_get_result(sfd, c_req.header.tag, &res)) { 184 if (usbmuxd_get_result(sfd, c_req.header.tag, &res)) {
162 if (res == 0) { 185 if (res == 0) {
163 //fprintf(stderr, "%s: Connect success!\n", __func__); 186 //fprintf(stderr, "%s: Connect success!\n", __func__);
164 connected = 1; 187 connected = 1;
165 } else { 188 } else {
166 fprintf(stderr, "%s: Connect failed, Error code=%d\n", __func__, res); 189 fprintf(stderr, "%s: Connect failed, Error code=%d\n",
190 __func__, res);
191 }
167 } 192 }
168 }
169 } 193 }
170 194
171 if (connected) { 195 if (connected) {
@@ -173,6 +197,6 @@ int usbmuxd_connect(const int handle, const unsigned short tcp_port)
173 } 197 }
174 198
175 close(sfd); 199 close(sfd);
176 200
177 return -1; 201 return -1;
178} 202}
diff --git a/main.c b/main.c
index 43f0425..e7292cc 100644
--- a/main.c
+++ b/main.c
@@ -59,29 +59,29 @@ static int foreground = 0;
59static int exit_on_no_devices = 0; 59static int exit_on_no_devices = 0;
60 60
61struct device_info { 61struct device_info {
62 uint32_t device_id; 62 uint32_t device_id;
63 usbmux_device_t phone; 63 usbmux_device_t phone;
64 int use_count; 64 int use_count;
65 pthread_t bulk_reader; 65 pthread_t bulk_reader;
66 pthread_mutex_t mutex; 66 pthread_mutex_t mutex;
67 /* mutex for mutual exclusion of calling the usbmux_send function 67 /* mutex for mutual exclusion of calling the usbmux_send function
68 * TODO: I don't know if we need really need this? */ 68 * TODO: I don't know if we need really need this? */
69 pthread_mutex_t writer_mutex; 69 pthread_mutex_t writer_mutex;
70}; 70};
71 71
72struct client_data { 72struct client_data {
73 volatile int dead; 73 volatile int dead;
74 int socket; 74 int socket;
75 int tag; 75 int tag;
76 pthread_t thread; 76 pthread_t thread;
77 pthread_t handler; 77 pthread_t handler;
78 pthread_t reader; 78 pthread_t reader;
79 int reader_quit; 79 int reader_quit;
80 int reader_dead; 80 int reader_dead;
81 int handler_dead; 81 int handler_dead;
82 int connected; 82 int connected;
83 usbmux_client_t muxclient; 83 usbmux_client_t muxclient;
84 struct device_info *dev; 84 struct device_info *dev;
85}; 85};
86 86
87static struct device_info **devices = NULL; 87static struct device_info **devices = NULL;
@@ -97,69 +97,77 @@ static pthread_mutex_t usb_mutex = PTHREAD_MUTEX_INITIALIZER;
97 */ 97 */
98static void logmsg(int prio, const char *format, ...) 98static void logmsg(int prio, const char *format, ...)
99{ 99{
100 va_list args; 100 va_list args;
101 va_start(args, format); 101 va_start(args, format);
102 102
103 if (!foreground) { 103 if (!foreground) {
104 // daemon. log using syslog. 104 // daemon. log using syslog.
105 vsyslog(prio, format, args); 105 vsyslog(prio, format, args);
106 } else { 106 } else {
107 // running in foreground. log to stdout/stderr. 107 // running in foreground. log to stdout/stderr.
108 char msgbuf[256]; 108 char msgbuf[256];
109 FILE *lfp = stdout; 109 FILE *lfp = stdout;
110 switch(prio) { 110 switch (prio) {
111 case LOG_EMERG: 111 case LOG_EMERG:
112 case LOG_ALERT: 112 case LOG_ALERT:
113 case LOG_CRIT: 113 case LOG_CRIT:
114 case LOG_ERR: 114 case LOG_ERR:
115 case LOG_WARNING: 115 case LOG_WARNING:
116 lfp = stderr; 116 lfp = stderr;
117 break; 117 break;
118 default: 118 default:
119 lfp = stdout; 119 lfp = stdout;
120 }
121 strcpy(msgbuf, "usbmuxd: ");
122 vsnprintf(msgbuf + 9, 244, format, args);
123 strcat(msgbuf, "\n");
124 fputs(msgbuf, lfp);
120 } 125 }
121 strcpy(msgbuf, "usbmuxd: ");
122 vsnprintf(msgbuf+9, 244, format, args);
123 strcat(msgbuf, "\n");
124 fputs(msgbuf, lfp);
125 }
126 126
127 va_end(args); 127 va_end(args);
128} 128}
129 129
130#ifdef DEBUG 130#ifdef DEBUG
131/** 131/**
132 * for debugging purposes. 132 * for debugging purposes.
133 */ 133 */
134static void print_buffer(FILE *fp, const char *data, const int length) 134static void print_buffer(FILE * fp, const char *data, const int length)
135{ 135{
136 int i; 136 int i;
137 int j; 137 int j;
138 unsigned char c; 138 unsigned char c;
139 139
140 for(i=0; i<length; i+=16) { 140 for (i = 0; i < length; i += 16) {
141 if (verbose >= 4) fprintf(fp, "%04x: ", i); 141 if (verbose >= 4)
142 for (j=0;j<16;j++) { 142 fprintf(fp, "%04x: ", i);
143 if (i+j >= length) { 143 for (j = 0; j < 16; j++) {
144 if (verbose >= 4) fprintf(fp, " "); 144 if (i + j >= length) {
145 if (verbose >= 4)
146 fprintf(fp, " ");
145 continue; 147 continue;
146 } 148 }
147 if (verbose >= 4) fprintf(fp, "%02hhx ", *(data+i+j)); 149 if (verbose >= 4)
150 fprintf(fp, "%02hhx ", *(data + i + j));
148 } 151 }
149 if (verbose >= 4) fprintf(fp, " | "); 152 if (verbose >= 4)
150 for(j=0;j<16;j++) { 153 fprintf(fp, " | ");
151 if (i+j >= length) 154 for (j = 0; j < 16; j++) {
155 if (i + j >= length)
152 break; 156 break;
153 c = *(data+i+j); 157 c = *(data + i + j);
154 if ((c < 32) || (c > 127)) { 158 if ((c < 32) || (c > 127)) {
155 if (verbose >= 4) fprintf(fp, "."); 159 if (verbose >= 4)
160 fprintf(fp, ".");
156 continue; 161 continue;
157 } 162 }
158 if (verbose >= 4) fprintf(fp, "%c", c); 163 if (verbose >= 4)
164 fprintf(fp, "%c", c);
159 } 165 }
160 if (verbose >= 4) fprintf(fp, "\n"); 166 if (verbose >= 4)
167 fprintf(fp, "\n");
161 } 168 }
162 if (verbose >= 4) fprintf(fp, "\n"); 169 if (verbose >= 4)
170 fprintf(fp, "\n");
163} 171}
164#endif 172#endif
165 173
@@ -176,35 +184,40 @@ static void print_buffer(FILE *fp, const char *data, const int length)
176 */ 184 */
177static int usbmuxd_get_request(int fd, void **data, size_t len) 185static int usbmuxd_get_request(int fd, void **data, size_t len)
178{ 186{
179 uint32_t pktlen; 187 uint32_t pktlen;
180 int recv_len; 188 int recv_len;
181 189
182 if (peek_buf(fd, &pktlen, sizeof(pktlen)) < (int)sizeof(pktlen)) { 190 if (peek_buf(fd, &pktlen, sizeof(pktlen)) < (int) sizeof(pktlen)) {
183 return -errno; 191 return -errno;
184 } 192 }
185
186 if (len == 0) {
187 // allocate buffer space
188 *data = malloc(pktlen);
189 } else if (len < pktlen) {
190 // target buffer is to small to hold this packet! fix it!
191 if (verbose >= 2) logmsg(LOG_WARNING, "%s: WARNING -- packet (%d) is larger than target buffer (%d)! Truncating.", __func__, pktlen, len);
192 pktlen = len;
193 }
194
195 recv_len = recv_buf(fd, *data, pktlen);
196 if ((recv_len > 0) && ((uint32_t)recv_len < pktlen)) {
197 if (verbose >= 2) logmsg(LOG_WARNING, "%s: Uh-oh, we got less than the packet's size, %d instead of %d...", __func__, recv_len, pktlen);
198 }
199 193
194 if (len == 0) {
195 // allocate buffer space
196 *data = malloc(pktlen);
197 } else if (len < pktlen) {
198 // target buffer is to small to hold this packet! fix it!
199 if (verbose >= 2)
200 logmsg(LOG_WARNING,
201 "%s: WARNING -- packet (%d) is larger than target buffer (%d)! Truncating.",
202 __func__, pktlen, len);
203 pktlen = len;
204 }
205
206 recv_len = recv_buf(fd, *data, pktlen);
207 if ((recv_len > 0) && ((uint32_t) recv_len < pktlen)) {
208 if (verbose >= 2)
209 logmsg(LOG_WARNING,
210 "%s: Uh-oh, we got less than the packet's size, %d instead of %d...",
211 __func__, recv_len, pktlen);
212 }
200#ifdef DEBUG 213#ifdef DEBUG
201 if (*data && (recv_len > 0) && verbose >= 4) { 214 if (*data && (recv_len > 0) && verbose >= 4) {
202 fprintf(stderr, "%s: received:\n", __func__); 215 fprintf(stderr, "%s: received:\n", __func__);
203 print_buffer(stderr, *data, recv_len); 216 print_buffer(stderr, *data, recv_len);
204 } 217 }
205#endif 218#endif
206 219
207 return recv_len; 220 return recv_len;
208} 221}
209 222
210/** 223/**
@@ -218,20 +231,22 @@ static int usbmuxd_get_request(int fd, void **data, size_t len)
218 */ 231 */
219static int usbmuxd_send_result(int fd, uint32_t tag, uint32_t result_code) 232static int usbmuxd_send_result(int fd, uint32_t tag, uint32_t result_code)
220{ 233{
221 struct usbmuxd_result res; 234 struct usbmuxd_result res;
222 int ret; 235 int ret;
223 236
224 res.header.length = sizeof(res); 237 res.header.length = sizeof(res);
225 res.header.reserved = 0; 238 res.header.reserved = 0;
226 res.header.type = USBMUXD_RESULT; 239 res.header.type = USBMUXD_RESULT;
227 res.header.tag = tag; 240 res.header.tag = tag;
228 res.result = result_code; 241 res.result = result_code;
229 242
230 if (verbose >= 4) logmsg(LOG_NOTICE, "%s: tag=%d result=%d", __func__, res.header.tag, res.result); 243 if (verbose >= 4)
231 244 logmsg(LOG_NOTICE, "%s: tag=%d result=%d", __func__,
232 ret = send_buf(fd, &res, sizeof(res)); 245 res.header.tag, res.result);
233 fsync(fd); // let's get it sent 246
234 return ret; 247 ret = send_buf(fd, &res, sizeof(res));
248 fsync(fd); // let's get it sent
249 return ret;
235} 250}
236 251
237/** 252/**
@@ -244,69 +259,84 @@ static int usbmuxd_send_result(int fd, uint32_t tag, uint32_t result_code)
244 */ 259 */
245static void *usbmuxd_client_reader_thread(void *arg) 260static void *usbmuxd_client_reader_thread(void *arg)
246{ 261{
247 struct client_data *cdata; 262 struct client_data *cdata;
248 263
249 char rbuffer[512]; 264 char rbuffer[512];
250 uint32_t rbuffersize = 512; 265 uint32_t rbuffersize = 512;
251 uint32_t rlen; 266 uint32_t rlen;
252 int err; 267 int err;
253 char *cursor; 268 char *cursor;
254 ssize_t len; 269 ssize_t len;
255 int result; 270 int result;
256 271
257 if (!arg) { 272 if (!arg) {
258 if (verbose >= 2) logmsg(LOG_ERR, "%s: invalid client_data supplied!", __func__); 273 if (verbose >= 2)
259 cdata->reader_dead = 1; 274 logmsg(LOG_ERR, "%s: invalid client_data supplied!", __func__);
260 return NULL; 275 cdata->reader_dead = 1;
261 } 276 return NULL;
277 }
262 278
263 cdata = (struct client_data*)arg; 279 cdata = (struct client_data *) arg;
264 280
265 cdata->reader_dead = 0; 281 cdata->reader_dead = 0;
266 282
267 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%d:%d]: started", __func__, cdata->dev->device_id, cdata->dev->use_count); 283 if (verbose >= 3)
284 logmsg(LOG_NOTICE, "%s[%d:%d]: started", __func__,
285 cdata->dev->device_id, cdata->dev->use_count);
268 286
269 while (!quit_flag && !cdata->reader_quit) { 287 while (!quit_flag && !cdata->reader_quit) {
270 result = check_fd(cdata->socket, FD_WRITE, DEFAULT_TIMEOUT); 288 result = check_fd(cdata->socket, FD_WRITE, DEFAULT_TIMEOUT);
271 if (result <= 0) { 289 if (result <= 0) {
272 if (result < 0) { 290 if (result < 0) {
273 if (verbose >= 2) logmsg(LOG_ERR, "%s: select error: %s", __func__, strerror(errno)); 291 if (verbose >= 2)
274 } 292 logmsg(LOG_ERR, "%s: select error: %s", __func__,
275 continue; 293 strerror(errno));
276 } 294 }
295 continue;
296 }
277 297
278 rlen = 0; 298 rlen = 0;
279 err = usbmux_recv_timeout(cdata->muxclient, rbuffer, rbuffersize, &rlen, DEFAULT_TIMEOUT); 299 err =
280 if (err != 0) { 300 usbmux_recv_timeout(cdata->muxclient, rbuffer, rbuffersize,
281 if (verbose >= 2) logmsg(LOG_ERR, "%s[%d:%d]: encountered USB read error: %d", __func__, cdata->dev->device_id, cdata->dev->use_count, err); 301 &rlen, DEFAULT_TIMEOUT);
282 break; 302 if (err != 0) {
283 } 303 if (verbose >= 2)
304 logmsg(LOG_ERR,
305 "%s[%d:%d]: encountered USB read error: %d",
306 __func__, cdata->dev->device_id,
307 cdata->dev->use_count, err);
308 break;
309 }
284 310
285 cursor = rbuffer; 311 cursor = rbuffer;
286 while (rlen > 0) { 312 while (rlen > 0) {
287 len = send_buf(cdata->socket, cursor, rlen); 313 len = send_buf(cdata->socket, cursor, rlen);
288 if (len <= 0) { 314 if (len <= 0) {
289 logmsg(LOG_ERR, "%s: Error: send returned %d", __func__, len); 315 logmsg(LOG_ERR, "%s: Error: send returned %d", __func__,
290 err = 1; 316 len);
291 break; 317 err = 1;
292 } 318 break;
293 // calculate remainder 319 }
294 rlen -= len; 320 // calculate remainder
295 // advance cursor 321 rlen -= len;
296 cursor += len; 322 // advance cursor
297 } 323 cursor += len;
298 if (err != 0) { 324 }
299 logmsg(LOG_ERR, "%s: Error when writing to client...", __func__); 325 if (err != 0) {
300 break; 326 logmsg(LOG_ERR, "%s: Error when writing to client...",
327 __func__);
328 break;
329 }
330 fsync(cdata->socket);
301 } 331 }
302 fsync(cdata->socket);
303 }
304 332
305 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%d:%d]: terminated", __func__, cdata->dev->device_id, cdata->dev->use_count); 333 if (verbose >= 3)
334 logmsg(LOG_NOTICE, "%s[%d:%d]: terminated", __func__,
335 cdata->dev->device_id, cdata->dev->use_count);
306 336
307 cdata->reader_dead = 1; 337 cdata->reader_dead = 1;
308 338
309 return NULL; 339 return NULL;
310} 340}
311 341
312/** 342/**
@@ -321,60 +351,73 @@ static void *usbmuxd_client_reader_thread(void *arg)
321 */ 351 */
322static int usbmuxd_handleConnectResult(struct client_data *cdata) 352static int usbmuxd_handleConnectResult(struct client_data *cdata)
323{ 353{
324 int result; 354 int result;
325 char buffer[512]; 355 char buffer[512];
326 char err_type[64]; 356 char err_type[64];
327 int err_code; 357 int err_code;
328 ssize_t maxlen = 512; 358 ssize_t maxlen = 512;
329 uint32_t rlen; 359 uint32_t rlen;
330 int err; 360 int err;
331 361
332 if (!cdata) { 362 if (!cdata) {
333 if (verbose >= 2) logmsg(LOG_ERR, "%s: Invalid client_data provided!", __func__); 363 if (verbose >= 2)
334 return -EINVAL; 364 logmsg(LOG_ERR, "%s: Invalid client_data provided!", __func__);
335 } 365 return -EINVAL;
336
337 result = check_fd(cdata->socket, FD_WRITE, DEFAULT_TIMEOUT);
338 if (result <= 0) {
339 if (result < 0) {
340 if (verbose >= 2) logmsg(LOG_ERR, "%s: select error: %s", __func__, strerror(errno));
341 return result;
342 } 366 }
343 } else { 367
344 result = 0; 368 result = check_fd(cdata->socket, FD_WRITE, DEFAULT_TIMEOUT);
345 err = usbmux_recv_timeout(cdata->muxclient, buffer, maxlen, &rlen, 100); 369 if (result <= 0) {
346 if (err < 0) { 370 if (result < 0) {
347 if (verbose >= 2) logmsg(LOG_ERR, "%s: encountered USB read error: %d", __func__, err); 371 if (verbose >= 2)
348 usbmuxd_send_result(cdata->socket, cdata->tag, -err); 372 logmsg(LOG_ERR, "%s: select error: %s", __func__,
349 return err; 373 strerror(errno));
374 return result;
375 }
350 } else { 376 } else {
351 if (rlen > 0) { 377 result = 0;
352 if ((buffer[0] == 1) && (rlen > 20) && !memcmp(buffer+1, "handleConnectResult:", 20)) { 378 err =
353 // hm... we got an error message! 379 usbmux_recv_timeout(cdata->muxclient, buffer, maxlen, &rlen,
354 buffer[rlen] = 0; 380 100);
355 if (verbose >= 1) logmsg(LOG_ERR, "%s: %s\n", __func__, buffer+22); 381 if (err < 0) {
356 382 if (verbose >= 2)
357 if (sscanf(buffer+22, "%s - %d\n", err_type, &err_code) == 2) { 383 logmsg(LOG_ERR, "%s: encountered USB read error: %d",
358 usbmuxd_send_result(cdata->socket, cdata->tag, err_code); 384 __func__, err);
359 return -err_code; 385 usbmuxd_send_result(cdata->socket, cdata->tag, -err);
360 } else { 386 return err;
361 usbmuxd_send_result(cdata->socket, cdata->tag, ENODATA);
362 return -ENODATA;
363 }
364 } else { 387 } else {
365 // send success result 388 if (rlen > 0) {
366 usbmuxd_send_result(cdata->socket, cdata->tag, 0); 389 if ((buffer[0] == 1) && (rlen > 20)
367 // and the server greeting message 390 && !memcmp(buffer + 1, "handleConnectResult:", 20)) {
368 send_buf(cdata->socket, buffer, rlen); 391 // hm... we got an error message!
392 buffer[rlen] = 0;
393 if (verbose >= 1)
394 logmsg(LOG_ERR, "%s: %s\n", __func__, buffer + 22);
395
396 if (sscanf
397 (buffer + 22, "%s - %d\n", err_type, &err_code)
398 == 2) {
399 usbmuxd_send_result(cdata->socket, cdata->tag,
400 err_code);
401 return -err_code;
402 } else {
403 usbmuxd_send_result(cdata->socket, cdata->tag,
404 ENODATA);
405 return -ENODATA;
406 }
407 } else {
408 // send success result
409 usbmuxd_send_result(cdata->socket, cdata->tag, 0);
410 // and the server greeting message
411 send_buf(cdata->socket, buffer, rlen);
412 }
413 } else {
414 // no server greeting? this seems to be ok. send success.
415 usbmuxd_send_result(cdata->socket, cdata->tag, 0);
416 }
369 } 417 }
370 } else { 418 //fsync(cdata->socket);
371 // no server greeting? this seems to be ok. send success.
372 usbmuxd_send_result(cdata->socket, cdata->tag, 0);
373 }
374 } 419 }
375 //fsync(cdata->socket); 420 return result;
376 }
377 return result;
378} 421}
379 422
380/** 423/**
@@ -383,96 +426,115 @@ static int usbmuxd_handleConnectResult(struct client_data *cdata)
383 */ 426 */
384static void *usbmuxd_client_handler_thread(void *arg) 427static void *usbmuxd_client_handler_thread(void *arg)
385{ 428{
386 struct client_data *cdata; 429 struct client_data *cdata;
387 int result; 430 int result;
388 char *cursor; 431 char *cursor;
389 char buffer[65536]; 432 char buffer[65536];
390 ssize_t len; 433 ssize_t len;
391 ssize_t maxlen = sizeof(buffer); 434 ssize_t maxlen = sizeof(buffer);
392 uint32_t wlen; 435 uint32_t wlen;
393 int err; 436 int err;
394 437
395 if (!arg) { 438 if (!arg) {
396 if (verbose >= 2) logmsg(LOG_ERR, "%s: invalid client_data provided!", __func__); 439 if (verbose >= 2)
397 return NULL; 440 logmsg(LOG_ERR, "%s: invalid client_data provided!", __func__);
398 } 441 return NULL;
399 442 }
400 cdata = (struct client_data*)arg;
401
402 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%d:%d]: started", __func__, cdata->dev->device_id,cdata->dev->use_count);
403 443
404 if (usbmuxd_handleConnectResult(cdata)) { 444 cdata = (struct client_data *) arg;
405 if (verbose >= 3) logmsg(LOG_ERR, "handleConnectResult: Error");
406 goto leave;
407 } else {
408 if (verbose >= 3) logmsg(LOG_NOTICE, "handleConnectResult: Success");
409 }
410 445
411 // starting mux reader thread 446 if (verbose >= 3)
412 cdata->reader_quit = 0; 447 logmsg(LOG_NOTICE, "%s[%d:%d]: started", __func__,
413 cdata->reader_dead = 0; 448 cdata->dev->device_id, cdata->dev->use_count);
414 if (pthread_create(&cdata->reader, NULL, usbmuxd_client_reader_thread, cdata) != 0) {
415 if (verbose >= 2) logmsg(LOG_ERR, "%s: could not start client_reader thread", __func__);
416 cdata->reader = 0;
417 }
418 449
419 while (!quit_flag && !cdata->reader_dead) { 450 if (usbmuxd_handleConnectResult(cdata)) {
420 result = check_fd(cdata->socket, FD_READ, DEFAULT_TIMEOUT); 451 if (verbose >= 3)
421 if (result <= 0) { 452 logmsg(LOG_ERR, "handleConnectResult: Error");
422 if (result < 0) { 453 goto leave;
423 if (verbose >= 3) logmsg(LOG_ERR, "%s: Error: checkfd: %s", __func__, strerror(errno)); 454 } else {
424 } 455 if (verbose >= 3)
425 continue; 456 logmsg(LOG_NOTICE, "handleConnectResult: Success");
426 } 457 }
427 458
428 // check_fd told us there's data available, so read from client 459 // starting mux reader thread
429 // and push to USB device. 460 cdata->reader_quit = 0;
430 len = recv(cdata->socket, buffer, maxlen, 0); 461 cdata->reader_dead = 0;
431 if (len == 0) { 462 if (pthread_create
432 break; 463 (&cdata->reader, NULL, usbmuxd_client_reader_thread, cdata) != 0) {
433 } 464 if (verbose >= 2)
434 if (len < 0) { 465 logmsg(LOG_ERR, "%s: could not start client_reader thread",
435 if (verbose >= 2) logmsg(LOG_ERR, "%s[%d:%d]: Error: recv: %s", __func__, cdata->dev->device_id, cdata->dev->use_count, strerror(errno)); 466 __func__);
436 break; 467 cdata->reader = 0;
437 } 468 }
438 469
439 cursor = buffer; 470 while (!quit_flag && !cdata->reader_dead) {
440 471 result = check_fd(cdata->socket, FD_READ, DEFAULT_TIMEOUT);
441 pthread_mutex_lock(&cdata->dev->writer_mutex); 472 if (result <= 0) {
442 do { 473 if (result < 0) {
443 wlen = 0; 474 if (verbose >= 3)
444 err = usbmux_send(cdata->muxclient, cursor, len, &wlen); 475 logmsg(LOG_ERR, "%s: Error: checkfd: %s", __func__,
445 if (err == -ETIMEDOUT) { 476 strerror(errno));
446 // some kind of timeout... just be patient and retry. 477 }
447 } else if (err < 0) { 478 continue;
448 if (verbose >= 2) logmsg(LOG_ERR, "%s[%d:%d]: USB write error: %d", __func__, cdata->dev->device_id, cdata->dev->use_count, err); 479 }
449 len = -1; 480 // check_fd told us there's data available, so read from client
450 break; 481 // and push to USB device.
451 } 482 len = recv(cdata->socket, buffer, maxlen, 0);
452 483 if (len == 0) {
453 // calculate remainder. 484 break;
454 len -= wlen; 485 }
455 // advance cursor appropiately. 486 if (len < 0) {
456 cursor += wlen; 487 if (verbose >= 2)
457 } while ((len > 0) && !quit_flag); 488 logmsg(LOG_ERR, "%s[%d:%d]: Error: recv: %s", __func__,
458 pthread_mutex_unlock(&cdata->dev->writer_mutex); 489 cdata->dev->device_id, cdata->dev->use_count,
459 if (len < 0) { 490 strerror(errno));
460 break; 491 break;
492 }
493
494 cursor = buffer;
495
496 pthread_mutex_lock(&cdata->dev->writer_mutex);
497 do {
498 wlen = 0;
499 err = usbmux_send(cdata->muxclient, cursor, len, &wlen);
500 if (err == -ETIMEDOUT) {
501 // some kind of timeout... just be patient and retry.
502 } else if (err < 0) {
503 if (verbose >= 2)
504 logmsg(LOG_ERR, "%s[%d:%d]: USB write error: %d",
505 __func__, cdata->dev->device_id,
506 cdata->dev->use_count, err);
507 len = -1;
508 break;
509 }
510 // calculate remainder.
511 len -= wlen;
512 // advance cursor appropiately.
513 cursor += wlen;
514 }
515 while ((len > 0) && !quit_flag);
516 pthread_mutex_unlock(&cdata->dev->writer_mutex);
517 if (len < 0) {
518 break;
519 }
461 } 520 }
462 }
463 521
464leave: 522 leave:
465 // cleanup 523 // cleanup
466 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%d:%d]: terminating", __func__, cdata->dev->device_id, cdata->dev->use_count); 524 if (verbose >= 3)
467 if (cdata->reader != 0) { 525 logmsg(LOG_NOTICE, "%s[%d:%d]: terminating", __func__,
468 cdata->reader_quit = 1; 526 cdata->dev->device_id, cdata->dev->use_count);
469 pthread_join(cdata->reader, NULL); 527 if (cdata->reader != 0) {
470 } 528 cdata->reader_quit = 1;
529 pthread_join(cdata->reader, NULL);
530 }
471 531
472 cdata->handler_dead = 1; 532 cdata->handler_dead = 1;
473 533
474 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%d:%d]: terminated", __func__, cdata->dev->device_id, cdata->dev->use_count); 534 if (verbose >= 3)
475 return NULL; 535 logmsg(LOG_NOTICE, "%s[%d:%d]: terminated", __func__,
536 cdata->dev->device_id, cdata->dev->use_count);
537 return NULL;
476} 538}
477 539
478/** 540/**
@@ -481,36 +543,41 @@ leave:
481 */ 543 */
482static void *usbmuxd_bulk_reader_thread(void *arg) 544static void *usbmuxd_bulk_reader_thread(void *arg)
483{ 545{
484 struct device_info *cur_dev; 546 struct device_info *cur_dev;
485 int err; 547 int err;
486 548
487 if (!arg) { 549 if (!arg) {
488 if (verbose >= 2) logmsg(LOG_ERR, "%s: Invalid client_data provided", __func__); 550 if (verbose >= 2)
489 return NULL; 551 logmsg(LOG_ERR, "%s: Invalid client_data provided", __func__);
490 } 552 return NULL;
553 }
491 554
492 cur_dev = (struct device_info*)arg; 555 cur_dev = (struct device_info *) arg;
493 556
494 if (verbose >= 3) logmsg(LOG_NOTICE, "%s: started", __func__); 557 if (verbose >= 3)
558 logmsg(LOG_NOTICE, "%s: started", __func__);
495 559
496 while (!quit_flag && cur_dev) { 560 while (!quit_flag && cur_dev) {
497 561
498 pthread_mutex_lock(&cur_dev->mutex); 562 pthread_mutex_lock(&cur_dev->mutex);
499 if (cur_dev->use_count <= 0) { 563 if (cur_dev->use_count <= 0) {
500 pthread_mutex_unlock(&cur_dev->mutex); 564 pthread_mutex_unlock(&cur_dev->mutex);
501 break; 565 break;
502 } 566 }
503 pthread_mutex_unlock(&cur_dev->mutex); 567 pthread_mutex_unlock(&cur_dev->mutex);
504 568
505 if ((err = usbmux_pullbulk(cur_dev->phone)) < 0) { 569 if ((err = usbmux_pullbulk(cur_dev->phone)) < 0) {
506 if (verbose >= 1) logmsg(LOG_ERR, "%s: error %d when reading from device", __func__, err); 570 if (verbose >= 1)
507 break; 571 logmsg(LOG_ERR, "%s: error %d when reading from device",
572 __func__, err);
573 break;
574 }
508 } 575 }
509 }
510 576
511 if (verbose >= 3) logmsg(LOG_NOTICE, "%s: terminated", __func__); 577 if (verbose >= 3)
578 logmsg(LOG_NOTICE, "%s: terminated", __func__);
512 579
513 return NULL; 580 return NULL;
514} 581}
515 582
516/** 583/**
@@ -520,286 +587,374 @@ static void *usbmuxd_bulk_reader_thread(void *arg)
520 */ 587 */
521static void *usbmuxd_client_init_thread(void *arg) 588static void *usbmuxd_client_init_thread(void *arg)
522{ 589{
523 struct client_data *cdata; 590 struct client_data *cdata;
524 struct usbmuxd_scan_request *s_req = NULL; 591 struct usbmuxd_scan_request *s_req = NULL;
525 struct usbmuxd_device_info_record dev_info_rec; 592 struct usbmuxd_device_info_record dev_info_rec;
526 struct usbmuxd_connect_request *c_req = NULL; 593 struct usbmuxd_connect_request *c_req = NULL;
594
595 struct usb_bus *bus;
596 struct usb_device *dev;
597
598 int recv_len;
599 int found = 0;
600 int res;
601 int i;
602
603 usbmux_device_t phone = NULL;
604 struct device_info *cur_dev = NULL;
605
606 if (!arg) {
607 if (verbose >= 1)
608 logmsg(LOG_ERR, "%s[%x]: invalid client_data provided!",
609 __func__, THREAD);
610 return NULL;
611 }
527 612
528 struct usb_bus *bus; 613 cdata = (struct client_data *) arg;
529 struct usb_device *dev; 614 cdata->dead = 0;
530 615
531 int recv_len; 616 if (verbose >= 3)
532 int found = 0; 617 logmsg(LOG_NOTICE, "%s[%x]: started (fd=%d)", __func__, THREAD,
533 int res; 618 cdata->socket);
534 int i;
535 619
536 usbmux_device_t phone = NULL; 620 if ((recv_len =
537 struct device_info *cur_dev = NULL; 621 usbmuxd_get_request(cdata->socket, (void **) &s_req, 0)) <= 0) {
622 if (verbose >= 2)
623 logmsg(LOG_ERR, "%s[%x]: No scan packet received, error %s",
624 __func__, THREAD, strerror(errno));
625 goto leave;
626 }
538 627
539 if (!arg) { 628 if ((recv_len == sizeof(struct usbmuxd_scan_request))
540 if (verbose >= 1) logmsg(LOG_ERR, "%s[%x]: invalid client_data provided!", __func__, THREAD); 629 && (s_req->header.length == sizeof(struct usbmuxd_scan_request))
541 return NULL; 630 && (s_req->header.reserved == 0)
542 } 631 && (s_req->header.type == USBMUXD_SCAN)) {
543 632 // send success response
544 cdata = (struct client_data*)arg; 633 if (verbose >= 3)
545 cdata->dead = 0; 634 logmsg(LOG_NOTICE, "%s[%x]: Got scan packet!", __func__,
546 635 THREAD);
547 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%x]: started (fd=%d)", __func__, THREAD, cdata->socket); 636 usbmuxd_send_result(cdata->socket, s_req->header.tag, 0);
548 637 } else if ((recv_len == sizeof(struct usbmuxd_connect_request))
549 if ((recv_len = usbmuxd_get_request(cdata->socket, (void**)&s_req, 0)) <= 0) { 638 && (s_req->header.type == USBMUXD_CONNECT)) {
550 if (verbose >= 2) logmsg(LOG_ERR, "%s[%x]: No scan packet received, error %s", __func__, THREAD, strerror(errno)); 639 c_req = (struct usbmuxd_connect_request *) s_req;
551 goto leave; 640 s_req = NULL;
552 } 641 goto connect;
553 642 } else {
554 if ((recv_len == sizeof(struct usbmuxd_scan_request)) && (s_req->header.length == sizeof(struct usbmuxd_scan_request)) 643 // send error response and exit
555 && (s_req->header.reserved == 0) && (s_req->header.type == USBMUXD_SCAN)) { 644 if (verbose >= 2)
556 // send success response 645 logmsg(LOG_ERR, "%s[%x]: Invalid scan packet received.",
557 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%x]: Got scan packet!", __func__, THREAD); 646 __func__, THREAD);
558 usbmuxd_send_result(cdata->socket, s_req->header.tag, 0); 647 // TODO is this required?!
559 } else if ((recv_len == sizeof(struct usbmuxd_connect_request)) && (s_req->header.type == USBMUXD_CONNECT)) { 648 usbmuxd_send_result(cdata->socket, s_req->header.tag, EINVAL);
560 c_req = (struct usbmuxd_connect_request*)s_req; 649 goto leave;
561 s_req = NULL; 650 }
562 goto connect;
563 } else {
564 // send error response and exit
565 if (verbose >= 2) logmsg(LOG_ERR, "%s[%x]: Invalid scan packet received.", __func__, THREAD);
566 // TODO is this required?!
567 usbmuxd_send_result(cdata->socket, s_req->header.tag, EINVAL);
568 goto leave;
569 }
570
571 pthread_mutex_lock(&usb_mutex);
572 // gather data about all iPhones/iPods attached
573
574 if (verbose >= 5) logmsg(LOG_DEBUG, "%s[%x]: usb init", __func__, THREAD);
575 usb_init();
576 if (verbose >= 5) logmsg(LOG_DEBUG, "%s[%x]: usb find busses", __func__, THREAD);
577 usb_find_busses();
578 if (verbose >= 5) logmsg(LOG_DEBUG, "%s[%x]: usb find devices", __func__, THREAD);
579 usb_find_devices();
580
581 if (verbose >= 2) logmsg(LOG_NOTICE, "%s[%x]: Looking for attached devices...", __func__, THREAD);
582
583 for (bus = usb_get_busses(); bus; bus = bus->next) {
584 for (dev = bus->devices; dev; dev = dev->next) {
585 if (dev->descriptor.idVendor == 0x05ac
586 && dev->descriptor.idProduct >= 0x1290
587 && dev->descriptor.idProduct <= 0x1293)
588 {
589 if (verbose >= 1) logmsg(LOG_NOTICE, "%s[%x]: Found device on bus %d, id %d", __func__, THREAD, bus->location, dev->devnum);
590 found++;
591
592 // construct packet
593 memset(&dev_info_rec, 0, sizeof(dev_info_rec));
594 dev_info_rec.header.length = sizeof(dev_info_rec);
595 dev_info_rec.header.type = USBMUXD_DEVICE_INFO;
596 dev_info_rec.device.device_id = dev->devnum;
597 dev_info_rec.device.product_id = dev->descriptor.idProduct;
598 if (dev->descriptor.iSerialNumber) {
599 usb_dev_handle *udev;
600 //pthread_mutex_lock(&usbmux_mutex);
601 udev = usb_open(dev);
602 if (udev) {
603 usb_get_string_simple(udev, dev->descriptor.iSerialNumber, dev_info_rec.device.serial_number, sizeof(dev_info_rec.device.serial_number)+1);
604 usb_close(udev);
605 }
606 //pthread_mutex_unlock(&usbmux_mutex);
607 }
608 651
652 pthread_mutex_lock(&usb_mutex);
653 // gather data about all iPhones/iPods attached
654
655 if (verbose >= 5)
656 logmsg(LOG_DEBUG, "%s[%x]: usb init", __func__, THREAD);
657 usb_init();
658 if (verbose >= 5)
659 logmsg(LOG_DEBUG, "%s[%x]: usb find busses", __func__, THREAD);
660 usb_find_busses();
661 if (verbose >= 5)
662 logmsg(LOG_DEBUG, "%s[%x]: usb find devices", __func__, THREAD);
663 usb_find_devices();
664
665 if (verbose >= 2)
666 logmsg(LOG_NOTICE, "%s[%x]: Looking for attached devices...",
667 __func__, THREAD);
668
669 for (bus = usb_get_busses(); bus; bus = bus->next) {
670 for (dev = bus->devices; dev; dev = dev->next) {
671 if (dev->descriptor.idVendor == 0x05ac
672 && dev->descriptor.idProduct >= 0x1290
673 && dev->descriptor.idProduct <= 0x1293) {
674 if (verbose >= 1)
675 logmsg(LOG_NOTICE,
676 "%s[%x]: Found device on bus %d, id %d",
677 __func__, THREAD, bus->location, dev->devnum);
678 found++;
679
680 // construct packet
681 memset(&dev_info_rec, 0, sizeof(dev_info_rec));
682 dev_info_rec.header.length = sizeof(dev_info_rec);
683 dev_info_rec.header.type = USBMUXD_DEVICE_INFO;
684 dev_info_rec.device.device_id = dev->devnum;
685 dev_info_rec.device.product_id = dev->descriptor.idProduct;
686 if (dev->descriptor.iSerialNumber) {
687 usb_dev_handle *udev;
688 //pthread_mutex_lock(&usbmux_mutex);
689 udev = usb_open(dev);
690 if (udev) {
691 usb_get_string_simple(udev,
692 dev->descriptor.
693 iSerialNumber,
694 dev_info_rec.device.
695 serial_number,
696 sizeof(dev_info_rec.device.
697 serial_number) + 1);
698 usb_close(udev);
699 }
700 //pthread_mutex_unlock(&usbmux_mutex);
701 }
609#ifdef DEBUG 702#ifdef DEBUG
610 if (verbose >= 4) print_buffer(stderr, (char*)&dev_info_rec, sizeof(dev_info_rec)); 703 if (verbose >= 4)
704 print_buffer(stderr, (char *) &dev_info_rec,
705 sizeof(dev_info_rec));
611#endif 706#endif
612 707
613 // send it 708 // send it
614 if (send_buf(cdata->socket, &dev_info_rec, sizeof(dev_info_rec)) <= 0) { 709 if (send_buf
615 if (verbose >= 3) logmsg(LOG_ERR, "%s[%x]: Error: Could not send device info: %s", __func__, THREAD, strerror(errno)); 710 (cdata->socket, &dev_info_rec,
616 found--; 711 sizeof(dev_info_rec)) <= 0) {
712 if (verbose >= 3)
713 logmsg(LOG_ERR,
714 "%s[%x]: Error: Could not send device info: %s",
715 __func__, THREAD, strerror(errno));
716 found--;
717 }
718 }
617 } 719 }
618 }
619 } 720 }
620 } 721 pthread_mutex_unlock(&usb_mutex);
621 pthread_mutex_unlock(&usb_mutex); 722
622 723 if (found <= 0) {
623 if (found <= 0) { 724 if (verbose >= 1)
624 if (verbose >= 1) logmsg(LOG_NOTICE, "%s[%x]: No attached iPhone/iPod devices found.", __func__, THREAD); 725 logmsg(LOG_NOTICE,
625 goto leave; 726 "%s[%x]: No attached iPhone/iPod devices found.",
626 } 727 __func__, THREAD);
627 728 goto leave;
628 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%x]: Waiting for connect request", __func__, THREAD);
629
630 // now wait for connect request
631 //memset(&c_req, 0, sizeof(c_req));
632 if ((recv_len = usbmuxd_get_request(cdata->socket, (void**)&c_req, 0)) <= 0) {
633 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%x]: Did not receive any connect request.", __func__, THREAD);
634 goto leave;
635 }
636
637connect:
638
639 if (c_req->header.type != USBMUXD_CONNECT) {
640 if (verbose >= 2) logmsg(LOG_ERR, "%s[%x]: Unexpected packet of type %d received.", __func__, THREAD, c_req->header.type);
641 goto leave;
642 }
643
644 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%x]: Setting up connection to usb device #%d on port %d", __func__, THREAD, c_req->device_id, ntohs(c_req->tcp_dport));
645
646 // find the device, and open usb connection
647 pthread_mutex_lock(&usbmux_mutex);
648 phone = NULL;
649 cur_dev = NULL;
650 // first check if we already have an open connection
651 if (devices) {
652 for (i = 0; i < device_count; i++) {
653 if (devices[i]) {
654 if (devices[i]->device_id == c_req->device_id) {
655 devices[i]->use_count++;
656 cur_dev = devices[i];
657 phone = cur_dev->phone;
658 break;
659 }
660 }
661 } 729 }
662 }
663 if (!phone) {
664 // if not found, make a new connection
665 if (verbose >= 2) logmsg(LOG_NOTICE, "%s[%x]: creating new usb connection, device_id=%d", __func__, THREAD, c_req->device_id);
666 730
667 pthread_mutex_lock(&usb_mutex); 731 if (verbose >= 3)
668 if (usbmux_get_specific_device(0, c_req->device_id, &phone) < 0) { 732 logmsg(LOG_NOTICE, "%s[%x]: Waiting for connect request", __func__,
669 pthread_mutex_unlock(&usb_mutex); 733 THREAD);
670 pthread_mutex_unlock(&usbmux_mutex); 734
671 if (verbose >= 1) logmsg(LOG_ERR, "%s[%x]: device_id %d could not be opened", __func__, THREAD, c_req->device_id); 735 // now wait for connect request
672 usbmuxd_send_result(cdata->socket, c_req->header.tag, ENODEV); 736 //memset(&c_req, 0, sizeof(c_req));
673 goto leave; 737 if ((recv_len =
738 usbmuxd_get_request(cdata->socket, (void **) &c_req, 0)) <= 0) {
739 if (verbose >= 3)
740 logmsg(LOG_NOTICE,
741 "%s[%x]: Did not receive any connect request.",
742 __func__, THREAD);
743 goto leave;
674 } 744 }
675 pthread_mutex_unlock(&usb_mutex); 745
676 746 connect:
677 // create device object 747
678 if (verbose >= 3) logmsg(LOG_DEBUG, "%s[%x]: add to device list", __func__, THREAD); 748 if (c_req->header.type != USBMUXD_CONNECT) {
679 cur_dev = (struct device_info*)malloc(sizeof(struct device_info)); 749 if (verbose >= 2)
680 memset(cur_dev, 0, sizeof(struct device_info)); 750 logmsg(LOG_ERR,
681 cur_dev->use_count = 1; 751 "%s[%x]: Unexpected packet of type %d received.",
682 cur_dev->device_id = c_req->device_id; 752 __func__, THREAD, c_req->header.type);
683 cur_dev->phone = phone; 753 goto leave;
684 cur_dev->bulk_reader = 0; 754 }
685 pthread_mutex_init(&cur_dev->mutex, NULL); 755
686 pthread_mutex_init(&cur_dev->writer_mutex, NULL); 756 if (verbose >= 3)
687 757 logmsg(LOG_NOTICE,
688 if (verbose >= 3) logmsg(LOG_DEBUG, "%s[%x]: device_count = %d", __func__, THREAD, device_count); 758 "%s[%x]: Setting up connection to usb device #%d on port %d",
689 759 __func__, THREAD, c_req->device_id,
690 // add to list of devices 760 ntohs(c_req->tcp_dport));
691 devices = (struct device_info**)realloc(devices, sizeof(struct device_info*) * (device_count+1)); 761
762 // find the device, and open usb connection
763 pthread_mutex_lock(&usbmux_mutex);
764 phone = NULL;
765 cur_dev = NULL;
766 // first check if we already have an open connection
692 if (devices) { 767 if (devices) {
693 devices[device_count] = cur_dev; 768 for (i = 0; i < device_count; i++) {
694 device_count++; 769 if (devices[i]) {
770 if (devices[i]->device_id == c_req->device_id) {
771 devices[i]->use_count++;
772 cur_dev = devices[i];
773 phone = cur_dev->phone;
774 break;
775 }
776 }
777 }
778 }
779 if (!phone) {
780 // if not found, make a new connection
781 if (verbose >= 2)
782 logmsg(LOG_NOTICE,
783 "%s[%x]: creating new usb connection, device_id=%d",
784 __func__, THREAD, c_req->device_id);
785
786 pthread_mutex_lock(&usb_mutex);
787 if (usbmux_get_specific_device(0, c_req->device_id, &phone) < 0) {
788 pthread_mutex_unlock(&usb_mutex);
789 pthread_mutex_unlock(&usbmux_mutex);
790 if (verbose >= 1)
791 logmsg(LOG_ERR, "%s[%x]: device_id %d could not be opened",
792 __func__, THREAD, c_req->device_id);
793 usbmuxd_send_result(cdata->socket, c_req->header.tag, ENODEV);
794 goto leave;
795 }
796 pthread_mutex_unlock(&usb_mutex);
797
798 // create device object
799 if (verbose >= 3)
800 logmsg(LOG_DEBUG, "%s[%x]: add to device list", __func__,
801 THREAD);
802 cur_dev =
803 (struct device_info *) malloc(sizeof(struct device_info));
804 memset(cur_dev, 0, sizeof(struct device_info));
805 cur_dev->use_count = 1;
806 cur_dev->device_id = c_req->device_id;
807 cur_dev->phone = phone;
808 cur_dev->bulk_reader = 0;
809 pthread_mutex_init(&cur_dev->mutex, NULL);
810 pthread_mutex_init(&cur_dev->writer_mutex, NULL);
811
812 if (verbose >= 3)
813 logmsg(LOG_DEBUG, "%s[%x]: device_count = %d", __func__,
814 THREAD, device_count);
815
816 // add to list of devices
817 devices =
818 (struct device_info **) realloc(devices,
819 sizeof(struct device_info *) *
820 (device_count + 1));
821 if (devices) {
822 devices[device_count] = cur_dev;
823 device_count++;
824 }
825 } else {
826 if (verbose >= 2)
827 logmsg(LOG_NOTICE,
828 "%s[%x]: reusing usb connection, device_id=%d",
829 __func__, THREAD, c_req->device_id);
695 } 830 }
696 } else { 831 pthread_mutex_unlock(&usbmux_mutex);
697 if (verbose >= 2) logmsg(LOG_NOTICE, "%s[%x]: reusing usb connection, device_id=%d", __func__, THREAD, c_req->device_id);
698 }
699 pthread_mutex_unlock(&usbmux_mutex);
700 832
701 // setup connection to iPhone/iPod 833 // setup connection to iPhone/iPod
702// pthread_mutex_lock(&usbmux_mutex); 834// pthread_mutex_lock(&usbmux_mutex);
703 res = usbmux_new_client(cur_dev->phone, 0, ntohs(c_req->tcp_dport), &(cdata->muxclient)); 835 res =
836 usbmux_new_client(cur_dev->phone, 0, ntohs(c_req->tcp_dport),
837 &(cdata->muxclient));
704// pthread_mutex_unlock(&usbmux_mutex); 838// pthread_mutex_unlock(&usbmux_mutex);
705 839
706 if (res != 0) { 840 if (res != 0) {
707 usbmuxd_send_result(cdata->socket, c_req->header.tag, res); 841 usbmuxd_send_result(cdata->socket, c_req->header.tag, res);
708 if (verbose >= 1) logmsg(LOG_ERR, "%s[%x]: mux_new_client returned %d, aborting.", __func__, THREAD, res); 842 if (verbose >= 1)
709 goto leave; 843 logmsg(LOG_ERR,
710 } 844 "%s[%x]: mux_new_client returned %d, aborting.",
711 845 __func__, THREAD, res);
712 // start bulk reader thread (once per device) 846 goto leave;
713 pthread_mutex_lock(&cur_dev->mutex); 847 }
714 if (cur_dev->bulk_reader == 0) { 848 // start bulk reader thread (once per device)
715 pthread_create(&cur_dev->bulk_reader, NULL, usbmuxd_bulk_reader_thread, cur_dev);
716 }
717 pthread_mutex_unlock(&cur_dev->mutex);
718
719 // start connection handler thread
720 cdata->handler_dead = 0;
721 cdata->tag = c_req->header.tag;
722 cdata->dev = cur_dev;
723 if (pthread_create(&cdata->handler, NULL, usbmuxd_client_handler_thread, cdata) != 0) {
724 if (verbose >= 1) logmsg(LOG_ERR, "%s[%x]: could not create usbmuxd_client_handler_thread!", __func__, THREAD);
725 cdata->handler = 0;
726 goto leave;
727 }
728
729 // wait for handler thread to finish its work
730 if (cdata->handler != 0) {
731 pthread_join(cdata->handler, NULL);
732 }
733
734 if (verbose >= 2) logmsg(LOG_NOTICE, "%s[%x]: closing connection", __func__, THREAD);
735
736 // time to clean up
737 if (cdata && cdata->muxclient) { // should be non-NULL
738 usbmux_free_client(cdata->muxclient);
739 }
740
741leave:
742 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%x]: terminating", __func__, THREAD);
743
744 if (s_req) {
745 free(s_req);
746 }
747 if (c_req) {
748 free(c_req);
749 }
750
751 // this has to be freed only if it's not in use anymore as it closes
752 // the USB connection
753 pthread_mutex_lock(&usbmux_mutex);
754 if (cur_dev) {
755 pthread_mutex_lock(&cur_dev->mutex); 849 pthread_mutex_lock(&cur_dev->mutex);
756 if (cur_dev->use_count > 1) { 850 if (cur_dev->bulk_reader == 0) {
757 if (verbose >= 2) logmsg(LOG_NOTICE, "%s[%x]: decreasing device use count (from %d to %d)", __func__, THREAD, cur_dev->use_count, cur_dev->use_count-1); 851 pthread_create(&cur_dev->bulk_reader, NULL,
758 cur_dev->use_count--; 852 usbmuxd_bulk_reader_thread, cur_dev);
759 pthread_mutex_unlock(&cur_dev->mutex); 853 }
760 } else { 854 pthread_mutex_unlock(&cur_dev->mutex);
761 if (verbose >= 2) logmsg(LOG_NOTICE, "%s[%x]: last client disconnected, cleaning up", __func__, THREAD); 855
762 cur_dev->use_count = 0; 856 // start connection handler thread
763 pthread_mutex_unlock(&cur_dev->mutex); 857 cdata->handler_dead = 0;
764 if (cur_dev->bulk_reader != 0) { 858 cdata->tag = c_req->header.tag;
765 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%x]: joining bulk_reader...", __func__, THREAD); 859 cdata->dev = cur_dev;
766 pthread_join(cur_dev->bulk_reader, NULL); 860 if (pthread_create
767 } 861 (&cdata->handler, NULL, usbmuxd_client_handler_thread, cdata) != 0)
768 pthread_mutex_lock(&usb_mutex); 862 {
769 usbmux_free_device(cur_dev->phone); 863 if (verbose >= 1)
770 pthread_mutex_unlock(&usb_mutex); 864 logmsg(LOG_ERR,
771 pthread_mutex_destroy(&cur_dev->writer_mutex); 865 "%s[%x]: could not create usbmuxd_client_handler_thread!",
772 pthread_mutex_destroy(&cur_dev->mutex); 866 __func__, THREAD);
773 free(cur_dev); 867 cdata->handler = 0;
774 cur_dev = NULL; 868 goto leave;
775 if (device_count > 1) { 869 }
776 struct device_info **newlist; 870 // wait for handler thread to finish its work
777 int j; 871 if (cdata->handler != 0) {
778 872 pthread_join(cdata->handler, NULL);
779 newlist = (struct device_info**)malloc(sizeof(struct device_info*) * device_count-1); 873 }
780 for (i = 0; i < device_count; i++) { 874
781 if (devices[i] != NULL) { 875 if (verbose >= 2)
782 newlist[j++] = devices[i]; 876 logmsg(LOG_NOTICE, "%s[%x]: closing connection", __func__, THREAD);
783 } 877
878 // time to clean up
879 if (cdata && cdata->muxclient) { // should be non-NULL
880 usbmux_free_client(cdata->muxclient);
881 }
882
883 leave:
884 if (verbose >= 3)
885 logmsg(LOG_NOTICE, "%s[%x]: terminating", __func__, THREAD);
886
887 if (s_req) {
888 free(s_req);
889 }
890 if (c_req) {
891 free(c_req);
892 }
893 // this has to be freed only if it's not in use anymore as it closes
894 // the USB connection
895 pthread_mutex_lock(&usbmux_mutex);
896 if (cur_dev) {
897 pthread_mutex_lock(&cur_dev->mutex);
898 if (cur_dev->use_count > 1) {
899 if (verbose >= 2)
900 logmsg(LOG_NOTICE,
901 "%s[%x]: decreasing device use count (from %d to %d)",
902 __func__, THREAD, cur_dev->use_count,
903 cur_dev->use_count - 1);
904 cur_dev->use_count--;
905 pthread_mutex_unlock(&cur_dev->mutex);
906 } else {
907 if (verbose >= 2)
908 logmsg(LOG_NOTICE,
909 "%s[%x]: last client disconnected, cleaning up",
910 __func__, THREAD);
911 cur_dev->use_count = 0;
912 pthread_mutex_unlock(&cur_dev->mutex);
913 if (cur_dev->bulk_reader != 0) {
914 if (verbose >= 3)
915 logmsg(LOG_NOTICE, "%s[%x]: joining bulk_reader...",
916 __func__, THREAD);
917 pthread_join(cur_dev->bulk_reader, NULL);
918 }
919 pthread_mutex_lock(&usb_mutex);
920 usbmux_free_device(cur_dev->phone);
921 pthread_mutex_unlock(&usb_mutex);
922 pthread_mutex_destroy(&cur_dev->writer_mutex);
923 pthread_mutex_destroy(&cur_dev->mutex);
924 free(cur_dev);
925 cur_dev = NULL;
926 if (device_count > 1) {
927 struct device_info **newlist;
928 int j;
929
930 newlist =
931 (struct device_info **)
932 malloc(sizeof(struct device_info *)
933 * device_count - 1);
934 for (i = 0; i < device_count; i++) {
935 if (devices[i] != NULL) {
936 newlist[j++] = devices[i];
937 }
938 }
939 free(devices);
940 devices = newlist;
941 device_count--;
942 } else {
943 free(devices);
944 devices = NULL;
945 device_count = 0;
946 }
784 } 947 }
785 free(devices);
786 devices = newlist;
787 device_count--;
788 } else {
789 free(devices);
790 devices = NULL;
791 device_count = 0;
792 }
793 } 948 }
794 } 949 pthread_mutex_unlock(&usbmux_mutex);
795 pthread_mutex_unlock(&usbmux_mutex); 950
951 cdata->dead = 1;
952 close(cdata->socket);
796 953
797 cdata->dead = 1; 954 if (verbose >= 3)
798 close(cdata->socket); 955 logmsg(LOG_NOTICE, "%s[%x]: terminated", __func__, THREAD);
799
800 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%x]: terminated", __func__, THREAD);
801 956
802 return NULL; 957 return NULL;
803} 958}
804 959
805/** 960/**
@@ -807,44 +962,42 @@ leave:
807 */ 962 */
808static int daemonize() 963static int daemonize()
809{ 964{
810 pid_t pid; 965 pid_t pid;
811 pid_t sid; 966 pid_t sid;
812 967
813 // already a daemon 968 // already a daemon
814 if (getppid() == 1) return 0; 969 if (getppid() == 1)
970 return 0;
815 971
816 pid = fork(); 972 pid = fork();
817 if (pid < 0) { 973 if (pid < 0) {
818 exit(EXIT_FAILURE); 974 exit(EXIT_FAILURE);
819 } 975 }
820
821 if (pid > 0) {
822 // exit parent process
823 exit(EXIT_SUCCESS);
824 }
825
826 // At this point we are executing as the child process
827
828 // Change the file mode mask
829 umask(0);
830 976
831 // Create a new SID for the child process 977 if (pid > 0) {
832 sid = setsid(); 978 // exit parent process
833 if (sid < 0) { 979 exit(EXIT_SUCCESS);
834 return -1; 980 }
835 } 981 // At this point we are executing as the child process
836 982
837 // Change the current working directory. 983 // Change the file mode mask
838 if ((chdir("/")) < 0) { 984 umask(0);
839 return -2;
840 }
841 985
842 // Redirect standard files to /dev/null 986 // Create a new SID for the child process
843 freopen("/dev/null", "r", stdin); 987 sid = setsid();
844 freopen("/dev/null", "w", stdout); 988 if (sid < 0) {
845 freopen("/dev/null", "w", stderr); 989 return -1;
990 }
991 // Change the current working directory.
992 if ((chdir("/")) < 0) {
993 return -2;
994 }
995 // Redirect standard files to /dev/null
996 freopen("/dev/null", "r", stdin);
997 freopen("/dev/null", "w", stdout);
998 freopen("/dev/null", "w", stderr);
846 999
847 return 0; 1000 return 0;
848} 1001}
849 1002
850/** 1003/**
@@ -852,56 +1005,57 @@ static int daemonize()
852 */ 1005 */
853static void clean_exit(int sig) 1006static void clean_exit(int sig)
854{ 1007{
855 if (sig == SIGINT) { 1008 if (sig == SIGINT) {
856 if (verbose >= 1) fprintf(stderr, "CTRL+C pressed\n"); 1009 if (verbose >= 1)
857 } 1010 fprintf(stderr, "CTRL+C pressed\n");
858 quit_flag = 1; 1011 }
1012 quit_flag = 1;
859} 1013}
860 1014
861static void usage() 1015static void usage()
862{ 1016{
863 printf("usage: usbmuxd [options]\n"); 1017 printf("usage: usbmuxd [options]\n");
864 printf("\t-h|--help print this message.\n"); 1018 printf("\t-h|--help print this message.\n");
865 printf("\t-v|--verbose be verbose\n"); 1019 printf("\t-v|--verbose be verbose\n");
866 printf("\t-f|--foreground do not daemonize\n"); 1020 printf("\t-f|--foreground do not daemonize\n");
867 printf("\n"); 1021 printf("\n");
868} 1022}
869 1023
870static void parse_opts(int argc, char **argv) 1024static void parse_opts(int argc, char **argv)
871{ 1025{
872 static struct option longopts[] = { 1026 static struct option longopts[] = {
873 { "help", 0, NULL, 'h' }, 1027 {"help", 0, NULL, 'h'},
874 { "foreground", 0, NULL, 'f' }, 1028 {"foreground", 0, NULL, 'f'},
875 { "verbose", 0, NULL, 'v' }, 1029 {"verbose", 0, NULL, 'v'},
876 { "exit-on-no-devices", 0, NULL, 'e' }, 1030 {"exit-on-no-devices", 0, NULL, 'e'},
877 { NULL, 0, NULL, 0} 1031 {NULL, 0, NULL, 0}
878 }; 1032 };
879 int c; 1033 int c;
880 1034
881 while (1) { 1035 while (1) {
882 c = getopt_long(argc, argv, "hfve", longopts, (int *) 0); 1036 c = getopt_long(argc, argv, "hfve", longopts, (int *) 0);
883 if (c == -1) { 1037 if (c == -1) {
884 break; 1038 break;
885 } 1039 }
886 1040
887 switch (c) { 1041 switch (c) {
888 case 'h': 1042 case 'h':
889 usage(); 1043 usage();
890 exit(0); 1044 exit(0);
891 case 'f': 1045 case 'f':
892 foreground = 1; 1046 foreground = 1;
893 break; 1047 break;
894 case 'v': 1048 case 'v':
895 sock_stuff_set_verbose(++verbose); 1049 sock_stuff_set_verbose(++verbose);
896 break; 1050 break;
897 case 'e': 1051 case 'e':
898 exit_on_no_devices = 1; 1052 exit_on_no_devices = 1;
899 break; 1053 break;
900 default: 1054 default:
901 usage(); 1055 usage();
902 exit(2); 1056 exit(2);
1057 }
903 } 1058 }
904 }
905} 1059}
906 1060
907/** 1061/**
@@ -911,26 +1065,25 @@ static void parse_opts(int argc, char **argv)
911 */ 1065 */
912static int devices_attached() 1066static int devices_attached()
913{ 1067{
914 struct usb_bus *bus; 1068 struct usb_bus *bus;
915 struct usb_device *dev; 1069 struct usb_device *dev;
916 int res = 0; 1070 int res = 0;
917 1071
918 usb_init(); 1072 usb_init();
919 usb_find_busses(); 1073 usb_find_busses();
920 usb_find_devices(); 1074 usb_find_devices();
921 1075
922 for (bus = usb_get_busses(); bus; bus = bus->next) { 1076 for (bus = usb_get_busses(); bus; bus = bus->next) {
923 for (dev = bus->devices; dev; dev = dev->next) { 1077 for (dev = bus->devices; dev; dev = dev->next) {
924 if (dev->descriptor.idVendor == 0x05ac 1078 if (dev->descriptor.idVendor == 0x05ac
925 && dev->descriptor.idProduct >= 0x1290 1079 && dev->descriptor.idProduct >= 0x1290
926 && dev->descriptor.idProduct <= 0x1293) 1080 && dev->descriptor.idProduct <= 0x1293) {
927 { 1081 res++;
928 res++; 1082 }
929 } 1083 }
930 } 1084 }
931 }
932 1085
933 return res; 1086 return res;
934} 1087}
935 1088
936/** 1089/**
@@ -938,233 +1091,261 @@ static int devices_attached()
938 */ 1091 */
939int main(int argc, char **argv) 1092int main(int argc, char **argv)
940{ 1093{
941 struct sockaddr_un c_addr; 1094 struct sockaddr_un c_addr;
942 socklen_t len = sizeof(struct sockaddr_un); 1095 socklen_t len = sizeof(struct sockaddr_un);
943 struct client_data *cdata = NULL; 1096 struct client_data *cdata = NULL;
944 struct client_data **children = NULL; 1097 struct client_data **children = NULL;
945 int children_capacity = DEFAULT_CHILDREN_CAPACITY; 1098 int children_capacity = DEFAULT_CHILDREN_CAPACITY;
946 int i; 1099 int i;
947 int result = 0; 1100 int result = 0;
948 int cnt = 0; 1101 int cnt = 0;
949 FILE *lfd = NULL; 1102 FILE *lfd = NULL;
950 struct flock lock; 1103 struct flock lock;
951 1104
952 parse_opts(argc, argv); 1105 parse_opts(argc, argv);
953 1106
954 argc -= optind; 1107 argc -= optind;
955 argv += optind; 1108 argv += optind;
956 1109
957 if (!foreground) { 1110 if (!foreground) {
958 openlog("usbmuxd", LOG_PID, 0); 1111 openlog("usbmuxd", LOG_PID, 0);
959 }
960
961 if (verbose >= 2) logmsg(LOG_NOTICE, "starting");
962
963 // signal(SIGHUP, reload_conf); // none yet
964 signal(SIGINT, clean_exit);
965 signal(SIGQUIT, clean_exit);
966 signal(SIGTERM, clean_exit);
967 signal(SIGPIPE, SIG_IGN);
968
969 // check for other running instance
970 lfd = fopen(LOCKFILE, "r");
971 if (lfd) {
972 lock.l_type = 0;
973 lock.l_whence = SEEK_SET;
974 lock.l_start = 0;
975 lock.l_len = 0;
976 fcntl(fileno(lfd), F_GETLK, &lock);
977 fclose(lfd);
978 if (lock.l_type != F_UNLCK) {
979 logmsg(LOG_NOTICE, "another instance is already running. exiting.");
980 return -1;
981 } 1112 }
982 }
983 1113
984 if (exit_on_no_devices) { 1114 if (verbose >= 2)
985 if (devices_attached() <= 0) { 1115 logmsg(LOG_NOTICE, "starting");
986 logmsg(LOG_NOTICE, "no devices attached. exiting."); 1116
987 return 0; 1117 // signal(SIGHUP, reload_conf); // none yet
1118 signal(SIGINT, clean_exit);
1119 signal(SIGQUIT, clean_exit);
1120 signal(SIGTERM, clean_exit);
1121 signal(SIGPIPE, SIG_IGN);
1122
1123 // check for other running instance
1124 lfd = fopen(LOCKFILE, "r");
1125 if (lfd) {
1126 lock.l_type = 0;
1127 lock.l_whence = SEEK_SET;
1128 lock.l_start = 0;
1129 lock.l_len = 0;
1130 fcntl(fileno(lfd), F_GETLK, &lock);
1131 fclose(lfd);
1132 if (lock.l_type != F_UNLCK) {
1133 logmsg(LOG_NOTICE,
1134 "another instance is already running. exiting.");
1135 return -1;
1136 }
988 } 1137 }
989 }
990 1138
991 fsock = create_unix_socket(USBMUXD_SOCKET_FILE); 1139 if (exit_on_no_devices) {
992 if (fsock < 0) { 1140 if (devices_attached() <= 0) {
993 logmsg(LOG_ERR, "Could not create socket, exiting"); 1141 logmsg(LOG_NOTICE, "no devices attached. exiting.");
994 if (!foreground) { 1142 return 0;
995 closelog(); 1143 }
996 } 1144 }
997 return -1;
998 }
999 1145
1000 chmod(USBMUXD_SOCKET_FILE, 0666); 1146 fsock = create_unix_socket(USBMUXD_SOCKET_FILE);
1147 if (fsock < 0) {
1148 logmsg(LOG_ERR, "Could not create socket, exiting");
1149 if (!foreground) {
1150 closelog();
1151 }
1152 return -1;
1153 }
1001 1154
1002 if (verbose >= 3) usbmux_set_debug(1); 1155 chmod(USBMUXD_SOCKET_FILE, 0666);
1003 1156
1004 if (!foreground) { 1157 if (verbose >= 3)
1005 if (daemonize() < 0) { 1158 usbmux_set_debug(1);
1006 fprintf(stderr, "usbmuxd: FATAL: Could not daemonize!\n");
1007 syslog(LOG_ERR, "FATAL: Could not daemonize!");
1008 closelog();
1009 exit(EXIT_FAILURE);
1010 }
1011 }
1012
1013 // now open the lockfile and place the lock
1014 lfd = fopen(LOCKFILE, "w");
1015 if (lfd) {
1016 lock.l_type = F_WRLCK;
1017 lock.l_whence = SEEK_SET;
1018 lock.l_start = 0;
1019 lock.l_len = 0;
1020 if (fcntl(fileno(lfd), F_SETLK, &lock) == -1) {
1021 logmsg(LOG_ERR, "ERROR: lockfile locking failed!");
1022 }
1023 }
1024 1159
1025 // drop elevated privileges 1160 if (!foreground) {
1026 if (getuid() == 0 || geteuid() == 0) { 1161 if (daemonize() < 0) {
1027 struct passwd *pw = getpwnam("nobody"); 1162 fprintf(stderr, "usbmuxd: FATAL: Could not daemonize!\n");
1028 if (pw) { 1163 syslog(LOG_ERR, "FATAL: Could not daemonize!");
1029 setuid(pw->pw_uid); 1164 closelog();
1030 } else { 1165 exit(EXIT_FAILURE);
1031 logmsg(LOG_ERR, "ERROR: Dropping privileges failed, check if user 'nobody' exists! Will now terminate."); 1166 }
1032 exit(EXIT_FAILURE);
1033 } 1167 }
1168 // now open the lockfile and place the lock
1169 lfd = fopen(LOCKFILE, "w");
1170 if (lfd) {
1171 lock.l_type = F_WRLCK;
1172 lock.l_whence = SEEK_SET;
1173 lock.l_start = 0;
1174 lock.l_len = 0;
1175 if (fcntl(fileno(lfd), F_SETLK, &lock) == -1) {
1176 logmsg(LOG_ERR, "ERROR: lockfile locking failed!");
1177 }
1178 }
1179 // drop elevated privileges
1180 if (getuid() == 0 || geteuid() == 0) {
1181 struct passwd *pw = getpwnam("nobody");
1182 if (pw) {
1183 setuid(pw->pw_uid);
1184 } else {
1185 logmsg(LOG_ERR,
1186 "ERROR: Dropping privileges failed, check if user 'nobody' exists! Will now terminate.");
1187 exit(EXIT_FAILURE);
1188 }
1034 1189
1035 // security check 1190 // security check
1036 if (setuid(0) != -1) { 1191 if (setuid(0) != -1) {
1037 logmsg(LOG_ERR, "ERROR: Failed to drop privileges properly!"); 1192 logmsg(LOG_ERR, "ERROR: Failed to drop privileges properly!");
1038 exit(EXIT_FAILURE); 1193 exit(EXIT_FAILURE);
1194 }
1195 if (verbose >= 2)
1196 logmsg(LOG_NOTICE, "Successfully dropped privileges");
1039 } 1197 }
1040 if (verbose >= 2) logmsg(LOG_NOTICE, "Successfully dropped privileges"); 1198 // Reserve space for 10 clients which should be enough. If not, the
1041 } 1199 // buffer gets enlarged later.
1042 1200 children =
1043 // Reserve space for 10 clients which should be enough. If not, the 1201 (struct client_data **) malloc(sizeof(struct client_data *) *
1044 // buffer gets enlarged later. 1202 children_capacity);
1045 children = (struct client_data**)malloc(sizeof(struct client_data*) * children_capacity); 1203 if (!children) {
1046 if (!children) { 1204 logmsg(LOG_ERR,
1047 logmsg(LOG_ERR, "Out of memory when allocating memory for child threads. Terminating."); 1205 "Out of memory when allocating memory for child threads. Terminating.");
1048 if (!foreground) { 1206 if (!foreground) {
1049 closelog(); 1207 closelog();
1208 }
1209 exit(EXIT_FAILURE);
1050 } 1210 }
1051 exit(EXIT_FAILURE); 1211 memset(children, 0, sizeof(struct client_data *) * children_capacity);
1052 } 1212
1053 memset(children, 0, sizeof(struct client_data*) * children_capacity); 1213 if (verbose >= 2)
1054 1214 logmsg(LOG_NOTICE, "waiting for connection");
1055 if (verbose >= 2) logmsg(LOG_NOTICE, "waiting for connection"); 1215 while (!quit_flag) {
1056 while (!quit_flag) { 1216 // Check the file descriptor before accepting a connection.
1057 // Check the file descriptor before accepting a connection. 1217 // If no connection attempt is made, just repeat...
1058 // If no connection attempt is made, just repeat... 1218 result = check_fd(fsock, FD_READ, 1000);
1059 result = check_fd(fsock, FD_READ, 1000); 1219 if (result <= 0) {
1060 if (result <= 0) { 1220 if (result == 0) {
1061 if (result == 0) { 1221 // cleanup
1062 // cleanup 1222 for (i = 0; i < children_capacity; i++) {
1063 for (i = 0; i < children_capacity; i++) { 1223 if (children[i]) {
1064 if (children[i]) { 1224 if (children[i]->dead != 0) {
1065 if (children[i]->dead != 0) { 1225 pthread_join(children[i]->thread, NULL);
1066 pthread_join(children[i]->thread, NULL); 1226 if (verbose >= 3)
1067 if (verbose >= 3) logmsg(LOG_NOTICE, "reclaimed client thread (fd=%d)", children[i]->socket); 1227 logmsg(LOG_NOTICE,
1068 free(children[i]); 1228 "reclaimed client thread (fd=%d)",
1069 children[i] = NULL; 1229 children[i]->socket);
1070 cnt++; 1230 free(children[i]);
1231 children[i] = NULL;
1232 cnt++;
1233 } else {
1234 cnt = 0;
1235 }
1236 } else {
1237 cnt++;
1238 }
1239 }
1240
1241 if ((children_capacity > DEFAULT_CHILDREN_CAPACITY)
1242 && ((children_capacity - cnt) <=
1243 DEFAULT_CHILDREN_CAPACITY)) {
1244 children_capacity = DEFAULT_CHILDREN_CAPACITY;
1245 children =
1246 realloc(children,
1247 sizeof(struct client_data *) *
1248 children_capacity);
1249 }
1250 continue;
1071 } else { 1251 } else {
1072 cnt = 0; 1252 if (verbose >= 3)
1253 logmsg(LOG_ERR, "usbmuxd: select error: %s",
1254 strerror(errno));
1255 continue;
1073 } 1256 }
1074 } else {
1075 cnt++;
1076 }
1077 } 1257 }
1078 1258
1079 if ((children_capacity > DEFAULT_CHILDREN_CAPACITY) 1259 cdata = (struct client_data *) malloc(sizeof(struct client_data));
1080 && ((children_capacity - cnt) <= DEFAULT_CHILDREN_CAPACITY)) { 1260 memset(cdata, 0, sizeof(struct client_data));
1081 children_capacity = DEFAULT_CHILDREN_CAPACITY; 1261 if (!cdata) {
1082 children = realloc(children, sizeof(struct client_data*) * children_capacity); 1262 quit_flag = 1;
1263 logmsg(LOG_ERR, "Error: Out of memory! Terminating.");
1264 break;
1083 } 1265 }
1084 continue;
1085 } else {
1086 if (verbose >= 3) logmsg(LOG_ERR, "usbmuxd: select error: %s", strerror(errno));
1087 continue;
1088 }
1089 }
1090 1266
1091 cdata = (struct client_data*)malloc(sizeof(struct client_data)); 1267 cdata->socket = accept(fsock, (struct sockaddr *) &c_addr, &len);
1092 memset(cdata, 0, sizeof(struct client_data)); 1268 if (cdata->socket < 0) {
1093 if (!cdata) { 1269 free(cdata);
1094 quit_flag = 1; 1270 if (errno == EINTR) {
1095 logmsg(LOG_ERR, "Error: Out of memory! Terminating."); 1271 continue;
1096 break; 1272 } else {
1097 } 1273 if (verbose >= 3)
1098 1274 logmsg(LOG_ERR, "Error in accept: %s",
1099 cdata->socket = accept(fsock, (struct sockaddr*)&c_addr, &len); 1275 strerror(errno));
1100 if (cdata->socket < 0) { 1276 continue;
1101 free(cdata); 1277 }
1102 if (errno == EINTR) { 1278 }
1103 continue;
1104 } else {
1105 if (verbose >= 3) logmsg(LOG_ERR, "Error in accept: %s", strerror(errno));
1106 continue;
1107 }
1108 }
1109 1279
1110 if (verbose >= 1) logmsg(LOG_NOTICE, "new client connected (fd=%d)", cdata->socket); 1280 if (verbose >= 1)
1111 1281 logmsg(LOG_NOTICE, "new client connected (fd=%d)",
1112 // create client thread: 1282 cdata->socket);
1113 if (pthread_create(&cdata->thread, NULL, usbmuxd_client_init_thread, cdata) == 0) { 1283
1114 for (i = 0; i < children_capacity; i++) { 1284 // create client thread:
1115 if (children[i] == NULL) break; 1285 if (pthread_create
1116 } 1286 (&cdata->thread, NULL, usbmuxd_client_init_thread, cdata) == 0)
1117 if (i == children_capacity) { 1287 {
1118 // enlarge buffer 1288 for (i = 0; i < children_capacity; i++) {
1119 children_capacity++; 1289 if (children[i] == NULL)
1120 children = realloc(children, sizeof(struct client_data*) * children_capacity); 1290 break;
1121 if (!children) { 1291 }
1122 logmsg(LOG_ERR, "Out of memory when enlarging child thread buffer"); 1292 if (i == children_capacity) {
1293 // enlarge buffer
1294 children_capacity++;
1295 children =
1296 realloc(children,
1297 sizeof(struct client_data *) *
1298 children_capacity);
1299 if (!children) {
1300 logmsg(LOG_ERR,
1301 "Out of memory when enlarging child thread buffer");
1302 }
1303 }
1304 children[i] = cdata;
1305 } else {
1306 logmsg(LOG_ERR, "Failed to create client_init_thread.");
1307 close(cdata->socket);
1308 free(cdata);
1309 cdata = NULL;
1123 } 1310 }
1124 }
1125 children[i] = cdata;
1126 } else {
1127 logmsg(LOG_ERR, "Failed to create client_init_thread.");
1128 close(cdata->socket);
1129 free(cdata);
1130 cdata = NULL;
1131 } 1311 }
1132 }
1133 1312
1134 if (verbose >= 3) logmsg(LOG_NOTICE, "terminating"); 1313 if (verbose >= 3)
1314 logmsg(LOG_NOTICE, "terminating");
1135 1315
1136 // preparing for shutdown: wait for child threads to terminate (if any) 1316 // preparing for shutdown: wait for child threads to terminate (if any)
1137 if (verbose >= 2) logmsg(LOG_NOTICE, "waiting for child threads to terminate..."); 1317 if (verbose >= 2)
1138 for (i = 0; i < children_capacity; i++) { 1318 logmsg(LOG_NOTICE, "waiting for child threads to terminate...");
1139 if (children[i] != NULL) { 1319 for (i = 0; i < children_capacity; i++) {
1140 pthread_join(children[i]->thread, NULL); 1320 if (children[i] != NULL) {
1141 free(children[i]); 1321 pthread_join(children[i]->thread, NULL);
1142 } 1322 free(children[i]);
1143 } 1323 }
1324 }
1144 1325
1145 // delete the children set. 1326 // delete the children set.
1146 free(children); 1327 free(children);
1147 children = NULL; 1328 children = NULL;
1148 1329
1149 1330
1150 if (fsock >= 0) { 1331 if (fsock >= 0) {
1151 close(fsock); 1332 close(fsock);
1152 } 1333 }
1153 1334
1154 unlink(USBMUXD_SOCKET_FILE); 1335 unlink(USBMUXD_SOCKET_FILE);
1155 1336
1156 // unlock lock file and close it. 1337 // unlock lock file and close it.
1157 if (lfd) { 1338 if (lfd) {
1158 lock.l_type = F_UNLCK; 1339 lock.l_type = F_UNLCK;
1159 fcntl(fileno(lfd), F_SETLK, &lock); 1340 fcntl(fileno(lfd), F_SETLK, &lock);
1160 fclose(lfd); 1341 fclose(lfd);
1161 } 1342 }
1162 1343
1163 if (verbose >= 1) logmsg(LOG_NOTICE, "usbmuxd: terminated"); 1344 if (verbose >= 1)
1164 if (!foreground) { 1345 logmsg(LOG_NOTICE, "usbmuxd: terminated");
1165 closelog(); 1346 if (!foreground) {
1166 } 1347 closelog();
1348 }
1167 1349
1168 return 0; 1350 return 0;
1169} 1351}
1170
diff --git a/sock_stuff.c b/sock_stuff.c
index 43fdf0e..b51d6ba 100644
--- a/sock_stuff.c
+++ b/sock_stuff.c
@@ -17,270 +17,282 @@ static int verbose = 0;
17 17
18void sock_stuff_set_verbose(int level) 18void sock_stuff_set_verbose(int level)
19{ 19{
20 verbose = level; 20 verbose = level;
21} 21}
22 22
23int create_unix_socket (const char *filename) 23int create_unix_socket(const char *filename)
24{ 24{
25 struct sockaddr_un name; 25 struct sockaddr_un name;
26 int sock; 26 int sock;
27 size_t size; 27 size_t size;
28 28
29 // remove if still present 29 // remove if still present
30 unlink(filename); 30 unlink(filename);
31 31
32 /* Create the socket. */ 32 /* Create the socket. */
33 sock = socket (PF_LOCAL, SOCK_STREAM, 0); 33 sock = socket(PF_LOCAL, SOCK_STREAM, 0);
34 if (sock < 0) { 34 if (sock < 0) {
35 perror ("socket"); 35 perror("socket");
36 return -1; 36 return -1;
37 } 37 }
38 38
39 /* Bind a name to the socket. */ 39 /* Bind a name to the socket. */
40 name.sun_family = AF_LOCAL; 40 name.sun_family = AF_LOCAL;
41 strncpy (name.sun_path, filename, sizeof (name.sun_path)); 41 strncpy(name.sun_path, filename, sizeof(name.sun_path));
42 name.sun_path[sizeof (name.sun_path) - 1] = '\0'; 42 name.sun_path[sizeof(name.sun_path) - 1] = '\0';
43 43
44 /* The size of the address is 44 /* The size of the address is
45 the offset of the start of the filename, 45 the offset of the start of the filename,
46 plus its length, 46 plus its length,
47 plus one for the terminating null byte. 47 plus one for the terminating null byte.
48 Alternatively you can just do: 48 Alternatively you can just do:
49 size = SUN_LEN (&name); 49 size = SUN_LEN (&name);
50 */ 50 */
51 size = (offsetof (struct sockaddr_un, sun_path) 51 size = (offsetof(struct sockaddr_un, sun_path)
52 + strlen (name.sun_path) + 1); 52 + strlen(name.sun_path) + 1);
53 53
54 if (bind (sock, (struct sockaddr *) &name, size) < 0) { 54 if (bind(sock, (struct sockaddr *) &name, size) < 0) {
55 perror("bind"); 55 perror("bind");
56 close(sock); 56 close(sock);
57 return -1; 57 return -1;
58 } 58 }
59 59
60 if (listen(sock, 10) < 0) { 60 if (listen(sock, 10) < 0) {
61 perror("listen"); 61 perror("listen");
62 close(sock); 62 close(sock);
63 return -1; 63 return -1;
64 } 64 }
65 65
66 return sock; 66 return sock;
67} 67}
68 68
69int connect_unix_socket(const char *filename) 69int connect_unix_socket(const char *filename)
70{ 70{
71 struct sockaddr_un name; 71 struct sockaddr_un name;
72 int sfd = -1; 72 int sfd = -1;
73 size_t size; 73 size_t size;
74 struct stat fst; 74 struct stat fst;
75 75
76 // check if socket file exists... 76 // check if socket file exists...
77 if (stat(filename, &fst) != 0) { 77 if (stat(filename, &fst) != 0) {
78 if (verbose >= 2) fprintf(stderr, "%s: stat '%s': %s\n", __func__, filename, strerror(errno)); 78 if (verbose >= 2)
79 return -1; 79 fprintf(stderr, "%s: stat '%s': %s\n", __func__, filename,
80 } 80 strerror(errno));
81 81 return -1;
82 // ... and if it is a unix domain socket 82 }
83 if (!S_ISSOCK(fst.st_mode)) { 83 // ... and if it is a unix domain socket
84 if (verbose >= 2) fprintf(stderr, "%s: File '%s' is not a socket!\n", __func__, filename); 84 if (!S_ISSOCK(fst.st_mode)) {
85 return -1; 85 if (verbose >= 2)
86 } 86 fprintf(stderr, "%s: File '%s' is not a socket!\n", __func__,
87 87 filename);
88 // make a new socket 88 return -1;
89 if ((sfd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) { 89 }
90 if (verbose >= 2) fprintf(stderr, "%s: socket: %s\n", __func__, strerror(errno)); 90 // make a new socket
91 return -1; 91 if ((sfd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) {
92 } 92 if (verbose >= 2)
93 93 fprintf(stderr, "%s: socket: %s\n", __func__, strerror(errno));
94 // and connect to 'filename' 94 return -1;
95 name.sun_family = AF_LOCAL; 95 }
96 strncpy(name.sun_path, filename, sizeof(name.sun_path)); 96 // and connect to 'filename'
97 name.sun_path[sizeof(name.sun_path) - 1] = 0; 97 name.sun_family = AF_LOCAL;
98 98 strncpy(name.sun_path, filename, sizeof(name.sun_path));
99 size = (offsetof (struct sockaddr_un, sun_path) 99 name.sun_path[sizeof(name.sun_path) - 1] = 0;
100 + strlen (name.sun_path) + 1); 100
101 101 size = (offsetof(struct sockaddr_un, sun_path)
102 if (connect(sfd, (struct sockaddr*)&name, size) < 0) { 102 + strlen(name.sun_path) + 1);
103 close(sfd); 103
104 if (verbose >= 2) fprintf(stderr, "%s: connect: %s\n", __func__, strerror(errno)); 104 if (connect(sfd, (struct sockaddr *) &name, size) < 0) {
105 return -1; 105 close(sfd);
106 } 106 if (verbose >= 2)
107 107 fprintf(stderr, "%s: connect: %s\n", __func__,
108 return sfd; 108 strerror(errno));
109 return -1;
110 }
111
112 return sfd;
109} 113}
110 114
111int create_socket(uint16_t port) 115int create_socket(uint16_t port)
112{ 116{
113 int sfd = -1; 117 int sfd = -1;
114 int yes = 1; 118 int yes = 1;
115 struct sockaddr_in saddr; 119 struct sockaddr_in saddr;
116 120
117 if ( 0 > ( sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) ) ) { 121 if (0 > (sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) {
118 perror("socket()"); 122 perror("socket()");
119 return -1; 123 return -1;
120 } 124 }
121 125
122 if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { 126 if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
123 perror("setsockopt()"); 127 perror("setsockopt()");
124 close(sfd); 128 close(sfd);
125 return -1; 129 return -1;
126 } 130 }
127 131
128 memset((void *)&saddr, 0, sizeof(saddr)); 132 memset((void *) &saddr, 0, sizeof(saddr));
129 saddr.sin_family = AF_INET; 133 saddr.sin_family = AF_INET;
130 saddr.sin_addr.s_addr = htonl(INADDR_ANY); 134 saddr.sin_addr.s_addr = htonl(INADDR_ANY);
131 saddr.sin_port = htons(port); 135 saddr.sin_port = htons(port);
132 136
133 if(0 > bind(sfd, (struct sockaddr *)&saddr , sizeof(saddr))) { 137 if (0 > bind(sfd, (struct sockaddr *) &saddr, sizeof(saddr))) {
134 perror("bind()"); 138 perror("bind()");
135 close(sfd); 139 close(sfd);
136 return -1; 140 return -1;
137 } 141 }
138 142
139 if (listen(sfd, 1) == -1) { 143 if (listen(sfd, 1) == -1) {
140 perror("listen()"); 144 perror("listen()");
141 close(sfd); 145 close(sfd);
142 return -1; 146 return -1;
143 } 147 }
144 148
145 return sfd; 149 return sfd;
146} 150}
147 151
148int connect_socket(const char *addr, uint16_t port) 152int connect_socket(const char *addr, uint16_t port)
149{ 153{
150 int sfd = -1; 154 int sfd = -1;
151 int yes = 1; 155 int yes = 1;
152 struct hostent *hp; 156 struct hostent *hp;
153 struct sockaddr_in saddr; 157 struct sockaddr_in saddr;
154 158
155 if (!addr) { 159 if (!addr) {
156 errno = EINVAL; 160 errno = EINVAL;
157 return -1; 161 return -1;
158 } 162 }
159 163
160 if ((hp = gethostbyname(addr)) == NULL) { 164 if ((hp = gethostbyname(addr)) == NULL) {
161 if (verbose >= 2) fprintf(stderr, "%s: unknown host '%s'\n", __func__, addr); 165 if (verbose >= 2)
162 return -1; 166 fprintf(stderr, "%s: unknown host '%s'\n", __func__, addr);
163 } 167 return -1;
164 168 }
165 if (!hp->h_addr) { 169
166 if (verbose >= 2) fprintf(stderr, "%s: gethostbyname returned NULL address!\n", __func__); 170 if (!hp->h_addr) {
167 return -1; 171 if (verbose >= 2)
168 } 172 fprintf(stderr, "%s: gethostbyname returned NULL address!\n",
169 173 __func__);
170 if ( 0 > ( sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) ) ) { 174 return -1;
171 perror("socket()"); 175 }
172 return -1; 176
173 } 177 if (0 > (sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) {
174 178 perror("socket()");
175 if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { 179 return -1;
176 perror("setsockopt()"); 180 }
177 close(sfd); 181
178 return -1; 182 if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
179 } 183 perror("setsockopt()");
180 184 close(sfd);
181 memset((void *)&saddr, 0, sizeof(saddr)); 185 return -1;
182 saddr.sin_family = AF_INET; 186 }
183 saddr.sin_addr.s_addr = *(uint32_t*)hp->h_addr; 187
184 saddr.sin_port = htons(port); 188 memset((void *) &saddr, 0, sizeof(saddr));
185 189 saddr.sin_family = AF_INET;
186 if (connect(sfd, (struct sockaddr*)&saddr, sizeof(saddr)) < 0) { 190 saddr.sin_addr.s_addr = *(uint32_t *) hp->h_addr;
187 perror("connect"); 191 saddr.sin_port = htons(port);
188 close(sfd); 192
189 return -2; 193 if (connect(sfd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
190 } 194 perror("connect");
191 195 close(sfd);
192 return sfd; 196 return -2;
197 }
198
199 return sfd;
193} 200}
194 201
195int check_fd(int fd, fd_mode fdm, unsigned int timeout) 202int check_fd(int fd, fd_mode fdm, unsigned int timeout)
196{ 203{
197 fd_set fds; 204 fd_set fds;
198 int sret; 205 int sret;
199 int eagain; 206 int eagain;
200 struct timeval to; 207 struct timeval to;
201 208
202 if (fd <= 0) { 209 if (fd <= 0) {
203 if (verbose >= 2) fprintf(stderr, "ERROR: invalid fd in check_fd %d\n", fd); 210 if (verbose >= 2)
204 return -1; 211 fprintf(stderr, "ERROR: invalid fd in check_fd %d\n", fd);
205 }
206
207 FD_ZERO(&fds);
208 FD_SET(fd, &fds);
209
210 to.tv_sec = (time_t)(timeout/1000);
211 to.tv_usec = (time_t)((timeout-(to.tv_sec*1000))*1000);
212
213 sret = -1;
214
215 do {
216 eagain = 0;
217 switch(fdm) {
218 case FD_READ:
219 sret = select(fd+1,&fds,NULL,NULL,&to);
220 break;
221 case FD_WRITE:
222 sret = select(fd+1,NULL,&fds,NULL,&to);
223 break;
224 case FD_EXCEPT:
225 sret = select(fd+1,NULL,NULL,&fds,&to);
226 break;
227 default:
228 return -1; 212 return -1;
229 } 213 }
230
231 if (sret < 0) {
232 switch(errno) {
233 case EINTR:
234 // interrupt signal in select
235 if (verbose >= 2) fprintf(stderr, "%s: EINTR\n", __func__);
236 eagain = 1;
237 break;
238 case EAGAIN:
239 if (verbose >= 2) fprintf(stderr, "%s: EAGAIN\n", __func__);
240 break;
241 default:
242 if (verbose >= 2) fprintf(stderr, "%s: select failed: %s\n", __func__, strerror(errno));
243 return -1;
244 }
245 }
246 } while (eagain);
247 214
248 return sret; 215 FD_ZERO(&fds);
216 FD_SET(fd, &fds);
217
218 to.tv_sec = (time_t) (timeout / 1000);
219 to.tv_usec = (time_t) ((timeout - (to.tv_sec * 1000)) * 1000);
220
221 sret = -1;
222
223 do {
224 eagain = 0;
225 switch (fdm) {
226 case FD_READ:
227 sret = select(fd + 1, &fds, NULL, NULL, &to);
228 break;
229 case FD_WRITE:
230 sret = select(fd + 1, NULL, &fds, NULL, &to);
231 break;
232 case FD_EXCEPT:
233 sret = select(fd + 1, NULL, NULL, &fds, &to);
234 break;
235 default:
236 return -1;
237 }
238
239 if (sret < 0) {
240 switch (errno) {
241 case EINTR:
242 // interrupt signal in select
243 if (verbose >= 2)
244 fprintf(stderr, "%s: EINTR\n", __func__);
245 eagain = 1;
246 break;
247 case EAGAIN:
248 if (verbose >= 2)
249 fprintf(stderr, "%s: EAGAIN\n", __func__);
250 break;
251 default:
252 if (verbose >= 2)
253 fprintf(stderr, "%s: select failed: %s\n", __func__,
254 strerror(errno));
255 return -1;
256 }
257 }
258 } while (eagain);
259
260 return sret;
249} 261}
250 262
251int recv_buf(int fd, void *data, size_t length) 263int recv_buf(int fd, void *data, size_t length)
252{ 264{
253 return recv_buf_timeout(fd, data, length, 0, RECV_TIMEOUT); 265 return recv_buf_timeout(fd, data, length, 0, RECV_TIMEOUT);
254} 266}
255 267
256int peek_buf(int fd, void *data, size_t length) 268int peek_buf(int fd, void *data, size_t length)
257{ 269{
258 return recv_buf_timeout(fd, data, length, MSG_PEEK, RECV_TIMEOUT); 270 return recv_buf_timeout(fd, data, length, MSG_PEEK, RECV_TIMEOUT);
259} 271}
260 272
261int recv_buf_timeout(int fd, void *data, size_t length, int flags, unsigned int timeout) 273int recv_buf_timeout(int fd, void *data, size_t length, int flags,
274 unsigned int timeout)
262{ 275{
263 int res; 276 int res;
264 int result; 277 int result;
265 278
266 // check if data is available 279 // check if data is available
267 res = check_fd(fd, FD_READ, timeout); 280 res = check_fd(fd, FD_READ, timeout);
268 if (res <= 0) { 281 if (res <= 0) {
269 return res; 282 return res;
270 } 283 }
271 284 // if we get here, there _is_ data available
272 // if we get here, there _is_ data available 285 result = recv(fd, data, length, flags);
273 result = recv(fd, data, length, flags); 286 if (res > 0 && result == 0) {
274 if (res > 0 && result == 0) { 287 // but this is an error condition
275 // but this is an error condition 288 if (verbose >= 3)
276 if (verbose >= 3) fprintf(stderr, "%s: fd=%d recv returned 0\n", __func__, fd); 289 fprintf(stderr, "%s: fd=%d recv returned 0\n", __func__, fd);
277 return -1; 290 return -1;
278 } 291 }
279 return result; 292 return result;
280} 293}
281 294
282int send_buf(int fd, void *data, size_t length) 295int send_buf(int fd, void *data, size_t length)
283{ 296{
284 return send(fd, data, length, 0); 297 return send(fd, data, length, 0);
285} 298}
286
diff --git a/sock_stuff.h b/sock_stuff.h
index b9766ba..190f7e1 100644
--- a/sock_stuff.h
+++ b/sock_stuff.h
@@ -3,11 +3,10 @@
3 3
4#include <stdint.h> 4#include <stdint.h>
5 5
6enum fd_mode 6enum fd_mode {
7{ 7 FD_READ,
8 FD_READ, 8 FD_WRITE,
9 FD_WRITE, 9 FD_EXCEPT
10 FD_EXCEPT
11}; 10};
12typedef enum fd_mode fd_mode; 11typedef enum fd_mode fd_mode;
13 12
@@ -19,11 +18,11 @@ int check_fd(int fd, fd_mode fdm, unsigned int timeout);
19 18
20int recv_buf(int fd, void *data, size_t size); 19int recv_buf(int fd, void *data, size_t size);
21int peek_buf(int fd, void *data, size_t size); 20int peek_buf(int fd, void *data, size_t size);
22int recv_buf_timeout(int fd, void *data, size_t size, int flags, unsigned int timeout); 21int recv_buf_timeout(int fd, void *data, size_t size, int flags,
22 unsigned int timeout);
23 23
24int send_buf(int fd, void *data, size_t size); 24int send_buf(int fd, void *data, size_t size);
25 25
26void sock_stuff_set_verbose(int level); 26void sock_stuff_set_verbose(int level);
27 27
28#endif /* __SOCK_STUFF_H */ 28#endif /* __SOCK_STUFF_H */
29
diff --git a/usbmux.c b/usbmux.c
index 0a175ed..106c5ff 100644
--- a/usbmux.c
+++ b/usbmux.c
@@ -50,7 +50,7 @@ static const uint32_t WINDOW_MAX = 5 * 1024;
50static const uint32_t WINDOW_INCREMENT = 512; 50static const uint32_t WINDOW_INCREMENT = 512;
51 51
52typedef struct { 52typedef struct {
53 char* buffer; 53 char *buffer;
54 int leftover; 54 int leftover;
55 int capacity; 55 int capacity;
56} receivebuf_t; 56} receivebuf_t;
@@ -145,20 +145,20 @@ static void print_buffer(const char *data, const int length)
145 int j; 145 int j;
146 unsigned char c; 146 unsigned char c;
147 147
148 for(i=0; i<length; i+=16) { 148 for (i = 0; i < length; i += 16) {
149 printf("%04x: ", i); 149 printf("%04x: ", i);
150 for (j=0;j<16;j++) { 150 for (j = 0; j < 16; j++) {
151 if (i+j >= length) { 151 if (i + j >= length) {
152 printf(" "); 152 printf(" ");
153 continue; 153 continue;
154 } 154 }
155 printf("%02hhx ", *(data+i+j)); 155 printf("%02hhx ", *(data + i + j));
156 } 156 }
157 printf(" | "); 157 printf(" | ");
158 for(j=0;j<16;j++) { 158 for (j = 0; j < 16; j++) {
159 if (i+j >= length) 159 if (i + j >= length)
160 break; 160 break;
161 c = *(data+i+j); 161 c = *(data + i + j);
162 if ((c < 32) || (c > 127)) { 162 if ((c < 32) || (c > 127)) {
163 printf("."); 163 printf(".");
164 continue; 164 continue;
@@ -171,7 +171,7 @@ static void print_buffer(const char *data, const int length)
171} 171}
172#endif 172#endif
173 173
174void hton_header(usbmux_tcp_header *hdr) 174void hton_header(usbmux_tcp_header * hdr)
175{ 175{
176 if (hdr) { 176 if (hdr) {
177 hdr->length = htonl(hdr->length); 177 hdr->length = htonl(hdr->length);
@@ -181,7 +181,7 @@ void hton_header(usbmux_tcp_header *hdr)
181 } 181 }
182} 182}
183 183
184void ntoh_header(usbmux_tcp_header *hdr) 184void ntoh_header(usbmux_tcp_header * hdr)
185{ 185{
186 if (hdr) { 186 if (hdr) {
187 hdr->length = ntohl(hdr->length); 187 hdr->length = ntohl(hdr->length);
@@ -197,7 +197,8 @@ void ntoh_header(usbmux_tcp_header *hdr)
197 */ 197 */
198usbmux_version_header *version_header() 198usbmux_version_header *version_header()
199{ 199{
200 usbmux_version_header *version = (usbmux_version_header *) malloc(sizeof(usbmux_version_header)); 200 usbmux_version_header *version =
201 (usbmux_version_header *) malloc(sizeof(usbmux_version_header));
201 version->type = 0; 202 version->type = 0;
202 version->length = htonl(20); 203 version->length = htonl(20);
203 version->major = htonl(1); 204 version->major = htonl(1);
@@ -222,25 +223,34 @@ static int usbmux_config_usb_device(usbmux_device_t device)
222#if 0 223#if 0
223 log_debug_msg("checking configuration...\n"); 224 log_debug_msg("checking configuration...\n");
224 if (device->__device->config->bConfigurationValue != 3) { 225 if (device->__device->config->bConfigurationValue != 3) {
225 log_debug_msg("WARNING: usb device configuration is not 3 as expected!\n"); 226 log_debug_msg
227 ("WARNING: usb device configuration is not 3 as expected!\n");
226 } 228 }
227 229
228 log_debug_msg("setting configuration...\n"); 230 log_debug_msg("setting configuration...\n");
229 ret = usb_set_configuration(device->device, 3); 231 ret = usb_set_configuration(device->device, 3);
230 if (ret != 0) { 232 if (ret != 0) {
231 log_debug_msg("Hm, usb_set_configuration returned %d: %s\n", ret, strerror(-ret)); 233 log_debug_msg("Hm, usb_set_configuration returned %d: %s\n", ret,
234 strerror(-ret));
232#if LIBUSB_HAS_GET_DRIVER_NP 235#if LIBUSB_HAS_GET_DRIVER_NP
233 log_debug_msg("trying to fix:\n"); 236 log_debug_msg("trying to fix:\n");
234 log_debug_msg("-> detaching kernel driver... "); 237 log_debug_msg("-> detaching kernel driver... ");
235 ret = usb_detach_kernel_driver_np(device->device, device->__device->config->interface->altsetting->bInterfaceNumber); 238 ret =
239 usb_detach_kernel_driver_np(device->device,
240 device->__device->config->
241 interface->altsetting->
242 bInterfaceNumber);
236 if (ret != 0) { 243 if (ret != 0) {
237 log_debug_msg("usb_detach_kernel_driver_np returned %d: %s\n", ret, strerror(-ret)); 244 log_debug_msg("usb_detach_kernel_driver_np returned %d: %s\n",
245 ret, strerror(-ret));
238 } else { 246 } else {
239 log_debug_msg("done.\n"); 247 log_debug_msg("done.\n");
240 log_debug_msg("setting configuration again... "); 248 log_debug_msg("setting configuration again... ");
241 ret = usb_set_configuration(device->device, 3); 249 ret = usb_set_configuration(device->device, 3);
242 if (ret != 0) { 250 if (ret != 0) {
243 log_debug_msg("Error: usb_set_configuration returned %d: %s\n", ret, strerror(-ret)); 251 log_debug_msg
252 ("Error: usb_set_configuration returned %d: %s\n", ret,
253 strerror(-ret));
244 log_debug_msg("--> trying to continue anyway...\n"); 254 log_debug_msg("--> trying to continue anyway...\n");
245 } else { 255 } else {
246 log_debug_msg("done.\n"); 256 log_debug_msg("done.\n");
@@ -257,7 +267,8 @@ static int usbmux_config_usb_device(usbmux_device_t device)
257 log_debug_msg("claiming interface... "); 267 log_debug_msg("claiming interface... ");
258 ret = usb_claim_interface(device->usbdev, 1); 268 ret = usb_claim_interface(device->usbdev, 1);
259 if (ret != 0) { 269 if (ret != 0) {
260 log_debug_msg("Error: usb_claim_interface returned %d: %s\n", ret, strerror(-ret)); 270 log_debug_msg("Error: usb_claim_interface returned %d: %s\n", ret,
271 strerror(-ret));
261 return -ENODEV; 272 return -ENODEV;
262 } else { 273 } else {
263 log_debug_msg("done.\n"); 274 log_debug_msg("done.\n");
@@ -266,7 +277,7 @@ static int usbmux_config_usb_device(usbmux_device_t device)
266 do { 277 do {
267 bytes = usb_bulk_read(device->usbdev, BULKIN, buf, 512, 800); 278 bytes = usb_bulk_read(device->usbdev, BULKIN, buf, 512, 800);
268 } while (bytes > 0); 279 } while (bytes > 0);
269 280
270 return 0; 281 return 0;
271} 282}
272 283
@@ -283,7 +294,8 @@ static int usbmux_config_usb_device(usbmux_device_t device)
283 * descriptor on return. 294 * descriptor on return.
284 * @return 0 if ok, otherwise a negative errno value. 295 * @return 0 if ok, otherwise a negative errno value.
285 */ 296 */
286int usbmux_get_specific_device(int bus_n, int dev_n, usbmux_device_t * device) 297int usbmux_get_specific_device(int bus_n, int dev_n,
298 usbmux_device_t * device)
287{ 299{
288 struct usb_bus *bus; 300 struct usb_bus *bus;
289 struct usb_device *dev; 301 struct usb_device *dev;
@@ -294,7 +306,8 @@ int usbmux_get_specific_device(int bus_n, int dev_n, usbmux_device_t * device)
294 if (!device || (device && *device)) 306 if (!device || (device && *device))
295 return -EINVAL; 307 return -EINVAL;
296 308
297 usbmux_device_t newdevice = (usbmux_device_t) malloc(sizeof(struct usbmux_device_int)); 309 usbmux_device_t newdevice =
310 (usbmux_device_t) malloc(sizeof(struct usbmux_device_int));
298 311
299 // Initialize the struct 312 // Initialize the struct
300 newdevice->usbdev = NULL; 313 newdevice->usbdev = NULL;
@@ -314,40 +327,49 @@ int usbmux_get_specific_device(int bus_n, int dev_n, usbmux_device_t * device)
314 // Set the device configuration 327 // Set the device configuration
315 for (bus = usb_get_busses(); bus; bus = bus->next) 328 for (bus = usb_get_busses(); bus; bus = bus->next)
316 //if (bus->location == bus_n) 329 //if (bus->location == bus_n)
317 for (dev = bus->devices; dev != NULL; dev = dev->next) 330 for (dev = bus->devices; dev != NULL; dev = dev->next)
318 if (dev->devnum == dev_n) { 331 if (dev->devnum == dev_n) {
319 newdevice->__device = dev; 332 newdevice->__device = dev;
320 newdevice->usbdev = usb_open(newdevice->__device); 333 newdevice->usbdev = usb_open(newdevice->__device);
321 if (usbmux_config_usb_device(newdevice) == 0) { 334 if (usbmux_config_usb_device(newdevice) == 0) {
322 goto found; 335 goto found;
323 }
324 } 336 }
337 }
325 338
326 usbmux_free_device(newdevice); 339 usbmux_free_device(newdevice);
327 340
328 log_debug_msg("usbmux_get_specific_device: device not found\n"); 341 log_debug_msg("usbmux_get_specific_device: device not found\n");
329 return -ENODEV; 342 return -ENODEV;
330 343
331found: 344 found:
332 // Send the version command to the device 345 // Send the version command to the device
333 version = version_header(); 346 version = version_header();
334 bytes = usb_bulk_write(newdevice->usbdev, BULKOUT, (char *) version, sizeof(*version), 800); 347 bytes =
348 usb_bulk_write(newdevice->usbdev, BULKOUT, (char *) version,
349 sizeof(*version), 800);
335 if (bytes < 20) { 350 if (bytes < 20) {
336 log_debug_msg("%s: libusb did NOT send enough!\n", __func__); 351 log_debug_msg("%s: libusb did NOT send enough!\n", __func__);
337 if (bytes < 0) { 352 if (bytes < 0) {
338 log_debug_msg("%s: libusb gave me the error %d: %s (%s)\n", __func__, bytes, usb_strerror(), strerror(-bytes)); 353 log_debug_msg("%s: libusb gave me the error %d: %s (%s)\n",
354 __func__, bytes, usb_strerror(),
355 strerror(-bytes));
339 } 356 }
340 } 357 }
341 // Read the device's response 358 // Read the device's response
342 bytes = usb_bulk_read(newdevice->usbdev, BULKIN, (char *) version, sizeof(*version), 800); 359 bytes =
360 usb_bulk_read(newdevice->usbdev, BULKIN, (char *) version,
361 sizeof(*version), 800);
343 362
344 // Check for bad response 363 // Check for bad response
345 if (bytes < 20) { 364 if (bytes < 20) {
346 free(version); 365 free(version);
347 usbmux_free_device(newdevice); 366 usbmux_free_device(newdevice);
348 log_debug_msg("%s: Invalid version message -- header too short.\n", __func__); 367 log_debug_msg("%s: Invalid version message -- header too short.\n",
368 __func__);
349 if (bytes < 0) { 369 if (bytes < 0) {
350 log_debug_msg("%s: libusb error message %d: %s (%s)\n", __func__, bytes, usb_strerror(), strerror(-bytes)); 370 log_debug_msg("%s: libusb error message %d: %s (%s)\n",
371 __func__, bytes, usb_strerror(),
372 strerror(-bytes));
351 return bytes; 373 return bytes;
352 } 374 }
353 return -EBADMSG; 375 return -EBADMSG;
@@ -363,7 +385,8 @@ found:
363 // Bad header 385 // Bad header
364 usbmux_free_device(newdevice); 386 usbmux_free_device(newdevice);
365 free(version); 387 free(version);
366 log_debug_msg("%s: Received a bad header/invalid version number.", __func__); 388 log_debug_msg("%s: Received a bad header/invalid version number.",
389 __func__);
367 return -EBADMSG; 390 return -EBADMSG;
368 } 391 }
369 392
@@ -371,7 +394,7 @@ found:
371 log_debug_msg("%s: Unknown error.\n", __func__); 394 log_debug_msg("%s: Unknown error.\n", __func__);
372 usbmux_free_device(newdevice); 395 usbmux_free_device(newdevice);
373 free(version); 396 free(version);
374 return -EBADMSG; // if it got to this point it's gotta be bad 397 return -EBADMSG; // if it got to this point it's gotta be bad
375} 398}
376 399
377/** Cleans up an usbmux_device_t structure, then frees the structure itself. 400/** Cleans up an usbmux_device_t structure, then frees the structure itself.
@@ -435,25 +458,31 @@ int send_to_device(usbmux_device_t device, char *data, int datalen)
435 int bytes = 0; 458 int bytes = 0;
436 459
437#ifdef DEBUG 460#ifdef DEBUG
438 #ifdef DEBUG_MORE 461#ifdef DEBUG_MORE
439 printf("===============================\n%s: trying to send\n", __func__); 462 printf("===============================\n%s: trying to send\n",
463 __func__);
440 print_buffer(data, datalen); 464 print_buffer(data, datalen);
441 printf("===============================\n"); 465 printf("===============================\n");
442 #endif 466#endif
443#endif 467#endif
444 do { 468 do {
445 if (retrycount > 3) { 469 if (retrycount > 3) {
446 log_debug_msg("EPIC FAIL! aborting on retry count overload.\n"); 470 log_debug_msg
471 ("EPIC FAIL! aborting on retry count overload.\n");
447 return -ECOMM; 472 return -ECOMM;
448 } 473 }
449 474
450 bytes = usb_bulk_write(device->usbdev, BULKOUT, data, datalen, timeout); 475 bytes =
476 usb_bulk_write(device->usbdev, BULKOUT, data, datalen,
477 timeout);
451 if (bytes == -ETIMEDOUT) { 478 if (bytes == -ETIMEDOUT) {
452 // timed out waiting for write. 479 // timed out waiting for write.
453 log_debug_msg("usb_bulk_write timeout error.\n"); 480 log_debug_msg("usb_bulk_write timeout error.\n");
454 return bytes; 481 return bytes;
455 } else if (bytes < 0) { 482 } else if (bytes < 0) {
456 log_debug_msg("usb_bulk_write failed with error. err:%d (%s)(%s)\n", bytes, usb_strerror(), strerror(-bytes)); 483 log_debug_msg
484 ("usb_bulk_write failed with error. err:%d (%s)(%s)\n",
485 bytes, usb_strerror(), strerror(-bytes));
457 return bytes; 486 return bytes;
458 } else if (bytes == 0) { 487 } else if (bytes == 0) {
459 log_debug_msg("usb_bulk_write sent nothing. retrying.\n"); 488 log_debug_msg("usb_bulk_write sent nothing. retrying.\n");
@@ -461,22 +490,24 @@ int send_to_device(usbmux_device_t device, char *data, int datalen)
461 retrycount++; 490 retrycount++;
462 continue; 491 continue;
463 } else if (bytes < datalen) { 492 } else if (bytes < datalen) {
464 log_debug_msg("usb_bulk_write failed to send full dataload. %d of %d\n", bytes, datalen); 493 log_debug_msg
494 ("usb_bulk_write failed to send full dataload. %d of %d\n",
495 bytes, datalen);
465 timeout = timeout * 4; 496 timeout = timeout * 4;
466 retrycount++; 497 retrycount++;
467 data += bytes; 498 data += bytes;
468 datalen -= bytes; 499 datalen -= bytes;
469 continue; 500 continue;
470 } 501 }
471 } while(0); // fall out 502 } while (0); // fall out
472 503
473#ifdef DEBUG 504#ifdef DEBUG
474 if (bytes > 0) { 505 if (bytes > 0) {
475 if (toto_debug > 0) { 506 if (toto_debug > 0) {
476 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); 507 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
477 printf("%s: sent to device\n", __func__); 508 printf("%s: sent to device\n", __func__);
478 print_buffer(data, bytes); 509 print_buffer(data, bytes);
479 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); 510 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
480 } 511 }
481 } 512 }
482#endif 513#endif
@@ -493,13 +524,16 @@ int send_to_device(usbmux_device_t device, char *data, int datalen)
493 * 524 *
494 * @return How many bytes were read in, or -1 on error. 525 * @return How many bytes were read in, or -1 on error.
495 */ 526 */
496int recv_from_device_timeout(usbmux_device_t device, char *data, int datalen, int timeoutmillis) 527int recv_from_device_timeout(usbmux_device_t device, char *data,
528 int datalen, int timeoutmillis)
497{ 529{
498 if (!device) 530 if (!device)
499 return -EINVAL; 531 return -EINVAL;
500 //log_debug_msg("%s: attempting to receive %i bytes\n", __func__, datalen); 532 //log_debug_msg("%s: attempting to receive %i bytes\n", __func__, datalen);
501 533
502 int bytes = usb_bulk_read(device->usbdev, BULKIN, data, datalen, timeoutmillis); 534 int bytes =
535 usb_bulk_read(device->usbdev, BULKIN, data, datalen,
536 timeoutmillis);
503 // There are some things which are errors, others which are no problem. 537 // There are some things which are errors, others which are no problem.
504 // It's not documented in libUSB, but it seems that the error values 538 // It's not documented in libUSB, but it seems that the error values
505 // returned are just negated ERRNO values. 539 // returned are just negated ERRNO values.
@@ -509,12 +543,14 @@ int recv_from_device_timeout(usbmux_device_t device, char *data, int datalen, in
509 // picked up any data. no problem. 543 // picked up any data. no problem.
510 return 0; 544 return 0;
511 } else { 545 } else {
512 fprintf(stderr, "%s: libusb gave me the error %d: %s (%s)\n", __func__, bytes, usb_strerror(), strerror(-bytes)); 546 fprintf(stderr, "%s: libusb gave me the error %d: %s (%s)\n",
513 log_debug_msg("%s: libusb gave me the error %d: %s (%s)\n", __func__, bytes, usb_strerror(), strerror(-bytes)); 547 __func__, bytes, usb_strerror(), strerror(-bytes));
548 log_debug_msg("%s: libusb gave me the error %d: %s (%s)\n",
549 __func__, bytes, usb_strerror(),
550 strerror(-bytes));
514 } 551 }
515 return bytes; 552 return bytes;
516 } 553 }
517
518#ifdef DEBUG 554#ifdef DEBUG
519 if (bytes > 0) { 555 if (bytes > 0) {
520 if (toto_debug > 0) { 556 if (toto_debug > 0) {
@@ -538,7 +574,8 @@ int recv_from_device_timeout(usbmux_device_t device, char *data, int datalen, in
538 */ 574 */
539usbmux_tcp_header *new_mux_packet(uint16_t s_port, uint16_t d_port) 575usbmux_tcp_header *new_mux_packet(uint16_t s_port, uint16_t d_port)
540{ 576{
541 usbmux_tcp_header *conn = (usbmux_tcp_header *) malloc(sizeof(usbmux_tcp_header)); 577 usbmux_tcp_header *conn =
578 (usbmux_tcp_header *) malloc(sizeof(usbmux_tcp_header));
542 conn->type = htonl(6); 579 conn->type = htonl(6);
543 conn->length = HEADERLEN; 580 conn->length = HEADERLEN;
544 conn->sport = htons(s_port); 581 conn->sport = htons(s_port);
@@ -566,7 +603,9 @@ static void delete_connection(usbmux_client_t connection)
566 603
567 // update the global list of connections 604 // update the global list of connections
568 if (clients > 1) { 605 if (clients > 1) {
569 newlist = (usbmux_client_t *) malloc(sizeof(usbmux_client_t) * (clients - 1)); 606 newlist =
607 (usbmux_client_t *) malloc(sizeof(usbmux_client_t) *
608 (clients - 1));
570 int i = 0, j = 0; 609 int i = 0, j = 0;
571 for (i = 0; i < clients; i++) { 610 for (i = 0; i < clients; i++) {
572 if (connlist[i] == connection) 611 if (connlist[i] == connection)
@@ -607,7 +646,9 @@ static void add_connection(usbmux_client_t connection)
607{ 646{
608 pthread_mutex_lock(&usbmuxmutex); 647 pthread_mutex_lock(&usbmuxmutex);
609 usbmux_client_t *newlist = 648 usbmux_client_t *newlist =
610 (usbmux_client_t *) realloc(connlist, sizeof(usbmux_client_t) * (clients + 1)); 649 (usbmux_client_t *) realloc(connlist,
650 sizeof(usbmux_client_t) * (clients +
651 1));
611 newlist[clients] = connection; 652 newlist[clients] = connection;
612 connlist = newlist; 653 connlist = newlist;
613 clients++; 654 clients++;
@@ -661,7 +702,8 @@ static uint16_t get_free_port()
661 * @param client A mux TCP header for the connection which is used for tracking and data transfer. 702 * @param client A mux TCP header for the connection which is used for tracking and data transfer.
662 * @return 0 on success, a negative errno value otherwise. 703 * @return 0 on success, a negative errno value otherwise.
663 */ 704 */
664int usbmux_new_client(usbmux_device_t device, uint16_t src_port, uint16_t dst_port, usbmux_client_t * client) 705int usbmux_new_client(usbmux_device_t device, uint16_t src_port,
706 uint16_t dst_port, usbmux_client_t * client)
665{ 707{
666 if (!device || !dst_port) 708 if (!device || !dst_port)
667 return -EINVAL; 709 return -EINVAL;
@@ -670,11 +712,11 @@ int usbmux_new_client(usbmux_device_t device, uint16_t src_port, uint16_t dst_po
670 712
671 if (!src_port) { 713 if (!src_port) {
672 // this is a special case, if we get 0, this is not good, so 714 // this is a special case, if we get 0, this is not good, so
673 return -EISCONN; // TODO: error code suitable? 715 return -EISCONN; // TODO: error code suitable?
674 } 716 }
675
676 // Initialize connection stuff 717 // Initialize connection stuff
677 usbmux_client_t new_connection = (usbmux_client_t) malloc(sizeof(struct usbmux_client_int)); 718 usbmux_client_t new_connection =
719 (usbmux_client_t) malloc(sizeof(struct usbmux_client_int));
678 new_connection->header = new_mux_packet(src_port, dst_port); 720 new_connection->header = new_mux_packet(src_port, dst_port);
679 721
680 // send TCP syn 722 // send TCP syn
@@ -682,7 +724,8 @@ int usbmux_new_client(usbmux_device_t device, uint16_t src_port, uint16_t dst_po
682 int err = 0; 724 int err = 0;
683 new_connection->header->tcp_flags = TCP_SYN; 725 new_connection->header->tcp_flags = TCP_SYN;
684 new_connection->header->length = new_connection->header->length; 726 new_connection->header->length = new_connection->header->length;
685 new_connection->header->length16 = new_connection->header->length16; 727 new_connection->header->length16 =
728 new_connection->header->length16;
686 new_connection->header->scnt = 0; 729 new_connection->header->scnt = 0;
687 new_connection->header->ocnt = 0; 730 new_connection->header->ocnt = 0;
688 new_connection->device = device; 731 new_connection->device = device;
@@ -697,8 +740,12 @@ int usbmux_new_client(usbmux_device_t device, uint16_t src_port, uint16_t dst_po
697 new_connection->error = 0; 740 new_connection->error = 0;
698 new_connection->cleanup = 0; 741 new_connection->cleanup = 0;
699 hton_header(new_connection->header); 742 hton_header(new_connection->header);
700 log_debug_msg("%s: send_to_device (%d --> %d)\n", __func__, ntohs(new_connection->header->sport), ntohs(new_connection->header->dport)); 743 log_debug_msg("%s: send_to_device (%d --> %d)\n", __func__,
701 err = send_to_device(device, (char *) new_connection->header, sizeof(usbmux_tcp_header)); 744 ntohs(new_connection->header->sport),
745 ntohs(new_connection->header->dport));
746 err =
747 send_to_device(device, (char *) new_connection->header,
748 sizeof(usbmux_tcp_header));
702 if (err >= 0) { 749 if (err >= 0) {
703 *client = new_connection; 750 *client = new_connection;
704 return 0; 751 return 0;
@@ -732,7 +779,9 @@ int usbmux_free_client(usbmux_client_t client)
732 client->header->length16 = 0x1C; 779 client->header->length16 = 0x1C;
733 hton_header(client->header); 780 hton_header(client->header);
734 781
735 err = send_to_device(client->device, (char*)client->header, sizeof(usbmux_tcp_header)); 782 err =
783 send_to_device(client->device, (char *) client->header,
784 sizeof(usbmux_tcp_header));
736 if (err < 0) { 785 if (err < 0) {
737 log_debug_msg("%s: error sending TCP_FIN\n", __func__); 786 log_debug_msg("%s: error sending TCP_FIN\n", __func__);
738 result = err; 787 result = err;
@@ -762,7 +811,8 @@ int usbmux_free_client(usbmux_client_t client)
762 * 811 *
763 * @return 0 on success or a negative errno value on error. 812 * @return 0 on success or a negative errno value on error.
764 */ 813 */
765int usbmux_send(usbmux_client_t client, const char *data, uint32_t datalen, uint32_t * sent_bytes) 814int usbmux_send(usbmux_client_t client, const char *data, uint32_t datalen,
815 uint32_t * sent_bytes)
766{ 816{
767 if (!client->device || !client || !sent_bytes) 817 if (!client->device || !client || !sent_bytes)
768 return -EINVAL; 818 return -EINVAL;
@@ -781,7 +831,8 @@ int usbmux_send(usbmux_client_t client, const char *data, uint32_t datalen, uint
781 clock_gettime(CLOCK_REALTIME, &ts); 831 clock_gettime(CLOCK_REALTIME, &ts);
782 //ts.tv_sec += 1; 832 //ts.tv_sec += 1;
783 ts.tv_nsec += 750 * 1000; 833 ts.tv_nsec += 750 * 1000;
784 if (pthread_cond_timedwait(&client->wait, &client->mutex, &ts) == ETIMEDOUT) { 834 if (pthread_cond_timedwait(&client->wait, &client->mutex, &ts) ==
835 ETIMEDOUT) {
785 // timed out. optimistically grow the window and try to make progress 836 // timed out. optimistically grow the window and try to make progress
786 client->wr_window += WINDOW_INCREMENT; 837 client->wr_window += WINDOW_INCREMENT;
787 } 838 }
@@ -791,7 +842,7 @@ int usbmux_send(usbmux_client_t client, const char *data, uint32_t datalen, uint
791 842
792 // client->scnt and client->ocnt should already be in host notation... 843 // client->scnt and client->ocnt should already be in host notation...
793 // we don't need to change them juuuust yet. 844 // we don't need to change them juuuust yet.
794 char *buffer = (char *) malloc(blocksize + 2); // allow 2 bytes of safety padding 845 char *buffer = (char *) malloc(blocksize + 2); // allow 2 bytes of safety padding
795 // Set the length 846 // Set the length
796 client->header->length = blocksize; 847 client->header->length = blocksize;
797 client->header->length16 = blocksize; 848 client->header->length16 = blocksize;
@@ -802,7 +853,9 @@ int usbmux_send(usbmux_client_t client, const char *data, uint32_t datalen, uint
802 memcpy(buffer, client->header, sizeof(usbmux_tcp_header)); 853 memcpy(buffer, client->header, sizeof(usbmux_tcp_header));
803 memcpy(buffer + sizeof(usbmux_tcp_header), data, datalen); 854 memcpy(buffer + sizeof(usbmux_tcp_header), data, datalen);
804 855
805 log_debug_msg("%s: send_to_device(%d --> %d)\n", __func__, ntohs(client->header->sport), ntohs(client->header->dport)); 856 log_debug_msg("%s: send_to_device(%d --> %d)\n", __func__,
857 ntohs(client->header->sport),
858 ntohs(client->header->dport));
806 sendresult = send_to_device(client->device, buffer, blocksize); 859 sendresult = send_to_device(client->device, buffer, blocksize);
807 // Now that we've sent it off, we can clean up after our sloppy selves. 860 // Now that we've sent it off, we can clean up after our sloppy selves.
808 if (buffer) 861 if (buffer)
@@ -812,7 +865,7 @@ int usbmux_send(usbmux_client_t client, const char *data, uint32_t datalen, uint
812 ntoh_header(client->header); 865 ntoh_header(client->header);
813 866
814 // update counts ONLY if the send succeeded. 867 // update counts ONLY if the send succeeded.
815 if ((uint32_t)sendresult == blocksize) { 868 if ((uint32_t) sendresult == blocksize) {
816 // Re-calculate scnt 869 // Re-calculate scnt
817 client->header->scnt += datalen; 870 client->header->scnt += datalen;
818 client->wr_window -= blocksize; 871 client->wr_window -= blocksize;
@@ -826,12 +879,14 @@ int usbmux_send(usbmux_client_t client, const char *data, uint32_t datalen, uint
826 return -ETIMEDOUT; 879 return -ETIMEDOUT;
827 } else if (sendresult < 0) { 880 } else if (sendresult < 0) {
828 return sendresult; 881 return sendresult;
829 } else if ((uint32_t)sendresult == blocksize) { 882 } else if ((uint32_t) sendresult == blocksize) {
830 // actual number of data bytes sent. 883 // actual number of data bytes sent.
831 *sent_bytes = sendresult - HEADERLEN; 884 *sent_bytes = sendresult - HEADERLEN;
832 return 0; 885 return 0;
833 } else { 886 } else {
834 fprintf(stderr, "usbsend managed to dump a packet that is not full size. %d of %d\n", sendresult, blocksize); 887 fprintf(stderr,
888 "usbsend managed to dump a packet that is not full size. %d of %d\n",
889 sendresult, blocksize);
835 return -EBADMSG; 890 return -EBADMSG;
836 } 891 }
837} 892}
@@ -844,14 +899,15 @@ int usbmux_send(usbmux_client_t client, const char *data, uint32_t datalen, uint
844 * 899 *
845 * @return number of bytes consumed (header + data) 900 * @return number of bytes consumed (header + data)
846 */ 901 */
847uint32_t append_receive_buffer(usbmux_client_t client, char* packet) 902uint32_t append_receive_buffer(usbmux_client_t client, char *packet)
848{ 903{
849 if (client == NULL || packet == NULL) return 0; 904 if (client == NULL || packet == NULL)
905 return 0;
850 906
851 usbmux_tcp_header *header = (usbmux_tcp_header *) packet; 907 usbmux_tcp_header *header = (usbmux_tcp_header *) packet;
852 char* data = &packet[HEADERLEN]; 908 char *data = &packet[HEADERLEN];
853 uint32_t packetlen = ntohl(header->length); 909 uint32_t packetlen = ntohl(header->length);
854 uint32_t datalen = packetlen-HEADERLEN; 910 uint32_t datalen = packetlen - HEADERLEN;
855 911
856 int dobroadcast = 0; 912 int dobroadcast = 0;
857 913
@@ -860,7 +916,7 @@ uint32_t append_receive_buffer(usbmux_client_t client, char* packet)
860 // we need to handle a few corner case tasks and book-keeping which 916 // we need to handle a few corner case tasks and book-keeping which
861 // falls on our responsibility because we are the ones reading in 917 // falls on our responsibility because we are the ones reading in
862 // feedback. 918 // feedback.
863 if (client->header->scnt == 0 && client->header->ocnt == 0 ) { 919 if (client->header->scnt == 0 && client->header->ocnt == 0) {
864 log_debug_msg("client is still waiting for handshake.\n"); 920 log_debug_msg("client is still waiting for handshake.\n");
865 if (header->tcp_flags == (TCP_SYN | TCP_ACK)) { 921 if (header->tcp_flags == (TCP_SYN | TCP_ACK)) {
866 log_debug_msg("yes, got syn+ack ; replying with ack.\n"); 922 log_debug_msg("yes, got syn+ack ; replying with ack.\n");
@@ -872,9 +928,14 @@ uint32_t append_receive_buffer(usbmux_client_t client, char* packet)
872 hton_header(client->header); 928 hton_header(client->header);
873 // push it to USB 929 // push it to USB
874 // TODO: need to check for error in the send here.... :( 930 // TODO: need to check for error in the send here.... :(
875 log_debug_msg("%s: send_to_device (%d --> %d)\n", __func__, ntohs(client->header->sport), ntohs(client->header->dport)); 931 log_debug_msg("%s: send_to_device (%d --> %d)\n", __func__,
876 if (send_to_device(client->device, (char *)client->header, sizeof(usbmux_tcp_header)) <= 0) { 932 ntohs(client->header->sport),
877 log_debug_msg("%s: error when pushing to usb...\n", __func__); 933 ntohs(client->header->dport));
934 if (send_to_device
935 (client->device, (char *) client->header,
936 sizeof(usbmux_tcp_header)) <= 0) {
937 log_debug_msg("%s: error when pushing to usb...\n",
938 __func__);
878 } 939 }
879 // need to revert some of the fields back to host notation. 940 // need to revert some of the fields back to host notation.
880 ntoh_header(client->header); 941 ntoh_header(client->header);
@@ -885,7 +946,6 @@ uint32_t append_receive_buffer(usbmux_client_t client, char* packet)
885 log_debug_msg("WOAH! client failed to get proper syn+ack.\n"); 946 log_debug_msg("WOAH! client failed to get proper syn+ack.\n");
886 } 947 }
887 } 948 }
888
889 // update TCP counters and windows. 949 // update TCP counters and windows.
890 // 950 //
891 // save the window that we're getting from the USB device. 951 // save the window that we're getting from the USB device.
@@ -899,30 +959,33 @@ uint32_t append_receive_buffer(usbmux_client_t client, char* packet)
899 char e_msg[128]; 959 char e_msg[128];
900 e_msg[0] = 0; 960 e_msg[0] = 0;
901 if (datalen > 1) { 961 if (datalen > 1) {
902 memcpy(e_msg, data+1, datalen-1); 962 memcpy(e_msg, data + 1, datalen - 1);
903 e_msg[datalen-1] = 0; 963 e_msg[datalen - 1] = 0;
904 } 964 }
905 // fetch the message 965 // fetch the message
906 switch(data[0]) { 966 switch (data[0]) {
907 case 0: 967 case 0:
908 // this is not an error, it's just a status message. 968 // this is not an error, it's just a status message.
909 log_debug_msg("received status message: %s\n", e_msg); 969 log_debug_msg("received status message: %s\n", e_msg);
910 datalen = 0; 970 datalen = 0;
911 break; 971 break;
912 case 1: 972 case 1:
913 log_debug_msg("received error message: %s\n", e_msg); 973 log_debug_msg("received error message: %s\n", e_msg);
914 datalen = 0; 974 datalen = 0;
915 break; 975 break;
916 default: 976 default:
917 log_debug_msg("received unknown message (type 0x%02x): %s\n", data[0], e_msg); 977 log_debug_msg
918 //datalen = 0; // <-- we let this commented out for testing 978 ("received unknown message (type 0x%02x): %s\n",
919 break; 979 data[0], e_msg);
980 //datalen = 0; // <-- we let this commented out for testing
981 break;
920 } 982 }
921 } else { 983 } else {
922 log_debug_msg("peer sent connection reset. setting error: %d\n", client->error); 984 log_debug_msg
985 ("peer sent connection reset. setting error: %d\n",
986 client->error);
923 } 987 }
924 } 988 }
925
926 // the packet's ocnt tells us how much of our data the device has received. 989 // the packet's ocnt tells us how much of our data the device has received.
927 if (header->tcp_flags & TCP_ACK) { 990 if (header->tcp_flags & TCP_ACK) {
928 // this is a hacky magic number condition. it seems that once 991 // this is a hacky magic number condition. it seems that once
@@ -930,7 +993,7 @@ uint32_t append_receive_buffer(usbmux_client_t client, char* packet)
930 // number, we quickly fall into connection reset problems. 993 // number, we quickly fall into connection reset problems.
931 // Once we see the reported window size start falling off, 994 // Once we see the reported window size start falling off,
932 // ut off and wait for solid acks to come back. 995 // ut off and wait for solid acks to come back.
933 if (ntohs(header->window) < 256) 996 if (ntohs(header->window) < 256)
934 client->wr_window = 0; 997 client->wr_window = 0;
935 998
936 // check what just got acked. 999 // check what just got acked.
@@ -938,21 +1001,24 @@ uint32_t append_receive_buffer(usbmux_client_t client, char* packet)
938 // we got some kind of ack, but it hasn't caught up 1001 // we got some kind of ack, but it hasn't caught up
939 // with the pending that have been sent. 1002 // with the pending that have been sent.
940 pthread_cond_broadcast(&client->wr_wait); 1003 pthread_cond_broadcast(&client->wr_wait);
941 } else if (ntohl(header->ocnt) > /*client->wr_pending_scnt*/ client->header->scnt) { 1004 } else if (ntohl(header->ocnt) >
942 fprintf(stderr, "WTF?! acks overtook pending outstanding. %u,%u\n", ntohl(header->ocnt), client->wr_pending_scnt); 1005 /*client->wr_pending_scnt */ client->header->scnt) {
1006 fprintf(stderr,
1007 "WTF?! acks overtook pending outstanding. %u,%u\n",
1008 ntohl(header->ocnt), client->wr_pending_scnt);
943 } else { 1009 } else {
944 // reset the window 1010 // reset the window
945 client->wr_window = WINDOW_MAX; 1011 client->wr_window = WINDOW_MAX;
946 pthread_cond_broadcast(&client->wr_wait); 1012 pthread_cond_broadcast(&client->wr_wait);
947 } 1013 }
948 } 1014 }
949
950 // the packet's scnt will be our new ocnt. 1015 // the packet's scnt will be our new ocnt.
951 client->header->ocnt = ntohl(header->scnt); 1016 client->header->ocnt = ntohl(header->scnt);
952 1017
953 // ensure there is enough space, either by first malloc or realloc 1018 // ensure there is enough space, either by first malloc or realloc
954 if (datalen > 0) { 1019 if (datalen > 0) {
955 log_debug_msg("%s: putting %d bytes into client's recv_buffer\n", __func__, datalen); 1020 log_debug_msg("%s: putting %d bytes into client's recv_buffer\n",
1021 __func__, datalen);
956 if (client->r_len == 0) 1022 if (client->r_len == 0)
957 dobroadcast = 1; 1023 dobroadcast = 1;
958 1024
@@ -960,7 +1026,8 @@ uint32_t append_receive_buffer(usbmux_client_t client, char* packet)
960 client->recv_buffer = malloc(datalen); 1026 client->recv_buffer = malloc(datalen);
961 client->r_len = 0; 1027 client->r_len = 0;
962 } else { 1028 } else {
963 client->recv_buffer = realloc(client->recv_buffer, client->r_len + datalen); 1029 client->recv_buffer =
1030 realloc(client->recv_buffer, client->r_len + datalen);
964 } 1031 }
965 1032
966 memcpy(&client->recv_buffer[client->r_len], data, datalen); 1033 memcpy(&client->recv_buffer[client->r_len], data, datalen);
@@ -982,7 +1049,7 @@ uint32_t append_receive_buffer(usbmux_client_t client, char* packet)
982 * because we're only called from one location, pullbulk, where the lock 1049 * because we're only called from one location, pullbulk, where the lock
983 * is already held. 1050 * is already held.
984 */ 1051 */
985usbmux_client_t find_client(usbmux_tcp_header* recv_header) 1052usbmux_client_t find_client(usbmux_tcp_header * recv_header)
986{ 1053{
987 // remember, as we're looking for the client, the receive header is 1054 // remember, as we're looking for the client, the receive header is
988 // coming from the USB into our client. This means that when we check 1055 // coming from the USB into our client. This means that when we check
@@ -1017,17 +1084,19 @@ int usbmux_pullbulk(usbmux_device_t device)
1017 return -EINVAL; 1084 return -EINVAL;
1018 1085
1019 int res = 0; 1086 int res = 0;
1020 static const int DEFAULT_CAPACITY = 128*1024; 1087 static const int DEFAULT_CAPACITY = 128 * 1024;
1021 if (device->usbReceive.buffer == NULL) { 1088 if (device->usbReceive.buffer == NULL) {
1022 device->usbReceive.capacity = DEFAULT_CAPACITY; 1089 device->usbReceive.capacity = DEFAULT_CAPACITY;
1023 device->usbReceive.buffer = malloc(device->usbReceive.capacity); 1090 device->usbReceive.buffer = malloc(device->usbReceive.capacity);
1024 device->usbReceive.leftover = 0; 1091 device->usbReceive.leftover = 0;
1025 } 1092 }
1026
1027 // start the cursor off just ahead of the leftover. 1093 // start the cursor off just ahead of the leftover.
1028 char* cursor = &device->usbReceive.buffer[device->usbReceive.leftover]; 1094 char *cursor = &device->usbReceive.buffer[device->usbReceive.leftover];
1029 // pull in content, note that the amount we can pull is capacity minus leftover 1095 // pull in content, note that the amount we can pull is capacity minus leftover
1030 int readlen = recv_from_device_timeout(device, cursor, device->usbReceive.capacity - device->usbReceive.leftover, 3000); 1096 int readlen =
1097 recv_from_device_timeout(device, cursor,
1098 device->usbReceive.capacity -
1099 device->usbReceive.leftover, 3000);
1031 if (readlen < 0) { 1100 if (readlen < 0) {
1032 res = readlen; 1101 res = readlen;
1033 //fprintf(stderr, "recv_from_device_timeout gave us an error.\n"); 1102 //fprintf(stderr, "recv_from_device_timeout gave us an error.\n");
@@ -1036,7 +1105,6 @@ int usbmux_pullbulk(usbmux_device_t device)
1036 if (readlen > 0) { 1105 if (readlen > 0) {
1037 //fprintf(stdout, "recv_from_device_timeout pulled an extra %d bytes\n", readlen); 1106 //fprintf(stdout, "recv_from_device_timeout pulled an extra %d bytes\n", readlen);
1038 } 1107 }
1039
1040 // the amount of content we have to work with is the remainder plus 1108 // the amount of content we have to work with is the remainder plus
1041 // what we managed to read 1109 // what we managed to read
1042 device->usbReceive.leftover += readlen; 1110 device->usbReceive.leftover += readlen;
@@ -1050,23 +1118,29 @@ int usbmux_pullbulk(usbmux_device_t device)
1050 break; 1118 break;
1051 usbmux_tcp_header *header = (usbmux_tcp_header *) cursor; 1119 usbmux_tcp_header *header = (usbmux_tcp_header *) cursor;
1052 1120
1053 log_debug_msg("%s: recv_from_device_timeout (%d --> %d)\n", __func__, ntohs(header->sport), ntohs(header->dport)); 1121 log_debug_msg("%s: recv_from_device_timeout (%d --> %d)\n",
1122 __func__, ntohs(header->sport),
1123 ntohs(header->dport));
1054 1124
1055 // now that we have a header, check if there is sufficient data 1125 // now that we have a header, check if there is sufficient data
1056 // to construct a full packet, including its data 1126 // to construct a full packet, including its data
1057 uint32_t packetlen = ntohl(header->length); 1127 uint32_t packetlen = ntohl(header->length);
1058 if ((uint32_t)device->usbReceive.leftover < packetlen) { 1128 if ((uint32_t) device->usbReceive.leftover < packetlen) {
1059 fprintf(stderr, "%s: not enough data to construct a full packet\n", __func__); 1129 fprintf(stderr,
1130 "%s: not enough data to construct a full packet\n",
1131 __func__);
1060 break; 1132 break;
1061 } 1133 }
1062
1063 // ok... find the client this packet will get stuffed to. 1134 // ok... find the client this packet will get stuffed to.
1064 usbmux_client_t client = find_client(header); 1135 usbmux_client_t client = find_client(header);
1065 if (client == NULL) { 1136 if (client == NULL) {
1066 log_debug_msg("WARNING: client for packet cannot be found. dropping packet.\n"); 1137 log_debug_msg
1138 ("WARNING: client for packet cannot be found. dropping packet.\n");
1067 } else { 1139 } else {
1068 // stuff the data 1140 // stuff the data
1069 log_debug_msg("%s: found client, calling append_receive_buffer\n", __func__); 1141 log_debug_msg
1142 ("%s: found client, calling append_receive_buffer\n",
1143 __func__);
1070 append_receive_buffer(client, cursor); 1144 append_receive_buffer(client, cursor);
1071 1145
1072 // perhaps this is too general, == -ECONNRESET 1146 // perhaps this is too general, == -ECONNRESET
@@ -1075,7 +1149,9 @@ int usbmux_pullbulk(usbmux_device_t device)
1075 pthread_mutex_lock(&client->mutex); 1149 pthread_mutex_lock(&client->mutex);
1076 if (client->cleanup) { 1150 if (client->cleanup) {
1077 pthread_mutex_unlock(&client->mutex); 1151 pthread_mutex_unlock(&client->mutex);
1078 log_debug_msg("freeing up connection (%d->%d)\n", ntohs(client->header->sport), ntohs(client->header->dport)); 1152 log_debug_msg("freeing up connection (%d->%d)\n",
1153 ntohs(client->header->sport),
1154 ntohs(client->header->dport));
1079 delete_connection(client); 1155 delete_connection(client);
1080 } else { 1156 } else {
1081 pthread_mutex_unlock(&client->mutex); 1157 pthread_mutex_unlock(&client->mutex);
@@ -1096,9 +1172,10 @@ int usbmux_pullbulk(usbmux_device_t device)
1096 // 1172 //
1097 // if there are no leftovers, we just leave the datastructure as is, 1173 // if there are no leftovers, we just leave the datastructure as is,
1098 // and re-use the block next time. 1174 // and re-use the block next time.
1099 if (device->usbReceive.leftover > 0 && cursor != device->usbReceive.buffer) { 1175 if (device->usbReceive.leftover > 0
1176 && cursor != device->usbReceive.buffer) {
1100 log_debug_msg("%s: we got a leftover, so handle it\n", __func__); 1177 log_debug_msg("%s: we got a leftover, so handle it\n", __func__);
1101 char* newbuff = malloc(DEFAULT_CAPACITY); 1178 char *newbuff = malloc(DEFAULT_CAPACITY);
1102 memcpy(newbuff, cursor, device->usbReceive.leftover); 1179 memcpy(newbuff, cursor, device->usbReceive.leftover);
1103 free(device->usbReceive.buffer); 1180 free(device->usbReceive.buffer);
1104 device->usbReceive.buffer = newbuff; 1181 device->usbReceive.buffer = newbuff;
@@ -1133,7 +1210,9 @@ int usbmux_get_error(usbmux_client_t client)
1133 * 1210 *
1134 * @return 0 on success or a negative errno value on failure. 1211 * @return 0 on success or a negative errno value on failure.
1135 */ 1212 */
1136int usbmux_recv_timeout(usbmux_client_t client, char *data, uint32_t datalen, uint32_t * recv_bytes, int timeout) 1213int usbmux_recv_timeout(usbmux_client_t client, char *data,
1214 uint32_t datalen, uint32_t * recv_bytes,
1215 int timeout)
1137{ 1216{
1138 1217
1139 if (!client || !data || datalen == 0 || !recv_bytes) 1218 if (!client || !data || datalen == 0 || !recv_bytes)
@@ -1147,15 +1226,15 @@ int usbmux_recv_timeout(usbmux_client_t client, char *data, uint32_t datalen, ui
1147 if (timeout > 0 && (client->recv_buffer == NULL || client->r_len == 0)) { 1226 if (timeout > 0 && (client->recv_buffer == NULL || client->r_len == 0)) {
1148 struct timespec ts; 1227 struct timespec ts;
1149 clock_gettime(CLOCK_REALTIME, &ts); 1228 clock_gettime(CLOCK_REALTIME, &ts);
1150 ts.tv_sec += timeout/1000; 1229 ts.tv_sec += timeout / 1000;
1151 ts.tv_nsec += (timeout-((int)(timeout/1000))*1000)*1000; 1230 ts.tv_nsec += (timeout - ((int) (timeout / 1000)) * 1000) * 1000;
1152 pthread_cond_timedwait(&client->wait, &client->mutex, &ts); 1231 pthread_cond_timedwait(&client->wait, &client->mutex, &ts);
1153 } 1232 }
1154 1233
1155 *recv_bytes = 0; 1234 *recv_bytes = 0;
1156 if (client->recv_buffer != NULL && client->r_len > 0) { 1235 if (client->recv_buffer != NULL && client->r_len > 0) {
1157 uint32_t foolen = datalen; 1236 uint32_t foolen = datalen;
1158 if ((int)foolen > client->r_len) 1237 if ((int) foolen > client->r_len)
1159 foolen = client->r_len; 1238 foolen = client->r_len;
1160 memcpy(data, client->recv_buffer, foolen); 1239 memcpy(data, client->recv_buffer, foolen);
1161 *recv_bytes = foolen; 1240 *recv_bytes = foolen;
@@ -1163,7 +1242,7 @@ int usbmux_recv_timeout(usbmux_client_t client, char *data, uint32_t datalen, ui
1163 // preserve any left-over unread amounts. 1242 // preserve any left-over unread amounts.
1164 int remainder = client->r_len - foolen; 1243 int remainder = client->r_len - foolen;
1165 if (remainder > 0) { 1244 if (remainder > 0) {
1166 char* newbuf = malloc(remainder); 1245 char *newbuf = malloc(remainder);
1167 memcpy(newbuf, client->recv_buffer + foolen, remainder); 1246 memcpy(newbuf, client->recv_buffer + foolen, remainder);
1168 client->r_len = remainder; 1247 client->r_len = remainder;
1169 free(client->recv_buffer); 1248 free(client->recv_buffer);