summaryrefslogtreecommitdiffstats
path: root/libusbmuxd.c
diff options
context:
space:
mode:
Diffstat (limited to 'libusbmuxd.c')
-rw-r--r--libusbmuxd.c170
1 files changed, 170 insertions, 0 deletions
diff --git a/libusbmuxd.c b/libusbmuxd.c
new file mode 100644
index 0000000..4e4ec10
--- /dev/null
+++ b/libusbmuxd.c
@@ -0,0 +1,170 @@
1#include <stdint.h>
2#include <stdlib.h>
3#include <errno.h>
4#include <stdio.h>
5#include <string.h>
6#include <sys/socket.h>
7#include <arpa/inet.h>
8#include <unistd.h>
9
10#include <usbmuxd.h>
11#include "sock_stuff.h"
12
13static int usbmuxd_get_result(int sfd, uint32_t tag, uint32_t *result)
14{
15 struct usbmuxd_result res;
16 int recv_len;
17
18 if (!result) {
19 return -EINVAL;
20 }
21
22 if ((recv_len = recv_buf(sfd, &res, sizeof(res))) <= 0) {
23 perror("recv");
24 return -errno;
25 } else {
26 if ((recv_len == sizeof(res))
27 && (res.header.length == recv_len)
28 && (res.header.reserved == 0)
29 && (res.header.type == USBMUXD_RESULT)
30 ) {
31 *result = res.result;
32 if (res.header.tag == tag) {
33 return 1;
34 } else {
35 return 0;
36 }
37 }
38 }
39
40 return -1;
41}
42
43int usbmuxd_scan(usbmuxd_device_t **devices)
44{
45 struct usbmuxd_scan_request s_req;
46 int sfd;
47 int scan_success = 0;
48 uint32_t res;
49 uint32_t pktlen;
50 int recv_len;
51 usbmuxd_device_t *newlist = NULL;
52 struct usbmuxd_device_info_record dev_info_pkt;
53 int dev_cnt = 0;
54
55 sfd = connect_unix_socket(USBMUXD_SOCKET_FILE);
56 if (sfd < 0) {
57 fprintf(stderr, "%s: error opening socket!\n", __func__);
58 return sfd;
59 }
60
61 s_req.header.length = sizeof(struct usbmuxd_scan_request);
62 s_req.header.reserved = 0;
63 s_req.header.type = USBMUXD_SCAN;
64 s_req.header.tag = 2;
65
66 // send scan request packet
67 if (send_buf(sfd, &s_req, s_req.header.length) == s_req.header.length) {
68 res = -1;
69 // get response
70 if (usbmuxd_get_result(sfd, s_req.header.tag, &res) && (res == 0)) {
71 scan_success = 1;
72 } else {
73 fprintf(stderr, "%s: Did not get response to scan request (with result=0)...\n", __func__);
74 close(sfd);
75 return res;
76 }
77 }
78
79 if (!scan_success) {
80 fprintf(stderr, "%s: Could not send scan request!\n", __func__);
81 return -1;
82 }
83
84 *devices = NULL;
85 // receive device list
86 while (1) {
87 if (recv_buf_timeout(sfd, &pktlen, 4, MSG_PEEK, 500) == 4) {
88 if (pktlen != sizeof(dev_info_pkt)) {
89 // invalid packet size received!
90 fprintf(stderr, "%s: Invalid packet size (%d) received when expecting a device info record.\n", __func__, pktlen);
91 break;
92 }
93
94 recv_len = recv_buf(sfd, &dev_info_pkt, pktlen);
95 if (recv_len <= 0) {
96 fprintf(stderr, "%s: Error when receiving device info record\n", __func__);
97 break;
98 } else if (recv_len < pktlen) {
99 fprintf(stderr, "%s: received less data than specified in header!\n", __func__);
100 } else {
101 //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);
102 newlist = (usbmuxd_device_t*)realloc(*devices, sizeof(usbmuxd_device_t) * (dev_cnt+1));
103 if (newlist) {
104 memcpy(newlist+dev_cnt, &dev_info_pkt.device, sizeof(usbmuxd_device_t));
105 *devices = newlist;
106 dev_cnt++;
107 } else {
108 fprintf(stderr, "%s: ERROR: out of memory when trying to realloc!\n", __func__);
109 break;
110 }
111 }
112 } else {
113 // we _should_ have all of them now.
114 // or perhaps an error occured.
115 break;
116 }
117 }
118
119 // terminating zero record
120 newlist = (usbmuxd_device_t*)realloc(*devices, sizeof(usbmuxd_device_t) * (dev_cnt+1));
121 memset(newlist+dev_cnt, 0, sizeof(usbmuxd_device_t));
122 *devices = newlist;
123
124 return 0;
125}
126
127int usbmuxd_connect(uint32_t device_id, uint16_t port)
128{
129 int sfd;
130 struct usbmuxd_connect_request c_req;
131 int connected = 0;
132 uint32_t res = -1;
133
134 sfd = connect_unix_socket(USBMUXD_SOCKET_FILE);
135 if (sfd < 0) {
136 fprintf(stderr, "%s: Error: Connection to usbmuxd failed: %s\n", __func__, strerror(errno));
137 return sfd;
138 }
139
140 c_req.header.length = sizeof(c_req);
141 c_req.header.reserved = 0;
142 c_req.header.type = USBMUXD_CONNECT;
143 c_req.header.tag = 3;
144 c_req.device_id = device_id;
145 c_req.tcp_dport = htons(port);
146 c_req.reserved = 0;
147
148 if (send_buf(sfd, &c_req, sizeof(c_req)) < 0) {
149 perror("send");
150 } else {
151 // read ACK
152 fprintf(stderr, "%s: Reading connect result...\n", __func__);
153 if (usbmuxd_get_result(sfd, c_req.header.tag, &res)) {
154 if (res == 0) {
155 fprintf(stderr, "%s: Connect success!\n", __func__);
156 connected = 1;
157 } else {
158 fprintf(stderr, "%s: Connect failed, Error code=%d\n", __func__, res);
159 }
160 }
161 }
162
163 if (connected) {
164 return sfd;
165 }
166
167 close(sfd);
168
169 return -1;
170}