diff options
| author | 2010-05-24 18:57:10 +0200 | |
|---|---|---|
| committer | 2010-05-26 01:39:28 +0200 | |
| commit | 6cb505257ff848aa7ead80b60b575effc3a915fa (patch) | |
| tree | 941978b9186158ea2775f50c5929f9e8b88764be /daemon | |
| parent | 847eaeba69de3b22e5d65b3a98311655876df80e (diff) | |
| download | usbmuxd-6cb505257ff848aa7ead80b60b575effc3a915fa.tar.gz usbmuxd-6cb505257ff848aa7ead80b60b575effc3a915fa.tar.bz2 | |
Add protocol version 1 (plist based) support using libplist
Diffstat (limited to 'daemon')
| -rw-r--r-- | daemon/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | daemon/client.c | 198 |
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 @@ | |||
| 1 | find_package(USB REQUIRED) | 1 | find_package(USB REQUIRED) |
| 2 | include_directories(${USB_INCLUDE_DIRS}) | 2 | include_directories(${USB_INCLUDE_DIRS}) |
| 3 | set(LIBS ${LIBS} ${USB_LIBRARIES}) | 3 | set(LIBS ${LIBS} ${USB_LIBRARIES} ${OPT_LIBS}) |
| 4 | 4 | if(HAVE_PLIST) | |
| 5 | message("-- usbmuxd will be built with protocol version 1 support") | ||
| 6 | endif() | ||
| 5 | include_directories (${CMAKE_SOURCE_DIR}/common) | 7 | include_directories (${CMAKE_SOURCE_DIR}/common) |
| 6 | include_directories (${CMAKE_SOURCE_DIR}/daemon) | 8 | include_directories (${CMAKE_SOURCE_DIR}/daemon) |
| 7 | include_directories (${CMAKE_SOURCE_DIR}/libusbmuxd) | 9 | include_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 | ||
| 43 | enum client_state { | 51 | enum 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 | ||
| 66 | static struct collection client_list; | 75 | static struct collection client_list; |
| @@ -155,7 +164,7 @@ void client_get_fds(struct fdlist *list) | |||
| 155 | static int send_pkt(struct mux_client *client, uint32_t tag, enum usbmuxd_msgtype msg, void *payload, int payload_length) | 164 | static 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 | ||
| 176 | static int send_result(struct mux_client *client, uint32_t tag, uint32_t result) | 185 | static 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 | ||
| 181 | int client_notify_connect(struct mux_client *client, enum usbmuxd_result result) | 213 | int 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 | ||
| 204 | static int notify_device_add(struct mux_client *client, struct device_info *dev) | 236 | static 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 | ||
| 216 | static int notify_device_remove(struct mux_client *client, uint32_t device_id) | 279 | static 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 | ||
| 221 | static int start_listen(struct mux_client *client) | 307 | static 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) { |
