summaryrefslogtreecommitdiffstats
path: root/src/MobileSync.c
diff options
context:
space:
mode:
authorGravatar Matt Colyer2009-04-13 08:48:00 -0700
committerGravatar Matt Colyer2009-04-13 08:48:00 -0700
commit6671ca3d6de6a1fd27853e3b1ce7a81d568703f0 (patch)
tree735c5ace7ed57cd4e19f2fde423b22e6104eaa98 /src/MobileSync.c
parentbd31783d7fde0b5bd101f4a3f97ca1aca2aa6fab (diff)
parent288929f45cb2641690879b52ec514097995cd41a (diff)
downloadlibimobiledevice-6671ca3d6de6a1fd27853e3b1ce7a81d568703f0.tar.gz
libimobiledevice-6671ca3d6de6a1fd27853e3b1ce7a81d568703f0.tar.bz2
Merged in Jonathan's libplist libiphone. [#2 state:resolved]
Diffstat (limited to 'src/MobileSync.c')
-rw-r--r--src/MobileSync.c299
1 files changed, 299 insertions, 0 deletions
diff --git a/src/MobileSync.c b/src/MobileSync.c
new file mode 100644
index 0000000..b16a51b
--- /dev/null
+++ b/src/MobileSync.c
@@ -0,0 +1,299 @@
1/*
2 * MobileSync.c
3 * Contains functions for the built-in MobileSync client.
4 *
5 * Copyright (c) 2009 Jonathan Beck All Rights Reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
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
20 */
21
22#include "MobileSync.h"
23#include <plist/plist.h>
24#include <string.h>
25
26
27#define MSYNC_VERSION_INT1 100
28#define MSYNC_VERSION_INT2 100
29
30iphone_error_t iphone_msync_new_client(iphone_device_t device, int src_port, int dst_port,
31 iphone_msync_client_t * client)
32{
33 if (!device || src_port == 0 || dst_port == 0 || !client || *client)
34 return IPHONE_E_INVALID_ARG;
35
36 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
37
38 iphone_msync_client_t client_loc = (iphone_msync_client_t) malloc(sizeof(struct iphone_msync_client_int));
39
40 // Attempt connection
41 client_loc->connection = NULL;
42 ret = iphone_mux_new_client(device, src_port, dst_port, &client_loc->connection);
43 if (IPHONE_E_SUCCESS != ret || !client_loc->connection) {
44 free(client_loc);
45 return ret;
46 }
47 //perform handshake
48 plist_t array = NULL;
49
50 //first receive version
51 ret = iphone_msync_recv(client_loc, &array);
52
53 plist_t msg_node = plist_find_node_by_string(array, "DLMessageVersionExchange");
54 plist_t ver_1 = plist_get_next_sibling(msg_node);
55 plist_t ver_2 = plist_get_next_sibling(ver_1);
56
57 plist_type ver_1_type = plist_get_node_type(ver_1);
58 plist_type ver_2_type = plist_get_node_type(ver_2);
59
60 if (PLIST_UINT == ver_1_type && PLIST_UINT == ver_2_type) {
61
62 uint64_t ver_1_val = 0;
63 uint64_t ver_2_val = 0;
64
65 plist_get_uint_val(ver_1, &ver_1_val);
66 plist_get_uint_val(ver_2, &ver_2_val);
67
68 plist_free(array);
69 array = NULL;
70
71 if (ver_1_type == PLIST_UINT && ver_2_type == PLIST_UINT && ver_1_val == MSYNC_VERSION_INT1
72 && ver_2_val == MSYNC_VERSION_INT2) {
73
74 array = plist_new_array();
75 plist_add_sub_string_el(array, "DLMessageVersionExchange");
76 plist_add_sub_string_el(array, "DLVersionsOk");
77
78 ret = iphone_msync_send(client_loc, array);
79
80 plist_free(array);
81 array = NULL;
82
83 ret = iphone_msync_recv(client_loc, &array);
84 plist_t rep_node = plist_find_node_by_string(array, "DLMessageDeviceReady");
85
86 if (rep_node) {
87 ret = IPHONE_E_SUCCESS;
88 *client = client_loc;
89 }
90 plist_free(array);
91 array = NULL;
92
93 }
94 }
95
96 if (IPHONE_E_SUCCESS != ret)
97 iphone_msync_free_client(client_loc);
98
99 return ret;
100}
101
102static void iphone_msync_stop_session(iphone_msync_client_t client)
103{
104 if (!client)
105 return;
106
107 plist_t array = plist_new_array();
108 plist_add_sub_string_el(array, "DLMessageDisconnect");
109 plist_add_sub_string_el(array, "All done, thanks for the memories");
110
111 iphone_msync_send(client, array);
112 plist_free(array);
113 array = NULL;
114}
115
116iphone_error_t iphone_msync_free_client(iphone_msync_client_t client)
117{
118 if (!client)
119 return IPHONE_E_INVALID_ARG;
120
121 iphone_msync_stop_session(client);
122 return iphone_mux_free_client(client->connection);
123}
124
125/** Polls the iPhone for MobileSync data.
126 *
127 * @param client The MobileSync client
128 * @param dump_data The pointer to the location of the buffer in which to store
129 * the received data
130 * @param recv_byhtes The number of bytes received
131 *
132 * @return an error code
133 */
134iphone_error_t iphone_msync_recv(iphone_msync_client_t client, plist_t * plist)
135{
136 if (!client || !plist || (plist && *plist))
137 return IPHONE_E_INVALID_ARG;
138 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
139 char *receive;
140 uint32_t datalen = 0, bytes = 0;
141
142 ret = iphone_mux_recv(client->connection, (char *) &datalen, sizeof(datalen), &bytes);
143 datalen = ntohl(datalen);
144
145 receive = (char *) malloc(sizeof(char) * datalen);
146 ret = iphone_mux_recv(client->connection, receive, datalen, &bytes);
147
148 plist_from_bin(receive, bytes, plist);
149
150 char *XMLContent = NULL;
151 uint32_t length = 0;
152 plist_to_xml(*plist, &XMLContent, &length);
153 log_dbg_msg(DBGMASK_MOBILESYNC, "Recv msg :\nsize : %i\nbuffer :\n%s\n", length, XMLContent);
154 free(XMLContent);
155
156 return ret;
157}
158
159/** Sends MobileSync data to the iPhone
160 *
161 * @note This function is low-level and should only be used if you need to send
162 * a new type of message.
163 *
164 * @param client The MobileSync client
165 * @param raw_data The null terminated string buffer to send
166 * @param length The length of data to send
167 * @param sent_bytes The number of bytes sent
168 *
169 * @return an error code
170 */
171iphone_error_t iphone_msync_send(iphone_msync_client_t client, plist_t plist)
172{
173 if (!client || !plist)
174 return IPHONE_E_INVALID_ARG;
175
176 char *XMLContent = NULL;
177 uint32_t length = 0;
178 plist_to_xml(plist, &XMLContent, &length);
179 log_dbg_msg(DBGMASK_MOBILESYNC, "Send msg :\nsize : %i\nbuffer :\n%s\n", length, XMLContent);
180 free(XMLContent);
181
182 char *content = NULL;
183 length = 0;
184
185 plist_to_bin(plist, &content, &length);
186
187 char *real_query;
188 int bytes;
189 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
190
191 real_query = (char *) malloc(sizeof(char) * (length + 4));
192 length = htonl(length);
193 memcpy(real_query, &length, sizeof(length));
194 memcpy(real_query + 4, content, ntohl(length));
195
196 ret = iphone_mux_send(client->connection, real_query, ntohl(length) + sizeof(length), &bytes);
197 free(real_query);
198 return ret;
199}
200
201iphone_error_t iphone_msync_get_all_contacts(iphone_msync_client_t client)
202{
203 if (!client)
204 return IPHONE_E_INVALID_ARG;
205
206 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
207 plist_t array = NULL;
208
209 array = plist_new_array();
210 plist_add_sub_string_el(array, "SDMessageSyncDataClassWithDevice");
211 plist_add_sub_string_el(array, "com.apple.Contacts");
212 plist_add_sub_string_el(array, "---");
213 plist_add_sub_string_el(array, "2009-01-09 18:03:58 +0100");
214 plist_add_sub_uint_el(array, 106);
215 plist_add_sub_string_el(array, "___EmptyParameterString___");
216
217 ret = iphone_msync_send(client, array);
218 plist_free(array);
219 array = NULL;
220
221 ret = iphone_msync_recv(client, &array);
222
223 plist_t rep_node = plist_find_node_by_string(array, "SDSyncTypeSlow");
224
225 if (!rep_node)
226 return ret;
227
228 plist_free(array);
229 array = NULL;
230
231 array = plist_new_array();
232 plist_add_sub_string_el(array, "SDMessageGetAllRecordsFromDevice");
233 plist_add_sub_string_el(array, "com.apple.Contacts");
234
235
236 ret = iphone_msync_send(client, array);
237 plist_free(array);
238 array = NULL;
239
240 ret = iphone_msync_recv(client, &array);
241
242 plist_t contact_node;
243 plist_t switch_node;
244
245 contact_node = plist_find_node_by_string(array, "com.apple.Contacts");
246 switch_node = plist_find_node_by_string(array, "SDMessageDeviceReadyToReceiveChanges");
247
248 while (NULL == switch_node) {
249
250 plist_free(array);
251 array = NULL;
252
253 array = plist_new_array();
254 plist_add_sub_string_el(array, "SDMessageAcknowledgeChangesFromDevice");
255 plist_add_sub_string_el(array, "com.apple.Contacts");
256
257 ret = iphone_msync_send(client, array);
258 plist_free(array);
259 array = NULL;
260
261 ret = iphone_msync_recv(client, &array);
262
263 contact_node = plist_find_node_by_string(array, "com.apple.Contacts");
264 switch_node = plist_find_node_by_string(array, "SDMessageDeviceReadyToReceiveChanges");
265 }
266
267 array = plist_new_array();
268 plist_add_sub_string_el(array, "DLMessagePing");
269 plist_add_sub_string_el(array, "Preparing to get changes for device");
270
271 ret = iphone_msync_send(client, array);
272 plist_free(array);
273 array = NULL;
274
275 array = plist_new_array();
276 plist_add_sub_string_el(array, "SDMessageProcessChanges");
277 plist_add_sub_string_el(array, "com.apple.Contacts");
278 plist_add_sub_node(array, plist_new_dict());
279 plist_add_sub_bool_el(array, 0);
280 plist_t dict = plist_new_dict();
281 plist_add_sub_node(array, dict);
282 plist_add_sub_key_el(dict, "SyncDeviceLinkEntityNamesKey");
283 plist_t array2 = plist_new_array();
284 plist_add_sub_string_el(array2, "com.apple.contacts.Contact");
285 plist_add_sub_string_el(array2, "com.apple.contacts.Group");
286 plist_add_sub_key_el(dict, "SyncDeviceLinkAllRecordsOfPulledEntityTypeSentKey");
287 plist_add_sub_bool_el(dict, 0);
288
289 ret = iphone_msync_send(client, array);
290 plist_free(array);
291 array = NULL;
292
293 ret = iphone_msync_recv(client, &array);
294 plist_free(array);
295 array = NULL;
296
297
298 return ret;
299}