summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2010-03-16 02:18:16 +0100
committerGravatar Martin Szulecki2010-03-16 02:29:13 +0100
commit5ac0f4272b4985627ae27693b28c93eea37a4d3b (patch)
tree4016459a234eae8ae9fa535b39c392765214a295 /src
parent2bde7add91ea63f0c2f2e3f090cf872168b504f9 (diff)
downloadlibimobiledevice-5ac0f4272b4985627ae27693b28c93eea37a4d3b.tar.gz
libimobiledevice-5ac0f4272b4985627ae27693b28c93eea37a4d3b.tar.bz2
mobilebackup: new functions added
Diffstat (limited to 'src')
-rw-r--r--src/mobilebackup.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/src/mobilebackup.c b/src/mobilebackup.c
index 91b9e73..d4f36d6 100644
--- a/src/mobilebackup.c
+++ b/src/mobilebackup.c
@@ -129,3 +129,153 @@ mobilebackup_error_t mobilebackup_send(mobilebackup_client_t client, plist_t pli
129 return mobilebackup_error(device_link_service_send(client->parent, plist)); 129 return mobilebackup_error(device_link_service_send(client->parent, plist));
130} 130}
131 131
132/**
133 * Request a backup from the connected device.
134 *
135 * @param client The connected MobileBackup client to use.
136 * @param backup_manifest The backup manifest, a plist_t of type PLIST_DICT
137 * containing the backup state of the last backup. For a first-time backup
138 * set this parameter to NULL.
139 * @param base_path The base path on the device to use for the backup
140 * operation, usually "/".
141 * @param proto_version A string denoting the version of the backup protocol
142 * to use. Latest known version is "1.6"
143 *
144 * @return MOBILEBACKUP_E_SUCCESS on success, MOBILEBACKUP_E_INVALID_ARG if
145 * one of the parameters is invalid, MOBILEBACKUP_E_PLIST_ERROR if
146 * backup_manifest is not of type PLIST_DICT, MOBILEBACKUP_E_MUX_ERROR
147 * if a communication error occurs, MOBILEBACKUP_E_REPLY_NOT_OK
148 */
149mobilebackup_error_t mobilebackup_request_backup(mobilebackup_client_t client, plist_t backup_manifest, const char *base_path, const char *proto_version)
150{
151 if (!client || !client->parent || !base_path || !proto_version)
152 return MOBILEBACKUP_E_INVALID_ARG;
153
154 if (backup_manifest && (plist_get_node_type(backup_manifest) != PLIST_DICT))
155 return MOBILEBACKUP_E_PLIST_ERROR;
156
157 mobilebackup_error_t err;
158
159 /* construct request plist */
160 plist_t dict = plist_new_dict();
161 if (backup_manifest)
162 plist_dict_insert_item(dict, "BackupManifestKey", plist_copy(backup_manifest));
163 plist_dict_insert_item(dict, "BackupComputerBasePathKey", plist_new_string(base_path));
164 plist_dict_insert_item(dict, "BackupMessageTypeKey", plist_new_string("BackupMessageBackupRequest"));
165 plist_dict_insert_item(dict, "BackupProtocolVersion", plist_new_string(proto_version));
166
167 /* send it as DLMessageProcessMessage */
168 err = mobilebackup_error(device_link_service_send_process_message(client->parent, dict));
169 plist_free(dict);
170 dict = NULL;
171 if (err != MOBILEBACKUP_E_SUCCESS) {
172 debug_info("ERROR: Could not send backup request message (%d)!", err);
173 goto leave;
174 }
175
176 /* now receive and hopefully get a BackupMessageBackupReplyOK */
177 err = mobilebackup_error(device_link_service_receive_process_message(client->parent, &dict));
178 if (err != MOBILEBACKUP_E_SUCCESS) {
179 debug_info("ERROR: Could not receive BackupReplyOK message (%d)!", err);
180 goto leave;
181 }
182
183 plist_t node = plist_dict_get_item(dict, "BackupMessageTypeKey");
184 if (!node) {
185 debug_info("ERROR: BackupMessageTypeKey not found in BackupReplyOK message!");
186 err = MOBILEBACKUP_E_PLIST_ERROR;
187 goto leave;
188 }
189
190 char *str = NULL;
191 plist_get_string_val(node, &str);
192 if (!str || (strcmp(str, "BackupMessageBackupReplyOK") != 0)) {
193 debug_info("ERROR: BackupMessageTypeKey value does not match 'BackupMessageBackupReplyOK'");
194 err = MOBILEBACKUP_E_REPLY_NOT_OK;
195 if (str)
196 free(str);
197 goto leave;
198 }
199 free(str);
200 str = NULL;
201
202 node = plist_dict_get_item(dict, "BackupProtocolVersion");
203 if (node) {
204 plist_get_string_val(node, &str);
205 if (str) {
206 if (strcmp(str, proto_version) != 0) {
207 err = MOBILEBACKUP_E_BAD_VERSION;
208 }
209 free(str);
210 }
211 }
212 if (err != MOBILEBACKUP_E_SUCCESS)
213 goto leave;
214
215 /* BackupMessageBackupReplyOK received, send it back */
216 err = mobilebackup_error(device_link_service_send_process_message(client->parent, dict));
217 if (err != MOBILEBACKUP_E_SUCCESS) {
218 debug_info("ERROR: Could not send BackupReplyOK ACK (%d)", err);
219 }
220
221leave:
222 if (dict)
223 plist_free(dict);
224 return err;
225}
226
227/**
228 * Sends a confirmation to the device that a backup file has been received.
229 *
230 * @param client The connected MobileBackup client to use.
231 *
232 * @return MOBILEBACKUP_E_SUCCESS on success, MOBILEBACKUP_E_INVALID_ARG if
233 * client is invalid, or MOBILEBACKUP_E_MUX_ERROR if a communication error
234 * occurs.
235 */
236mobilebackup_error_t mobilebackup_send_backup_file_received(mobilebackup_client_t client)
237{
238 if (!client || !client->parent)
239 return MOBILEBACKUP_E_INVALID_ARG;
240
241 mobilebackup_error_t err;
242
243 /* construct ACK plist */
244 plist_t dict = plist_new_dict();
245 plist_dict_insert_item(dict, "BackupMessageTypeKey", plist_new_string("kBackupMessageBackupFileReceived"));
246
247 /* send it as DLMessageProcessMessage */
248 err = mobilebackup_error(device_link_service_send_process_message(client->parent, dict));
249 plist_free(dict);
250
251 return err;
252}
253
254/**
255 * Sends a backup error message to the device.
256 *
257 * @param client The connected MobileBackup client to use.
258 * @param reason A string describing the reason for the error message.
259 *
260 * @return MOBILEBACKUP_E_SUCCESS on success, MOBILEBACKUP_E_INVALID_ARG if
261 * one of the parameters is invalid, or MOBILEBACKUP_E_MUX_ERROR if a
262 * communication error occurs.
263 */
264mobilebackup_error_t mobilebackup_send_error(mobilebackup_client_t client, const char *reason)
265{
266 if (!client || !client->parent || !reason)
267 return MOBILEBACKUP_E_INVALID_ARG;
268
269 mobilebackup_error_t err;
270
271 /* construct error plist */
272 plist_t dict = plist_new_dict();
273 plist_dict_insert_item(dict, "BackupMessageTypeKey", plist_new_string("BackupMessageError"));
274 plist_dict_insert_item(dict, "BackupErrorReasonKey", plist_new_string(reason));
275
276 /* send it as DLMessageProcessMessage */
277 err = mobilebackup_error(device_link_service_send_process_message(client->parent, dict));
278 plist_free(dict);
279
280 return err;
281}