diff options
Diffstat (limited to 'libusbmuxd')
-rw-r--r-- | libusbmuxd/CMakeLists.txt | 45 | ||||
-rw-r--r-- | libusbmuxd/libusbmuxd.c | 975 | ||||
-rw-r--r-- | libusbmuxd/sock_stuff.c | 375 | ||||
-rw-r--r-- | libusbmuxd/sock_stuff.h | 65 | ||||
-rw-r--r-- | libusbmuxd/usbmuxd-proto.h | 97 | ||||
-rw-r--r-- | libusbmuxd/usbmuxd.h | 191 |
6 files changed, 0 insertions, 1748 deletions
diff --git a/libusbmuxd/CMakeLists.txt b/libusbmuxd/CMakeLists.txt deleted file mode 100644 index 737eb02..0000000 --- a/libusbmuxd/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -include_directories (${CMAKE_SOURCE_DIR}/common) -find_package(Threads) - -option(WANT_INOTIFY "Build with inotify support" ON) -if (WANT_INOTIFY) -find_package(Inotify) -if (INOTIFY_FOUND) - add_definitions("-DHAVE_INOTIFY") - message("-- libusbmuxd will be built with inotify support") -endif() -endif(WANT_INOTIFY) - -add_library (libusbmuxd SHARED libusbmuxd.c sock_stuff.c ${CMAKE_SOURCE_DIR}/common/utils.c) -find_library (PTHREAD pthread) - -if (HAVE_PLIST) - add_definitions("-DHAVE_PLIST") - message("-- libusbmuxd will be built with protocol version 1 support") -endif() -if(WIN32) - set(OPT_LIBS ${OPT_LIBS} ws2_32) -endif() -include_directories(${OPT_INCLUDES}) -target_link_libraries (libusbmuxd ${CMAKE_THREAD_LIBS_INIT} ${OPT_LIBS}) - -# 'lib' is a UNIXism, the proper CMake target is usbmuxd -# But we can't use that due to the conflict with the usbmuxd daemon, -# so instead change the library output base name to usbmuxd here -set_target_properties(libusbmuxd PROPERTIES OUTPUT_NAME usbmuxd) -set_target_properties(libusbmuxd PROPERTIES VERSION ${LIBUSBMUXD_VERSION}) -set_target_properties(libusbmuxd PROPERTIES SOVERSION ${LIBUSBMUXD_SOVERSION}) - -if(APPLE) - set_target_properties(libusbmuxd PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}") -endif() -if(WIN32) - set_target_properties(libusbmuxd PROPERTIES PREFIX "lib" IMPORT_PREFIX "lib") -endif() - -install(TARGETS libusbmuxd - RUNTIME DESTINATION bin - ARCHIVE DESTINATION lib${LIB_SUFFIX} - LIBRARY DESTINATION lib${LIB_SUFFIX} -) -install(FILES usbmuxd.h usbmuxd-proto.h DESTINATION include) diff --git a/libusbmuxd/libusbmuxd.c b/libusbmuxd/libusbmuxd.c deleted file mode 100644 index 20ac8ab..0000000 --- a/libusbmuxd/libusbmuxd.c +++ /dev/null @@ -1,975 +0,0 @@ -/* - libusbmuxd - client library to talk to usbmuxd - -Copyright (C) 2009-2010 Nikias Bassen <nikias@gmx.li> -Copyright (C) 2009 Paul Sladen <libiphone@paul.sladen.org> -Copyright (C) 2009 Martin Szulecki <opensuse@sukimashita.com> - -This library is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as -published by the Free Software Foundation, either version 2.1 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include <stdint.h> -#include <stdlib.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> -#ifdef WIN32 -#include <windows.h> -#include <winsock2.h> -#define sleep(x) Sleep(x*1000) -#ifndef EPROTO -#define EPROTO 134 -#endif -#ifndef EBADMSG -#define EBADMSG 104 -#endif -#else -#include <sys/socket.h> -#include <arpa/inet.h> -#include <pthread.h> -#endif - -#ifdef HAVE_INOTIFY -#include <sys/inotify.h> -#define EVENT_SIZE (sizeof (struct inotify_event)) -#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16)) -#define USBMUXD_DIRNAME "/var/run" -#define USBMUXD_SOCKET_NAME "usbmuxd" -#endif /* HAVE_INOTIFY */ - -#include <unistd.h> -#include <signal.h> - -#ifdef HAVE_PLIST -#include <plist/plist.h> -#define PLIST_BUNDLE_ID "com.marcansoft.usbmuxd" -#define PLIST_CLIENT_VERSION_STRING "usbmuxd built for freedom" -#define PLIST_PROGNAME "libusbmuxd" -#endif - -// usbmuxd public interface -#include "usbmuxd.h" -// usbmuxd protocol -#include "usbmuxd-proto.h" -// socket utility functions -#include "sock_stuff.h" -// misc utility functions -#include "utils.h" - -static int libusbmuxd_debug = 0; -#define DEBUG(x, y, ...) if (x <= libusbmuxd_debug) fprintf(stderr, (y), __VA_ARGS__); - -static struct collection devices; -static usbmuxd_event_cb_t event_cb = NULL; -#ifdef WIN32 -HANDLE devmon = NULL; -CRITICAL_SECTION mutex; -static int mutex_initialized = 0; -#define LOCK if (!mutex_initialized) { InitializeCriticalSection(&mutex); mutex_initialized = 1; } EnterCriticalSection(&mutex); -#define UNLOCK LeaveCriticalSection(&mutex); -#else -pthread_t devmon; -pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -#define LOCK pthread_mutex_lock(&mutex) -#define UNLOCK pthread_mutex_unlock(&mutex) -#endif -static int listenfd = -1; - -static int use_tag = 0; -static int proto_version = 0; - -/** - * Finds a device info record by its handle. - * if the record is not found, NULL is returned. - */ -static usbmuxd_device_info_t *devices_find(int handle) -{ - FOREACH(usbmuxd_device_info_t *dev, &devices) { - if (dev && dev->handle == handle) { - return dev; - } - } ENDFOREACH - return NULL; -} - -/** - * Creates a socket connection to usbmuxd. - * For Mac/Linux it is a unix domain socket, - * for Windows it is a tcp socket. - */ -static int connect_usbmuxd_socket() -{ -#if defined(WIN32) || defined(__CYGWIN__) - return connect_socket("127.0.0.1", USBMUXD_SOCKET_PORT); -#else - return connect_unix_socket(USBMUXD_SOCKET_FILE); -#endif -} - -static int receive_packet(int sfd, struct usbmuxd_header *header, void **payload, int timeout) -{ - int recv_len; - struct usbmuxd_header hdr; - char *payload_loc = NULL; - - header->length = 0; - header->version = 0; - header->message = 0; - header->tag = 0; - - recv_len = recv_buf_timeout(sfd, &hdr, sizeof(hdr), 0, timeout); - if (recv_len < 0) { - return recv_len; - } else if (recv_len < sizeof(hdr)) { - return recv_len; - } - - uint32_t payload_size = hdr.length - sizeof(hdr); - if (payload_size > 0) { - payload_loc = (char*)malloc(payload_size); - if (recv_buf_timeout(sfd, payload_loc, payload_size, 0, 5000) != payload_size) { - DEBUG(1, "%s: Error receiving payload of size %d\n", __func__, payload_size); - free(payload_loc); - return -EBADMSG; - } - } - -#ifdef HAVE_PLIST - if (hdr.message == MESSAGE_PLIST) { - char *message = NULL; - plist_t plist = NULL; - plist_from_xml(payload_loc, payload_size, &plist); - free(payload_loc); - - if (!plist) { - DEBUG(1, "%s: Error getting plist from payload!\n", __func__); - return -EBADMSG; - } - - plist_t node = plist_dict_get_item(plist, "MessageType"); - if (plist_get_node_type(node) != PLIST_STRING) { - DEBUG(1, "%s: Error getting message type from plist!\n", __func__); - free(plist); - return -EBADMSG; - } - - plist_get_string_val(node, &message); - if (message) { - uint64_t val = 0; - if (strcmp(message, "Result") == 0) { - /* result message */ - uint32_t dwval = 0; - plist_t n = plist_dict_get_item(plist, "Number"); - plist_get_uint_val(n, &val); - *payload = malloc(sizeof(uint32_t)); - dwval = val; - memcpy(*payload, &dwval, sizeof(dwval)); - hdr.length = sizeof(hdr) + sizeof(dwval); - hdr.message = MESSAGE_RESULT; - } else if (strcmp(message, "Attached") == 0) { - /* device add message */ - struct usbmuxd_device_record *dev = NULL; - plist_t props = plist_dict_get_item(plist, "Properties"); - if (!props) { - DEBUG(1, "%s: Could not get properties for message '%s' from plist!\n", __func__, message); - free(message); - plist_free(plist); - return -EBADMSG; - } - dev = (struct usbmuxd_device_record*)malloc(sizeof(struct usbmuxd_device_record)); - memset(dev, 0, sizeof(struct usbmuxd_device_record)); - - plist_t n = plist_dict_get_item(props, "DeviceID"); - plist_get_uint_val(n, &val); - dev->device_id = (uint32_t)val; - - n = plist_dict_get_item(props, "ProductID"); - plist_get_uint_val(n, &val); - dev->product_id = (uint32_t)val; - - n = plist_dict_get_item(props, "SerialNumber"); - char *strval = NULL; - plist_get_string_val(n, &strval); - if (strval) { - strncpy(dev->serial_number, strval, 255); - free(strval); - } - n = plist_dict_get_item(props, "LocationID"); - plist_get_uint_val(n, &val); - dev->location = (uint32_t)val; - *payload = (void*)dev; - hdr.length = sizeof(hdr) + sizeof(struct usbmuxd_device_record); - hdr.message = MESSAGE_DEVICE_ADD; - } else if (strcmp(message, "Detached") == 0) { - /* device remove message */ - uint32_t dwval = 0; - plist_t n = plist_dict_get_item(plist, "DeviceID"); - if (n) { - plist_get_uint_val(n, &val); - *payload = malloc(sizeof(uint32_t)); - dwval = val; - memcpy(*payload, &dwval, sizeof(dwval)); - hdr.length = sizeof(hdr) + sizeof(dwval); - hdr.message = MESSAGE_DEVICE_REMOVE; - } - } else { - DEBUG(1, "%s: Unexpected message '%s' in plist!\n", __func__, message); - free(message); - plist_free(plist); - return -EBADMSG; - } - free(message); - } - plist_free(plist); - } else -#endif - { - *payload = payload_loc; - } - - memcpy(header, &hdr, sizeof(hdr)); - - return hdr.length; -} - -/** - * Retrieves the result code to a previously sent request. - */ -static int usbmuxd_get_result(int sfd, uint32_t tag, uint32_t * result) -{ - struct usbmuxd_header hdr; - int recv_len; - uint32_t *res = NULL; - - if (!result) { - return -EINVAL; - } - *result = -1; - - if ((recv_len = receive_packet(sfd, &hdr, (void**)&res, 5000)) < 0) { - DEBUG(1, "%s: Error receiving packet: %d\n", __func__, errno); - if (res) - free(res); - return -errno; - } - if (recv_len < sizeof(hdr)) { - DEBUG(1, "%s: Received packet is too small!\n", __func__); - if (res) - free(res); - return -EPROTO; - } - - if (hdr.message == MESSAGE_RESULT) { - int ret = 0; - if (res && (hdr.tag == tag)) { - memcpy(result, res, sizeof(uint32_t)); - ret = 1; - } - if (res) - free(res); - return ret; - } - DEBUG(1, "%s: Unexpected message of type %d received!\n", __func__, hdr.message); - if (res) - free(res); - return -EPROTO; -} - -static int send_packet(int sfd, uint32_t message, uint32_t tag, void *payload, uint32_t payload_size) -{ - struct usbmuxd_header header; - - header.length = sizeof(struct usbmuxd_header); - header.version = proto_version; - header.message = message; - header.tag = tag; - if (payload && (payload_size > 0)) { - header.length += payload_size; - } - int sent = send_buf(sfd, &header, sizeof(header)); - if (sent != sizeof(header)) { - DEBUG(1, "%s: ERROR: could not send packet header\n", __func__); - return -1; - } - if (payload && (payload_size > 0)) { - sent += send_buf(sfd, payload, payload_size); - } - if (sent != (int)header.length) { - DEBUG(1, "%s: ERROR: could not send whole packet\n", __func__); - close_socket(sfd); - return -1; - } - return sent; -} - -static int send_listen_packet(int sfd, uint32_t tag) -{ - int res = 0; -#ifdef HAVE_PLIST - if (proto_version == 1) { - /* plist packet */ - char *payload = NULL; - uint32_t payload_size = 0; - plist_t plist; - - /* construct message plist */ - plist = plist_new_dict(); - plist_dict_insert_item(plist, "BundleID", plist_new_string(PLIST_BUNDLE_ID)); - plist_dict_insert_item(plist, "ClientVersionString", plist_new_string(PLIST_CLIENT_VERSION_STRING)); - plist_dict_insert_item(plist, "MessageType", plist_new_string("Listen")); - plist_dict_insert_item(plist, "ProgName", plist_new_string(PLIST_PROGNAME)); - plist_to_xml(plist, &payload, &payload_size); - plist_free(plist); - - res = send_packet(sfd, MESSAGE_PLIST, tag, payload, payload_size); - free(payload); - } else -#endif - { - /* binary packet */ - res = send_packet(sfd, MESSAGE_LISTEN, tag, NULL, 0); - } - return res; -} - -static int send_connect_packet(int sfd, uint32_t tag, uint32_t device_id, uint16_t port) -{ - int res = 0; -#ifdef HAVE_PLIST - if (proto_version == 1) { - /* plist packet */ - char *payload = NULL; - uint32_t payload_size = 0; - plist_t plist; - - /* construct message plist */ - plist = plist_new_dict(); - plist_dict_insert_item(plist, "BundleID", plist_new_string(PLIST_BUNDLE_ID)); - plist_dict_insert_item(plist, "ClientVersionString", plist_new_string(PLIST_CLIENT_VERSION_STRING)); - plist_dict_insert_item(plist, "MessageType", plist_new_string("Connect")); - plist_dict_insert_item(plist, "DeviceID", plist_new_uint(device_id)); - plist_dict_insert_item(plist, "PortNumber", plist_new_uint(htons(port))); - plist_dict_insert_item(plist, "ProgName", plist_new_string(PLIST_PROGNAME)); - plist_to_xml(plist, &payload, &payload_size); - plist_free(plist); - - res = send_packet(sfd, MESSAGE_PLIST, tag, (void*)payload, payload_size); - free(payload); - } else -#endif - { - /* binary packet */ - struct { - uint32_t device_id; - uint16_t port; - uint16_t reserved; - } conninfo; - - conninfo.device_id = device_id; - conninfo.port = htons(port); - conninfo.reserved = 0; - - res = send_packet(sfd, MESSAGE_CONNECT, tag, &conninfo, sizeof(conninfo)); - } - return res; -} - -/** - * Generates an event, i.e. calls the callback function. - * A reference to a populated usbmuxd_event_t with information about the event - * and the corresponding device will be passed to the callback function. - */ -static void generate_event(usbmuxd_event_cb_t callback, const usbmuxd_device_info_t *dev, enum usbmuxd_event_type event, void *user_data) -{ - usbmuxd_event_t ev; - - if (!callback || !dev) { - return; - } - - ev.event = event; - memcpy(&ev.device, dev, sizeof(usbmuxd_device_info_t)); - - callback(&ev, user_data); -} - -static int usbmuxd_listen_poll() -{ - int sfd; - - sfd = connect_usbmuxd_socket(); - if (sfd < 0) { - while (event_cb) { - if ((sfd = connect_usbmuxd_socket()) > 0) { - break; - } - sleep(1); - } - } - - return sfd; -} - -#ifdef HAVE_INOTIFY -static int use_inotify = 1; - -static int usbmuxd_listen_inotify() -{ - int inot_fd; - int watch_d; - int sfd; - - if (!use_inotify) { - return -2; - } - - sfd = connect_usbmuxd_socket(); - if (sfd >= 0) - return sfd; - - sfd = -1; - inot_fd = inotify_init (); - if (inot_fd < 0) { - DEBUG(1, "%s: Failed to setup inotify\n", __func__); - return -2; - } - - /* inotify is setup, listen for events that concern us */ - watch_d = inotify_add_watch (inot_fd, USBMUXD_DIRNAME, IN_CREATE); - if (watch_d < 0) { - DEBUG(1, "%s: Failed to setup watch descriptor for socket dir\n", __func__); - close (inot_fd); - return -2; - } - - while (1) { - ssize_t len, i; - char buff[EVENT_BUF_LEN] = {0}; - - i = 0; - len = read (inot_fd, buff, EVENT_BUF_LEN -1); - if (len < 0) - goto end; - while (i < len) { - struct inotify_event *pevent = (struct inotify_event *) & buff[i]; - - /* check that it's ours */ - if (pevent->mask & IN_CREATE && - pevent->len && - pevent->name != NULL && - strcmp(pevent->name, USBMUXD_SOCKET_NAME) == 0) { - sfd = connect_usbmuxd_socket (); - goto end; - } - i += EVENT_SIZE + pevent->len; - } - } - -end: - inotify_rm_watch(inot_fd, watch_d); - close(inot_fd); - - return sfd; -} -#endif /* HAVE_INOTIFY */ - -/** - * Tries to connect to usbmuxd and wait if it is not running. - */ -static int usbmuxd_listen() -{ - int sfd; - uint32_t res = -1; - -#ifdef HAVE_PLIST -retry: -#endif - -#ifdef HAVE_INOTIFY - sfd = usbmuxd_listen_inotify(); - if (sfd == -2) - sfd = usbmuxd_listen_poll(); -#else - sfd = usbmuxd_listen_poll(); -#endif - - if (sfd < 0) { - DEBUG(1, "%s: ERROR: usbmuxd was supposed to be running here...\n", __func__); - return sfd; - } - - use_tag++; - LOCK; - if (send_listen_packet(sfd, use_tag) <= 0) { - UNLOCK; - DEBUG(1, "%s: ERROR: could not send listen packet\n", __func__); - close_socket(sfd); - return -1; - } - if (usbmuxd_get_result(sfd, use_tag, &res) && (res != 0)) { - UNLOCK; - close_socket(sfd); -#ifdef HAVE_PLIST - if ((res == RESULT_BADVERSION) && (proto_version != 1)) { - proto_version = 1; - goto retry; - } -#endif - DEBUG(1, "%s: ERROR: did not get OK but %d\n", __func__, res); - return -1; - } - UNLOCK; - - return sfd; -} - -/** - * Waits for an event to occur, i.e. a packet coming from usbmuxd. - * Calls generate_event to pass the event via callback to the client program. - */ -int get_next_event(int sfd, usbmuxd_event_cb_t callback, void *user_data) -{ - struct usbmuxd_header hdr; - void *payload = NULL; - - /* block until we receive something */ - if (receive_packet(sfd, &hdr, &payload, 0) < 0) { - // when then usbmuxd connection fails, - // generate remove events for every device that - // is still present so applications know about it - FOREACH(usbmuxd_device_info_t *dev, &devices) { - generate_event(callback, dev, UE_DEVICE_REMOVE, user_data); - collection_remove(&devices, dev); - free(dev); - } ENDFOREACH - return -EIO; - } - - if ((hdr.length > sizeof(hdr)) && !payload) { - DEBUG(1, "%s: Invalid packet received, payload is missing!\n", __func__); - return -EBADMSG; - } - - if (hdr.message == MESSAGE_DEVICE_ADD) { - struct usbmuxd_device_record *dev = payload; - usbmuxd_device_info_t *devinfo = (usbmuxd_device_info_t*)malloc(sizeof(usbmuxd_device_info_t)); - if (!devinfo) { - DEBUG(1, "%s: Out of memory!\n", __func__); - free(payload); - return -1; - } - - devinfo->handle = dev->device_id; - devinfo->product_id = dev->product_id; - memset(devinfo->udid, '\0', sizeof(devinfo->udid)); - memcpy(devinfo->udid, dev->serial_number, sizeof(devinfo->udid)); - - if (strcasecmp(devinfo->udid, "ffffffffffffffffffffffffffffffffffffffff") == 0) { - sprintf(devinfo->udid + 32, "%08x", devinfo->handle); - } - - collection_add(&devices, devinfo); - generate_event(callback, devinfo, UE_DEVICE_ADD, user_data); - } else if (hdr.message == MESSAGE_DEVICE_REMOVE) { - uint32_t handle; - usbmuxd_device_info_t *devinfo; - - memcpy(&handle, payload, sizeof(uint32_t)); - - devinfo = devices_find(handle); - if (!devinfo) { - DEBUG(1, "%s: WARNING: got device remove message for handle %d, but couldn't find the corresponding handle in the device list. This event will be ignored.\n", __func__, handle); - } else { - generate_event(callback, devinfo, UE_DEVICE_REMOVE, user_data); - collection_remove(&devices, devinfo); - free(devinfo); - } - } else if (hdr.length > 0) { - DEBUG(1, "%s: Unexpected message type %d length %d received!\n", __func__, hdr.message, hdr.length); - } - if (payload) { - free(payload); - } - return 0; -} - -static void device_monitor_cleanup(void* data) -{ - FOREACH(usbmuxd_device_info_t *dev, &devices) { - collection_remove(&devices, dev); - free(dev); - } ENDFOREACH - collection_free(&devices); - - close_socket(listenfd); - listenfd = -1; -} - -/** - * Device Monitor thread function. - * - * This function sets up a connection to usbmuxd - */ -static void *device_monitor(void *data) -{ - collection_init(&devices); - -#ifndef WIN32 - pthread_cleanup_push(device_monitor_cleanup, NULL); -#endif - while (event_cb) { - - listenfd = usbmuxd_listen(); - if (listenfd < 0) { - continue; - } - - while (event_cb) { - int res = get_next_event(listenfd, event_cb, data); - if (res < 0) { - break; - } - } - } - -#ifndef WIN32 - pthread_cleanup_pop(1); -#else - device_monitor_cleanup(NULL); -#endif - return NULL; -} - -int usbmuxd_subscribe(usbmuxd_event_cb_t callback, void *user_data) -{ - int res; - - if (!callback) { - return -EINVAL; - } - event_cb = callback; - -#ifdef WIN32 - res = 0; - devmon = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)device_monitor, user_data, 0, NULL); - if (devmon == NULL) { - res = GetLastError(); - } -#else - res = pthread_create(&devmon, NULL, device_monitor, user_data); -#endif - if (res != 0) { - DEBUG(1, "%s: ERROR: Could not start device watcher thread!\n", __func__); - return res; - } - return 0; -} - -int usbmuxd_unsubscribe() -{ - event_cb = NULL; - - shutdown_socket(listenfd, SHUT_RDWR); - -#ifdef WIN32 - if (devmon != NULL) { - WaitForSingleObject(devmon, INFINITE); - } -#else - if (pthread_kill(devmon, 0) == 0) { - pthread_cancel(devmon); - pthread_join(devmon, NULL); - } -#endif - - return 0; -} - -int usbmuxd_get_device_list(usbmuxd_device_info_t **device_list) -{ - int sfd; - int listen_success = 0; - uint32_t res; - struct collection tmpdevs; - usbmuxd_device_info_t *newlist = NULL; - struct usbmuxd_header hdr; - struct usbmuxd_device_record *dev; - int dev_cnt = 0; - void *payload = NULL; - - *device_list = NULL; - -#ifdef HAVE_PLIST -retry: -#endif - sfd = connect_usbmuxd_socket(); - if (sfd < 0) { - DEBUG(1, "%s: error opening socket!\n", __func__); - return sfd; - } - - use_tag++; - LOCK; - if (send_listen_packet(sfd, use_tag) > 0) { - res = -1; - // get response - if (usbmuxd_get_result(sfd, use_tag, &res) && (res == 0)) { - listen_success = 1; - } else { - UNLOCK; - close_socket(sfd); -#ifdef HAVE_PLIST - if ((res == RESULT_BADVERSION) && (proto_version != 1)) { - proto_version = 1; - goto retry; - } -#endif - DEBUG(1, "%s: Did not get response to scan request (with result=0)...\n", __func__); - return res; - } - } - - if (!listen_success) { - UNLOCK; - DEBUG(1, "%s: Could not send listen request!\n", __func__); - return -1; - } - - collection_init(&tmpdevs); - - // receive device list - while (1) { - if (receive_packet(sfd, &hdr, &payload, 1000) > 0) { - if (hdr.message == MESSAGE_DEVICE_ADD) { - dev = payload; - usbmuxd_device_info_t *devinfo = (usbmuxd_device_info_t*)malloc(sizeof(usbmuxd_device_info_t)); - if (!devinfo) { - UNLOCK; - DEBUG(1, "%s: Out of memory!\n", __func__); - free(payload); - return -1; - } - - devinfo->handle = dev->device_id; - devinfo->product_id = dev->product_id; - memset(devinfo->udid, '\0', sizeof(devinfo->udid)); - memcpy(devinfo->udid, dev->serial_number, sizeof(devinfo->udid)); - - if (strcasecmp(devinfo->udid, "ffffffffffffffffffffffffffffffffffffffff") == 0) { - sprintf(devinfo->udid + 32, "%08x", devinfo->handle); - } - - collection_add(&tmpdevs, devinfo); - - } else if (hdr.message == MESSAGE_DEVICE_REMOVE) { - uint32_t handle; - usbmuxd_device_info_t *devinfo = NULL; - - memcpy(&handle, payload, sizeof(uint32_t)); - - FOREACH(usbmuxd_device_info_t *di, &tmpdevs) { - if (di && di->handle == handle) { - devinfo = di; - break; - } - } ENDFOREACH - if (devinfo) { - collection_remove(&tmpdevs, devinfo); - free(devinfo); - } - } else { - DEBUG(1, "%s: Unexpected message %d\n", __func__, hdr.message); - } - if (payload) - free(payload); - } else { - // we _should_ have all of them now. - // or perhaps an error occured. - break; - } - } - UNLOCK; - - // explicitly close connection - close_socket(sfd); - - // create copy of device info entries from collection - newlist = (usbmuxd_device_info_t*)malloc(sizeof(usbmuxd_device_info_t) * (collection_count(&tmpdevs) + 1)); - dev_cnt = 0; - FOREACH(usbmuxd_device_info_t *di, &tmpdevs) { - if (di) { - memcpy(&newlist[dev_cnt], di, sizeof(usbmuxd_device_info_t)); - free(di); - dev_cnt++; - } - } ENDFOREACH - collection_free(&tmpdevs); - - memset(&newlist[dev_cnt], 0, sizeof(usbmuxd_device_info_t)); - *device_list = newlist; - - return dev_cnt; -} - -int usbmuxd_device_list_free(usbmuxd_device_info_t **device_list) -{ - if (device_list) { - free(*device_list); - } - return 0; -} - -int usbmuxd_get_device_by_udid(const char *udid, usbmuxd_device_info_t *device) -{ - usbmuxd_device_info_t *dev_list = NULL; - - if (!device) { - return -EINVAL; - } - if (usbmuxd_get_device_list(&dev_list) < 0) { - return -ENODEV; - } - - int i; - int result = 0; - for (i = 0; dev_list[i].handle > 0; i++) { - if (!udid) { - device->handle = dev_list[i].handle; - device->product_id = dev_list[i].product_id; - strcpy(device->udid, dev_list[i].udid); - result = 1; - break; - } - if (!strcmp(udid, dev_list[i].udid)) { - device->handle = dev_list[i].handle; - device->product_id = dev_list[i].product_id; - strcpy(device->udid, dev_list[i].udid); - result = 1; - break; - } - } - - free(dev_list); - - return result; -} - -int usbmuxd_connect(const int handle, const unsigned short port) -{ - int sfd; - int connected = 0; - uint32_t res = -1; - -#ifdef HAVE_PLIST -retry: -#endif - sfd = connect_usbmuxd_socket(); - if (sfd < 0) { - DEBUG(1, "%s: Error: Connection to usbmuxd failed: %s\n", - __func__, strerror(errno)); - return sfd; - } - - use_tag++; - if (send_connect_packet(sfd, use_tag, (uint32_t)handle, (uint16_t)port) <= 0) { - DEBUG(1, "%s: Error sending connect message!\n", __func__); - } else { - // read ACK - DEBUG(2, "%s: Reading connect result...\n", __func__); - if (usbmuxd_get_result(sfd, use_tag, &res)) { - if (res == 0) { - DEBUG(2, "%s: Connect success!\n", __func__); - connected = 1; - } else { -#ifdef HAVE_PLIST - if ((res == RESULT_BADVERSION) && (proto_version == 0)) { - proto_version = 1; - close_socket(sfd); - goto retry; - } -#endif - DEBUG(1, "%s: Connect failed, Error code=%d\n", __func__, res); - } - } - } - - if (connected) { - return sfd; - } - - close_socket(sfd); - - return -1; -} - -int usbmuxd_disconnect(int sfd) -{ - return close_socket(sfd); -} - -int usbmuxd_send(int sfd, const char *data, uint32_t len, uint32_t *sent_bytes) -{ - int num_sent; - - if (sfd < 0) { - return -EINVAL; - } - - num_sent = send(sfd, (void*)data, len, 0); - if (num_sent < 0) { - *sent_bytes = 0; - DEBUG(1, "%s: Error %d when sending: %s\n", __func__, num_sent, strerror(errno)); - return num_sent; - } else if ((uint32_t)num_sent < len) { - DEBUG(1, "%s: Warning: Did not send enough (only %d of %d)\n", __func__, num_sent, len); - } - - *sent_bytes = num_sent; - - return 0; -} - -int usbmuxd_recv_timeout(int sfd, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout) -{ - int num_recv = recv_buf_timeout(sfd, (void*)data, len, 0, timeout); - if (num_recv < 0) { - *recv_bytes = 0; - return num_recv; - } - - *recv_bytes = num_recv; - - return 0; -} - -int usbmuxd_recv(int sfd, char *data, uint32_t len, uint32_t *recv_bytes) -{ - return usbmuxd_recv_timeout(sfd, data, len, recv_bytes, 5000); -} - -void libusbmuxd_set_use_inotify(int set) -{ -#ifdef HAVE_INOTIFY - use_inotify = set; -#endif - return; -} - -void libusbmuxd_set_debug_level(int level) -{ - libusbmuxd_debug = level; - sock_stuff_set_verbose(level); -} diff --git a/libusbmuxd/sock_stuff.c b/libusbmuxd/sock_stuff.c deleted file mode 100644 index 609c8ad..0000000 --- a/libusbmuxd/sock_stuff.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - libusbmuxd - client library to talk to usbmuxd - -Copyright (C) 2009 Nikias Bassen <nikias@gmx.li> -Copyright (C) 2009 Paul Sladen <libiphone@paul.sladen.org> -Copyright (C) 2009 Martin Szulecki <opensuse@sukimashita.com> - -This library is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as -published by the Free Software Foundation, either version 2.1 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#include <stdio.h> -#include <stddef.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <sys/time.h> -#include <sys/stat.h> -#ifdef WIN32 -#include <windows.h> -#include <winsock2.h> -static int wsa_init = 0; -#else -#include <sys/socket.h> -#include <sys/un.h> -#include <netinet/in.h> -#include <netdb.h> -#include <arpa/inet.h> -#endif -#include "sock_stuff.h" - -#define RECV_TIMEOUT 20000 - -static int verbose = 0; - -void sock_stuff_set_verbose(int level) -{ - verbose = level; -} - -#ifndef WIN32 -int create_unix_socket(const char *filename) -{ - struct sockaddr_un name; - int sock; - size_t size; - - // remove if still present - unlink(filename); - - /* Create the socket. */ - sock = socket(PF_LOCAL, SOCK_STREAM, 0); - if (sock < 0) { - perror("socket"); - return -1; - } - - /* Bind a name to the socket. */ - name.sun_family = AF_LOCAL; - strncpy(name.sun_path, filename, sizeof(name.sun_path)); - name.sun_path[sizeof(name.sun_path) - 1] = '\0'; - - /* The size of the address is - the offset of the start of the filename, - plus its length, - plus one for the terminating null byte. - Alternatively you can just do: - size = SUN_LEN (&name); - */ - size = (offsetof(struct sockaddr_un, sun_path) - + strlen(name.sun_path) + 1); - - if (bind(sock, (struct sockaddr *) &name, size) < 0) { - perror("bind"); - close_socket(sock); - return -1; - } - - if (listen(sock, 10) < 0) { - perror("listen"); - close_socket(sock); - return -1; - } - - return sock; -} - -int connect_unix_socket(const char *filename) -{ - struct sockaddr_un name; - int sfd = -1; - size_t size; - struct stat fst; - - // check if socket file exists... - if (stat(filename, &fst) != 0) { - if (verbose >= 2) - fprintf(stderr, "%s: stat '%s': %s\n", __func__, filename, - strerror(errno)); - return -1; - } - // ... and if it is a unix domain socket - if (!S_ISSOCK(fst.st_mode)) { - if (verbose >= 2) - fprintf(stderr, "%s: File '%s' is not a socket!\n", __func__, - filename); - return -1; - } - // make a new socket - if ((sfd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) { - if (verbose >= 2) - fprintf(stderr, "%s: socket: %s\n", __func__, strerror(errno)); - return -1; - } - // and connect to 'filename' - name.sun_family = AF_LOCAL; - strncpy(name.sun_path, filename, sizeof(name.sun_path)); - name.sun_path[sizeof(name.sun_path) - 1] = 0; - - size = (offsetof(struct sockaddr_un, sun_path) - + strlen(name.sun_path) + 1); - - if (connect(sfd, (struct sockaddr *) &name, size) < 0) { - close_socket(sfd); - if (verbose >= 2) - fprintf(stderr, "%s: connect: %s\n", __func__, - strerror(errno)); - return -1; - } - - return sfd; -} -#endif - -int create_socket(uint16_t port) -{ - int sfd = -1; - int yes = 1; -#ifdef WIN32 - WSADATA wsa_data; - if (!wsa_init) { - if (WSAStartup(MAKEWORD(2,2), &wsa_data) != ERROR_SUCCESS) { - fprintf(stderr, "WSAStartup failed!\n"); - ExitProcess(-1); - } - wsa_init = 1; - } -#endif - struct sockaddr_in saddr; - - if (0 > (sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) { - perror("socket()"); - return -1; - } - - if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(int)) == -1) { - perror("setsockopt()"); - close_socket(sfd); - return -1; - } - - memset((void *) &saddr, 0, sizeof(saddr)); - saddr.sin_family = AF_INET; - saddr.sin_addr.s_addr = htonl(INADDR_ANY); - saddr.sin_port = htons(port); - - if (0 > bind(sfd, (struct sockaddr *) &saddr, sizeof(saddr))) { - perror("bind()"); - close_socket(sfd); - return -1; - } - - if (listen(sfd, 1) == -1) { - perror("listen()"); - close_socket(sfd); - return -1; - } - - return sfd; -} - -#if defined(WIN32) || defined(__CYGWIN__) -int connect_socket(const char *addr, uint16_t port) -{ - int sfd = -1; - int yes = 1; - struct hostent *hp; - struct sockaddr_in saddr; -#ifdef WIN32 - WSADATA wsa_data; - if (!wsa_init) { - if (WSAStartup(MAKEWORD(2,2), &wsa_data) != ERROR_SUCCESS) { - fprintf(stderr, "WSAStartup failed!\n"); - ExitProcess(-1); - } - wsa_init = 1; - } -#endif - - if (!addr) { - errno = EINVAL; - return -1; - } - - if ((hp = gethostbyname(addr)) == NULL) { - if (verbose >= 2) - fprintf(stderr, "%s: unknown host '%s'\n", __func__, addr); - return -1; - } - - if (!hp->h_addr) { - if (verbose >= 2) - fprintf(stderr, "%s: gethostbyname returned NULL address!\n", - __func__); - return -1; - } - - if (0 > (sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) { - perror("socket()"); - return -1; - } - - if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(int)) == -1) { - perror("setsockopt()"); - close_socket(sfd); - return -1; - } - - memset((void *) &saddr, 0, sizeof(saddr)); - saddr.sin_family = AF_INET; - saddr.sin_addr.s_addr = *(uint32_t *) hp->h_addr; - saddr.sin_port = htons(port); - - if (connect(sfd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { - perror("connect"); - close_socket(sfd); - return -2; - } - - return sfd; -} -#endif /* WIN32 || __CYGWIN__ */ - -int check_fd(int fd, fd_mode fdm, unsigned int timeout) -{ - fd_set fds; - int sret; - int eagain; - struct timeval to; - struct timeval *pto; - - if (fd <= 0) { - if (verbose >= 2) - fprintf(stderr, "ERROR: invalid fd in check_fd %d\n", fd); - return -1; - } - - FD_ZERO(&fds); - FD_SET(fd, &fds); - - if (timeout > 0) { - to.tv_sec = (time_t) (timeout / 1000); - to.tv_usec = (time_t) ((timeout - (to.tv_sec * 1000)) * 1000); - pto = &to; - } else { - pto = NULL; - } - - sret = -1; - - do { - eagain = 0; - switch (fdm) { - case FDM_READ: - sret = select(fd + 1, &fds, NULL, NULL, pto); - break; - case FDM_WRITE: - sret = select(fd + 1, NULL, &fds, NULL, pto); - break; - case FDM_EXCEPT: - sret = select(fd + 1, NULL, NULL, &fds, pto); - break; - default: - return -1; - } - - if (sret < 0) { - switch (errno) { - case EINTR: - // interrupt signal in select - if (verbose >= 2) - fprintf(stderr, "%s: EINTR\n", __func__); - eagain = 1; - break; - case EAGAIN: - if (verbose >= 2) - fprintf(stderr, "%s: EAGAIN\n", __func__); - break; - default: - if (verbose >= 2) - fprintf(stderr, "%s: select failed: %s\n", __func__, - strerror(errno)); - return -1; - } - } - } while (eagain); - - return sret; -} - -int shutdown_socket(int fd, int how) -{ - return shutdown(fd, how); -} - -int close_socket(int fd) { -#ifdef WIN32 - return closesocket(fd); -#else - return close(fd); -#endif -} - -int recv_buf(int fd, void *data, size_t length) -{ - return recv_buf_timeout(fd, data, length, 0, RECV_TIMEOUT); -} - -int peek_buf(int fd, void *data, size_t length) -{ - return recv_buf_timeout(fd, data, length, MSG_PEEK, RECV_TIMEOUT); -} - -int recv_buf_timeout(int fd, void *data, size_t length, int flags, - unsigned int timeout) -{ - int res; - int result; - - // check if data is available - res = check_fd(fd, FDM_READ, timeout); - if (res <= 0) { - return res; - } - // if we get here, there _is_ data available - result = recv(fd, data, length, flags); - if (res > 0 && result == 0) { - // but this is an error condition - if (verbose >= 3) - fprintf(stderr, "%s: fd=%d recv returned 0\n", __func__, fd); - return -EAGAIN; - } - if (result < 0) { - return -errno; - } - return result; -} - -int send_buf(int fd, void *data, size_t length) -{ - return send(fd, data, length, 0); -} diff --git a/libusbmuxd/sock_stuff.h b/libusbmuxd/sock_stuff.h deleted file mode 100644 index 5efcd27..0000000 --- a/libusbmuxd/sock_stuff.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - libusbmuxd - client library to talk to usbmuxd - -Copyright (C) 2009 Nikias Bassen <nikias@gmx.li> -Copyright (C) 2009 Paul Sladen <libiphone@paul.sladen.org> -Copyright (C) 2009 Martin Szulecki <opensuse@sukimashita.com> - -This library is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as -published by the Free Software Foundation, either version 2.1 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#ifndef __SOCK_STUFF_H -#define __SOCK_STUFF_H - -#include <stdint.h> - -enum fd_mode { - FDM_READ, - FDM_WRITE, - FDM_EXCEPT -}; -typedef enum fd_mode fd_mode; - -#ifdef WIN32 -#include <winsock2.h> -#define SHUT_RD SD_READ -#define SHUT_WR SD_WRITE -#define SHUT_RDWR SD_BOTH -#endif - -#ifndef WIN32 -int create_unix_socket(const char *filename); -int connect_unix_socket(const char *filename); -#endif -int create_socket(uint16_t port); -#if defined(WIN32) || defined(__CYGWIN__) -int connect_socket(const char *addr, uint16_t port); -#endif -int check_fd(int fd, fd_mode fdm, unsigned int timeout); - -int shutdown_socket(int fd, int how); -int close_socket(int fd); - -int recv_buf(int fd, void *data, size_t size); -int peek_buf(int fd, void *data, size_t size); -int recv_buf_timeout(int fd, void *data, size_t size, int flags, - unsigned int timeout); - -int send_buf(int fd, void *data, size_t size); - -void sock_stuff_set_verbose(int level); - -#endif /* __SOCK_STUFF_H */ diff --git a/libusbmuxd/usbmuxd-proto.h b/libusbmuxd/usbmuxd-proto.h deleted file mode 100644 index be9e709..0000000 --- a/libusbmuxd/usbmuxd-proto.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - libusbmuxd - client library to talk to usbmuxd - -Copyright (C) 2009 Paul Sladen <libiphone@paul.sladen.org> -Copyright (C) 2009 Nikias Bassen <nikias@gmx.li> -Copyright (C) 2009 Hector Martin "marcan" <hector@marcansoft.com> - -This library is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as -published by the Free Software Foundation, either version 2.1 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -/* Protocol defintion for usbmuxd proxy protocol */ -#ifndef __USBMUXD_PROTO_H -#define __USBMUXD_PROTO_H - -#include <stdint.h> -#define USBMUXD_PROTOCOL_VERSION 0 - -#if defined(WIN32) || defined(__CYGWIN__) -#define USBMUXD_SOCKET_PORT 27015 -#else -#define USBMUXD_SOCKET_FILE "/var/run/usbmuxd" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -enum usbmuxd_result { - RESULT_OK = 0, - RESULT_BADCOMMAND = 1, - RESULT_BADDEV = 2, - RESULT_CONNREFUSED = 3, - // ??? - // ??? - RESULT_BADVERSION = 6, -}; - -enum usbmuxd_msgtype { - MESSAGE_RESULT = 1, - MESSAGE_CONNECT = 2, - MESSAGE_LISTEN = 3, - MESSAGE_DEVICE_ADD = 4, - MESSAGE_DEVICE_REMOVE = 5, - //??? - //??? - MESSAGE_PLIST = 8, -}; - -struct usbmuxd_header { - uint32_t length; // length of message, including header - uint32_t version; // protocol version - uint32_t message; // message type - uint32_t tag; // responses to this query will echo back this tag -} __attribute__((__packed__)); - -struct usbmuxd_result_msg { - struct usbmuxd_header header; - uint32_t result; -} __attribute__((__packed__)); - -struct usbmuxd_connect_request { - struct usbmuxd_header header; - uint32_t device_id; - uint16_t port; // TCP port number - uint16_t reserved; // set to zero -} __attribute__((__packed__)); - -struct usbmuxd_listen_request { - struct usbmuxd_header header; -} __attribute__((__packed__)); - -struct usbmuxd_device_record { - uint32_t device_id; - uint16_t product_id; - char serial_number[256]; - uint16_t padding; - uint32_t location; -} __attribute__((__packed__)); - -#ifdef __cplusplus -} -#endif - -#endif /* __USBMUXD_PROTO_H */ diff --git a/libusbmuxd/usbmuxd.h b/libusbmuxd/usbmuxd.h deleted file mode 100644 index 0f7b862..0000000 --- a/libusbmuxd/usbmuxd.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - libusbmuxd - client library to talk to usbmuxd - -Copyright (C) 2009 Nikias Bassen <nikias@gmx.li> -Copyright (C) 2009 Paul Sladen <libiphone@paul.sladen.org> -Copyright (C) 2009 Martin Szulecki <opensuse@sukimashita.com> - -This library is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as -published by the Free Software Foundation, either version 2.1 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#ifndef __USBMUXD_H -#define __USBMUXD_H -#include <stdint.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Device information structure holding data to identify the device. - * The relevant 'handle' should be passed to 'usbmuxd_connect()', to - * start a proxy connection. The value 'handle' should be considered - * opaque and no presumption made about the meaning of its value. - */ -typedef struct { - int handle; - int product_id; - char udid[41]; -} usbmuxd_device_info_t; - -/** - * event types for event callback function - */ -enum usbmuxd_event_type { - UE_DEVICE_ADD = 1, - UE_DEVICE_REMOVE -}; - -/** - * Event structure that will be passed to the callback function. - * 'event' will contains the type of the event, and 'device' will contains - * information about the device. - */ -typedef struct { - int event; - usbmuxd_device_info_t device; -} usbmuxd_event_t; - -/** - * Callback function prototype. - */ -typedef void (*usbmuxd_event_cb_t) (const usbmuxd_event_t *event, void *user_data); - -/** - * Subscribe a callback function so that applications get to know about - * device add/remove events. - * - * @param callback A callback function that is executed when an event occurs. - * - * @return 0 on success or negative on error. - */ -int usbmuxd_subscribe(usbmuxd_event_cb_t callback, void *user_data); - -/** - * Unsubscribe callback. - * - * @return only 0 for now. - */ -int usbmuxd_unsubscribe(); - -/** - * Contacts usbmuxd and retrieves a list of connected devices. - * - * @param device_list A pointer to an array of usbmuxd_device_info_t - * that will hold records of the connected devices. The last record - * is a null-terminated record with all fields set to 0/NULL. - * @note The user has to free the list returned. - * - * @return number of attached devices, zero on no devices, or negative - * if an error occured. - */ -int usbmuxd_get_device_list(usbmuxd_device_info_t **device_list); - -/** - * Frees the device list returned by an usbmuxd_get_device_list call - * - * @param device_list A pointer to an array of usbmuxd_device_info_t to free. - * - * @return 0 on success, -1 on error. - */ -int usbmuxd_device_list_free(usbmuxd_device_info_t **device_list); - -/** - * Gets device information for the device specified by udid. - * - * @param udid A device UDID of the device to look for. If udid is NULL, - * This function will return the first device found. - * @param device Pointer to a previously allocated (or static) - * usbmuxd_device_info_t that will be filled with the device info. - * - * @return 0 if no matching device is connected, 1 if the device was found, - * or a negative value on error. - */ -int usbmuxd_get_device_by_udid(const char *udid, usbmuxd_device_info_t *device); - -/** - * Request proxy connect to - * - * @param handle returned by 'usbmuxd_scan()' - * - * @param tcp_port TCP port number on device, in range 0-65535. - * common values are 62078 for lockdown, and 22 for SSH. - * - * @return file descriptor socket of the connection, or -1 on error - */ -int usbmuxd_connect(const int handle, const unsigned short tcp_port); - -/** - * Disconnect. For now, this just closes the socket file descriptor. - * - * @param sfd socker file descriptor returned by usbmuxd_connect() - * - * @return 0 on success, -1 on error. - */ -int usbmuxd_disconnect(int sfd); - -/** - * Send data to the specified socket. - * - * @param sfd socket file descriptor returned by usbmuxd_connect() - * @param data buffer to send - * @param len size of buffer to send - * @param sent_bytes how many bytes sent - * - * @return 0 on success, a negative errno value otherwise. - */ -int usbmuxd_send(int sfd, const char *data, uint32_t len, uint32_t *sent_bytes); - -/** - * Receive data from the specified socket. - * - * @param sfd socket file descriptor returned by usbmuxd_connect() - * @param data buffer to put the data to - * @param len number of bytes to receive - * @param recv_bytes number of bytes received - * @param timeout how many milliseconds to wait for data - * - * @return 0 on success, a negative errno value otherwise. - */ -int usbmuxd_recv_timeout(int sfd, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout); - -/** - * Receive data from the specified socket with a default timeout. - * - * @param sfd socket file descriptor returned by usbmuxd_connect() - * @param data buffer to put the data to - * @param len number of bytes to receive - * @param recv_bytes number of bytes received - * - * @return 0 on success, a negative errno value otherwise. - */ -int usbmuxd_recv(int sfd, char *data, uint32_t len, uint32_t *recv_bytes); - -/** - * Enable or disable the use of inotify extension. Enabled by default. - * Use 0 to disable and 1 to enable inotify support. - * This only has an effect on linux systems if inotify support has been built - * in. Otherwise and on all other platforms this function has no effect. - */ -void libusbmuxd_set_use_inotify(int set); - -void libusbmuxd_set_debug_level(int level); - -#ifdef __cplusplus -} -#endif - -#endif /* __USBMUXD_H */ |