summaryrefslogtreecommitdiffstats
path: root/daemon
diff options
context:
space:
mode:
Diffstat (limited to 'daemon')
-rw-r--r--daemon/CMakeLists.txt6
-rw-r--r--daemon/client.c198
2 files changed, 191 insertions, 13 deletions
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) {