summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt17
-rw-r--r--daemon/CMakeLists.txt6
-rw-r--r--daemon/client.c198
-rw-r--r--libusbmuxd/CMakeLists.txt6
-rw-r--r--libusbmuxd/libusbmuxd.c201
-rw-r--r--libusbmuxd/usbmuxd-proto.h2
6 files changed, 402 insertions, 28 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5f0a6a8..93fa715 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -25,6 +25,23 @@ if(CMAKE_C_FLAGS STREQUAL "")
25 set(CMAKE_C_FLAGS "-O2") 25 set(CMAKE_C_FLAGS "-O2")
26endif() 26endif()
27 27
28option(WANT_PLIST "Build with protocol version 1 support using libplist" ON)
29
30set(OPT_INCLUDES "")
31set(OPT_LIBS "")
32if(WANT_PLIST)
33 find_package(PLIST)
34 if(PLIST_FOUND)
35 set(HAVE_PLIST ON)
36 set(OPT_INCLUDES ${OPT_INCLUDES} ${PLIST_INCLUDE_DIRS})
37 set(OPT_LIBS ${OPT_LIBS} ${PLIST_LIBRARIES})
38 else()
39 message("* NOTE: libplist was not found!")
40 message("* libusbmuxd/usbmuxd will be build WITHOUT support for version 1")
41 message("* of the usbmux protocol (plist based).")
42 endif()
43endif()
44
28option(WITH_USBMUXD "Build usbmux daemon (usbmuxd)" ON) 45option(WITH_USBMUXD "Build usbmux daemon (usbmuxd)" ON)
29if(WIN32 AND WITH_USBMUXD) 46if(WIN32 AND WITH_USBMUXD)
30 message("** NOTE: usbmuxd cannot be built on WIN32 due to missing libusb-1.0 support!") 47 message("** NOTE: usbmuxd cannot be built on WIN32 due to missing libusb-1.0 support!")
diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt
index 6593deb..48ff0c6 100644
--- a/daemon/CMakeLists.txt
+++ b/daemon/CMakeLists.txt
@@ -1,7 +1,9 @@
1find_package(USB REQUIRED) 1find_package(USB REQUIRED)
2include_directories(${USB_INCLUDE_DIRS}) 2include_directories(${USB_INCLUDE_DIRS})
3set(LIBS ${LIBS} ${USB_LIBRARIES}) 3set(LIBS ${LIBS} ${USB_LIBRARIES} ${OPT_LIBS})
4 4if(HAVE_PLIST)
5 message("-- usbmuxd will be built with protocol version 1 support")
6endif()
5include_directories (${CMAKE_SOURCE_DIR}/common) 7include_directories (${CMAKE_SOURCE_DIR}/common)
6include_directories (${CMAKE_SOURCE_DIR}/daemon) 8include_directories (${CMAKE_SOURCE_DIR}/daemon)
7include_directories (${CMAKE_SOURCE_DIR}/libusbmuxd) 9include_directories (${CMAKE_SOURCE_DIR}/libusbmuxd)
diff --git a/daemon/client.c b/daemon/client.c
index 194632d..80bc0c7 100644
--- a/daemon/client.c
+++ b/daemon/client.c
@@ -32,12 +32,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32#include <sys/un.h> 32#include <sys/un.h>
33#include <arpa/inet.h> 33#include <arpa/inet.h>
34 34
35#ifdef HAVE_PLIST
36#include <plist/plist.h>
37#endif
38
35#include "log.h" 39#include "log.h"
36#include "usb.h" 40#include "usb.h"
37#include "client.h" 41#include "client.h"
38#include "device.h" 42#include "device.h"
39 43
44#ifdef HAVE_PLIST
45#define CMD_BUF_SIZE 1024
46#else
40#define CMD_BUF_SIZE 256 47#define CMD_BUF_SIZE 256
48#endif
41#define REPLY_BUF_SIZE 1024 49#define REPLY_BUF_SIZE 1024
42 50
43enum client_state { 51enum client_state {
@@ -61,6 +69,7 @@ struct mux_client {
61 uint32_t connect_tag; 69 uint32_t connect_tag;
62 int connect_device; 70 int connect_device;
63 enum client_state state; 71 enum client_state state;
72 uint32_t proto_version;
64}; 73};
65 74
66static struct collection client_list; 75static struct collection client_list;
@@ -155,7 +164,7 @@ void client_get_fds(struct fdlist *list)
155static int send_pkt(struct mux_client *client, uint32_t tag, enum usbmuxd_msgtype msg, void *payload, int payload_length) 164static int send_pkt(struct mux_client *client, uint32_t tag, enum usbmuxd_msgtype msg, void *payload, int payload_length)
156{ 165{
157 struct usbmuxd_header hdr; 166 struct usbmuxd_header hdr;
158 hdr.version = USBMUXD_PROTOCOL_VERSION; 167 hdr.version = client->proto_version;
159 hdr.length = sizeof(hdr) + payload_length; 168 hdr.length = sizeof(hdr) + payload_length;
160 hdr.message = msg; 169 hdr.message = msg;
161 hdr.tag = tag; 170 hdr.tag = tag;
@@ -175,7 +184,30 @@ static int send_pkt(struct mux_client *client, uint32_t tag, enum usbmuxd_msgtyp
175 184
176static int send_result(struct mux_client *client, uint32_t tag, uint32_t result) 185static int send_result(struct mux_client *client, uint32_t tag, uint32_t result)
177{ 186{
178 return send_pkt(client, tag, MESSAGE_RESULT, &result, sizeof(uint32_t)); 187 int res = -1;
188#ifdef HAVE_PLIST
189 if (client->proto_version == 1) {
190 /* XML plist packet */
191 char *xml = NULL;
192 uint32_t xmlsize = 0;
193 plist_t dict = plist_new_dict();
194 plist_dict_insert_item(dict, "MessageType", plist_new_string("Result"));
195 plist_dict_insert_item(dict, "Number", plist_new_uint(result));
196 plist_to_xml(dict, &xml, &xmlsize);
197 plist_free(dict);
198 if (xml) {
199 res = send_pkt(client, tag, MESSAGE_PLIST, xml, xmlsize);
200 free(xml);
201 } else {
202 usbmuxd_log(LL_ERROR, "%s: Could not convert plist to xml", __func__);
203 }
204 } else
205#endif
206 {
207 /* binary packet */
208 res = send_pkt(client, tag, MESSAGE_RESULT, &result, sizeof(uint32_t));
209 }
210 return res;
179} 211}
180 212
181int client_notify_connect(struct mux_client *client, enum usbmuxd_result result) 213int client_notify_connect(struct mux_client *client, enum usbmuxd_result result)
@@ -203,19 +235,73 @@ int client_notify_connect(struct mux_client *client, enum usbmuxd_result result)
203 235
204static int notify_device_add(struct mux_client *client, struct device_info *dev) 236static int notify_device_add(struct mux_client *client, struct device_info *dev)
205{ 237{
206 struct usbmuxd_device_record dmsg; 238 int res = -1;
207 memset(&dmsg, 0, sizeof(dmsg)); 239#ifdef HAVE_PLIST
208 dmsg.device_id = dev->id; 240 if (client->proto_version == 1) {
209 strncpy(dmsg.serial_number, dev->serial, 256); 241 /* XML plist packet */
210 dmsg.serial_number[255] = 0; 242 char *xml = NULL;
211 dmsg.location = dev->location; 243 uint32_t xmlsize = 0;
212 dmsg.product_id = dev->pid; 244 plist_t dict = plist_new_dict();
213 return send_pkt(client, 0, MESSAGE_DEVICE_ADD, &dmsg, sizeof(dmsg)); 245 plist_dict_insert_item(dict, "MessageType", plist_new_string("Attached"));
246 plist_t props = plist_new_dict();
247 // TODO: get current usb speed
248 plist_dict_insert_item(props, "ConnectionSpeed", plist_new_uint(480000000));
249 plist_dict_insert_item(props, "ConnectionType", plist_new_string("USB"));
250 plist_dict_insert_item(props, "DeviceID", plist_new_uint(dev->id));
251 plist_dict_insert_item(props, "LocationID", plist_new_uint(dev->location));
252 plist_dict_insert_item(props, "ProductID", plist_new_uint(dev->pid));
253 plist_dict_insert_item(props, "SerialNumber", plist_new_string(dev->serial));
254 plist_dict_insert_item(dict, "Properties", props);
255 plist_to_xml(dict, &xml, &xmlsize);
256 plist_free(dict);
257 if (xml) {
258 res = send_pkt(client, 0, MESSAGE_PLIST, xml, xmlsize);
259 free(xml);
260 } else {
261 usbmuxd_log(LL_ERROR, "%s: Could not convert plist to xml", __func__);
262 }
263 } else
264#endif
265 {
266 /* binary packet */
267 struct usbmuxd_device_record dmsg;
268 memset(&dmsg, 0, sizeof(dmsg));
269 dmsg.device_id = dev->id;
270 strncpy(dmsg.serial_number, dev->serial, 256);
271 dmsg.serial_number[255] = 0;
272 dmsg.location = dev->location;
273 dmsg.product_id = dev->pid;
274 res = send_pkt(client, 0, MESSAGE_DEVICE_ADD, &dmsg, sizeof(dmsg));
275 }
276 return res;
214} 277}
215 278
216static int notify_device_remove(struct mux_client *client, uint32_t device_id) 279static int notify_device_remove(struct mux_client *client, uint32_t device_id)
217{ 280{
218 return send_pkt(client, 0, MESSAGE_DEVICE_REMOVE, &device_id, sizeof(uint32_t)); 281 int res = -1;
282#ifdef HAVE_PLIST
283 if (client->proto_version == 1) {
284 /* XML plist packet */
285 char *xml = NULL;
286 uint32_t xmlsize = 0;
287 plist_t dict = plist_new_dict();
288 plist_dict_insert_item(dict, "MessageType", plist_new_string("Detached"));
289 plist_dict_insert_item(dict, "DeviceID", plist_new_uint(device_id));
290 plist_to_xml(dict, &xml, &xmlsize);
291 plist_free(dict);
292 if (xml) {
293 res = send_pkt(client, 0, MESSAGE_PLIST, xml, xmlsize);
294 free(xml);
295 } else {
296 usbmuxd_log(LL_ERROR, "%s: Could not convert plist to xml", __func__);
297 }
298 } else
299#endif
300 {
301 /* binary packet */
302 res = send_pkt(client, 0, MESSAGE_DEVICE_REMOVE, &device_id, sizeof(uint32_t));
303 }
304 return res;
219} 305}
220 306
221static int start_listen(struct mux_client *client) 307static int start_listen(struct mux_client *client)
@@ -263,7 +349,92 @@ static int client_command(struct mux_client *client, struct usbmuxd_header *hdr)
263 } 349 }
264 350
265 struct usbmuxd_connect_request *ch; 351 struct usbmuxd_connect_request *ch;
352#ifdef HAVE_PLIST
353 char *payload;
354 uint32_t payload_size;
355#endif
356
266 switch(hdr->message) { 357 switch(hdr->message) {
358#ifdef HAVE_PLIST
359 case MESSAGE_PLIST:
360 client->proto_version = 1;
361 payload = (char*)(hdr) + sizeof(struct usbmuxd_header);
362 payload_size = hdr->length - sizeof(struct usbmuxd_header);
363 plist_t dict = NULL;
364 plist_from_xml(payload, payload_size, &dict);
365 if (!dict) {
366 usbmuxd_log(LL_ERROR, "Could not parse plist from payload!");
367 return -1;
368 } else {
369 char *message = NULL;
370 plist_t node = plist_dict_get_item(dict, "MessageType");
371 plist_get_string_val(node, &message);
372 if (!message) {
373 usbmuxd_log(LL_ERROR, "Could not extract MessageType from plist!");
374 plist_free(dict);
375 return -1;
376 }
377 if (!strcmp(message, "Listen")) {
378 free(message);
379 plist_free(dict);
380 if (send_result(client, hdr->tag, 0) < 0)
381 return -1;
382 usbmuxd_log(LL_DEBUG, "Client %d now LISTENING", client->fd);
383 return start_listen(client);
384 } else if (!strcmp(message, "Connect")) {
385 uint64_t val;
386 uint16_t portnum = 0;
387 uint32_t device_id = 0;
388 free(message);
389 // get device id
390 node = plist_dict_get_item(dict, "DeviceID");
391 if (!node) {
392 usbmuxd_log(LL_ERROR, "Received connect request without device_id!");
393 plist_free(dict);
394 if (send_result(client, hdr->tag, RESULT_BADDEV) < 0)
395 return -1;
396 return 0;
397 }
398 val = 0;
399 plist_get_uint_val(node, &val);
400 device_id = (uint32_t)val;
401
402 // get port number
403 node = plist_dict_get_item(dict, "PortNumber");
404 if (!node) {
405 usbmuxd_log(LL_ERROR, "Received connect request without port number!");
406 plist_free(dict);
407 if (send_result(client, hdr->tag, RESULT_BADCOMMAND) < 0)
408 return -1;
409 return 0;
410 }
411 val = 0;
412 plist_get_uint_val(node, &val);
413 portnum = (uint16_t)val;
414
415 usbmuxd_log(LL_DEBUG, "Client %d connection request to device %d port %d", client->fd, device_id, ntohs(portnum));
416 res = device_start_connect(device_id, ntohs(portnum), client);
417 if(res < 0) {
418 if (send_result(client, hdr->tag, -res) < 0)
419 return -1;
420 } else {
421 client->connect_tag = hdr->tag;
422 client->connect_device = device_id;
423 client->state = CLIENT_CONNECTING1;
424 }
425 return 0;
426 } else {
427 usbmuxd_log(LL_ERROR, "Unexpected command '%s' received!", message);
428 free(message);
429 plist_free(dict);
430 if (send_result(client, hdr->tag, RESULT_BADCOMMAND) < 0)
431 return -1;
432 return 0;
433 }
434 }
435 // should not be reached?!
436 return -1;
437#endif
267 case MESSAGE_LISTEN: 438 case MESSAGE_LISTEN:
268 if(send_result(client, hdr->tag, 0) < 0) 439 if(send_result(client, hdr->tag, 0) < 0)
269 return -1; 440 return -1;
@@ -341,8 +512,13 @@ static void process_recv(struct mux_client *client)
341 did_read = 1; 512 did_read = 1;
342 } 513 }
343 struct usbmuxd_header *hdr = (void*)client->ib_buf; 514 struct usbmuxd_header *hdr = (void*)client->ib_buf;
515#ifdef HAVE_PLIST
516 if((hdr->version != 0) && (hdr->version != 1)) {
517 usbmuxd_log(LL_INFO, "Client %d version mismatch: expected 0 or 1, got %d", client->fd, hdr->version);
518#else
344 if(hdr->version != USBMUXD_PROTOCOL_VERSION) { 519 if(hdr->version != USBMUXD_PROTOCOL_VERSION) {
345 usbmuxd_log(LL_INFO, "Client %d version mismatch: expected %d, got %d", client->fd, USBMUXD_PROTOCOL_VERSION, hdr->version); 520 usbmuxd_log(LL_INFO, "Client %d version mismatch: expected %d, got %d", client->fd, USBMUXD_PROTOCOL_VERSION, hdr->version);
521#endif
346 client_close(client); 522 client_close(client);
347 } 523 }
348 if(hdr->length > client->ib_capacity) { 524 if(hdr->length > client->ib_capacity) {
diff --git a/libusbmuxd/CMakeLists.txt b/libusbmuxd/CMakeLists.txt
index d275169..236cca3 100644
--- a/libusbmuxd/CMakeLists.txt
+++ b/libusbmuxd/CMakeLists.txt
@@ -3,7 +3,11 @@ find_package(Threads)
3 3
4add_library (libusbmuxd SHARED libusbmuxd.c sock_stuff.c ${CMAKE_SOURCE_DIR}/common/utils.c) 4add_library (libusbmuxd SHARED libusbmuxd.c sock_stuff.c ${CMAKE_SOURCE_DIR}/common/utils.c)
5find_library (PTHREAD pthread) 5find_library (PTHREAD pthread)
6target_link_libraries (libusbmuxd ${CMAKE_THREAD_LIBS_INIT}) 6
7if (HAVE_PLIST)
8 message("-- libusbmuxd will be built with protocol version 1 support")
9endif()
10target_link_libraries (libusbmuxd ${CMAKE_THREAD_LIBS_INIT} ${OPT_LIBS})
7 11
8# 'lib' is a UNIXism, the proper CMake target is usbmuxd 12# 'lib' is a UNIXism, the proper CMake target is usbmuxd
9# But we can't use that due to the conflict with the usbmuxd daemon, 13# But we can't use that due to the conflict with the usbmuxd daemon,
diff --git a/libusbmuxd/libusbmuxd.c b/libusbmuxd/libusbmuxd.c
index f5e5d1b..f465deb 100644
--- a/libusbmuxd/libusbmuxd.c
+++ b/libusbmuxd/libusbmuxd.c
@@ -32,6 +32,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32#include <signal.h> 32#include <signal.h>
33#include <pthread.h> 33#include <pthread.h>
34 34
35#ifdef HAVE_PLIST
36#include <plist/plist.h>
37#define PLIST_BUNDLE_ID "com.marcansoft.usbmuxd"
38#define PLIST_CLIENT_VERSION_STRING "usbmuxd built for freedom"
39#define PLIST_PROGNAME "libusbmuxd"
40#endif
41
35// usbmuxd public interface 42// usbmuxd public interface
36#include "usbmuxd.h" 43#include "usbmuxd.h"
37// usbmuxd protocol 44// usbmuxd protocol
@@ -47,6 +54,7 @@ pthread_t devmon;
47static int listenfd = -1; 54static int listenfd = -1;
48 55
49static int use_tag = 0; 56static int use_tag = 0;
57static int proto_version = 0;
50 58
51/** 59/**
52 * Finds a device info record by its handle. 60 * Finds a device info record by its handle.
@@ -104,7 +112,95 @@ static int receive_packet(int sfd, struct usbmuxd_header *header, void **payload
104 } 112 }
105 } 113 }
106 114
107 *payload = payload_loc; 115#ifdef HAVE_PLIST
116 if (hdr.message == MESSAGE_PLIST) {
117 char *message = NULL;
118 plist_t plist = NULL;
119 plist_from_xml(payload_loc, payload_size, &plist);
120 free(payload_loc);
121
122 if (!plist) {
123 fprintf(stderr, "%s: Error getting plist from payload!\n", __func__);
124 return -EBADMSG;
125 }
126
127 plist_t node = plist_dict_get_item(plist, "MessageType");
128 if (plist_get_node_type(node) != PLIST_STRING) {
129 fprintf(stderr, "%s: Error getting message type from plist!\n", __func__);
130 free(plist);
131 return -EBADMSG;
132 }
133
134 plist_get_string_val(node, &message);
135 if (message) {
136 uint64_t val = 0;
137 if (strcmp(message, "Result") == 0) {
138 /* result message */
139 uint32_t dwval = 0;
140 plist_t n = plist_dict_get_item(plist, "Number");
141 plist_get_uint_val(n, &val);
142 *payload = malloc(sizeof(uint32_t));
143 dwval = val;
144 memcpy(*payload, &dwval, sizeof(dwval));
145 hdr.length = sizeof(hdr) + sizeof(dwval);
146 hdr.message = MESSAGE_RESULT;
147 } else if (strcmp(message, "Attached") == 0) {
148 /* device add message */
149 struct usbmuxd_device_record *dev = NULL;
150 plist_t props = plist_dict_get_item(plist, "Properties");
151 if (!props) {
152 fprintf(stderr, "%s: Could not get properties for message '%s' from plist!\n", __func__, message);
153 plist_free(plist);
154 return -EBADMSG;
155 }
156 dev = (struct usbmuxd_device_record*)malloc(sizeof(struct usbmuxd_device_record));
157 memset(dev, 0, sizeof(struct usbmuxd_device_record));
158
159 plist_t n = plist_dict_get_item(props, "DeviceID");
160 plist_get_uint_val(n, &val);
161 dev->device_id = (uint32_t)val;
162
163 n = plist_dict_get_item(props, "ProductID");
164 plist_get_uint_val(n, &val);
165 dev->product_id = (uint32_t)val;
166
167 n = plist_dict_get_item(props, "SerialNumber");
168 char *strval = NULL;
169 plist_get_string_val(n, &strval);
170 if (strval) {
171 strcpy(dev->serial_number, strval);
172 free(strval);
173 }
174 n = plist_dict_get_item(props, "LocationID");
175 plist_get_uint_val(n, &val);
176 dev->location = (uint32_t)val;
177 *payload = (void*)dev;
178 hdr.length = sizeof(hdr) + sizeof(struct usbmuxd_device_record);
179 hdr.message = MESSAGE_DEVICE_ADD;
180 } else if (strcmp(message, "Detached") == 0) {
181 /* device remove message */
182 uint32_t dwval = 0;
183 plist_t n = plist_dict_get_item(plist, "DeviceID");
184 if (n) {
185 plist_get_uint_val(n, &val);
186 *payload = malloc(sizeof(uint32_t));
187 dwval = val;
188 memcpy(*payload, &dwval, sizeof(dwval));
189 hdr.length = sizeof(hdr) + sizeof(dwval);
190 hdr.message = MESSAGE_DEVICE_REMOVE;
191 }
192 } else {
193 fprintf(stderr, "%s: Unexpected message '%s' in plist!\n", __func__, message);
194 plist_free(plist);
195 return -EBADMSG;
196 }
197 }
198 plist_free(plist);
199 } else
200#endif
201 {
202 *payload = payload_loc;
203 }
108 204
109 memcpy(header, &hdr, sizeof(hdr)); 205 memcpy(header, &hdr, sizeof(hdr));
110 206
@@ -159,7 +255,7 @@ static int send_packet(int sfd, uint32_t message, uint32_t tag, void *payload, u
159 struct usbmuxd_header header; 255 struct usbmuxd_header header;
160 256
161 header.length = sizeof(struct usbmuxd_header); 257 header.length = sizeof(struct usbmuxd_header);
162 header.version = USBMUXD_PROTOCOL_VERSION; 258 header.version = proto_version;
163 header.message = message; 259 header.message = message;
164 header.tag = tag; 260 header.tag = tag;
165 if (payload && (payload_size > 0)) { 261 if (payload && (payload_size > 0)) {
@@ -183,23 +279,74 @@ static int send_packet(int sfd, uint32_t message, uint32_t tag, void *payload, u
183 279
184static int send_listen_packet(int sfd, uint32_t tag) 280static int send_listen_packet(int sfd, uint32_t tag)
185{ 281{
186 return send_packet(sfd, MESSAGE_LISTEN, tag, NULL, 0); 282 int res = 0;
283#ifdef HAVE_PLIST
284 if (proto_version == 1) {
285 /* plist packet */
286 char *payload = NULL;
287 uint32_t payload_size = 0;
288 plist_t plist;
289
290 /* construct message plist */
291 plist = plist_new_dict();
292 plist_dict_insert_item(plist, "BundleID", plist_new_string(PLIST_BUNDLE_ID));
293 plist_dict_insert_item(plist, "ClientVersionString", plist_new_string(PLIST_CLIENT_VERSION_STRING));
294 plist_dict_insert_item(plist, "MessageType", plist_new_string("Listen"));
295 plist_dict_insert_item(plist, "ProgName", plist_new_string(PLIST_PROGNAME));
296 plist_to_xml(plist, &payload, &payload_size);
297 plist_free(plist);
298
299 res = send_packet(sfd, MESSAGE_PLIST, tag, payload, payload_size);
300 free(payload);
301 } else
302#endif
303 {
304 /* binary packet */
305 res = send_packet(sfd, MESSAGE_LISTEN, tag, NULL, 0);
306 }
307 return res;
187} 308}
188 309
189static int send_connect_packet(int sfd, uint32_t tag, uint32_t device_id, uint16_t port) 310static int send_connect_packet(int sfd, uint32_t tag, uint32_t device_id, uint16_t port)
190{ 311{
191 struct { 312 int res = 0;
192 uint32_t device_id; 313#ifdef HAVE_PLIST
193 uint16_t port; 314 if (proto_version == 1) {
194 uint16_t reserved; 315 /* plist packet */
195 } conninfo; 316 char *payload = NULL;
196 317 uint32_t payload_size = 0;
197 conninfo.device_id = device_id; 318 plist_t plist;
198 conninfo.port = htons(port); 319
199 conninfo.reserved = 0; 320 /* construct message plist */
321 plist = plist_new_dict();
322 plist_dict_insert_item(plist, "BundleID", plist_new_string(PLIST_BUNDLE_ID));
323 plist_dict_insert_item(plist, "ClientVersionString", plist_new_string(PLIST_CLIENT_VERSION_STRING));
324 plist_dict_insert_item(plist, "MessageType", plist_new_string("Connect"));
325 plist_dict_insert_item(plist, "DeviceID", plist_new_uint(device_id));
326 plist_dict_insert_item(plist, "PortNumber", plist_new_uint(port));
327 plist_dict_insert_item(plist, "ProgName", plist_new_string(PLIST_PROGNAME));
328 plist_to_xml(plist, &payload, &payload_size);
329 plist_free(plist);
330
331 res = send_packet(sfd, MESSAGE_PLIST, tag, (void*)payload, payload_size);
332 free(payload);
333 } else
334#endif
335 {
336 /* binary packet */
337 struct {
338 uint32_t device_id;
339 uint16_t port;
340 uint16_t reserved;
341 } conninfo;
200 342
201 return send_packet(sfd, MESSAGE_CONNECT, tag, &conninfo, sizeof(conninfo)); 343 conninfo.device_id = device_id;
344 conninfo.port = htons(port);
345 conninfo.reserved = 0;
202 346
347 res = send_packet(sfd, MESSAGE_CONNECT, tag, &conninfo, sizeof(conninfo));
348 }
349 return res;
203} 350}
204 351
205/** 352/**
@@ -231,6 +378,9 @@ static int usbmuxd_listen()
231 int sfd; 378 int sfd;
232 uint32_t res = -1; 379 uint32_t res = -1;
233 380
381#ifdef HAVE_PLIST
382retry:
383#endif
234 sfd = connect_usbmuxd_socket(); 384 sfd = connect_usbmuxd_socket();
235 if (sfd < 0) { 385 if (sfd < 0) {
236 while (event_cb) { 386 while (event_cb) {
@@ -254,6 +404,12 @@ static int usbmuxd_listen()
254 } 404 }
255 if (usbmuxd_get_result(sfd, use_tag, &res) && (res != 0)) { 405 if (usbmuxd_get_result(sfd, use_tag, &res) && (res != 0)) {
256 close(sfd); 406 close(sfd);
407#ifdef HAVE_PLIST
408 if ((res == RESULT_BADVERSION) && (proto_version != 1)) {
409 proto_version = 1;
410 goto retry;
411 }
412#endif
257 fprintf(stderr, "%s: ERROR: did not get OK but %d\n", __func__, res); 413 fprintf(stderr, "%s: ERROR: did not get OK but %d\n", __func__, res);
258 return -1; 414 return -1;
259 } 415 }
@@ -396,6 +552,9 @@ int usbmuxd_get_device_list(usbmuxd_device_info_t **device_list)
396 int dev_cnt = 0; 552 int dev_cnt = 0;
397 void *payload = NULL; 553 void *payload = NULL;
398 554
555#ifdef HAVE_PLIST
556retry:
557#endif
399 sfd = connect_usbmuxd_socket(); 558 sfd = connect_usbmuxd_socket();
400 if (sfd < 0) { 559 if (sfd < 0) {
401 fprintf(stderr, "%s: error opening socket!\n", __func__); 560 fprintf(stderr, "%s: error opening socket!\n", __func__);
@@ -410,6 +569,12 @@ int usbmuxd_get_device_list(usbmuxd_device_info_t **device_list)
410 listen_success = 1; 569 listen_success = 1;
411 } else { 570 } else {
412 close(sfd); 571 close(sfd);
572#ifdef HAVE_PLIST
573 if ((res == RESULT_BADVERSION) && (proto_version != 1)) {
574 proto_version = 1;
575 goto retry;
576 }
577#endif
413 fprintf(stderr, 578 fprintf(stderr,
414 "%s: Did not get response to scan request (with result=0)...\n", 579 "%s: Did not get response to scan request (with result=0)...\n",
415 __func__); 580 __func__);
@@ -521,6 +686,9 @@ int usbmuxd_connect(const int handle, const unsigned short port)
521 int connected = 0; 686 int connected = 0;
522 uint32_t res = -1; 687 uint32_t res = -1;
523 688
689#ifdef HAVE_PLIST
690retry:
691#endif
524 sfd = connect_usbmuxd_socket(); 692 sfd = connect_usbmuxd_socket();
525 if (sfd < 0) { 693 if (sfd < 0) {
526 fprintf(stderr, "%s: Error: Connection to usbmuxd failed: %s\n", 694 fprintf(stderr, "%s: Error: Connection to usbmuxd failed: %s\n",
@@ -539,6 +707,13 @@ int usbmuxd_connect(const int handle, const unsigned short port)
539 //fprintf(stderr, "%s: Connect success!\n", __func__); 707 //fprintf(stderr, "%s: Connect success!\n", __func__);
540 connected = 1; 708 connected = 1;
541 } else { 709 } else {
710#ifdef HAVE_PLIST
711 if ((res == RESULT_BADVERSION) && (proto_version == 0)) {
712 proto_version = 1;
713 close(sfd);
714 goto retry;
715 }
716#endif
542 fprintf(stderr, "%s: Connect failed, Error code=%d\n", 717 fprintf(stderr, "%s: Connect failed, Error code=%d\n",
543 __func__, res); 718 __func__, res);
544 } 719 }
diff --git a/libusbmuxd/usbmuxd-proto.h b/libusbmuxd/usbmuxd-proto.h
index 0d4596c..11dd3cf 100644
--- a/libusbmuxd/usbmuxd-proto.h
+++ b/libusbmuxd/usbmuxd-proto.h
@@ -52,7 +52,7 @@ enum usbmuxd_msgtype {
52 MESSAGE_DEVICE_REMOVE = 5, 52 MESSAGE_DEVICE_REMOVE = 5,
53 //??? 53 //???
54 //??? 54 //???
55 //MESSAGE_PLIST = 8, 55 MESSAGE_PLIST = 8,
56}; 56};
57 57
58struct usbmuxd_header { 58struct usbmuxd_header {