summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2009-09-10 13:28:13 +0200
committerGravatar Martin Szulecki2009-09-12 11:41:38 +0200
commit1f6282ffddec7012df82fa929dfe72cfc74b063a (patch)
tree452c927c07806855f360ee9803111a1f72e05d3c
parent26ce10634d277df51c4e9c2bd61b409df3f5b060 (diff)
downloadlibimobiledevice-1f6282ffddec7012df82fa929dfe72cfc74b063a.tar.gz
libimobiledevice-1f6282ffddec7012df82fa929dfe72cfc74b063a.tar.bz2
Public API rework, extension and adaption to latest libusbmuxd-1.0 API.
-rw-r--r--include/libiphone/libiphone.h44
-rw-r--r--src/AFC.c40
-rw-r--r--src/AFC.h2
-rw-r--r--src/MobileSync.c14
-rw-r--r--src/MobileSync.h2
-rw-r--r--src/NotificationProxy.c28
-rw-r--r--src/NotificationProxy.h2
-rw-r--r--src/iphone.c371
-rw-r--r--src/iphone.h22
-rw-r--r--src/lockdown.c26
-rw-r--r--src/lockdown.h2
-rw-r--r--src/userpref.c6
-rw-r--r--src/userpref.h4
-rw-r--r--tools/iphone_id.c9
-rw-r--r--tools/iphoneinfo.c4
-rw-r--r--tools/iphonesyslog.c16
16 files changed, 437 insertions, 155 deletions
diff --git a/include/libiphone/libiphone.h b/include/libiphone/libiphone.h
index 1451f15..77860f8 100644
--- a/include/libiphone/libiphone.h
+++ b/include/libiphone/libiphone.h
@@ -31,7 +31,6 @@ extern "C" {
31#include <sys/types.h> 31#include <sys/types.h>
32#include <sys/stat.h> 32#include <sys/stat.h>
33#include <plist/plist.h> 33#include <plist/plist.h>
34#include <usbmuxd.h>
35 34
36/* Error Codes */ 35/* Error Codes */
37#define IPHONE_E_SUCCESS 0 36#define IPHONE_E_SUCCESS 0
@@ -46,19 +45,56 @@ typedef int16_t iphone_error_t;
46struct iphone_device_int; 45struct iphone_device_int;
47typedef struct iphone_device_int *iphone_device_t; 46typedef struct iphone_device_int *iphone_device_t;
48 47
48struct iphone_connection_int;
49typedef struct iphone_connection_int *iphone_connection_t;
50
49/* Debugging */ 51/* Debugging */
50#define DBGMASK_ALL 0xFFFF 52#define DBGMASK_ALL 0xFFFF
51#define DBGMASK_NONE 0x0000 53#define DBGMASK_NONE 0x0000
52#define DBGMASK_LOCKDOWND (1 << 1) 54#define DBGMASK_LOCKDOWND (1 << 1)
53#define DBGMASK_MOBILESYNC (1 << 2) 55#define DBGMASK_MOBILESYNC (1 << 2)
54 56
57/* generic */
55void iphone_set_debug_mask(uint16_t mask); 58void iphone_set_debug_mask(uint16_t mask);
56void iphone_set_debug_level(int level); 59void iphone_set_debug_level(int level);
57 60
58/* Interface */ 61/* discovery (events/asynchronous) */
59iphone_error_t iphone_get_device(iphone_device_t *device); 62// event type
60iphone_error_t iphone_get_device_by_uuid(iphone_device_t *device, const char *uuid); 63enum iphone_event_type {
64 IPHONE_DEVICE_ADD = 1,
65 IPHONE_DEVICE_REMOVE
66};
67
68// event data structure
69typedef struct {
70 enum iphone_event_type event;
71 const char *uuid;
72 int conn_type;
73} iphone_event_t;
74
75// event callback function prototype
76typedef void (*iphone_event_cb_t) (const iphone_event_t *event, void *user_data);
77
78// functions
79iphone_error_t iphone_event_subscribe(iphone_event_cb_t callback, void *user_data);
80iphone_error_t iphone_event_unsubscribe();
81
82/* discovery (synchronous) */
83iphone_error_t iphone_get_device_list(char ***devices, int *count);
84iphone_error_t iphone_free_device_list(char **devices);
85
86/* device structure creation and destruction */
87iphone_error_t iphone_device_new(iphone_device_t *device, const char *uuid);
61iphone_error_t iphone_device_free(iphone_device_t device); 88iphone_error_t iphone_device_free(iphone_device_t device);
89
90/* connection/disconnection and communication */
91iphone_error_t iphone_device_connect(iphone_device_t device, uint16_t dst_port, iphone_connection_t *connection);
92iphone_error_t iphone_device_disconnect(iphone_connection_t connection);
93iphone_error_t iphone_device_send(iphone_connection_t connection, const char *data, uint32_t len, uint32_t *sent_bytes);
94iphone_error_t iphone_device_recv_timeout(iphone_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout);
95iphone_error_t iphone_device_recv(iphone_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes);
96
97/* misc */
62iphone_error_t iphone_device_get_handle(iphone_device_t device, uint32_t *handle); 98iphone_error_t iphone_device_get_handle(iphone_device_t device, uint32_t *handle);
63iphone_error_t iphone_device_get_uuid(iphone_device_t device, char **uuid); 99iphone_error_t iphone_device_get_uuid(iphone_device_t device, char **uuid);
64 100
diff --git a/src/AFC.c b/src/AFC.c
index b27080a..ba436e7 100644
--- a/src/AFC.c
+++ b/src/AFC.c
@@ -68,18 +68,18 @@ afc_error_t afc_client_new(iphone_device_t device, int dst_port, afc_client_t *
68 return AFC_E_INVALID_ARGUMENT; 68 return AFC_E_INVALID_ARGUMENT;
69 69
70 /* attempt connection */ 70 /* attempt connection */
71 int sfd = usbmuxd_connect(device->handle, dst_port); 71 iphone_connection_t connection = NULL;
72 if (sfd < 0) { 72 if (iphone_device_connect(device, dst_port, &connection) != IPHONE_E_SUCCESS) {
73 return AFC_E_MUX_ERROR; 73 return AFC_E_MUX_ERROR;
74 } 74 }
75 75
76 afc_client_t client_loc = (afc_client_t) malloc(sizeof(struct afc_client_int)); 76 afc_client_t client_loc = (afc_client_t) malloc(sizeof(struct afc_client_int));
77 client_loc->sfd = sfd; 77 client_loc->connection = connection;
78 78
79 /* allocate a packet */ 79 /* allocate a packet */
80 client_loc->afc_packet = (AFCPacket *) malloc(sizeof(AFCPacket)); 80 client_loc->afc_packet = (AFCPacket *) malloc(sizeof(AFCPacket));
81 if (!client_loc->afc_packet) { 81 if (!client_loc->afc_packet) {
82 usbmuxd_disconnect(client_loc->sfd); 82 iphone_device_disconnect(client_loc->connection);
83 free(client_loc); 83 free(client_loc);
84 return AFC_E_NO_MEM; 84 return AFC_E_NO_MEM;
85 } 85 }
@@ -102,10 +102,10 @@ afc_error_t afc_client_new(iphone_device_t device, int dst_port, afc_client_t *
102 */ 102 */
103afc_error_t afc_client_free(afc_client_t client) 103afc_error_t afc_client_free(afc_client_t client)
104{ 104{
105 if (!client || client->sfd < 0 || !client->afc_packet) 105 if (!client || !client->connection || !client->afc_packet)
106 return AFC_E_INVALID_ARGUMENT; 106 return AFC_E_INVALID_ARGUMENT;
107 107
108 usbmuxd_disconnect(client->sfd); 108 iphone_device_disconnect(client->connection);
109 free(client->afc_packet); 109 free(client->afc_packet);
110 if (client->mutex) { 110 if (client->mutex) {
111 g_mutex_free(client->mutex); 111 g_mutex_free(client->mutex);
@@ -132,7 +132,7 @@ static int afc_dispatch_packet(afc_client_t client, const char *data, uint64_t l
132 int bytes = 0, offset = 0; 132 int bytes = 0, offset = 0;
133 char *buffer; 133 char *buffer;
134 134
135 if (!client || client->sfd < 0 || !client->afc_packet) 135 if (!client || !client->connection || !client->afc_packet)
136 return 0; 136 return 0;
137 137
138 if (!data || !length) 138 if (!data || !length)
@@ -164,7 +164,7 @@ static int afc_dispatch_packet(afc_client_t client, const char *data, uint64_t l
164 return -1; 164 return -1;
165 } 165 }
166 memcpy(buffer + sizeof(AFCPacket), data, offset); 166 memcpy(buffer + sizeof(AFCPacket), data, offset);
167 usbmuxd_send(client->sfd, buffer, client->afc_packet->this_length, (uint32_t*)&bytes); 167 iphone_device_send(client->connection, buffer, client->afc_packet->this_length, (uint32_t*)&bytes);
168 free(buffer); 168 free(buffer);
169 if (bytes <= 0) { 169 if (bytes <= 0) {
170 return bytes; 170 return bytes;
@@ -175,7 +175,7 @@ static int afc_dispatch_packet(afc_client_t client, const char *data, uint64_t l
175 log_debug_msg("%s: Buffer: \n", __func__); 175 log_debug_msg("%s: Buffer: \n", __func__);
176 log_debug_buffer(data + offset, length - offset); 176 log_debug_buffer(data + offset, length - offset);
177 177
178 usbmuxd_send(client->sfd, data + offset, length - offset, (uint32_t*)&bytes); 178 iphone_device_send(client->connection, data + offset, length - offset, (uint32_t*)&bytes);
179 return bytes; 179 return bytes;
180 } else { 180 } else {
181 log_debug_msg("%s: doin things the old way\n", __func__); 181 log_debug_msg("%s: doin things the old way\n", __func__);
@@ -188,7 +188,7 @@ static int afc_dispatch_packet(afc_client_t client, const char *data, uint64_t l
188 } 188 }
189 log_debug_buffer(buffer, client->afc_packet->this_length); 189 log_debug_buffer(buffer, client->afc_packet->this_length);
190 log_debug_msg("\n"); 190 log_debug_msg("\n");
191 usbmuxd_send(client->sfd, buffer, client->afc_packet->this_length, (uint32_t*)&bytes); 191 iphone_device_send(client->connection, buffer, client->afc_packet->this_length, (uint32_t*)&bytes);
192 192
193 if (buffer) { 193 if (buffer) {
194 free(buffer); 194 free(buffer);
@@ -220,7 +220,7 @@ static afc_error_t afc_receive_data(afc_client_t client, char **dump_here, int *
220 *bytes = 0; 220 *bytes = 0;
221 221
222 /* first, read the AFC header */ 222 /* first, read the AFC header */
223 usbmuxd_recv(client->sfd, (char*)&header, sizeof(AFCPacket), (uint32_t*)bytes); 223 iphone_device_recv(client->connection, (char*)&header, sizeof(AFCPacket), (uint32_t*)bytes);
224 if (*bytes <= 0) { 224 if (*bytes <= 0) {
225 log_debug_msg("%s: Just didn't get enough.\n", __func__); 225 log_debug_msg("%s: Just didn't get enough.\n", __func__);
226 *dump_here = NULL; 226 *dump_here = NULL;
@@ -273,7 +273,7 @@ static afc_error_t afc_receive_data(afc_client_t client, char **dump_here, int *
273 273
274 *dump_here = (char*)malloc(entire_len); 274 *dump_here = (char*)malloc(entire_len);
275 if (this_len > 0) { 275 if (this_len > 0) {
276 usbmuxd_recv(client->sfd, *dump_here, this_len, (uint32_t*)bytes); 276 iphone_device_recv(client->connection, *dump_here, this_len, (uint32_t*)bytes);
277 if (*bytes <= 0) { 277 if (*bytes <= 0) {
278 free(*dump_here); 278 free(*dump_here);
279 *dump_here = NULL; 279 *dump_here = NULL;
@@ -291,7 +291,7 @@ static afc_error_t afc_receive_data(afc_client_t client, char **dump_here, int *
291 291
292 if (entire_len > this_len) { 292 if (entire_len > this_len) {
293 while (current_count < entire_len) { 293 while (current_count < entire_len) {
294 usbmuxd_recv(client->sfd, (*dump_here)+current_count, entire_len - current_count, (uint32_t*)bytes); 294 iphone_device_recv(client->connection, (*dump_here)+current_count, entire_len - current_count, (uint32_t*)bytes);
295 if (*bytes <= 0) { 295 if (*bytes <= 0) {
296 log_debug_msg("%s: Error receiving data (recv returned %d)\n", __func__, *bytes); 296 log_debug_msg("%s: Error receiving data (recv returned %d)\n", __func__, *bytes);
297 break; 297 break;
@@ -517,7 +517,7 @@ afc_error_t afc_remove_path(afc_client_t client, const char *path)
517 int bytes; 517 int bytes;
518 afc_error_t ret = AFC_E_UNKNOWN_ERROR; 518 afc_error_t ret = AFC_E_UNKNOWN_ERROR;
519 519
520 if (!client || !path || !client->afc_packet || client->sfd < 0) 520 if (!client || !path || !client->afc_packet || !client->connection)
521 return AFC_E_INVALID_ARGUMENT; 521 return AFC_E_INVALID_ARGUMENT;
522 522
523 afc_lock(client); 523 afc_lock(client);
@@ -560,7 +560,7 @@ afc_error_t afc_rename_path(afc_client_t client, const char *from, const char *t
560 int bytes = 0; 560 int bytes = 0;
561 afc_error_t ret = AFC_E_UNKNOWN_ERROR; 561 afc_error_t ret = AFC_E_UNKNOWN_ERROR;
562 562
563 if (!client || !from || !to || !client->afc_packet || client->sfd < 0) 563 if (!client || !from || !to || !client->afc_packet || !client->connection)
564 return AFC_E_INVALID_ARGUMENT; 564 return AFC_E_INVALID_ARGUMENT;
565 565
566 afc_lock(client); 566 afc_lock(client);
@@ -687,7 +687,7 @@ afc_file_open(afc_client_t client, const char *filename,
687 // set handle to 0 so in case an error occurs, the handle is invalid 687 // set handle to 0 so in case an error occurs, the handle is invalid
688 *handle = 0; 688 *handle = 0;
689 689
690 if (!client || client->sfd < 0|| !client->afc_packet) 690 if (!client || !client->connection || !client->afc_packet)
691 return AFC_E_INVALID_ARGUMENT; 691 return AFC_E_INVALID_ARGUMENT;
692 692
693 afc_lock(client); 693 afc_lock(client);
@@ -742,7 +742,7 @@ afc_file_read(afc_client_t client, uint64_t handle, char *data, int length, uint
742 const int MAXIMUM_READ_SIZE = 1 << 16; 742 const int MAXIMUM_READ_SIZE = 1 << 16;
743 afc_error_t ret = AFC_E_SUCCESS; 743 afc_error_t ret = AFC_E_SUCCESS;
744 744
745 if (!client || !client->afc_packet || client->sfd < 0 || handle == 0) 745 if (!client || !client->afc_packet || !client->connection || handle == 0)
746 return AFC_E_INVALID_ARGUMENT; 746 return AFC_E_INVALID_ARGUMENT;
747 log_debug_msg("%s: called for length %i\n", __func__, length); 747 log_debug_msg("%s: called for length %i\n", __func__, length);
748 748
@@ -819,7 +819,7 @@ afc_file_write(afc_client_t client, uint64_t handle,
819 char *out_buffer = NULL; 819 char *out_buffer = NULL;
820 afc_error_t ret = AFC_E_SUCCESS; 820 afc_error_t ret = AFC_E_SUCCESS;
821 821
822 if (!client || !client->afc_packet || client->sfd < 0 || !bytes || (handle == 0)) 822 if (!client || !client->afc_packet || !client->connection || !bytes || (handle == 0))
823 return AFC_E_INVALID_ARGUMENT; 823 return AFC_E_INVALID_ARGUMENT;
824 824
825 afc_lock(client); 825 afc_lock(client);
@@ -1139,7 +1139,7 @@ afc_error_t afc_truncate(afc_client_t client, const char *path, off_t newsize)
1139 uint64_t size_requested = newsize; 1139 uint64_t size_requested = newsize;
1140 afc_error_t ret = AFC_E_UNKNOWN_ERROR; 1140 afc_error_t ret = AFC_E_UNKNOWN_ERROR;
1141 1141
1142 if (!client || !path || !client->afc_packet || client->sfd < 0) 1142 if (!client || !path || !client->afc_packet || !client->connection)
1143 return AFC_E_INVALID_ARGUMENT; 1143 return AFC_E_INVALID_ARGUMENT;
1144 1144
1145 afc_lock(client); 1145 afc_lock(client);
@@ -1183,7 +1183,7 @@ afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, const c
1183 uint64_t type = linktype; 1183 uint64_t type = linktype;
1184 afc_error_t ret = AFC_E_UNKNOWN_ERROR; 1184 afc_error_t ret = AFC_E_UNKNOWN_ERROR;
1185 1185
1186 if (!client || !target || !linkname || !client->afc_packet || client->sfd < 0) 1186 if (!client || !target || !linkname || !client->afc_packet || !client->connection)
1187 return AFC_E_INVALID_ARGUMENT; 1187 return AFC_E_INVALID_ARGUMENT;
1188 1188
1189 afc_lock(client); 1189 afc_lock(client);
diff --git a/src/AFC.h b/src/AFC.h
index 7ed6bd8..685d7b5 100644
--- a/src/AFC.h
+++ b/src/AFC.h
@@ -46,7 +46,7 @@ typedef struct __AFCToken {
46} AFCToken; 46} AFCToken;
47 47
48struct afc_client_int { 48struct afc_client_int {
49 int sfd; 49 iphone_connection_t connection;
50 AFCPacket *afc_packet; 50 AFCPacket *afc_packet;
51 int file_handle; 51 int file_handle;
52 int lock; 52 int lock;
diff --git a/src/MobileSync.c b/src/MobileSync.c
index 4463251..8a7d724 100644
--- a/src/MobileSync.c
+++ b/src/MobileSync.c
@@ -40,13 +40,13 @@ mobilesync_error_t mobilesync_client_new(iphone_device_t device, int dst_port,
40 mobilesync_error_t ret = MOBILESYNC_E_UNKNOWN_ERROR; 40 mobilesync_error_t ret = MOBILESYNC_E_UNKNOWN_ERROR;
41 41
42 /* Attempt connection */ 42 /* Attempt connection */
43 int sfd = usbmuxd_connect(device->handle, dst_port); 43 iphone_connection_t connection = NULL;
44 if (sfd < 0) { 44 if (iphone_device_connect(device, dst_port, &connection) != IPHONE_E_SUCCESS) {
45 return ret; 45 return ret;
46 } 46 }
47 47
48 mobilesync_client_t client_loc = (mobilesync_client_t) malloc(sizeof(struct mobilesync_client_int)); 48 mobilesync_client_t client_loc = (mobilesync_client_t) malloc(sizeof(struct mobilesync_client_int));
49 client_loc->sfd = sfd; 49 client_loc->connection = connection;
50 50
51 /* perform handshake */ 51 /* perform handshake */
52 plist_t array = NULL; 52 plist_t array = NULL;
@@ -126,7 +126,7 @@ mobilesync_error_t mobilesync_client_free(mobilesync_client_t client)
126 return IPHONE_E_INVALID_ARG; 126 return IPHONE_E_INVALID_ARG;
127 127
128 mobilesync_disconnect(client); 128 mobilesync_disconnect(client);
129 return (usbmuxd_disconnect(client->sfd) == 0 ? MOBILESYNC_E_SUCCESS: MOBILESYNC_E_MUX_ERROR); 129 return (iphone_device_disconnect(client->connection) == 0 ? MOBILESYNC_E_SUCCESS: MOBILESYNC_E_MUX_ERROR);
130} 130}
131 131
132/** Polls the iPhone for MobileSync data. 132/** Polls the iPhone for MobileSync data.
@@ -144,14 +144,14 @@ mobilesync_error_t mobilesync_recv(mobilesync_client_t client, plist_t * plist)
144 char *receive = NULL; 144 char *receive = NULL;
145 uint32_t datalen = 0, bytes = 0, received_bytes = 0; 145 uint32_t datalen = 0, bytes = 0, received_bytes = 0;
146 146
147 ret = usbmuxd_recv(client->sfd, (char *) &datalen, sizeof(datalen), &bytes); 147 ret = iphone_device_recv(client->connection, (char *) &datalen, sizeof(datalen), &bytes);
148 datalen = ntohl(datalen); 148 datalen = ntohl(datalen);
149 149
150 receive = (char *) malloc(sizeof(char) * datalen); 150 receive = (char *) malloc(sizeof(char) * datalen);
151 151
152 /* fill buffer and request more packets if needed */ 152 /* fill buffer and request more packets if needed */
153 while ((received_bytes < datalen) && (ret == MOBILESYNC_E_SUCCESS)) { 153 while ((received_bytes < datalen) && (ret == MOBILESYNC_E_SUCCESS)) {
154 ret = usbmuxd_recv(client->sfd, receive + received_bytes, datalen - received_bytes, &bytes); 154 ret = iphone_device_recv(client->connection, receive + received_bytes, datalen - received_bytes, &bytes);
155 received_bytes += bytes; 155 received_bytes += bytes;
156 } 156 }
157 157
@@ -207,7 +207,7 @@ mobilesync_error_t mobilesync_send(mobilesync_client_t client, plist_t plist)
207 memcpy(real_query, &length, sizeof(length)); 207 memcpy(real_query, &length, sizeof(length));
208 memcpy(real_query + 4, content, ntohl(length)); 208 memcpy(real_query + 4, content, ntohl(length));
209 209
210 ret = usbmuxd_send(client->sfd, real_query, ntohl(length) + sizeof(length), (uint32_t*)&bytes); 210 ret = iphone_device_send(client->connection, real_query, ntohl(length) + sizeof(length), (uint32_t*)&bytes);
211 free(real_query); 211 free(real_query);
212 return (ret == 0 ? MOBILESYNC_E_SUCCESS: MOBILESYNC_E_MUX_ERROR); 212 return (ret == 0 ? MOBILESYNC_E_SUCCESS: MOBILESYNC_E_MUX_ERROR);
213} 213}
diff --git a/src/MobileSync.h b/src/MobileSync.h
index 6347399..605145f 100644
--- a/src/MobileSync.h
+++ b/src/MobileSync.h
@@ -24,7 +24,7 @@
24#include "libiphone/mobilesync.h" 24#include "libiphone/mobilesync.h"
25 25
26struct mobilesync_client_int { 26struct mobilesync_client_int {
27 int sfd; 27 iphone_connection_t connection;
28}; 28};
29 29
30#endif 30#endif
diff --git a/src/NotificationProxy.c b/src/NotificationProxy.c
index e4735cc..da636ab 100644
--- a/src/NotificationProxy.c
+++ b/src/NotificationProxy.c
@@ -83,9 +83,9 @@ static np_error_t np_plist_send(np_client_t client, plist_t dict)
83 } 83 }
84 84
85 nlen = htonl(length); 85 nlen = htonl(length);
86 usbmuxd_send(client->sfd, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes); 86 iphone_device_send(client->connection, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes);
87 if (bytes == sizeof(nlen)) { 87 if (bytes == sizeof(nlen)) {
88 usbmuxd_send(client->sfd, XML_content, length, (uint32_t*)&bytes); 88 iphone_device_send(client->connection, XML_content, length, (uint32_t*)&bytes);
89 if (bytes > 0) { 89 if (bytes > 0) {
90 if ((uint32_t)bytes == length) { 90 if ((uint32_t)bytes == length) {
91 res = NP_E_SUCCESS; 91 res = NP_E_SUCCESS;
@@ -121,13 +121,13 @@ np_error_t np_client_new(iphone_device_t device, int dst_port, np_client_t *clie
121 return NP_E_INVALID_ARG; 121 return NP_E_INVALID_ARG;
122 122
123 /* Attempt connection */ 123 /* Attempt connection */
124 int sfd = usbmuxd_connect(device->handle, dst_port); 124 iphone_connection_t connection = NULL;
125 if (sfd < 0) { 125 if (iphone_device_connect(device, dst_port, &connection) != IPHONE_E_SUCCESS) {
126 return NP_E_UNKNOWN_ERROR; 126 return NP_E_UNKNOWN_ERROR;
127 } 127 }
128 128
129 np_client_t client_loc = (np_client_t) malloc(sizeof(struct np_client_int)); 129 np_client_t client_loc = (np_client_t) malloc(sizeof(struct np_client_int));
130 client_loc->sfd = sfd; 130 client_loc->connection = connection;
131 131
132 client_loc->mutex = g_mutex_new(); 132 client_loc->mutex = g_mutex_new();
133 133
@@ -146,8 +146,8 @@ np_error_t np_client_free(np_client_t client)
146 if (!client) 146 if (!client)
147 return NP_E_INVALID_ARG; 147 return NP_E_INVALID_ARG;
148 148
149 usbmuxd_disconnect(client->sfd); 149 iphone_device_disconnect(client->connection);
150 client->sfd = -1; 150 client->connection = NULL;
151 if (client->notifier) { 151 if (client->notifier) {
152 log_debug_msg("joining np callback\n"); 152 log_debug_msg("joining np callback\n");
153 g_thread_join(client->notifier); 153 g_thread_join(client->notifier);
@@ -293,12 +293,12 @@ static int np_get_notification(np_client_t client, char **notification)
293 char *XML_content = NULL; 293 char *XML_content = NULL;
294 plist_t dict = NULL; 294 plist_t dict = NULL;
295 295
296 if (!client || client->sfd < 0 || *notification) 296 if (!client || !client->connection || *notification)
297 return -1; 297 return -1;
298 298
299 np_lock(client); 299 np_lock(client);
300 300
301 usbmuxd_recv_timeout(client->sfd, (char*)&pktlen, sizeof(pktlen), &bytes, 500); 301 iphone_device_recv_timeout(client->connection, (char*)&pktlen, sizeof(pktlen), &bytes, 500);
302 log_debug_msg("NotificationProxy: initial read=%i\n", bytes); 302 log_debug_msg("NotificationProxy: initial read=%i\n", bytes);
303 if (bytes < 4) { 303 if (bytes < 4) {
304 log_debug_msg("NotificationProxy: no notification received!\n"); 304 log_debug_msg("NotificationProxy: no notification received!\n");
@@ -310,7 +310,7 @@ static int np_get_notification(np_client_t client, char **notification)
310 XML_content = (char*)malloc(pktlen); 310 XML_content = (char*)malloc(pktlen);
311 log_debug_msg("pointer %p\n", XML_content); 311 log_debug_msg("pointer %p\n", XML_content);
312 312
313 usbmuxd_recv_timeout(client->sfd, XML_content, pktlen, &bytes, 1000); 313 iphone_device_recv_timeout(client->connection, XML_content, pktlen, &bytes, 1000);
314 if (bytes <= 0) { 314 if (bytes <= 0) {
315 res = -1; 315 res = -1;
316 } else { 316 } else {
@@ -390,7 +390,7 @@ gpointer np_notifier( gpointer arg )
390 if (!npt) return NULL; 390 if (!npt) return NULL;
391 391
392 log_debug_msg("%s: starting callback.\n", __func__); 392 log_debug_msg("%s: starting callback.\n", __func__);
393 while (npt->client->sfd >= 0) { 393 while (npt->client->connection) {
394 np_get_notification(npt->client, &notification); 394 np_get_notification(npt->client, &notification);
395 if (notification) { 395 if (notification) {
396 npt->cbfunc(notification); 396 npt->cbfunc(notification);
@@ -429,11 +429,11 @@ np_error_t np_set_notify_callback( np_client_t client, np_notify_cb_t notify_cb
429 np_lock(client); 429 np_lock(client);
430 if (client->notifier) { 430 if (client->notifier) {
431 log_debug_msg("%s: callback already set, removing\n"); 431 log_debug_msg("%s: callback already set, removing\n");
432 int conn = client->sfd; 432 iphone_connection_t conn = client->connection;
433 client->sfd = -1; 433 client->connection = NULL;
434 g_thread_join(client->notifier); 434 g_thread_join(client->notifier);
435 client->notifier = NULL; 435 client->notifier = NULL;
436 client->sfd = conn; 436 client->connection = conn;
437 } 437 }
438 438
439 if (notify_cb) { 439 if (notify_cb) {
diff --git a/src/NotificationProxy.h b/src/NotificationProxy.h
index bc5be43..84f1f89 100644
--- a/src/NotificationProxy.h
+++ b/src/NotificationProxy.h
@@ -26,7 +26,7 @@
26#include "libiphone/notification_proxy.h" 26#include "libiphone/notification_proxy.h"
27 27
28struct np_client_int { 28struct np_client_int {
29 int sfd; 29 iphone_connection_t connection;
30 GMutex *mutex; 30 GMutex *mutex;
31 GThread *notifier; 31 GThread *notifier;
32}; 32};
diff --git a/src/iphone.c b/src/iphone.c
index e694373..80e796b 100644
--- a/src/iphone.c
+++ b/src/iphone.c
@@ -1,8 +1,9 @@
1/* 1/*
2 * iphone.c 2 * iphone.c
3 * Functions for creating and initializing iPhone structures. 3 * Device discovery and communication interface.
4 * 4 *
5 * Copyright (c) 2008 Zach C. All Rights Reserved. 5 * Copyright (c) 2008 Zach C. All Rights Reserved.
6 * Copyright (c) 2009 Nikias Bassen. All Rights Reserved.
6 * 7 *
7 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public 9 * modify it under the terms of the GNU Lesser General Public
@@ -19,104 +20,161 @@
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */ 21 */
21 22
22#include <stdio.h>
23#include <stdlib.h> 23#include <stdlib.h>
24#include <string.h> 24#include <string.h>
25#include <errno.h>
25 26
27#include <usbmuxd.h>
26#include "iphone.h" 28#include "iphone.h"
27#include "utils.h" 29#include "utils.h"
28 30
31static iphone_event_cb_t event_cb = NULL;
32
33static void usbmux_event_cb(const usbmuxd_event_t *event, void *user_data)
34{
35 iphone_event_t ev;
36
37 ev.event = event->event;
38 ev.uuid = event->device.uuid;
39 ev.conn_type = CONNECTION_USBMUXD;
40
41 if (event_cb) {
42 event_cb(&ev, user_data);
43 }
44}
45
29/** 46/**
30 * Retrieves a list of connected devices from usbmuxd and matches their 47 * Register a callback function that will be called when device add/remove
31 * UUID with the given UUID. If the given UUID is NULL then the first 48 * events occur.
32 * device reported by usbmuxd is used.
33 * 49 *
34 * @param device Upon calling this function, a pointer to a location of type 50 * @param callback Callback function to call.
35 * iphone_device_t, which must have the value NULL. On return, this location 51 * @param user_data Application-specific data passed as parameter
36 * will be filled with a handle to the device. 52 * to the registered callback function.
37 * @param uuid The UUID to match.
38 * 53 *
39 * @return IPHONE_E_SUCCESS if ok, otherwise an error code. 54 * @return IPHONE_E_SUCCESS on success or an error value when an error occured.
40 */ 55 */
41iphone_error_t iphone_get_device_by_uuid(iphone_device_t * device, const char *uuid) 56iphone_error_t iphone_event_subscribe(iphone_event_cb_t callback, void *user_data)
42{ 57{
43 iphone_device_t phone; 58 event_cb = callback;
44 uint32_t handle = 0; 59 int res = usbmuxd_subscribe(usbmux_event_cb, user_data);
45 char *serial_number = malloc(41); 60 if (res != 0) {
46 usbmuxd_scan_result *dev_list = NULL; 61 event_cb = NULL;
47 int i; 62 log_debug_msg("%s: Error %d when subscribing usbmux event callback!\n", __func__, res);
48 63 return IPHONE_E_UNKNOWN_ERROR;
49 if (usbmuxd_scan(&dev_list) < 0) {
50 log_debug_msg("%s: usbmuxd_scan returned an error, is usbmuxd running?\n", __func__);
51 }
52 if (dev_list && dev_list[0].handle > 0) {
53 if (!uuid) {
54 /* select first device found if no UUID specified */
55 handle = dev_list[0].handle;
56 strcpy(serial_number, dev_list[0].serial_number);
57 } else {
58 /* otherwise walk through the list */
59 for (i = 0; dev_list[i].handle > 0; i++) {
60 log_debug_msg("%s: device handle=%d, uuid=%s\n", __func__, dev_list[i].handle, dev_list[i].serial_number);
61 if (strcasecmp(uuid, dev_list[i].serial_number) == 0) {
62 handle = dev_list[i].handle;
63 strcpy(serial_number, dev_list[i].serial_number);
64 break;
65 }
66 }
67 }
68 free(dev_list);
69
70 if (handle > 0) {
71 phone = (iphone_device_t) malloc(sizeof(struct iphone_device_int));
72 phone->handle = handle;
73 phone->serial_number = serial_number;
74 *device = phone;
75 return IPHONE_E_SUCCESS;
76 }
77 } 64 }
65 return IPHONE_E_SUCCESS;
66}
78 67
79 return IPHONE_E_NO_DEVICE; 68/**
69 * Release the event callback function that has been registered with
70 * iphone_event_subscribe().
71 *
72 * @return IPHONE_E_SUCCESS on success or an error value when an error occured.
73 */
74iphone_error_t iphone_event_unsubscribe()
75{
76 event_cb = NULL;
77 int res = usbmuxd_unsubscribe();
78 if (res != 0) {
79 log_debug_msg("%s: Error %d when unsubscribing usbmux event callback!\n", __func__, res);
80 return IPHONE_E_UNKNOWN_ERROR;
81 }
82 return IPHONE_E_SUCCESS;
80} 83}
81 84
82/** 85/**
83 * This function has the purpose to retrieve a handle to the first 86 * Get a list of currently available devices.
84 * attached iPhone/iPod reported by usbmuxd.
85 * 87 *
86 * @param Upon calling this function, a pointer to a location of type 88 * @param devices List of uuids of devices that are currently available.
87 * iphone_device_t, which must have the value NULL. On return, this location 89 * This list is terminated by a NULL pointer.
88 * will be filled with a handle to the device. 90 * @param count Number of devices found.
89 * 91 *
90 * @return IPHONE_E_SUCCESS if ok, otherwise an error code. 92 * @return IPHONE_E_SUCCESS on success or an error value when an error occured.
91 */ 93 */
92iphone_error_t iphone_get_device(iphone_device_t * device) 94iphone_error_t iphone_get_device_list(char ***devices, int *count)
93{ 95{
94 return iphone_get_device_by_uuid(device, NULL); 96 usbmuxd_device_info_t *dev_list;
97
98 *devices = NULL;
99 *count = 0;
100
101 if (usbmuxd_get_device_list(&dev_list) < 0) {
102 log_debug_msg("%s: ERROR: usbmuxd is not running!\n", __func__);
103 return IPHONE_E_NO_DEVICE;
104 }
105
106 char **newlist = NULL;
107 int i, newcount = 0;
108
109 for (i = 0; dev_list[i].handle > 0; i++) {
110 newlist = realloc(*devices, sizeof(char*) * (newcount+1));
111 newlist[newcount++] = strdup(dev_list[i].uuid);
112 *devices = newlist;
113 }
114 usbmuxd_free_device_list(dev_list);
115
116 *count = newcount;
117 newlist = realloc(*devices, sizeof(char*) * (newcount+1));
118 newlist[newcount] = NULL;
119 *devices = newlist;
120
121 return IPHONE_E_SUCCESS;
95} 122}
96 123
97iphone_error_t iphone_device_get_handle(iphone_device_t device, uint32_t *handle) 124/**
125 * Free a list of device uuids.
126 *
127 * @param devices List of uuids to free.
128 *
129 * @return Always returnes IPHONE_E_SUCCESS.
130 */
131iphone_error_t iphone_free_device_list(char **devices)
98{ 132{
99 if (!device) 133 if (devices) {
100 return IPHONE_E_INVALID_ARG; 134 int i = 0;
101 135 while (devices[i++]) {
102 *handle = device->handle; 136 free(devices[i]);
137 }
138 free(devices);
139 }
103 return IPHONE_E_SUCCESS; 140 return IPHONE_E_SUCCESS;
104} 141}
105 142
106iphone_error_t iphone_device_get_uuid(iphone_device_t device, char **uuid) 143/**
144 * Creates an iphone_device_t structure for the device specified by uuid,
145 * if the device is available.
146 *
147 * @note The resulting iphone_device_t structure has to be freed with
148 * iphone_device_free() if it is no longer used.
149 *
150 * @param device Upon calling this function, a pointer to a location of type
151 * iphone_device_t. On successful return, this location will be populated.
152 * @param uuid The UUID to match.
153 *
154 * @return IPHONE_E_SUCCESS if ok, otherwise an error code.
155 */
156iphone_error_t iphone_device_new(iphone_device_t * device, const char *uuid)
107{ 157{
108 if (!device) 158 usbmuxd_device_info_t muxdev;
109 return IPHONE_E_INVALID_ARG; 159 int res = usbmuxd_get_device_by_uuid(uuid, &muxdev);
160 if (res > 0) {
161 iphone_device_t phone = (iphone_device_t) malloc(sizeof(struct iphone_device_int));
162 phone->uuid = strdup(muxdev.uuid);
163 phone->conn_type = CONNECTION_USBMUXD;
164 phone->conn_data = (void*)muxdev.handle;
165 *device = phone;
166 return IPHONE_E_SUCCESS;
167 }
168 /* other connection types could follow here */
110 169
111 *uuid = strdup(device->serial_number); 170 return IPHONE_E_NO_DEVICE;
112 return IPHONE_E_SUCCESS;
113} 171}
114 172
115/** Cleans up an iPhone structure, then frees the structure itself. 173/** Cleans up an iPhone structure, then frees the structure itself.
116 * This is a library-level function; deals directly with the iPhone to tear 174 * This is a library-level function; deals directly with the iPhone to tear
117 * down relations, but otherwise is mostly internal. 175 * down relations, but otherwise is mostly internal.
118 * 176 *
119 * @param phone A pointer to an iPhone structure. 177 * @param device A pointer to an iPhone structure.
120 */ 178 */
121iphone_error_t iphone_device_free(iphone_device_t device) 179iphone_error_t iphone_device_free(iphone_device_t device)
122{ 180{
@@ -126,8 +184,189 @@ iphone_error_t iphone_device_free(iphone_device_t device)
126 184
127 ret = IPHONE_E_SUCCESS; 185 ret = IPHONE_E_SUCCESS;
128 186
129 free(device->serial_number); 187 free(device->uuid);
188
189 if (device->conn_type == CONNECTION_USBMUXD) {
190 device->conn_data = 0;
191 }
192 if (device->conn_data) {
193 free(device->conn_data);
194 }
130 free(device); 195 free(device);
131 return ret; 196 return ret;
132} 197}
133 198
199/**
200 * Set up a connection to the given device.
201 *
202 * @param device The device to connect to.
203 * @param dst_port The destination port to connect to.
204 * @param connection Pointer to an iphone_connection_t that will be filled
205 * with the necessary data of the connection.
206 *
207 * @return IPHONE_E_SUCCESS if ok, otherwise an error code.
208 */
209iphone_error_t iphone_device_connect(iphone_device_t device, uint16_t dst_port, iphone_connection_t *connection)
210{
211 if (!device) {
212 return IPHONE_E_INVALID_ARG;
213 }
214
215 if (device->conn_type == CONNECTION_USBMUXD) {
216 int sfd = usbmuxd_connect((uint32_t)(device->conn_data), dst_port);
217 if (sfd < 0) {
218 log_debug_msg("%s: ERROR: Connecting to usbmuxd failed: %d (%s)\n", __func__, sfd, strerror(-sfd));
219 return IPHONE_E_UNKNOWN_ERROR;
220 }
221 iphone_connection_t new_connection = (iphone_connection_t)malloc(sizeof(struct iphone_connection_int));
222 new_connection->type = CONNECTION_USBMUXD;
223 new_connection->data = (void*)sfd;
224 *connection = new_connection;
225 return IPHONE_E_SUCCESS;
226 } else {
227 log_debug_msg("%s: Unknown connection type %d\n", __func__, device->conn_type);
228 }
229
230 return IPHONE_E_UNKNOWN_ERROR;
231}
232
233/**
234 * Disconnect from the device and clean up the connection structure.
235 *
236 * @param connection The connection to close.
237 *
238 * @return IPHONE_E_SUCCESS if ok, otherwise an error code.
239 */
240iphone_error_t iphone_device_disconnect(iphone_connection_t connection)
241{
242 if (!connection) {
243 return IPHONE_E_INVALID_ARG;
244 }
245 iphone_error_t result = IPHONE_E_UNKNOWN_ERROR;
246 if (connection->type == CONNECTION_USBMUXD) {
247 usbmuxd_disconnect((int)(connection->data));
248 result = IPHONE_E_SUCCESS;
249 } else {
250 log_debug_msg("%s: Unknown connection type %d\n", __func__, connection->type);
251 }
252 free(connection);
253 return result;
254}
255
256/**
257 * Send data to a device via the given connection.
258 *
259 * @param connection The connection to send data over.
260 * @param data Buffer with data to send.
261 * @param len Size of the buffer to send.
262 * @param sent_bytes Pointer to an uint32_t that will be filled
263 * with the number of bytes actually sent.
264 *
265 * @return IPHONE_E_SUCCESS if ok, otherwise an error code.
266 */
267iphone_error_t iphone_device_send(iphone_connection_t connection, const char *data, uint32_t len, uint32_t *sent_bytes)
268{
269 if (!connection || !data) {
270 return IPHONE_E_INVALID_ARG;
271 }
272
273 if (connection->type == CONNECTION_USBMUXD) {
274 int res = usbmuxd_send((int)(connection->data), data, len, sent_bytes);
275 if (res < 0) {
276 log_debug_msg("%s: ERROR: usbmuxd_send returned %d (%s)\n", __func__, res, strerror(-res));
277 return IPHONE_E_UNKNOWN_ERROR;
278 }
279 return IPHONE_E_SUCCESS;
280 } else {
281 log_debug_msg("%s: Unknown connection type %d\n", __func__, connection->type);
282 }
283 return IPHONE_E_UNKNOWN_ERROR;
284}
285
286/**
287 * Receive data from a device via the given connection.
288 * This function will return after the given timeout even if no data has been
289 * received.
290 *
291 * @param connection The connection to receive data from.
292 * @param data Buffer that will be filled with the received data.
293 * This buffer has to be large enough to hold len bytes.
294 * @param len Buffer size or number of bytes to receive.
295 * @param recv_bytes Number of bytes actually received.
296 * @param timeout Timeout in milliseconds after which this function should
297 * return even if no data has been received.
298 *
299 * @return IPHONE_E_SUCCESS if ok, otherwise an error code.
300 */
301iphone_error_t iphone_device_recv_timeout(iphone_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout)
302{
303 if (!connection) {
304 return IPHONE_E_INVALID_ARG;
305 }
306
307 if (connection->type == CONNECTION_USBMUXD) {
308 int res = usbmuxd_recv_timeout((int)(connection->data), data, len, recv_bytes, timeout);
309 if (res < 0) {
310 log_debug_msg("%s: ERROR: usbmuxd_recv_timeout returned %d (%s)\n", __func__, res, strerror(-res));
311 return IPHONE_E_UNKNOWN_ERROR;
312 }
313 } else {
314 log_debug_msg("%s: Unknown connection type %d\n", __func__, connection->type);
315 }
316 return IPHONE_E_UNKNOWN_ERROR;
317}
318
319/**
320 * Receive data from a device via the given connection.
321 * This function is like iphone_device_recv_timeout, but with a predefined
322 * reasonable timeout.
323 *
324 * @param connection The connection to receive data from.
325 * @param data Buffer that will be filled with the received data.
326 * This buffer has to be large enough to hold len bytes.
327 * @param len Buffer size or number of bytes to receive.
328 * @param recv_bytes Number of bytes actually received.
329 *
330 * @return IPHONE_E_SUCCESS if ok, otherwise an error code.
331 */
332iphone_error_t iphone_device_recv(iphone_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes)
333{
334 if (!connection) {
335 return -EINVAL;
336 }
337
338 if (connection->type == CONNECTION_USBMUXD) {
339 int res = usbmuxd_recv((int)(connection->data), data, len, recv_bytes);
340 if (res < 0) {
341 log_debug_msg("%s: ERROR: usbmuxd_recv returned %d (%s)\n", __func__, res, strerror(-res));
342 return IPHONE_E_UNKNOWN_ERROR;
343 }
344 } else {
345 log_debug_msg("%s: Unknown connection type %d\n", __func__, connection->type);
346 }
347 return IPHONE_E_UNKNOWN_ERROR;
348}
349
350iphone_error_t iphone_device_get_handle(iphone_device_t device, uint32_t *handle)
351{
352 if (!device)
353 return IPHONE_E_INVALID_ARG;
354
355 if (device->conn_type == CONNECTION_USBMUXD) {
356 *handle = (uint32_t)device->conn_data;
357 return IPHONE_E_SUCCESS;
358 } else {
359 log_debug_msg("%s: Unknown connection type %d\n", __func__, device->conn_type);
360 }
361 return IPHONE_E_UNKNOWN_ERROR;
362}
363
364iphone_error_t iphone_device_get_uuid(iphone_device_t device, char **uuid)
365{
366 if (!device)
367 return IPHONE_E_INVALID_ARG;
368
369 *uuid = strdup(device->uuid);
370 return IPHONE_E_SUCCESS;
371}
372
diff --git a/src/iphone.h b/src/iphone.h
index 6e14280..98b0ed8 100644
--- a/src/iphone.h
+++ b/src/iphone.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * iphone.h 2 * iphone.h
3 * iPhone struct 3 * Device discovery and communication interface -- header file.
4 * 4 *
5 * Copyright (c) 2008 Zach C. All Rights Reserved. 5 * Copyright (c) 2008 Zach C. All Rights Reserved.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
@@ -18,18 +18,24 @@
18 * License along with this library; if not, write to the Free Software 18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */ 20 */
21
22#ifndef IPHONE_H 21#ifndef IPHONE_H
23#define IPHONE_H 22#define IPHONE_H
24 23
25#include <stdint.h>
26
27#include "libiphone/libiphone.h" 24#include "libiphone/libiphone.h"
28 25
26enum connection_type {
27 CONNECTION_USBMUXD = 1
28};
29
30struct iphone_connection_int {
31 enum connection_type type;
32 void *data;
33};
34
29struct iphone_device_int { 35struct iphone_device_int {
30 char *buffer; 36 char *uuid;
31 uint32_t handle; 37 enum connection_type conn_type;
32 char *serial_number; 38 void *conn_data;
33}; 39};
34 40
35#endif 41#endif
diff --git a/src/lockdown.c b/src/lockdown.c
index 7a2aa7d..a05b5db 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -213,12 +213,14 @@ lockdownd_error_t lockdownd_client_free(lockdownd_client_t client)
213 213
214 lockdownd_stop_ssl_session(client); 214 lockdownd_stop_ssl_session(client);
215 215
216 if (client->sfd > 0) { 216 if (client->connection) {
217 lockdownd_goodbye(client); 217 lockdownd_goodbye(client);
218 218
219 // IMO, read of final "sessionUpcall connection closed" packet 219 // IMO, read of final "sessionUpcall connection closed" packet
220 // should come here instead of in iphone_free_device 220 // should come here instead of in iphone_free_device
221 ret = usbmuxd_disconnect(client->sfd); 221 if ((ret = iphone_device_disconnect(client->connection)) != IPHONE_E_SUCCESS) {
222 ret = LOCKDOWN_E_UNKNOWN_ERROR;
223 }
222 } 224 }
223 225
224 free(client); 226 free(client);
@@ -241,7 +243,7 @@ lockdownd_error_t lockdownd_recv(lockdownd_client_t client, plist_t *plist)
241 uint32_t datalen = 0, bytes = 0, received_bytes = 0; 243 uint32_t datalen = 0, bytes = 0, received_bytes = 0;
242 244
243 if (!client->in_SSL) 245 if (!client->in_SSL)
244 ret = usbmuxd_recv(client->sfd, (char *) &datalen, sizeof(datalen), &bytes); 246 ret = iphone_device_recv(client->connection, (char *) &datalen, sizeof(datalen), &bytes);
245 else { 247 else {
246 ssize_t res = gnutls_record_recv(*client->ssl_session, &datalen, sizeof(datalen)); 248 ssize_t res = gnutls_record_recv(*client->ssl_session, &datalen, sizeof(datalen));
247 if (res < 0) { 249 if (res < 0) {
@@ -260,7 +262,7 @@ lockdownd_error_t lockdownd_recv(lockdownd_client_t client, plist_t *plist)
260 /* fill buffer and request more packets if needed */ 262 /* fill buffer and request more packets if needed */
261 if (!client->in_SSL) { 263 if (!client->in_SSL) {
262 while ((received_bytes < datalen) && (ret == LOCKDOWN_E_SUCCESS)) { 264 while ((received_bytes < datalen) && (ret == LOCKDOWN_E_SUCCESS)) {
263 ret = usbmuxd_recv(client->sfd, receive + received_bytes, datalen - received_bytes, &bytes); 265 ret = iphone_device_recv(client->connection, receive + received_bytes, datalen - received_bytes, &bytes);
264 received_bytes += bytes; 266 received_bytes += bytes;
265 } 267 }
266 } else { 268 } else {
@@ -328,7 +330,7 @@ lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist_t plist)
328 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: made the query, sending it along\n", __func__); 330 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: made the query, sending it along\n", __func__);
329 331
330 if (!client->in_SSL) 332 if (!client->in_SSL)
331 ret = usbmuxd_send(client->sfd, real_query, ntohl(length) + sizeof(length), (uint32_t*)&bytes); 333 ret = iphone_device_send(client->connection, real_query, ntohl(length) + sizeof(length), (uint32_t*)&bytes);
332 else { 334 else {
333 ssize_t res = gnutls_record_send(*client->ssl_session, real_query, ntohl(length) + sizeof(length)); 335 ssize_t res = gnutls_record_send(*client->ssl_session, real_query, ntohl(length) + sizeof(length));
334 if (res < 0) { 336 if (res < 0) {
@@ -659,19 +661,19 @@ lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **de
659 */ 661 */
660lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_t *client) 662lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_t *client)
661{ 663{
662 if (!device || !client) 664 if (!client)
663 return LOCKDOWN_E_INVALID_ARG; 665 return LOCKDOWN_E_INVALID_ARG;
664 lockdownd_error_t ret = LOCKDOWN_E_SUCCESS; 666 lockdownd_error_t ret = LOCKDOWN_E_SUCCESS;
665 char *host_id = NULL; 667 char *host_id = NULL;
666 668
667 int sfd = usbmuxd_connect(device->handle, 0xf27e); 669 iphone_connection_t connection;
668 if (sfd < 0) { 670 if (iphone_device_connect(device, 0xf27e, &connection) != IPHONE_E_SUCCESS) {
669 log_debug_msg("%s: could not connect to lockdownd (device handle %d)\n", __func__, device->handle); 671 log_debug_msg("%s: could not connect to lockdownd (device %s)\n", __func__, device->uuid);
670 return LOCKDOWN_E_MUX_ERROR; 672 return LOCKDOWN_E_MUX_ERROR;
671 } 673 }
672 674
673 lockdownd_client_t client_loc = (lockdownd_client_t) malloc(sizeof(struct lockdownd_client_int)); 675 lockdownd_client_t client_loc = (lockdownd_client_t) malloc(sizeof(struct lockdownd_client_int));
674 client_loc->sfd = sfd; 676 client_loc->connection = connection;
675 client_loc->ssl_session = (gnutls_session_t *) malloc(sizeof(gnutls_session_t)); 677 client_loc->ssl_session = (gnutls_session_t *) malloc(sizeof(gnutls_session_t));
676 client_loc->in_SSL = 0; 678 client_loc->in_SSL = 0;
677 679
@@ -1176,7 +1178,7 @@ ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size
1176 client = (lockdownd_client_t) transport; 1178 client = (lockdownd_client_t) transport;
1177 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: called\n", __func__); 1179 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: called\n", __func__);
1178 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: pre-send length = %zi\n", __func__, length); 1180 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: pre-send length = %zi\n", __func__, length);
1179 usbmuxd_send(client->sfd, buffer, length, &bytes); 1181 iphone_device_send(client->connection, buffer, length, &bytes);
1180 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: post-send sent %i bytes\n", __func__, bytes); 1182 log_dbg_msg(DBGMASK_LOCKDOWND, "%s: post-send sent %i bytes\n", __func__, bytes);
1181 return bytes; 1183 return bytes;
1182} 1184}
@@ -1205,7 +1207,7 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_
1205 1207
1206 // repeat until we have the full data or an error occurs. 1208 // repeat until we have the full data or an error occurs.
1207 do { 1209 do {
1208 if ((res = usbmuxd_recv(client->sfd, recv_buffer, this_len, (uint32_t*)&bytes)) != LOCKDOWN_E_SUCCESS) { 1210 if ((res = iphone_device_recv(client->connection, recv_buffer, this_len, (uint32_t*)&bytes)) != LOCKDOWN_E_SUCCESS) {
1209 log_debug_msg("%s: ERROR: usbmux_recv returned %d\n", __func__, res); 1211 log_debug_msg("%s: ERROR: usbmux_recv returned %d\n", __func__, res);
1210 return res; 1212 return res;
1211 } 1213 }
diff --git a/src/lockdown.h b/src/lockdown.h
index 1e193f6..19cf9f2 100644
--- a/src/lockdown.h
+++ b/src/lockdown.h
@@ -28,7 +28,7 @@
28#include "libiphone/lockdown.h" 28#include "libiphone/lockdown.h"
29 29
30struct lockdownd_client_int { 30struct lockdownd_client_int {
31 int sfd; 31 iphone_connection_t connection;
32 gnutls_session_t *ssl_session; 32 gnutls_session_t *ssl_session;
33 int in_SSL; 33 int in_SSL;
34 char session_id[40]; 34 char session_id[40];
diff --git a/src/userpref.c b/src/userpref.c
index 9dd1a01..10c14a0 100644
--- a/src/userpref.c
+++ b/src/userpref.c
@@ -88,7 +88,7 @@ static char *userpref_generate_host_id()
88 * 88 *
89 * @param host_id A null terminated string containing a valid HostID. 89 * @param host_id A null terminated string containing a valid HostID.
90 */ 90 */
91static int userpref_set_host_id(char *host_id) 91static int userpref_set_host_id(const char *host_id)
92{ 92{
93 GKeyFile *key_file; 93 GKeyFile *key_file;
94 gsize length; 94 gsize length;
@@ -164,7 +164,7 @@ void userpref_get_host_id(char **host_id)
164 * @return 1 if the iPhone has been connected previously to this configuration 164 * @return 1 if the iPhone has been connected previously to this configuration
165 * or 0 otherwise. 165 * or 0 otherwise.
166 */ 166 */
167int userpref_has_device_public_key(char *uuid) 167int userpref_has_device_public_key(const char *uuid)
168{ 168{
169 int ret = 0; 169 int ret = 0;
170 gchar *config_file; 170 gchar *config_file;
@@ -187,7 +187,7 @@ int userpref_has_device_public_key(char *uuid)
187 * @return 1 on success and 0 if no public key is given or if it has already 187 * @return 1 on success and 0 if no public key is given or if it has already
188 * been marked as connected previously. 188 * been marked as connected previously.
189 */ 189 */
190userpref_error_t userpref_set_device_public_key(char *uuid, gnutls_datum_t public_key) 190userpref_error_t userpref_set_device_public_key(const char *uuid, gnutls_datum_t public_key)
191{ 191{
192 if (NULL == public_key.data) 192 if (NULL == public_key.data)
193 return USERPREF_E_INVALID_ARG; 193 return USERPREF_E_INVALID_ARG;
diff --git a/src/userpref.h b/src/userpref.h
index 414c093..fcb8b62 100644
--- a/src/userpref.h
+++ b/src/userpref.h
@@ -36,8 +36,8 @@ typedef int16_t userpref_error_t;
36userpref_error_t userpref_get_keys_and_certs(gnutls_x509_privkey_t root_privkey, gnutls_x509_crt_t root_crt, gnutls_x509_privkey_t host_privkey, gnutls_x509_crt_t host_crt); 36userpref_error_t userpref_get_keys_and_certs(gnutls_x509_privkey_t root_privkey, gnutls_x509_crt_t root_crt, gnutls_x509_privkey_t host_privkey, gnutls_x509_crt_t host_crt);
37userpref_error_t userpref_set_keys_and_certs(gnutls_datum_t * root_key, gnutls_datum_t * root_cert, gnutls_datum_t * host_key, gnutls_datum_t * host_cert); 37userpref_error_t userpref_set_keys_and_certs(gnutls_datum_t * root_key, gnutls_datum_t * root_cert, gnutls_datum_t * host_key, gnutls_datum_t * host_cert);
38userpref_error_t userpref_get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls_datum_t *pem_host_cert); 38userpref_error_t userpref_get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls_datum_t *pem_host_cert);
39userpref_error_t userpref_set_device_public_key(char *uuid, gnutls_datum_t public_key); 39userpref_error_t userpref_set_device_public_key(const char *uuid, gnutls_datum_t public_key);
40int userpref_has_device_public_key(char *uuid); 40int userpref_has_device_public_key(const char *uuid);
41void userpref_get_host_id(char **host_id); 41void userpref_get_host_id(char **host_id);
42 42
43#endif 43#endif
diff --git a/tools/iphone_id.c b/tools/iphone_id.c
index 835e214..ab36e7c 100644
--- a/tools/iphone_id.c
+++ b/tools/iphone_id.c
@@ -28,7 +28,7 @@ int main(int argc, char **argv)
28{ 28{
29 iphone_device_t phone = NULL; 29 iphone_device_t phone = NULL;
30 lockdownd_client_t client = NULL; 30 lockdownd_client_t client = NULL;
31 usbmuxd_scan_result *dev_list; 31 usbmuxd_device_info_t *dev_list;
32 char *devname = NULL; 32 char *devname = NULL;
33 int ret = 0; 33 int ret = 0;
34 int i; 34 int i;
@@ -65,7 +65,7 @@ int main(int argc, char **argv)
65 65
66 switch (mode) { 66 switch (mode) {
67 case MODE_SHOW_ID: 67 case MODE_SHOW_ID:
68 iphone_get_device_by_uuid(&phone, uuid); 68 iphone_device_new(&phone, uuid);
69 if (!phone) { 69 if (!phone) {
70 fprintf(stderr, "ERROR: No device with UUID=%s attached.\n", uuid); 70 fprintf(stderr, "ERROR: No device with UUID=%s attached.\n", uuid);
71 return -2; 71 return -2;
@@ -96,13 +96,14 @@ int main(int argc, char **argv)
96 return ret; 96 return ret;
97 case MODE_LIST_DEVICES: 97 case MODE_LIST_DEVICES:
98 default: 98 default:
99 if (usbmuxd_scan(&dev_list) < 0) { 99 if (usbmuxd_get_device_list(&dev_list) < 0) {
100 fprintf(stderr, "ERROR: usbmuxd is not running!\n"); 100 fprintf(stderr, "ERROR: usbmuxd is not running!\n");
101 return -1; 101 return -1;
102 } 102 }
103 for (i = 0; dev_list[i].handle > 0; i++) { 103 for (i = 0; dev_list[i].handle > 0; i++) {
104 printf("handle=%d product_id=%04x uuid=%s\n", dev_list[i].handle, dev_list[i].product_id, dev_list[i].serial_number); 104 printf("handle=%d product_id=%04x uuid=%s\n", dev_list[i].handle, dev_list[i].product_id, dev_list[i].uuid);
105 } 105 }
106 usbmuxd_free_device_list(dev_list);
106 return 0; 107 return 0;
107 } 108 }
108} 109}
diff --git a/tools/iphoneinfo.c b/tools/iphoneinfo.c
index 7e275b2..16a1069 100644
--- a/tools/iphoneinfo.c
+++ b/tools/iphoneinfo.c
@@ -121,7 +121,7 @@ int main(int argc, char *argv[])
121 } 121 }
122 122
123 if (uuid[0] != 0) { 123 if (uuid[0] != 0) {
124 ret = iphone_get_device_by_uuid(&phone, uuid); 124 ret = iphone_device_new(&phone, uuid);
125 if (ret != IPHONE_E_SUCCESS) { 125 if (ret != IPHONE_E_SUCCESS) {
126 printf("No device found with uuid %s, is it plugged in?\n", uuid); 126 printf("No device found with uuid %s, is it plugged in?\n", uuid);
127 return -1; 127 return -1;
@@ -129,7 +129,7 @@ int main(int argc, char *argv[])
129 } 129 }
130 else 130 else
131 { 131 {
132 ret = iphone_get_device(&phone); 132 ret = iphone_device_new(&phone, NULL);
133 if (ret != IPHONE_E_SUCCESS) { 133 if (ret != IPHONE_E_SUCCESS) {
134 printf("No device found, is it plugged in?\n"); 134 printf("No device found, is it plugged in?\n");
135 return -1; 135 return -1;
diff --git a/tools/iphonesyslog.c b/tools/iphonesyslog.c
index a096101..10b3fb6 100644
--- a/tools/iphonesyslog.c
+++ b/tools/iphonesyslog.c
@@ -28,7 +28,6 @@
28 28
29#include <libiphone/libiphone.h> 29#include <libiphone/libiphone.h>
30#include <libiphone/lockdown.h> 30#include <libiphone/lockdown.h>
31#include <usbmuxd.h>
32 31
33static int quit_flag = 0; 32static int quit_flag = 0;
34 33
@@ -86,7 +85,7 @@ int main(int argc, char *argv[])
86 } 85 }
87 86
88 if (uuid[0] != 0) { 87 if (uuid[0] != 0) {
89 ret = iphone_get_device_by_uuid(&phone, uuid); 88 ret = iphone_device_new(&phone, uuid);
90 if (ret != IPHONE_E_SUCCESS) { 89 if (ret != IPHONE_E_SUCCESS) {
91 printf("No device found with uuid %s, is it plugged in?\n", uuid); 90 printf("No device found with uuid %s, is it plugged in?\n", uuid);
92 return -1; 91 return -1;
@@ -94,7 +93,7 @@ int main(int argc, char *argv[])
94 } 93 }
95 else 94 else
96 { 95 {
97 ret = iphone_get_device(&phone); 96 ret = iphone_device_new(&phone, NULL);
98 if (ret != IPHONE_E_SUCCESS) { 97 if (ret != IPHONE_E_SUCCESS) {
99 printf("No device found, is it plugged in?\n"); 98 printf("No device found, is it plugged in?\n");
100 return -1; 99 return -1;
@@ -112,16 +111,15 @@ int main(int argc, char *argv[])
112 lockdownd_client_free(client); 111 lockdownd_client_free(client);
113 112
114 /* connect to socket relay messages */ 113 /* connect to socket relay messages */
115 iphone_device_get_handle(phone, &handle); 114 iphone_connection_t conn = NULL;
116 int sfd = usbmuxd_connect(handle, port); 115 if ((iphone_device_connect(phone, port, &conn) != IPHONE_E_SUCCESS) || !conn) {
117 if (sfd < 0) {
118 printf("ERROR: Could not open usbmux connection.\n"); 116 printf("ERROR: Could not open usbmux connection.\n");
119 } else { 117 } else {
120 while (!quit_flag) { 118 while (!quit_flag) {
121 char *receive = NULL; 119 char *receive = NULL;
122 uint32_t datalen = 0, bytes = 0, recv_bytes = 0; 120 uint32_t datalen = 0, bytes = 0, recv_bytes = 0;
123 121
124 ret = usbmuxd_recv(sfd, (char *) &datalen, sizeof(datalen), &bytes); 122 ret = iphone_device_recv(conn, (char *) &datalen, sizeof(datalen), &bytes);
125 datalen = ntohl(datalen); 123 datalen = ntohl(datalen);
126 124
127 if (datalen == 0) 125 if (datalen == 0)
@@ -131,7 +129,7 @@ int main(int argc, char *argv[])
131 receive = (char *) malloc(sizeof(char) * datalen); 129 receive = (char *) malloc(sizeof(char) * datalen);
132 130
133 while (!quit_flag && (recv_bytes <= datalen)) { 131 while (!quit_flag && (recv_bytes <= datalen)) {
134 ret = usbmuxd_recv(sfd, receive, datalen, &bytes); 132 ret = iphone_device_recv(conn, receive, datalen, &bytes);
135 133
136 if (bytes == 0) 134 if (bytes == 0)
137 break; 135 break;
@@ -144,7 +142,7 @@ int main(int argc, char *argv[])
144 free(receive); 142 free(receive);
145 } 143 }
146 } 144 }
147 usbmuxd_disconnect(sfd); 145 iphone_device_disconnect(conn);
148 } else { 146 } else {
149 printf("ERROR: Could not start service com.apple.syslog_relay.\n"); 147 printf("ERROR: Could not start service com.apple.syslog_relay.\n");
150 } 148 }