diff options
Diffstat (limited to 'libusbmuxd/libusbmuxd.c')
| -rw-r--r-- | libusbmuxd/libusbmuxd.c | 333 |
1 files changed, 288 insertions, 45 deletions
diff --git a/libusbmuxd/libusbmuxd.c b/libusbmuxd/libusbmuxd.c index 090695f..6a54765 100644 --- a/libusbmuxd/libusbmuxd.c +++ b/libusbmuxd/libusbmuxd.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <sys/socket.h> | 6 | #include <sys/socket.h> |
| 7 | #include <arpa/inet.h> | 7 | #include <arpa/inet.h> |
| 8 | #include <unistd.h> | 8 | #include <unistd.h> |
| 9 | #include <signal.h> | ||
| 9 | 10 | ||
| 10 | // usbmuxd public interface | 11 | // usbmuxd public interface |
| 11 | #include "usbmuxd.h" | 12 | #include "usbmuxd.h" |
| @@ -13,10 +14,48 @@ | |||
| 13 | #include "usbmuxd-proto.h" | 14 | #include "usbmuxd-proto.h" |
| 14 | // socket utility functions | 15 | // socket utility functions |
| 15 | #include "sock_stuff.h" | 16 | #include "sock_stuff.h" |
| 17 | // misc utility functions | ||
| 18 | #include "utils.h" | ||
| 16 | 19 | ||
| 20 | static struct collection devices; | ||
| 21 | static usbmuxd_event_cb_t event_cb = NULL; | ||
| 22 | pthread_t devmon; | ||
| 23 | static int listenfd = -1; | ||
| 24 | |||
| 25 | /** | ||
| 26 | * Finds a device info record by its handle. | ||
| 27 | * if the record is not found, NULL is returned. | ||
| 28 | */ | ||
| 29 | static usbmuxd_device_info_t *devices_find(int handle) | ||
| 30 | { | ||
| 31 | FOREACH(usbmuxd_device_info_t *dev, &devices) { | ||
| 32 | if (dev && dev->handle == handle) { | ||
| 33 | return dev; | ||
| 34 | } | ||
| 35 | } ENDFOREACH | ||
| 36 | return NULL; | ||
| 37 | } | ||
| 38 | |||
| 39 | /** | ||
| 40 | * Creates a socket connection to usbmuxd. | ||
| 41 | * For Mac/Linux it is a unix domain socket, | ||
| 42 | * for Windows it is a tcp socket. | ||
| 43 | */ | ||
| 44 | static int connect_usbmuxd_socket() | ||
| 45 | { | ||
| 46 | #ifdef WINDOWS | ||
| 47 | return connect_socket("127.0.0.1", 27015); | ||
| 48 | #else | ||
| 49 | return connect_unix_socket(USBMUXD_SOCKET_FILE); | ||
| 50 | #endif | ||
| 51 | } | ||
| 52 | |||
| 53 | /** | ||
| 54 | * Retrieves the result code to a previously sent request. | ||
| 55 | */ | ||
| 17 | static int usbmuxd_get_result(int sfd, uint32_t tag, uint32_t * result) | 56 | static int usbmuxd_get_result(int sfd, uint32_t tag, uint32_t * result) |
| 18 | { | 57 | { |
| 19 | struct usbmuxd_result res; | 58 | struct usbmuxd_result_msg res; |
| 20 | int recv_len; | 59 | int recv_len; |
| 21 | 60 | ||
| 22 | if (!result) { | 61 | if (!result) { |
| @@ -29,8 +68,8 @@ static int usbmuxd_get_result(int sfd, uint32_t tag, uint32_t * result) | |||
| 29 | } else { | 68 | } else { |
| 30 | if ((recv_len == sizeof(res)) | 69 | if ((recv_len == sizeof(res)) |
| 31 | && (res.header.length == (uint32_t) recv_len) | 70 | && (res.header.length == (uint32_t) recv_len) |
| 32 | && (res.header.reserved == 0) | 71 | && (res.header.version == USBMUXD_PROTOCOL_VERSION) |
| 33 | && (res.header.type == USBMUXD_RESULT) | 72 | && (res.header.message == MESSAGE_RESULT) |
| 34 | ) { | 73 | ) { |
| 35 | *result = res.result; | 74 | *result = res.result; |
| 36 | if (res.header.tag == tag) { | 75 | if (res.header.tag == tag) { |
| @@ -44,16 +83,229 @@ static int usbmuxd_get_result(int sfd, uint32_t tag, uint32_t * result) | |||
| 44 | return -1; | 83 | return -1; |
| 45 | } | 84 | } |
| 46 | 85 | ||
| 47 | int usbmuxd_scan(usbmuxd_scan_result ** available_devices) | 86 | /** |
| 87 | * Generates an event, i.e. calls the callback function. | ||
| 88 | * A reference to a populated usbmuxd_event_t with information about the event | ||
| 89 | * and the corresponding device will be passed to the callback function. | ||
| 90 | */ | ||
| 91 | static void generate_event(usbmuxd_event_cb_t callback, const usbmuxd_device_info_t *dev, enum usbmuxd_device_event event) | ||
| 92 | { | ||
| 93 | usbmuxd_event_t ev; | ||
| 94 | |||
| 95 | if (!callback || !dev) { | ||
| 96 | return; | ||
| 97 | } | ||
| 98 | |||
| 99 | ev.event = event; | ||
| 100 | memcpy(&ev.device, dev, sizeof(usbmuxd_device_info_t)); | ||
| 101 | |||
| 102 | printf("%s: event=%d, handle=%d\n", __func__, ev.event, ev.device.handle); | ||
| 103 | |||
| 104 | callback(&ev); | ||
| 105 | } | ||
| 106 | |||
| 107 | /** | ||
| 108 | * Tries to connect to usbmuxd and wait if it is not running. | ||
| 109 | * | ||
| 110 | * TODO inotify support should come here | ||
| 111 | */ | ||
| 112 | static int usbmuxd_listen() | ||
| 48 | { | 113 | { |
| 49 | struct usbmuxd_scan_request s_req; | ||
| 50 | int sfd; | 114 | int sfd; |
| 51 | int scan_success = 0; | 115 | uint32_t res = -1; |
| 116 | struct usbmuxd_listen_request req; | ||
| 117 | struct usbmuxd_header hdr; | ||
| 118 | |||
| 119 | req.header.length = sizeof(struct usbmuxd_listen_request); | ||
| 120 | req.header.version = USBMUXD_PROTOCOL_VERSION; | ||
| 121 | req.header.message = MESSAGE_LISTEN; | ||
| 122 | req.header.tag = 2; | ||
| 123 | |||
| 124 | sfd = connect_usbmuxd_socket(); | ||
| 125 | if (sfd < 0) { | ||
| 126 | fprintf(stderr, "DEBUG: waiting for usbmuxd to come up.\n"); | ||
| 127 | |||
| 128 | while (event_cb) { | ||
| 129 | if ((sfd = connect_usbmuxd_socket()) > 0) { | ||
| 130 | fprintf(stderr, "DEBUG: usbmuxd started\n"); | ||
| 131 | break; | ||
| 132 | } | ||
| 133 | sleep(1); | ||
| 134 | } | ||
| 135 | } | ||
| 136 | |||
| 137 | if (sfd < 0) { | ||
| 138 | fprintf(stderr, "ERROR: usbmuxd was supposed to be running here...\n"); | ||
| 139 | return sfd; | ||
| 140 | } | ||
| 141 | |||
| 142 | if (send_buf(sfd, &req, req.header.length) != (int)req.header.length) { | ||
| 143 | fprintf(stderr, "ERROR: could not send listen packet\n"); | ||
| 144 | close(sfd); | ||
| 145 | return -1; | ||
| 146 | } | ||
| 147 | if (usbmuxd_get_result(sfd, req.header.tag, &res) && (res != 0)) { | ||
| 148 | fprintf(stderr, "ERROR: did not get OK\n"); | ||
| 149 | close(sfd); | ||
| 150 | return -1; | ||
| 151 | } | ||
| 152 | |||
| 153 | return sfd; | ||
| 154 | } | ||
| 155 | |||
| 156 | /** | ||
| 157 | * Waits for an event to occur, i.e. a packet coming from usbmuxd. | ||
| 158 | * Calls generate_event to pass the event via callback to the client program. | ||
| 159 | */ | ||
| 160 | int get_next_event(int sfd, usbmuxd_event_cb_t callback) | ||
| 161 | { | ||
| 162 | int recv_len; | ||
| 163 | struct usbmuxd_listen_request req; | ||
| 164 | struct usbmuxd_header hdr; | ||
| 165 | |||
| 166 | /* block until we receive something */ | ||
| 167 | recv_len = recv_buf_timeout(sfd, &hdr, sizeof(hdr), 0, 0); | ||
| 168 | if (recv_len < 0) { | ||
| 169 | int i; | ||
| 170 | fprintf(stderr, "DEBUG: connection closed.\n"); | ||
| 171 | // when then usbmuxd connection fails, | ||
| 172 | // generate remove events for every device that | ||
| 173 | // is still present so applications know about it | ||
| 174 | // TODO: is this behaviour correct? | ||
| 175 | FOREACH(usbmuxd_device_info_t *dev, &devices) { | ||
| 176 | generate_event(callback, dev, UE_DEVICE_REMOVE); | ||
| 177 | } ENDFOREACH | ||
| 178 | collection_free(&devices); | ||
| 179 | return recv_len; | ||
| 180 | } else if (recv_len == sizeof(hdr)) { | ||
| 181 | if (hdr.message == MESSAGE_DEVICE_ADD) { | ||
| 182 | struct usbmuxd_device_record dev; | ||
| 183 | usbmuxd_device_info_t *devinfo = (usbmuxd_device_info_t*)malloc(sizeof(usbmuxd_device_info_t)); | ||
| 184 | if (!devinfo) { | ||
| 185 | fprintf(stderr, "Out of memory!\n"); | ||
| 186 | return -1; | ||
| 187 | } | ||
| 188 | |||
| 189 | if (hdr.length != sizeof(struct usbmuxd_header)+sizeof(struct usbmuxd_device_record)) { | ||
| 190 | fprintf(stderr, "WARNING: unexpected packet size%d for MESSAGE_DEVICE_ADD (expected %d)!\n", hdr.length, sizeof(struct usbmuxd_header)+sizeof(struct usbmuxd_device_record)); | ||
| 191 | } | ||
| 192 | recv_len = recv_buf_timeout(sfd, &dev, hdr.length - sizeof(struct usbmuxd_header), 0, 5000); | ||
| 193 | if (recv_len != (hdr.length - sizeof(struct usbmuxd_header))) { | ||
| 194 | fprintf(stderr, "Could not receive packet\n"); | ||
| 195 | return recv_len; | ||
| 196 | } | ||
| 197 | |||
| 198 | devinfo->handle = dev.device_id; | ||
| 199 | devinfo->product_id = dev.product_id; | ||
| 200 | memset(devinfo->uuid, '\0', sizeof(devinfo->uuid)); | ||
| 201 | memcpy(devinfo->uuid, dev.serial_number, sizeof(devinfo->uuid)); | ||
| 202 | |||
| 203 | collection_add(&devices, devinfo); | ||
| 204 | generate_event(callback, devinfo, UE_DEVICE_ADD); | ||
| 205 | } else if (hdr.message == MESSAGE_DEVICE_REMOVE) { | ||
| 206 | uint32_t handle; | ||
| 207 | usbmuxd_device_info_t *dev; | ||
| 208 | |||
| 209 | if (hdr.length != sizeof(struct usbmuxd_header)+sizeof(uint32_t)) { | ||
| 210 | fprintf(stderr, "WARNING: unexpected packet size%d for MESSAGE_DEVICE_REMOVE (expected %d)!\n", hdr.length, sizeof(struct usbmuxd_header)+sizeof(uint32_t)); | ||
| 211 | } | ||
| 212 | recv_len = recv_buf_timeout(sfd, &handle, sizeof(uint32_t), 0, 5000); | ||
| 213 | if (recv_len != sizeof(uint32_t)) { | ||
| 214 | fprintf(stderr, "Could not receive packet\n"); | ||
| 215 | return recv_len; | ||
| 216 | } | ||
| 217 | |||
| 218 | dev = devices_find(handle); | ||
| 219 | if (!dev) { | ||
| 220 | fprintf(stderr, "WARNING: got device remove message for handle %d, but couldn't find the corresponding handle in the device list. This event will be ignored.\n", handle); | ||
| 221 | } else { | ||
| 222 | generate_event(callback, dev, UE_DEVICE_REMOVE); | ||
| 223 | collection_remove(&devices, dev); | ||
| 224 | } | ||
| 225 | } else { | ||
| 226 | fprintf(stderr, "%s: Unknown message type %d length %d\n", __func__, hdr.message, hdr.length); | ||
| 227 | } | ||
| 228 | } else { | ||
| 229 | fprintf(stderr, "%s: ERROR: incomplete packet received!\n", __func__); | ||
| 230 | } | ||
| 231 | return 0; | ||
| 232 | } | ||
| 233 | |||
| 234 | /** | ||
| 235 | * Device Monitor thread function. | ||
| 236 | * | ||
| 237 | * This function sets up a connection to usbmuxd | ||
| 238 | */ | ||
| 239 | static void *device_monitor(void *data) | ||
| 240 | { | ||
| 241 | collection_init(&devices); | ||
| 242 | |||
| 243 | while (event_cb) { | ||
| 244 | |||
| 245 | listenfd = usbmuxd_listen(); | ||
| 246 | if (listenfd < 0) { | ||
| 247 | fprintf(stderr, "DEBUG: listenfd=%d\n", listenfd); | ||
| 248 | continue; | ||
| 249 | } | ||
| 250 | |||
| 251 | while (event_cb) { | ||
| 252 | printf("waiting for events\n"); | ||
| 253 | int res = get_next_event(listenfd, event_cb); | ||
| 254 | if (res < 0) { | ||
| 255 | fprintf(stderr, "%s: closing connection (code %d)\n", __func__, res); | ||
| 256 | break; | ||
| 257 | } | ||
| 258 | } | ||
| 259 | } | ||
| 260 | |||
| 261 | collection_free(&devices); | ||
| 262 | printf("%s: terminated\n", __func__); | ||
| 263 | |||
| 264 | return NULL; | ||
| 265 | } | ||
| 266 | |||
| 267 | int usbmuxd_subscribe(usbmuxd_event_cb_t callback) | ||
| 268 | { | ||
| 269 | int res; | ||
| 270 | |||
| 271 | if (!callback) { | ||
| 272 | return -EINVAL; | ||
| 273 | } | ||
| 274 | event_cb = callback; | ||
| 275 | |||
| 276 | res = pthread_create(&devmon, NULL, device_monitor, NULL); | ||
| 277 | if (res != 0) { | ||
| 278 | fprintf(stderr, "ERROR: Could not start device watcher thread!\n"); | ||
| 279 | return res; | ||
| 280 | } | ||
| 281 | return 0; | ||
| 282 | } | ||
| 283 | |||
| 284 | int usbmuxd_unsubscribe() | ||
| 285 | { | ||
| 286 | event_cb = NULL; | ||
| 287 | |||
| 288 | if (pthread_kill(devmon, 0) == 0) { | ||
| 289 | printf("%s: unsubscribing callback\n", __func__); | ||
| 290 | close(listenfd); | ||
| 291 | listenfd = -1; | ||
| 292 | pthread_kill(devmon, SIGINT); | ||
| 293 | pthread_join(devmon, NULL); | ||
| 294 | } | ||
| 295 | |||
| 296 | return 0; | ||
| 297 | } | ||
| 298 | |||
| 299 | int usbmuxd_scan(usbmuxd_device_info_t ** available_devices) | ||
| 300 | { | ||
| 301 | struct usbmuxd_listen_request s_req; | ||
| 302 | int sfd; | ||
| 303 | int listen_success = 0; | ||
| 52 | uint32_t res; | 304 | uint32_t res; |
| 53 | uint32_t pktlen; | ||
| 54 | int recv_len; | 305 | int recv_len; |
| 55 | usbmuxd_scan_result *newlist = NULL; | 306 | usbmuxd_device_info_t *newlist = NULL; |
| 56 | struct usbmuxd_device_info_record dev_info_pkt; | 307 | struct usbmuxd_header hdr; |
| 308 | struct usbmuxd_device_record dev_info; | ||
| 57 | int dev_cnt = 0; | 309 | int dev_cnt = 0; |
| 58 | 310 | ||
| 59 | sfd = connect_unix_socket(USBMUXD_SOCKET_FILE); | 311 | sfd = connect_unix_socket(USBMUXD_SOCKET_FILE); |
| @@ -62,9 +314,9 @@ int usbmuxd_scan(usbmuxd_scan_result ** available_devices) | |||
| 62 | return sfd; | 314 | return sfd; |
| 63 | } | 315 | } |
| 64 | 316 | ||
| 65 | s_req.header.length = sizeof(struct usbmuxd_scan_request); | 317 | s_req.header.length = sizeof(struct usbmuxd_listen_request); |
| 66 | s_req.header.reserved = 0; | 318 | s_req.header.version = USBMUXD_PROTOCOL_VERSION; |
| 67 | s_req.header.type = USBMUXD_SCAN; | 319 | s_req.header.message = MESSAGE_LISTEN; |
| 68 | s_req.header.tag = 2; | 320 | s_req.header.tag = 2; |
| 69 | 321 | ||
| 70 | // send scan request packet | 322 | // send scan request packet |
| @@ -73,7 +325,7 @@ int usbmuxd_scan(usbmuxd_scan_result ** available_devices) | |||
| 73 | res = -1; | 325 | res = -1; |
| 74 | // get response | 326 | // get response |
| 75 | if (usbmuxd_get_result(sfd, s_req.header.tag, &res) && (res == 0)) { | 327 | if (usbmuxd_get_result(sfd, s_req.header.tag, &res) && (res == 0)) { |
| 76 | scan_success = 1; | 328 | listen_success = 1; |
| 77 | } else { | 329 | } else { |
| 78 | fprintf(stderr, | 330 | fprintf(stderr, |
| 79 | "%s: Did not get response to scan request (with result=0)...\n", | 331 | "%s: Did not get response to scan request (with result=0)...\n", |
| @@ -83,50 +335,44 @@ int usbmuxd_scan(usbmuxd_scan_result ** available_devices) | |||
| 83 | } | 335 | } |
| 84 | } | 336 | } |
| 85 | 337 | ||
| 86 | if (!scan_success) { | 338 | if (!listen_success) { |
| 87 | fprintf(stderr, "%s: Could not send scan request!\n", __func__); | 339 | fprintf(stderr, "%s: Could not send listen request!\n", __func__); |
| 88 | return -1; | 340 | return -1; |
| 89 | } | 341 | } |
| 90 | 342 | ||
| 91 | *available_devices = NULL; | 343 | *available_devices = NULL; |
| 92 | // receive device list | 344 | // receive device list |
| 93 | while (1) { | 345 | while (1) { |
| 94 | if (recv_buf_timeout(sfd, &pktlen, 4, MSG_PEEK, 1000) == 4) { | 346 | if (recv_buf_timeout(sfd, &hdr, sizeof(hdr), 0, 1000) == sizeof(hdr)) { |
| 95 | if (pktlen != sizeof(dev_info_pkt)) { | 347 | if (hdr.length != sizeof(hdr)+sizeof(dev_info)) { |
| 96 | // invalid packet size received! | 348 | // invalid packet size received! |
| 97 | fprintf(stderr, | 349 | fprintf(stderr, |
| 98 | "%s: Invalid packet size (%d) received when expecting a device info record.\n", | 350 | "%s: Invalid packet size (%d) received when expecting a device info record.\n", |
| 99 | __func__, pktlen); | 351 | __func__, hdr.length); |
| 100 | break; | 352 | break; |
| 101 | } | 353 | } |
| 102 | 354 | ||
| 103 | recv_len = recv_buf(sfd, &dev_info_pkt, pktlen); | 355 | recv_len = recv_buf(sfd, &dev_info, hdr.length - sizeof(hdr)); |
| 104 | if (recv_len <= 0) { | 356 | if (recv_len <= 0) { |
| 105 | fprintf(stderr, | 357 | fprintf(stderr, |
| 106 | "%s: Error when receiving device info record\n", | 358 | "%s: Error when receiving device info record\n", |
| 107 | __func__); | 359 | __func__); |
| 108 | break; | 360 | break; |
| 109 | } else if ((uint32_t) recv_len < pktlen) { | 361 | } else if ((uint32_t) recv_len < hdr.length - sizeof(hdr)) { |
| 110 | fprintf(stderr, | 362 | fprintf(stderr, |
| 111 | "%s: received less data than specified in header!\n", | 363 | "%s: received less data than specified in header!\n", __func__); |
| 112 | __func__); | ||
| 113 | } else { | 364 | } else { |
| 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); | 365 | newlist = (usbmuxd_device_info_t *) realloc(*available_devices, sizeof(usbmuxd_device_info_t) * (dev_cnt + 1)); |
| 115 | newlist = | ||
| 116 | (usbmuxd_scan_result *) realloc(*available_devices, | ||
| 117 | sizeof | ||
| 118 | (usbmuxd_scan_result) * | ||
| 119 | (dev_cnt + 1)); | ||
| 120 | if (newlist) { | 366 | if (newlist) { |
| 121 | newlist[dev_cnt].handle = | 367 | newlist[dev_cnt].handle = |
| 122 | (int) dev_info_pkt.device.device_id; | 368 | (int) dev_info.device_id; |
| 123 | newlist[dev_cnt].product_id = | 369 | newlist[dev_cnt].product_id = |
| 124 | dev_info_pkt.device.product_id; | 370 | dev_info.product_id; |
| 125 | memset(newlist[dev_cnt].serial_number, '\0', | 371 | memset(newlist[dev_cnt].uuid, '\0', |
| 126 | sizeof(newlist[dev_cnt].serial_number)); | 372 | sizeof(newlist[dev_cnt].uuid)); |
| 127 | memcpy(newlist[dev_cnt].serial_number, | 373 | memcpy(newlist[dev_cnt].uuid, |
| 128 | dev_info_pkt.device.serial_number, | 374 | dev_info.serial_number, |
| 129 | sizeof(dev_info_pkt.device.serial_number)); | 375 | sizeof(newlist[dev_cnt].uuid)); |
| 130 | *available_devices = newlist; | 376 | *available_devices = newlist; |
| 131 | dev_cnt++; | 377 | dev_cnt++; |
| 132 | } else { | 378 | } else { |
| @@ -144,24 +390,21 @@ int usbmuxd_scan(usbmuxd_scan_result ** available_devices) | |||
| 144 | } | 390 | } |
| 145 | 391 | ||
| 146 | // terminating zero record | 392 | // terminating zero record |
| 147 | newlist = | 393 | newlist = (usbmuxd_device_info_t*) realloc(*available_devices, sizeof(usbmuxd_device_info_t) * (dev_cnt + 1)); |
| 148 | (usbmuxd_scan_result *) realloc(*available_devices, | 394 | memset(newlist + dev_cnt, 0, sizeof(usbmuxd_device_info_t)); |
| 149 | sizeof(usbmuxd_scan_result) * | ||
| 150 | (dev_cnt + 1)); | ||
| 151 | memset(newlist + dev_cnt, 0, sizeof(usbmuxd_scan_result)); | ||
| 152 | *available_devices = newlist; | 395 | *available_devices = newlist; |
| 153 | 396 | ||
| 154 | return dev_cnt; | 397 | return dev_cnt; |
| 155 | } | 398 | } |
| 156 | 399 | ||
| 157 | int usbmuxd_connect(const int handle, const unsigned short tcp_port) | 400 | int usbmuxd_connect(const int handle, const unsigned short port) |
| 158 | { | 401 | { |
| 159 | int sfd; | 402 | int sfd; |
| 160 | struct usbmuxd_connect_request c_req; | 403 | struct usbmuxd_connect_request c_req; |
| 161 | int connected = 0; | 404 | int connected = 0; |
| 162 | uint32_t res = -1; | 405 | uint32_t res = -1; |
| 163 | 406 | ||
| 164 | sfd = connect_unix_socket(USBMUXD_SOCKET_FILE); | 407 | sfd = connect_usbmuxd_socket(); |
| 165 | if (sfd < 0) { | 408 | if (sfd < 0) { |
| 166 | fprintf(stderr, "%s: Error: Connection to usbmuxd failed: %s\n", | 409 | fprintf(stderr, "%s: Error: Connection to usbmuxd failed: %s\n", |
| 167 | __func__, strerror(errno)); | 410 | __func__, strerror(errno)); |
| @@ -169,11 +412,11 @@ int usbmuxd_connect(const int handle, const unsigned short tcp_port) | |||
| 169 | } | 412 | } |
| 170 | 413 | ||
| 171 | c_req.header.length = sizeof(c_req); | 414 | c_req.header.length = sizeof(c_req); |
| 172 | c_req.header.reserved = 0; | 415 | c_req.header.version = USBMUXD_PROTOCOL_VERSION; |
| 173 | c_req.header.type = USBMUXD_CONNECT; | 416 | c_req.header.message = MESSAGE_CONNECT; |
| 174 | c_req.header.tag = 3; | 417 | c_req.header.tag = 3; |
| 175 | c_req.device_id = (uint32_t) handle; | 418 | c_req.device_id = (uint32_t) handle; |
| 176 | c_req.tcp_dport = htons(tcp_port); | 419 | c_req.port = htons(port); |
| 177 | c_req.reserved = 0; | 420 | c_req.reserved = 0; |
| 178 | 421 | ||
| 179 | if (send_buf(sfd, &c_req, sizeof(c_req)) < 0) { | 422 | if (send_buf(sfd, &c_req, sizeof(c_req)) < 0) { |
