summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2009-08-20 01:19:09 +0200
committerGravatar Hector Martin2009-08-21 03:08:18 +0200
commitc46062aca98f2f077b3bab5c5f72ff2cb57b9dc2 (patch)
tree0934caaa277436a42c515c9ccc86acb004620c7a
parent886d4014509d64023ecf99b57d0fd39818e85bd4 (diff)
downloadusbmuxd-c46062aca98f2f077b3bab5c5f72ff2cb57b9dc2.tar.gz
usbmuxd-c46062aca98f2f077b3bab5c5f72ff2cb57b9dc2.tar.bz2
Updated usbmuxd protocol definition and public header.
[Hector] Merged by putting utils.c into a common dir, avoiding log.c dependency for libusbmuxd, adding CMake magic to tie things up.
-rw-r--r--common/utils.c (renamed from usbmuxd/utils.c)11
-rw-r--r--common/utils.h (renamed from usbmuxd/utils.h)0
-rw-r--r--libusbmuxd/CMakeLists.txt4
-rw-r--r--libusbmuxd/libusbmuxd.c333
-rw-r--r--libusbmuxd/usbmuxd-proto.h58
-rw-r--r--libusbmuxd/usbmuxd.h61
-rw-r--r--tools/iproxy.c4
-rw-r--r--usbmuxd/CMakeLists.txt8
-rw-r--r--usbmuxd/client.c36
-rw-r--r--usbmuxd/client.h50
10 files changed, 409 insertions, 156 deletions
diff --git a/usbmuxd/utils.c b/common/utils.c
index 1ffa04a..6803941 100644
--- a/usbmuxd/utils.c
+++ b/common/utils.c
@@ -24,8 +24,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include <stdlib.h>
#include <string.h>
+#include <stdio.h>
#include "utils.h"
-#include "log.h"
+
+#ifdef USBMUXD_DAEMON
+# include "log.h"
+# define util_error(...) usbmuxd_log(LL_ERROR, __VA_ARGS__)
+#else
+# define util_error(...) fprintf(stderr, __VA_ARGS__)
+#endif
void fdlist_create(struct fdlist *list)
{
@@ -96,7 +103,7 @@ void collection_remove(struct collection *col, void *element)
return;
}
}
- usbmuxd_log(LL_ERROR, "collection_remove: element %p not present in collection %p (cap %d)", element, col, col->capacity);
+ util_error("collection_remove: element %p not present in collection %p (cap %d)", element, col, col->capacity);
}
int collection_count(struct collection *col)
diff --git a/usbmuxd/utils.h b/common/utils.h
index ad4ac9d..ad4ac9d 100644
--- a/usbmuxd/utils.h
+++ b/common/utils.h
diff --git a/libusbmuxd/CMakeLists.txt b/libusbmuxd/CMakeLists.txt
index 61de1a8..7f7b35f 100644
--- a/libusbmuxd/CMakeLists.txt
+++ b/libusbmuxd/CMakeLists.txt
@@ -1,4 +1,6 @@
-add_library (libusbmuxd libusbmuxd.c sock_stuff.c)
+include_directories (${CMAKE_SOURCE_DIR}/common)
+
+add_library (libusbmuxd libusbmuxd.c sock_stuff.c ../common/utils.c)
# 'lib' is a UNIXism, the proper CMake target is usbmuxd
# 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 090695f..6a54765 100644
--- a/libusbmuxd/libusbmuxd.c
+++ b/libusbmuxd/libusbmuxd.c
@@ -6,6 +6,7 @@
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
+#include <signal.h>
// usbmuxd public interface
#include "usbmuxd.h"
@@ -13,10 +14,48 @@
#include "usbmuxd-proto.h"
// socket utility functions
#include "sock_stuff.h"
+// misc utility functions
+#include "utils.h"
+static struct collection devices;
+static usbmuxd_event_cb_t event_cb = NULL;
+pthread_t devmon;
+static int listenfd = -1;
+
+/**
+ * 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()
+{
+#ifdef WINDOWS
+ return connect_socket("127.0.0.1", 27015);
+#else
+ return connect_unix_socket(USBMUXD_SOCKET_FILE);
+#endif
+}
+
+/**
+ * Retrieves the result code to a previously sent request.
+ */
static int usbmuxd_get_result(int sfd, uint32_t tag, uint32_t * result)
{
- struct usbmuxd_result res;
+ struct usbmuxd_result_msg res;
int recv_len;
if (!result) {
@@ -29,8 +68,8 @@ static int usbmuxd_get_result(int sfd, uint32_t tag, uint32_t * result)
} else {
if ((recv_len == sizeof(res))
&& (res.header.length == (uint32_t) recv_len)
- && (res.header.reserved == 0)
- && (res.header.type == USBMUXD_RESULT)
+ && (res.header.version == USBMUXD_PROTOCOL_VERSION)
+ && (res.header.message == MESSAGE_RESULT)
) {
*result = res.result;
if (res.header.tag == tag) {
@@ -44,16 +83,229 @@ static int usbmuxd_get_result(int sfd, uint32_t tag, uint32_t * result)
return -1;
}
-int usbmuxd_scan(usbmuxd_scan_result ** available_devices)
+/**
+ * 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_device_event event)
+{
+ usbmuxd_event_t ev;
+
+ if (!callback || !dev) {
+ return;
+ }
+
+ ev.event = event;
+ memcpy(&ev.device, dev, sizeof(usbmuxd_device_info_t));
+
+ printf("%s: event=%d, handle=%d\n", __func__, ev.event, ev.device.handle);
+
+ callback(&ev);
+}
+
+/**
+ * Tries to connect to usbmuxd and wait if it is not running.
+ *
+ * TODO inotify support should come here
+ */
+static int usbmuxd_listen()
{
- struct usbmuxd_scan_request s_req;
int sfd;
- int scan_success = 0;
+ uint32_t res = -1;
+ struct usbmuxd_listen_request req;
+ struct usbmuxd_header hdr;
+
+ req.header.length = sizeof(struct usbmuxd_listen_request);
+ req.header.version = USBMUXD_PROTOCOL_VERSION;
+ req.header.message = MESSAGE_LISTEN;
+ req.header.tag = 2;
+
+ sfd = connect_usbmuxd_socket();
+ if (sfd < 0) {
+ fprintf(stderr, "DEBUG: waiting for usbmuxd to come up.\n");
+
+ while (event_cb) {
+ if ((sfd = connect_usbmuxd_socket()) > 0) {
+ fprintf(stderr, "DEBUG: usbmuxd started\n");
+ break;
+ }
+ sleep(1);
+ }
+ }
+
+ if (sfd < 0) {
+ fprintf(stderr, "ERROR: usbmuxd was supposed to be running here...\n");
+ return sfd;
+ }
+
+ if (send_buf(sfd, &req, req.header.length) != (int)req.header.length) {
+ fprintf(stderr, "ERROR: could not send listen packet\n");
+ close(sfd);
+ return -1;
+ }
+ if (usbmuxd_get_result(sfd, req.header.tag, &res) && (res != 0)) {
+ fprintf(stderr, "ERROR: did not get OK\n");
+ close(sfd);
+ return -1;
+ }
+
+ 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)
+{
+ int recv_len;
+ struct usbmuxd_listen_request req;
+ struct usbmuxd_header hdr;
+
+ /* block until we receive something */
+ recv_len = recv_buf_timeout(sfd, &hdr, sizeof(hdr), 0, 0);
+ if (recv_len < 0) {
+ int i;
+ fprintf(stderr, "DEBUG: connection closed.\n");
+ // when then usbmuxd connection fails,
+ // generate remove events for every device that
+ // is still present so applications know about it
+ // TODO: is this behaviour correct?
+ FOREACH(usbmuxd_device_info_t *dev, &devices) {
+ generate_event(callback, dev, UE_DEVICE_REMOVE);
+ } ENDFOREACH
+ collection_free(&devices);
+ return recv_len;
+ } else if (recv_len == sizeof(hdr)) {
+ if (hdr.message == MESSAGE_DEVICE_ADD) {
+ struct usbmuxd_device_record dev;
+ usbmuxd_device_info_t *devinfo = (usbmuxd_device_info_t*)malloc(sizeof(usbmuxd_device_info_t));
+ if (!devinfo) {
+ fprintf(stderr, "Out of memory!\n");
+ return -1;
+ }
+
+ if (hdr.length != sizeof(struct usbmuxd_header)+sizeof(struct usbmuxd_device_record)) {
+ fprintf(stderr, "WARNING: unexpected packet size%d for MESSAGE_DEVICE_ADD (expected %d)!\n", hdr.length, sizeof(struct usbmuxd_header)+sizeof(struct usbmuxd_device_record));
+ }
+ recv_len = recv_buf_timeout(sfd, &dev, hdr.length - sizeof(struct usbmuxd_header), 0, 5000);
+ if (recv_len != (hdr.length - sizeof(struct usbmuxd_header))) {
+ fprintf(stderr, "Could not receive packet\n");
+ return recv_len;
+ }
+
+ devinfo->handle = dev.device_id;
+ devinfo->product_id = dev.product_id;
+ memset(devinfo->uuid, '\0', sizeof(devinfo->uuid));
+ memcpy(devinfo->uuid, dev.serial_number, sizeof(devinfo->uuid));
+
+ collection_add(&devices, devinfo);
+ generate_event(callback, devinfo, UE_DEVICE_ADD);
+ } else if (hdr.message == MESSAGE_DEVICE_REMOVE) {
+ uint32_t handle;
+ usbmuxd_device_info_t *dev;
+
+ if (hdr.length != sizeof(struct usbmuxd_header)+sizeof(uint32_t)) {
+ fprintf(stderr, "WARNING: unexpected packet size%d for MESSAGE_DEVICE_REMOVE (expected %d)!\n", hdr.length, sizeof(struct usbmuxd_header)+sizeof(uint32_t));
+ }
+ recv_len = recv_buf_timeout(sfd, &handle, sizeof(uint32_t), 0, 5000);
+ if (recv_len != sizeof(uint32_t)) {
+ fprintf(stderr, "Could not receive packet\n");
+ return recv_len;
+ }
+
+ dev = devices_find(handle);
+ if (!dev) {
+ fprintf(stderr, "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", handle);
+ } else {
+ generate_event(callback, dev, UE_DEVICE_REMOVE);
+ collection_remove(&devices, dev);
+ }
+ } else {
+ fprintf(stderr, "%s: Unknown message type %d length %d\n", __func__, hdr.message, hdr.length);
+ }
+ } else {
+ fprintf(stderr, "%s: ERROR: incomplete packet received!\n", __func__);
+ }
+ return 0;
+}
+
+/**
+ * Device Monitor thread function.
+ *
+ * This function sets up a connection to usbmuxd
+ */
+static void *device_monitor(void *data)
+{
+ collection_init(&devices);
+
+ while (event_cb) {
+
+ listenfd = usbmuxd_listen();
+ if (listenfd < 0) {
+ fprintf(stderr, "DEBUG: listenfd=%d\n", listenfd);
+ continue;
+ }
+
+ while (event_cb) {
+ printf("waiting for events\n");
+ int res = get_next_event(listenfd, event_cb);
+ if (res < 0) {
+ fprintf(stderr, "%s: closing connection (code %d)\n", __func__, res);
+ break;
+ }
+ }
+ }
+
+ collection_free(&devices);
+ printf("%s: terminated\n", __func__);
+
+ return NULL;
+}
+
+int usbmuxd_subscribe(usbmuxd_event_cb_t callback)
+{
+ int res;
+
+ if (!callback) {
+ return -EINVAL;
+ }
+ event_cb = callback;
+
+ res = pthread_create(&devmon, NULL, device_monitor, NULL);
+ if (res != 0) {
+ fprintf(stderr, "ERROR: Could not start device watcher thread!\n");
+ return res;
+ }
+ return 0;
+}
+
+int usbmuxd_unsubscribe()
+{
+ event_cb = NULL;
+
+ if (pthread_kill(devmon, 0) == 0) {
+ printf("%s: unsubscribing callback\n", __func__);
+ close(listenfd);
+ listenfd = -1;
+ pthread_kill(devmon, SIGINT);
+ pthread_join(devmon, NULL);
+ }
+
+ return 0;
+}
+
+int usbmuxd_scan(usbmuxd_device_info_t ** available_devices)
+{
+ struct usbmuxd_listen_request s_req;
+ int sfd;
+ int listen_success = 0;
uint32_t res;
- uint32_t pktlen;
int recv_len;
- usbmuxd_scan_result *newlist = NULL;
- struct usbmuxd_device_info_record dev_info_pkt;
+ usbmuxd_device_info_t *newlist = NULL;
+ struct usbmuxd_header hdr;
+ struct usbmuxd_device_record dev_info;
int dev_cnt = 0;
sfd = connect_unix_socket(USBMUXD_SOCKET_FILE);
@@ -62,9 +314,9 @@ int usbmuxd_scan(usbmuxd_scan_result ** available_devices)
return sfd;
}
- s_req.header.length = sizeof(struct usbmuxd_scan_request);
- s_req.header.reserved = 0;
- s_req.header.type = USBMUXD_SCAN;
+ s_req.header.length = sizeof(struct usbmuxd_listen_request);
+ s_req.header.version = USBMUXD_PROTOCOL_VERSION;
+ s_req.header.message = MESSAGE_LISTEN;
s_req.header.tag = 2;
// send scan request packet
@@ -73,7 +325,7 @@ int usbmuxd_scan(usbmuxd_scan_result ** available_devices)
res = -1;
// get response
if (usbmuxd_get_result(sfd, s_req.header.tag, &res) && (res == 0)) {
- scan_success = 1;
+ listen_success = 1;
} else {
fprintf(stderr,
"%s: Did not get response to scan request (with result=0)...\n",
@@ -83,50 +335,44 @@ int usbmuxd_scan(usbmuxd_scan_result ** available_devices)
}
}
- if (!scan_success) {
- fprintf(stderr, "%s: Could not send scan request!\n", __func__);
+ if (!listen_success) {
+ fprintf(stderr, "%s: Could not send listen request!\n", __func__);
return -1;
}
*available_devices = NULL;
// receive device list
while (1) {
- if (recv_buf_timeout(sfd, &pktlen, 4, MSG_PEEK, 1000) == 4) {
- if (pktlen != sizeof(dev_info_pkt)) {
+ if (recv_buf_timeout(sfd, &hdr, sizeof(hdr), 0, 1000) == sizeof(hdr)) {
+ if (hdr.length != sizeof(hdr)+sizeof(dev_info)) {
// invalid packet size received!
fprintf(stderr,
"%s: Invalid packet size (%d) received when expecting a device info record.\n",
- __func__, pktlen);
+ __func__, hdr.length);
break;
}
- recv_len = recv_buf(sfd, &dev_info_pkt, pktlen);
+ recv_len = recv_buf(sfd, &dev_info, hdr.length - sizeof(hdr));
if (recv_len <= 0) {
fprintf(stderr,
"%s: Error when receiving device info record\n",
__func__);
break;
- } else if ((uint32_t) recv_len < pktlen) {
+ } else if ((uint32_t) recv_len < hdr.length - sizeof(hdr)) {
fprintf(stderr,
- "%s: received less data than specified in header!\n",
- __func__);
+ "%s: received less data than specified in header!\n", __func__);
} else {
- //fprintf(stderr, "%s: got device record with id %d, UUID=%s\n", __func__, dev_info_pkt.device_info.device_id, dev_info_pkt.device_info.serial_number);
- newlist =
- (usbmuxd_scan_result *) realloc(*available_devices,
- sizeof
- (usbmuxd_scan_result) *
- (dev_cnt + 1));
+ newlist = (usbmuxd_device_info_t *) realloc(*available_devices, sizeof(usbmuxd_device_info_t) * (dev_cnt + 1));
if (newlist) {
newlist[dev_cnt].handle =
- (int) dev_info_pkt.device.device_id;
+ (int) dev_info.device_id;
newlist[dev_cnt].product_id =
- dev_info_pkt.device.product_id;
- memset(newlist[dev_cnt].serial_number, '\0',
- sizeof(newlist[dev_cnt].serial_number));
- memcpy(newlist[dev_cnt].serial_number,
- dev_info_pkt.device.serial_number,
- sizeof(dev_info_pkt.device.serial_number));
+ dev_info.product_id;
+ memset(newlist[dev_cnt].uuid, '\0',
+ sizeof(newlist[dev_cnt].uuid));
+ memcpy(newlist[dev_cnt].uuid,
+ dev_info.serial_number,
+ sizeof(newlist[dev_cnt].uuid));
*available_devices = newlist;
dev_cnt++;
} else {
@@ -144,24 +390,21 @@ int usbmuxd_scan(usbmuxd_scan_result ** available_devices)
}
// terminating zero record
- newlist =
- (usbmuxd_scan_result *) realloc(*available_devices,
- sizeof(usbmuxd_scan_result) *
- (dev_cnt + 1));
- memset(newlist + dev_cnt, 0, sizeof(usbmuxd_scan_result));
+ newlist = (usbmuxd_device_info_t*) realloc(*available_devices, sizeof(usbmuxd_device_info_t) * (dev_cnt + 1));
+ memset(newlist + dev_cnt, 0, sizeof(usbmuxd_device_info_t));
*available_devices = newlist;
return dev_cnt;
}
-int usbmuxd_connect(const int handle, const unsigned short tcp_port)
+int usbmuxd_connect(const int handle, const unsigned short port)
{
int sfd;
struct usbmuxd_connect_request c_req;
int connected = 0;
uint32_t res = -1;
- sfd = connect_unix_socket(USBMUXD_SOCKET_FILE);
+ sfd = connect_usbmuxd_socket();
if (sfd < 0) {
fprintf(stderr, "%s: Error: Connection to usbmuxd failed: %s\n",
__func__, strerror(errno));
@@ -169,11 +412,11 @@ int usbmuxd_connect(const int handle, const unsigned short tcp_port)
}
c_req.header.length = sizeof(c_req);
- c_req.header.reserved = 0;
- c_req.header.type = USBMUXD_CONNECT;
+ c_req.header.version = USBMUXD_PROTOCOL_VERSION;
+ c_req.header.message = MESSAGE_CONNECT;
c_req.header.tag = 3;
c_req.device_id = (uint32_t) handle;
- c_req.tcp_dport = htons(tcp_port);
+ c_req.port = htons(port);
c_req.reserved = 0;
if (send_buf(sfd, &c_req, sizeof(c_req)) < 0) {
diff --git a/libusbmuxd/usbmuxd-proto.h b/libusbmuxd/usbmuxd-proto.h
index 7f8c2d6..1ecb7bc 100644
--- a/libusbmuxd/usbmuxd-proto.h
+++ b/libusbmuxd/usbmuxd-proto.h
@@ -1,52 +1,62 @@
/* Protocol defintion for usbmuxd proxy protocol */
-
#ifndef __USBMUXD_PROTO_H
#define __USBMUXD_PROTO_H
#include <stdint.h>
+#define USBMUXD_PROTOCOL_VERSION 0
#define USBMUXD_SOCKET_FILE "/var/run/usbmuxd"
+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 reserved; // always zero
- uint32_t type; // message type
+ 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 {
+struct usbmuxd_result_msg {
struct usbmuxd_header header;
uint32_t result;
} __attribute__((__packed__));
-struct usbmuxd_connect_request {
+struct usbmuxd_connect_request {
struct usbmuxd_header header;
uint32_t device_id;
- uint16_t tcp_dport; // TCP port number
+ uint16_t port; // TCP port number
uint16_t reserved; // set to zero
} __attribute__((__packed__));
-struct usbmuxd_device {
- uint32_t device_id;
- uint16_t product_id;
- char serial_number[40];
-} __attribute__((__packed__));
-
-struct usbmuxd_device_info_record {
+struct usbmuxd_listen_request {
struct usbmuxd_header header;
- struct usbmuxd_device device;
- char padding[222];
} __attribute__((__packed__));
-struct usbmuxd_scan_request {
- struct usbmuxd_header header;
+struct usbmuxd_device_record {
+ uint32_t device_id;
+ uint16_t product_id;
+ char serial_number[256];
+ uint16_t padding;
+ uint32_t location;
} __attribute__((__packed__));
-enum {
- USBMUXD_RESULT = 1,
- USBMUXD_CONNECT = 2,
- USBMUXD_SCAN = 3,
- USBMUXD_DEVICE_INFO = 4,
-};
-
#endif /* __USBMUXD_PROTO_H */
diff --git a/libusbmuxd/usbmuxd.h b/libusbmuxd/usbmuxd.h
index ba45ec3..f12ae39 100644
--- a/libusbmuxd/usbmuxd.h
+++ b/libusbmuxd/usbmuxd.h
@@ -2,10 +2,7 @@
#define __USBMUXD_H
/**
- * Array entry returned by 'usbmuxd_scan()' scanning.
- *
- * If more than one device is available, 'product_id' and
- * 'serial_number' and be analysed to help make a selection.
+ * 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.
@@ -13,22 +10,58 @@
typedef struct {
int handle;
int product_id;
- char serial_number[41];
-} usbmuxd_scan_result;
+ char uuid[41];
+} usbmuxd_device_info_t;
+
+/**
+ * event types for event callback function
+ */
+enum usbmuxd_device_event {
+ 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);
+
+/**
+ * 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);
+
+/**
+ * Unsubscribe callback.
+ *
+ * @return only 0 for now.
+ */
+int usbmuxd_unsubscribe();
/**
- * Contacts usbmuxd and performs a scan for connected devices.
+ * Contacts usbmuxd and retrieves a list of connected devices.
*
- * @param available_devices pointer to array of usbmuxd_scan_result.
- * Array of available devices. The required 'handle'
- * should be passed to 'usbmuxd_connect()'. The returned array
- * is zero-terminated for convenience; the final (unused)
- * entry containing handle == 0. The returned array pointer
- * should be freed by passing to 'free()' after use.
+ * @param available_devices pointer to an array of usbmuxd_device_info_t
+ * that will hold records of the connected devices.
*
* @return number of available devices, zero on no devices, or negative on error
*/
-int usbmuxd_scan(usbmuxd_scan_result **available_devices);
+int usbmuxd_scan(usbmuxd_device_info_t **available_devices);
/**
* Request proxy connect to
diff --git a/tools/iproxy.c b/tools/iproxy.c
index 3cb2894..657ac89 100644
--- a/tools/iproxy.c
+++ b/tools/iproxy.c
@@ -141,7 +141,7 @@ void *run_ctos_loop(void *arg)
void *acceptor_thread(void *arg)
{
struct client_data *cdata;
- usbmuxd_scan_result *dev_list = NULL;
+ usbmuxd_device_info_t *dev_list = NULL;
pthread_t ctos;
int count;
@@ -166,7 +166,7 @@ void *acceptor_thread(void *arg)
return NULL;
}
- fprintf(stdout, "Requesting connecion to device handle == %d (serial: %s), port %d\n", dev_list[0].handle, dev_list[0].serial_number, device_port);
+ fprintf(stdout, "Requesting connecion to device handle == %d (serial: %s), port %d\n", dev_list[0].handle, dev_list[0].uuid, device_port);
cdata->sfd = usbmuxd_connect(dev_list[0].handle, device_port);
free(dev_list);
diff --git a/usbmuxd/CMakeLists.txt b/usbmuxd/CMakeLists.txt
index b982dc0..7d0d3d8 100644
--- a/usbmuxd/CMakeLists.txt
+++ b/usbmuxd/CMakeLists.txt
@@ -2,8 +2,12 @@ find_package(USB REQUIRED)
include_directories(${USB_INCLUDE_DIRS})
set(LIBS ${LIBS} ${USB_LIBRARIES})
-add_definitions(-Wall -O2 -g)
-add_executable(usbmuxd main.c usb-linux.c log.c utils.c device.c client.c)
+include_directories (${CMAKE_SOURCE_DIR}/common)
+include_directories (${CMAKE_SOURCE_DIR}/usbmuxd)
+include_directories (${CMAKE_SOURCE_DIR}/libusbmuxd)
+
+add_definitions(-Wall -O2 -g -DUSBMUXD_DAEMON)
+add_executable(usbmuxd main.c usb-linux.c log.c ../common/utils.c device.c client.c)
target_link_libraries(usbmuxd ${LIBS})
install(TARGETS usbmuxd RUNTIME DESTINATION sbin) \ No newline at end of file
diff --git a/usbmuxd/client.c b/usbmuxd/client.c
index 7a3160f..0e47e84 100644
--- a/usbmuxd/client.c
+++ b/usbmuxd/client.c
@@ -150,10 +150,10 @@ void client_get_fds(struct fdlist *list)
} ENDFOREACH
}
-static int send_pkt(struct mux_client *client, uint32_t tag, enum client_msgtype msg, void *payload, int payload_length)
+static int send_pkt(struct mux_client *client, uint32_t tag, enum usbmuxd_msgtype msg, void *payload, int payload_length)
{
- struct client_header hdr;
- hdr.version = CLIENT_PROTOCOL_VERSION;
+ struct usbmuxd_header hdr;
+ hdr.version = USBMUXD_PROTOCOL_VERSION;
hdr.length = sizeof(hdr) + payload_length;
hdr.message = msg;
hdr.tag = tag;
@@ -176,7 +176,7 @@ static int send_result(struct mux_client *client, uint32_t tag, uint32_t result)
return send_pkt(client, tag, MESSAGE_RESULT, &result, sizeof(uint32_t));
}
-int client_notify_connect(struct mux_client *client, enum client_result result)
+int client_notify_connect(struct mux_client *client, enum usbmuxd_result result)
{
usbmuxd_log(LL_SPEW, "client_notify_connect fd %d result %d", client->fd, result);
if(client->state == CLIENT_DEAD)
@@ -201,13 +201,13 @@ int client_notify_connect(struct mux_client *client, enum client_result result)
static int notify_device(struct mux_client *client, struct device_info *dev)
{
- struct client_msg_dev dmsg;
+ struct usbmuxd_device_record dmsg;
memset(&dmsg, 0, sizeof(dmsg));
dmsg.device_id = dev->id;
- strncpy(dmsg.device_serial, dev->serial, 256);
- dmsg.device_serial[255] = 0;
+ strncpy(dmsg.serial_number, dev->serial, 256);
+ dmsg.serial_number[255] = 0;
dmsg.location = dev->location;
- dmsg.device_pid = dev->pid;
+ dmsg.product_id = dev->pid;
return send_pkt(client, 0, MESSAGE_DEVICE_ADD, &dmsg, sizeof(dmsg));
}
@@ -225,7 +225,7 @@ static int start_listen(struct mux_client *client)
count = device_get_list(devs);
// going to need a larger buffer for many devices
- int needed_buffer = count * (sizeof(struct client_msg_dev) + sizeof(struct client_header)) + REPLY_BUF_SIZE;
+ int needed_buffer = count * (sizeof(struct usbmuxd_device_record) + sizeof(struct usbmuxd_header)) + REPLY_BUF_SIZE;
if(client->ob_capacity < needed_buffer) {
usbmuxd_log(LL_DEBUG, "Enlarging client %d reply buffer %d -> %d to make space for device notifications", client->fd, client->ob_capacity, needed_buffer);
client->ob_buf = realloc(client->ob_buf, needed_buffer);
@@ -242,7 +242,7 @@ static int start_listen(struct mux_client *client)
return count;
}
-static int client_command(struct mux_client *client, struct client_header *hdr, const char *payload)
+static int client_command(struct mux_client *client, struct usbmuxd_header *hdr, const char *payload)
{
int res;
usbmuxd_log(LL_DEBUG, "Client command in fd %d len %d ver %d msg %d tag %d", client->fd, hdr->length, hdr->version, hdr->message, hdr->tag);
@@ -255,7 +255,7 @@ static int client_command(struct mux_client *client, struct client_header *hdr,
return -1;
}
- struct client_msg_connect *ch;
+ struct usbmuxd_connect_request *ch;
switch(hdr->message) {
case MESSAGE_LISTEN:
if(send_result(client, hdr->tag, 0) < 0)
@@ -318,8 +318,8 @@ static void process_recv(struct mux_client *client)
{
int res;
int did_read = 0;
- if(client->ib_size < sizeof(struct client_header)) {
- res = recv(client->fd, client->ib_buf + client->ib_size, sizeof(struct client_header) - client->ib_size, 0);
+ if(client->ib_size < sizeof(struct usbmuxd_header)) {
+ res = recv(client->fd, client->ib_buf + client->ib_size, sizeof(struct usbmuxd_header) - client->ib_size, 0);
if(res <= 0) {
if(res < 0)
usbmuxd_log(LL_ERROR, "Receive from client fd %d failed: %s", client->fd, strerror(errno));
@@ -329,20 +329,20 @@ static void process_recv(struct mux_client *client)
return;
}
client->ib_size += res;
- if(client->ib_size < sizeof(struct client_header))
+ if(client->ib_size < sizeof(struct usbmuxd_header))
return;
did_read = 1;
}
- struct client_header *hdr = (void*)client->ib_buf;
- if(hdr->version != CLIENT_PROTOCOL_VERSION) {
- usbmuxd_log(LL_INFO, "Client %d version mismatch: expected %d, got %d", client->fd, CLIENT_PROTOCOL_VERSION, hdr->version);
+ struct usbmuxd_header *hdr = (void*)client->ib_buf;
+ if(hdr->version != USBMUXD_PROTOCOL_VERSION) {
+ usbmuxd_log(LL_INFO, "Client %d version mismatch: expected %d, got %d", client->fd, USBMUXD_PROTOCOL_VERSION, hdr->version);
client_close(client);
}
if(hdr->length > client->ib_capacity) {
usbmuxd_log(LL_INFO, "Client %d message is too long (%d bytes)", client->fd, hdr->length);
client_close(client);
}
- if(hdr->length < sizeof(struct client_header)) {
+ if(hdr->length < sizeof(struct usbmuxd_header)) {
usbmuxd_log(LL_ERROR, "Client %d message is too short (%d bytes)", client->fd, hdr->length);
client_close(client);
}
diff --git a/usbmuxd/client.h b/usbmuxd/client.h
index 0cda676..4fc1ab4 100644
--- a/usbmuxd/client.h
+++ b/usbmuxd/client.h
@@ -22,62 +22,16 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define __CLIENT_H__
#include <stdint.h>
+#include "usbmuxd-proto.h"
struct device_info;
struct mux_client;
-enum client_result {
- RESULT_OK = 0,
- RESULT_BADCOMMAND = 1,
- RESULT_BADDEV = 2,
- RESULT_CONNREFUSED = 3,
- // ???
- // ???
- RESULT_BADVERSION = 6,
-};
-
-enum client_msgtype {
- MESSAGE_RESULT = 1,
- MESSAGE_CONNECT = 2,
- MESSAGE_LISTEN = 3,
- MESSAGE_DEVICE_ADD = 4,
- MESSAGE_DEVICE_REMOVE = 5,
- //???
- //???
- //MESSAGE_PLIST = 8,
-};
-
-#define CLIENT_PROTOCOL_VERSION 0
-
-struct client_header {
- uint32_t length;
- uint32_t version;
- uint32_t message;
- uint32_t tag;
-};
-
-struct client_msg_result {
- uint32_t result;
-};
-
-struct client_msg_connect {
- uint32_t device_id;
- uint16_t port;
-};
-
-struct client_msg_dev {
- uint32_t device_id;
- uint16_t device_pid;
- char device_serial[256];
- uint16_t padding;
- uint32_t location;
-};
-
int client_read(struct mux_client *client, void *buffer, int len);
int client_write(struct mux_client *client, void *buffer, int len);
int client_set_events(struct mux_client *client, short events);
void client_close(struct mux_client *client);
-int client_notify_connect(struct mux_client *client, enum client_result result);
+int client_notify_connect(struct mux_client *client, enum usbmuxd_result result);
void client_device_add(struct device_info *dev);
void client_device_remove(int device_id);