diff options
| author | 2019-11-07 23:25:55 +0100 | |
|---|---|---|
| committer | 2019-11-07 23:25:55 +0100 | |
| commit | 5390060ec90bed0f565698a389cebc57c09c3ac8 (patch) | |
| tree | a73a3306a5a0449c7bf7cbe555dcaf2771ebda1c | |
| parent | 8872aec759699411be45a17798dab40b9539c2ae (diff) | |
| download | libimobiledevice-5390060ec90bed0f565698a389cebc57c09c3ac8.tar.gz libimobiledevice-5390060ec90bed0f565698a389cebc57c09c3ac8.tar.bz2 | |
Add propert support for network (WiFi) devices via new idevice_new_with_options()
| -rw-r--r-- | include/libimobiledevice/libimobiledevice.h | 56 | ||||
| -rw-r--r-- | src/idevice.c | 92 | ||||
| -rw-r--r-- | src/idevice.h | 8 |
3 files changed, 124 insertions, 32 deletions
diff --git a/include/libimobiledevice/libimobiledevice.h b/include/libimobiledevice/libimobiledevice.h index 8f8589d..c1d5460 100644 --- a/include/libimobiledevice/libimobiledevice.h +++ b/include/libimobiledevice/libimobiledevice.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | * @brief Device/Connection handling and communication | 3 | * @brief Device/Connection handling and communication |
| 4 | * \internal | 4 | * \internal |
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2010-2019 Nikias Bassen All Rights Reserved. | ||
| 6 | * Copyright (c) 2010-2014 Martin Szulecki All Rights Reserved. | 7 | * Copyright (c) 2010-2014 Martin Szulecki All Rights Reserved. |
| 7 | * Copyright (c) 2014 Christophe Fergeau All Rights Reserved. | 8 | * Copyright (c) 2014 Christophe Fergeau All Rights Reserved. |
| 8 | * Copyright (c) 2008 Jonathan Beck All Rights Reserved. | 9 | * Copyright (c) 2008 Jonathan Beck All Rights Reserved. |
| @@ -51,6 +52,26 @@ typedef idevice_private *idevice_t; /**< The device handle. */ | |||
| 51 | typedef struct idevice_connection_private idevice_connection_private; | 52 | typedef struct idevice_connection_private idevice_connection_private; |
| 52 | typedef idevice_connection_private *idevice_connection_t; /**< The connection handle. */ | 53 | typedef idevice_connection_private *idevice_connection_t; /**< The connection handle. */ |
| 53 | 54 | ||
| 55 | /** Options for idevice_new_with_options() */ | ||
| 56 | enum idevice_options { | ||
| 57 | IDEVICE_LOOKUP_USBMUX = 1 << 1, /**< include USBMUX devices during lookup */ | ||
| 58 | IDEVICE_LOOKUP_NETWORK = 1 << 2, /**< include network devices during lookup */ | ||
| 59 | IDEVICE_LOOKUP_PREFER_NETWORK = 1 << 3 /**< prefer network connection if device is available via USBMUX *and* network */ | ||
| 60 | }; | ||
| 61 | |||
| 62 | /** Type of connection a device is available on */ | ||
| 63 | enum idevice_connection_type { | ||
| 64 | CONNECTION_USBMUXD = 1, | ||
| 65 | CONNECTION_NETWORK | ||
| 66 | }; | ||
| 67 | |||
| 68 | struct idevice_info { | ||
| 69 | char *udid; | ||
| 70 | enum idevice_connection_type conn_type; | ||
| 71 | void* conn_data; | ||
| 72 | }; | ||
| 73 | typedef struct idevice_info* idevice_info_t; | ||
| 74 | |||
| 54 | /* discovery (events/asynchronous) */ | 75 | /* discovery (events/asynchronous) */ |
| 55 | /** The event type for device add or removal */ | 76 | /** The event type for device add or removal */ |
| 56 | enum idevice_event_type { | 77 | enum idevice_event_type { |
| @@ -64,7 +85,7 @@ enum idevice_event_type { | |||
| 64 | typedef struct { | 85 | typedef struct { |
| 65 | enum idevice_event_type event; /**< The event type. */ | 86 | enum idevice_event_type event; /**< The event type. */ |
| 66 | const char *udid; /**< The device unique id. */ | 87 | const char *udid; /**< The device unique id. */ |
| 67 | int conn_type; /**< The connection type. Currently only 1 for usbmuxd. */ | 88 | enum idevice_connection_type conn_type; /**< The connection type. */ |
| 68 | } idevice_event_t; | 89 | } idevice_event_t; |
| 69 | 90 | ||
| 70 | /* event callback function prototype */ | 91 | /* event callback function prototype */ |
| @@ -125,11 +146,15 @@ idevice_error_t idevice_device_list_free(char **devices); | |||
| 125 | /* device structure creation and destruction */ | 146 | /* device structure creation and destruction */ |
| 126 | 147 | ||
| 127 | /** | 148 | /** |
| 128 | * Creates an idevice_t structure for the device specified by udid, | 149 | * Creates an idevice_t structure for the device specified by UDID, |
| 129 | * if the device is available. | 150 | * if the device is available (USBMUX devices only). |
| 130 | * | 151 | * |
| 131 | * @note The resulting idevice_t structure has to be freed with | 152 | * @note The resulting idevice_t structure has to be freed with |
| 132 | * idevice_free() if it is no longer used. | 153 | * idevice_free() if it is no longer used. |
| 154 | * If you need to connect to a device available via network, use | ||
| 155 | * idevice_new_with_options() and include IDEVICE_LOOKUP_NETWORK in options. | ||
| 156 | * | ||
| 157 | * @see idevice_new_with_options | ||
| 133 | * | 158 | * |
| 134 | * @param device Upon calling this function, a pointer to a location of type | 159 | * @param device Upon calling this function, a pointer to a location of type |
| 135 | * idevice_t. On successful return, this location will be populated. | 160 | * idevice_t. On successful return, this location will be populated. |
| @@ -140,9 +165,30 @@ idevice_error_t idevice_device_list_free(char **devices); | |||
| 140 | idevice_error_t idevice_new(idevice_t *device, const char *udid); | 165 | idevice_error_t idevice_new(idevice_t *device, const char *udid); |
| 141 | 166 | ||
| 142 | /** | 167 | /** |
| 168 | * Creates an idevice_t structure for the device specified by UDID, | ||
| 169 | * if the device is available, with the given lookup options. | ||
| 170 | * | ||
| 171 | * @note The resulting idevice_t structure has to be freed with | ||
| 172 | * idevice_free() if it is no longer used. | ||
| 173 | * | ||
| 174 | * @param device Upon calling this function, a pointer to a location of type | ||
| 175 | * idevice_t. On successful return, this location will be populated. | ||
| 176 | * @param udid The UDID to match. | ||
| 177 | * @param options Specifies what connection types should be considered | ||
| 178 | * when looking up devices. Accepts bitwise or'ed values of idevice_options. | ||
| 179 | * If 0 (no option) is specified it will default to IDEVICE_LOOKUP_USBMUX. | ||
| 180 | * To lookup both USB and network-connected devices, pass | ||
| 181 | * IDEVICE_LOOKUP_USBMUX | IDEVICE_LOOKUP_NETWORK. If a device is available | ||
| 182 | * both via USBMUX *and* network, it will select the USB connection. | ||
| 183 | * This behavior can be changed by adding IDEVICE_LOOKUP_PREFER_NETWORK | ||
| 184 | * to the options in which case it will select the network connection. | ||
| 185 | * | ||
| 186 | * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. | ||
| 187 | */ | ||
| 188 | idevice_error_t idevice_new_with_options(idevice_t *device, const char *udid, enum idevice_options options); | ||
| 189 | |||
| 190 | /** | ||
| 143 | * Cleans up an idevice structure, then frees the structure itself. | 191 | * Cleans up an idevice structure, then frees the structure itself. |
| 144 | * This is a library-level function; deals directly with the device to tear | ||
| 145 | * down relations, but otherwise is mostly internal. | ||
| 146 | * | 192 | * |
| 147 | * @param device idevice_t to free. | 193 | * @param device idevice_t to free. |
| 148 | */ | 194 | */ |
diff --git a/src/idevice.c b/src/idevice.c index 06991c5..d23c5b5 100644 --- a/src/idevice.c +++ b/src/idevice.c | |||
| @@ -190,7 +190,14 @@ static void usbmux_event_cb(const usbmuxd_event_t *event, void *user_data) | |||
| 190 | 190 | ||
| 191 | ev.event = event->event; | 191 | ev.event = event->event; |
| 192 | ev.udid = event->device.udid; | 192 | ev.udid = event->device.udid; |
| 193 | ev.conn_type = CONNECTION_USBMUXD; | 193 | ev.conn_type = 0; |
| 194 | if (event->device.conn_type == CONNECTION_TYPE_USB) { | ||
| 195 | ev.conn_type = CONNECTION_USBMUXD; | ||
| 196 | } else if (event->device.conn_type == CONNECTION_TYPE_NETWORK) { | ||
| 197 | ev.conn_type = CONNECTION_NETWORK; | ||
| 198 | } else { | ||
| 199 | debug_info("Unknown connection type %d", event->device.conn_type); | ||
| 200 | } | ||
| 194 | 201 | ||
| 195 | if (event_cb) { | 202 | if (event_cb) { |
| 196 | event_cb(&ev, user_data); | 203 | event_cb(&ev, user_data); |
| @@ -236,9 +243,11 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_get_device_list(char ***devices, in | |||
| 236 | int i, newcount = 0; | 243 | int i, newcount = 0; |
| 237 | 244 | ||
| 238 | for (i = 0; dev_list[i].handle > 0; i++) { | 245 | for (i = 0; dev_list[i].handle > 0; i++) { |
| 239 | newlist = realloc(*devices, sizeof(char*) * (newcount+1)); | 246 | if (dev_list[i].conn_type == CONNECTION_TYPE_USB) { |
| 240 | newlist[newcount++] = strdup(dev_list[i].udid); | 247 | newlist = realloc(*devices, sizeof(char*) * (newcount+1)); |
| 241 | *devices = newlist; | 248 | newlist[newcount++] = strdup(dev_list[i].udid); |
| 249 | *devices = newlist; | ||
| 250 | } | ||
| 242 | } | 251 | } |
| 243 | usbmuxd_device_list_free(&dev_list); | 252 | usbmuxd_device_list_free(&dev_list); |
| 244 | 253 | ||
| @@ -268,25 +277,66 @@ LIBIMOBILEDEVICE_API void idevice_set_debug_level(int level) | |||
| 268 | internal_set_debug_level(level); | 277 | internal_set_debug_level(level); |
| 269 | } | 278 | } |
| 270 | 279 | ||
| 271 | LIBIMOBILEDEVICE_API idevice_error_t idevice_new(idevice_t * device, const char *udid) | 280 | static idevice_t idevice_from_mux_device(usbmuxd_device_info_t *muxdev) |
| 281 | { | ||
| 282 | if (!muxdev) | ||
| 283 | return NULL; | ||
| 284 | |||
| 285 | idevice_t device = (idevice_t)malloc(sizeof(struct idevice_private)); | ||
| 286 | if (!device) | ||
| 287 | return NULL; | ||
| 288 | |||
| 289 | device->udid = strdup(muxdev->udid); | ||
| 290 | device->mux_id = muxdev->handle; | ||
| 291 | device->version = 0; | ||
| 292 | switch (muxdev->conn_type) { | ||
| 293 | case CONNECTION_TYPE_USB: | ||
| 294 | device->conn_type = CONNECTION_USBMUXD; | ||
| 295 | device->conn_data = NULL; | ||
| 296 | break; | ||
| 297 | case CONNECTION_TYPE_NETWORK: | ||
| 298 | device->conn_type = CONNECTION_NETWORK; | ||
| 299 | size_t len = ((uint8_t*)muxdev->conn_data)[0]; | ||
| 300 | device->conn_data = malloc(len); | ||
| 301 | memcpy(device->conn_data, muxdev->conn_data, len); | ||
| 302 | break; | ||
| 303 | default: | ||
| 304 | device->conn_type = 0; | ||
| 305 | device->conn_data = NULL; | ||
| 306 | break; | ||
| 307 | } | ||
| 308 | return device; | ||
| 309 | } | ||
| 310 | |||
| 311 | LIBIMOBILEDEVICE_API idevice_error_t idevice_new_with_options(idevice_t * device, const char *udid, enum idevice_options options) | ||
| 272 | { | 312 | { |
| 273 | usbmuxd_device_info_t muxdev; | 313 | usbmuxd_device_info_t muxdev; |
| 274 | int res = usbmuxd_get_device_by_udid(udid, &muxdev); | 314 | int usbmux_options = 0; |
| 315 | if (options & IDEVICE_LOOKUP_USBMUX) { | ||
| 316 | usbmux_options |= DEVICE_LOOKUP_USBMUX; | ||
| 317 | } | ||
| 318 | if (options & IDEVICE_LOOKUP_NETWORK) { | ||
| 319 | usbmux_options |= DEVICE_LOOKUP_NETWORK; | ||
| 320 | } | ||
| 321 | if (options & IDEVICE_LOOKUP_PREFER_NETWORK) { | ||
| 322 | usbmux_options |= DEVICE_LOOKUP_PREFER_NETWORK; | ||
| 323 | } | ||
| 324 | int res = usbmuxd_get_device(udid, &muxdev, usbmux_options); | ||
| 275 | if (res > 0) { | 325 | if (res > 0) { |
| 276 | idevice_t dev = (idevice_t) malloc(sizeof(struct idevice_private)); | 326 | *device = idevice_from_mux_device(&muxdev); |
| 277 | dev->udid = strdup(muxdev.udid); | 327 | if (!*device) { |
| 278 | dev->mux_id = muxdev.handle; | 328 | return IDEVICE_E_UNKNOWN_ERROR; |
| 279 | dev->conn_type = CONNECTION_USBMUXD; | 329 | } |
| 280 | dev->conn_data = NULL; | ||
| 281 | dev->version = 0; | ||
| 282 | *device = dev; | ||
| 283 | return IDEVICE_E_SUCCESS; | 330 | return IDEVICE_E_SUCCESS; |
| 284 | } | 331 | } |
| 285 | /* other connection types could follow here */ | ||
| 286 | |||
| 287 | return IDEVICE_E_NO_DEVICE; | 332 | return IDEVICE_E_NO_DEVICE; |
| 288 | } | 333 | } |
| 289 | 334 | ||
| 335 | LIBIMOBILEDEVICE_API idevice_error_t idevice_new(idevice_t * device, const char *udid) | ||
| 336 | { | ||
| 337 | return idevice_new_with_options(device, udid, 0); | ||
| 338 | } | ||
| 339 | |||
| 290 | LIBIMOBILEDEVICE_API idevice_error_t idevice_free(idevice_t device) | 340 | LIBIMOBILEDEVICE_API idevice_error_t idevice_free(idevice_t device) |
| 291 | { | 341 | { |
| 292 | if (!device) | 342 | if (!device) |
| @@ -310,7 +360,7 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connect(idevice_t device, uint16_t | |||
| 310 | return IDEVICE_E_INVALID_ARG; | 360 | return IDEVICE_E_INVALID_ARG; |
| 311 | } | 361 | } |
| 312 | 362 | ||
| 313 | if (device->conn_type == CONNECTION_USBMUXD) { | 363 | if (device->conn_type == CONNECTION_USBMUXD || device->conn_type == CONNECTION_NETWORK) { |
| 314 | int sfd = usbmuxd_connect(device->mux_id, port); | 364 | int sfd = usbmuxd_connect(device->mux_id, port); |
| 315 | if (sfd < 0) { | 365 | if (sfd < 0) { |
| 316 | debug_info("ERROR: Connecting to usbmuxd failed: %d (%s)", sfd, strerror(-sfd)); | 366 | debug_info("ERROR: Connecting to usbmuxd failed: %d (%s)", sfd, strerror(-sfd)); |
| @@ -340,7 +390,7 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_disconnect(idevice_connection_t con | |||
| 340 | idevice_connection_disable_ssl(connection); | 390 | idevice_connection_disable_ssl(connection); |
| 341 | } | 391 | } |
| 342 | idevice_error_t result = IDEVICE_E_UNKNOWN_ERROR; | 392 | idevice_error_t result = IDEVICE_E_UNKNOWN_ERROR; |
| 343 | if (connection->type == CONNECTION_USBMUXD) { | 393 | if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) { |
| 344 | usbmuxd_disconnect((int)(long)connection->data); | 394 | usbmuxd_disconnect((int)(long)connection->data); |
| 345 | connection->data = NULL; | 395 | connection->data = NULL; |
| 346 | result = IDEVICE_E_SUCCESS; | 396 | result = IDEVICE_E_SUCCESS; |
| @@ -363,7 +413,7 @@ static idevice_error_t internal_connection_send(idevice_connection_t connection, | |||
| 363 | return IDEVICE_E_INVALID_ARG; | 413 | return IDEVICE_E_INVALID_ARG; |
| 364 | } | 414 | } |
| 365 | 415 | ||
| 366 | if (connection->type == CONNECTION_USBMUXD) { | 416 | if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) { |
| 367 | int res = usbmuxd_send((int)(long)connection->data, data, len, sent_bytes); | 417 | int res = usbmuxd_send((int)(long)connection->data, data, len, sent_bytes); |
| 368 | if (res < 0) { | 418 | if (res < 0) { |
| 369 | debug_info("ERROR: usbmuxd_send returned %d (%s)", res, strerror(-res)); | 419 | debug_info("ERROR: usbmuxd_send returned %d (%s)", res, strerror(-res)); |
| @@ -434,7 +484,7 @@ static idevice_error_t internal_connection_receive_timeout(idevice_connection_t | |||
| 434 | return IDEVICE_E_INVALID_ARG; | 484 | return IDEVICE_E_INVALID_ARG; |
| 435 | } | 485 | } |
| 436 | 486 | ||
| 437 | if (connection->type == CONNECTION_USBMUXD) { | 487 | if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) { |
| 438 | int conn_error = usbmuxd_recv_timeout((int)(long)connection->data, data, len, recv_bytes, timeout); | 488 | int conn_error = usbmuxd_recv_timeout((int)(long)connection->data, data, len, recv_bytes, timeout); |
| 439 | idevice_error_t error = socket_recv_to_idevice_error(conn_error, len, *recv_bytes); | 489 | idevice_error_t error = socket_recv_to_idevice_error(conn_error, len, *recv_bytes); |
| 440 | 490 | ||
| @@ -510,7 +560,7 @@ static idevice_error_t internal_connection_receive(idevice_connection_t connecti | |||
| 510 | return IDEVICE_E_INVALID_ARG; | 560 | return IDEVICE_E_INVALID_ARG; |
| 511 | } | 561 | } |
| 512 | 562 | ||
| 513 | if (connection->type == CONNECTION_USBMUXD) { | 563 | if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) { |
| 514 | int res = usbmuxd_recv((int)(long)connection->data, data, len, recv_bytes); | 564 | int res = usbmuxd_recv((int)(long)connection->data, data, len, recv_bytes); |
| 515 | if (res < 0) { | 565 | if (res < 0) { |
| 516 | debug_info("ERROR: usbmuxd_recv returned %d (%s)", res, strerror(-res)); | 566 | debug_info("ERROR: usbmuxd_recv returned %d (%s)", res, strerror(-res)); |
| @@ -554,7 +604,7 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_get_fd(idevice_connectio | |||
| 554 | } | 604 | } |
| 555 | 605 | ||
| 556 | idevice_error_t result = IDEVICE_E_UNKNOWN_ERROR; | 606 | idevice_error_t result = IDEVICE_E_UNKNOWN_ERROR; |
| 557 | if (connection->type == CONNECTION_USBMUXD) { | 607 | if (connection->type == CONNECTION_USBMUXD || connection->type == CONNECTION_NETWORK) { |
| 558 | *fd = (int)(long)connection->data; | 608 | *fd = (int)(long)connection->data; |
| 559 | result = IDEVICE_E_SUCCESS; | 609 | result = IDEVICE_E_SUCCESS; |
| 560 | } else { | 610 | } else { |
diff --git a/src/idevice.h b/src/idevice.h index f403c55..8709c9a 100644 --- a/src/idevice.h +++ b/src/idevice.h | |||
| @@ -48,10 +48,6 @@ | |||
| 48 | 48 | ||
| 49 | #define DEVICE_VERSION(maj, min, patch) (((maj & 0xFF) << 16) | ((min & 0xFF) << 8) | (patch & 0xFF)) | 49 | #define DEVICE_VERSION(maj, min, patch) (((maj & 0xFF) << 16) | ((min & 0xFF) << 8) | (patch & 0xFF)) |
| 50 | 50 | ||
| 51 | enum connection_type { | ||
| 52 | CONNECTION_USBMUXD = 1 | ||
| 53 | }; | ||
| 54 | |||
| 55 | struct ssl_data_private { | 51 | struct ssl_data_private { |
| 56 | #ifdef HAVE_OPENSSL | 52 | #ifdef HAVE_OPENSSL |
| 57 | SSL *session; | 53 | SSL *session; |
| @@ -69,7 +65,7 @@ typedef struct ssl_data_private *ssl_data_t; | |||
| 69 | 65 | ||
| 70 | struct idevice_connection_private { | 66 | struct idevice_connection_private { |
| 71 | idevice_t device; | 67 | idevice_t device; |
| 72 | enum connection_type type; | 68 | enum idevice_connection_type type; |
| 73 | void *data; | 69 | void *data; |
| 74 | ssl_data_t ssl_data; | 70 | ssl_data_t ssl_data; |
| 75 | }; | 71 | }; |
| @@ -77,7 +73,7 @@ struct idevice_connection_private { | |||
| 77 | struct idevice_private { | 73 | struct idevice_private { |
| 78 | char *udid; | 74 | char *udid; |
| 79 | uint32_t mux_id; | 75 | uint32_t mux_id; |
| 80 | enum connection_type conn_type; | 76 | enum idevice_connection_type conn_type; |
| 81 | void *conn_data; | 77 | void *conn_data; |
| 82 | int version; | 78 | int version; |
| 83 | }; | 79 | }; |
