diff options
Diffstat (limited to 'src/mobilesync.c')
-rw-r--r-- | src/mobilesync.c | 286 |
1 files changed, 41 insertions, 245 deletions
diff --git a/src/mobilesync.c b/src/mobilesync.c index ee9af5f..9b81a49 100644 --- a/src/mobilesync.c +++ b/src/mobilesync.c @@ -1,7 +1,7 @@ /* - * mobilesync.c + * mobilesync.c * Contains functions for the built-in MobileSync client. - * + * * Copyright (c) 2010 Bryan Forbes All Rights Reserved. * Copyright (c) 2009 Jonathan Beck All Rights Reserved. * @@ -9,31 +9,32 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif #define _GNU_SOURCE 1 #define __USE_GNU 1 - #include <plist/plist.h> #include <string.h> #include <stdlib.h> #include <stdio.h> -#include <glib.h> #include "mobilesync.h" #include "device_link_service.h" -#include "debug.h" +#include "common/debug.h" -#define MSYNC_VERSION_INT1 100 +#define MSYNC_VERSION_INT1 400 #define MSYNC_VERSION_INT2 100 #define EMPTY_PARAMETER_STRING "___EmptyParameterString___" @@ -58,6 +59,10 @@ static mobilesync_error_t mobilesync_error(device_link_service_error_t err) return MOBILESYNC_E_PLIST_ERROR; case DEVICE_LINK_SERVICE_E_MUX_ERROR: return MOBILESYNC_E_MUX_ERROR; + case DEVICE_LINK_SERVICE_E_SSL_ERROR: + return MOBILESYNC_E_SSL_ERROR; + case DEVICE_LINK_SERVICE_E_RECEIVE_TIMEOUT: + return MOBILESYNC_E_RECEIVE_TIMEOUT; case DEVICE_LINK_SERVICE_E_BAD_VERSION: return MOBILESYNC_E_BAD_VERSION; default: @@ -66,27 +71,14 @@ static mobilesync_error_t mobilesync_error(device_link_service_error_t err) return MOBILESYNC_E_UNKNOWN_ERROR; } -/** - * Connects to the mobilesync service on the specified device. - * - * @param device The device to connect to. - * @param port Destination port (usually given by lockdownd_start_service()). - * @param client Pointer that will be set to a newly allocated - * #mobilesync_client_t upon successful return. - * - * @retval MOBILESYNC_E_SUCCESS on success - * @retval MOBILESYNC_E_INVALID_ARG if one or more parameters are invalid - * @retval DEVICE_LINK_SERVICE_E_BAD_VERSION if the mobilesync version on - * the device is newer. - */ -mobilesync_error_t mobilesync_client_new(idevice_t device, uint16_t port, +mobilesync_error_t mobilesync_client_new(idevice_t device, lockdownd_service_descriptor_t service, mobilesync_client_t * client) { - if (!device || port == 0 || !client || *client) + if (!device || !service || service->port == 0 || !client || *client) return MOBILESYNC_E_INVALID_ARG; device_link_service_client_t dlclient = NULL; - mobilesync_error_t ret = mobilesync_error(device_link_service_client_new(device, port, &dlclient)); + mobilesync_error_t ret = mobilesync_error(device_link_service_client_new(device, service, &dlclient)); if (ret != MOBILESYNC_E_SUCCESS) { return ret; } @@ -109,33 +101,23 @@ mobilesync_error_t mobilesync_client_new(idevice_t device, uint16_t port, return ret; } -/** - * Disconnects a mobilesync client from the device and frees up the - * mobilesync client data. - * - * @param client The mobilesync client to disconnect and free. - * - * @retval MOBILESYNC_E_SUCCESS on success - * @retval MOBILESYNC_E_INVALID_ARG if \a client is NULL. - */ +mobilesync_error_t mobilesync_client_start_service(idevice_t device, mobilesync_client_t * client, const char* label) +{ + mobilesync_error_t err = MOBILESYNC_E_UNKNOWN_ERROR; + service_client_factory_start_service(device, MOBILESYNC_SERVICE_NAME, (void**)client, label, SERVICE_CONSTRUCTOR(mobilesync_client_new), &err); + return err; +} + mobilesync_error_t mobilesync_client_free(mobilesync_client_t client) { if (!client) return MOBILESYNC_E_INVALID_ARG; - device_link_service_disconnect(client->parent); + device_link_service_disconnect(client->parent, "All done, thanks for the memories"); mobilesync_error_t err = mobilesync_error(device_link_service_client_free(client->parent)); free(client); return err; } -/** - * Polls the device for mobilesync data. - * - * @param client The mobilesync client - * @param plist A pointer to the location where the plist should be stored - * - * @return an error code - */ mobilesync_error_t mobilesync_receive(mobilesync_client_t client, plist_t * plist) { if (!client) @@ -144,17 +126,6 @@ mobilesync_error_t mobilesync_receive(mobilesync_client_t client, plist_t * plis return ret; } -/** - * Sends mobilesync data to the device - * - * @note This function is low-level and should only be used if you need to send - * a new type of message. - * - * @param client The mobilesync client - * @param plist The location of the plist to send - * - * @return an error code - */ mobilesync_error_t mobilesync_send(mobilesync_client_t client, plist_t plist) { if (!client || !plist) @@ -162,26 +133,7 @@ mobilesync_error_t mobilesync_send(mobilesync_client_t client, plist_t plist) return mobilesync_error(device_link_service_send(client->parent, plist)); } -/** - * Requests starting synchronization of a data class with the device - * - * @param client The mobilesync client - * @param data_class The data class identifier to sync - * @param anchors The anchors required to exchange with the device. The anchors - * allow the device to tell if the synchronization information on the computer - * and device are consistent to determine what sync type is required. - * @param computer_data_class_version The version of the data class storage on the computer - * @param sync_type A pointer to store the sync type reported by the device_anchor - * @param device_data_class_version The version of the data class storage on the device - * - * @retval MOBILESYNC_E_SUCCESS on success - * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid - * @retval MOBILESYNC_E_PLIST_ERROR if the received plist is not of valid form - * @retval MOBILESYNC_E_SYNC_REFUSED if the device refused to sync - * @retval MOBILESYNC_E_CANCELLED if the device explicitly cancelled the - * sync request - */ -mobilesync_error_t mobilesync_start(mobilesync_client_t client, const char *data_class, mobilesync_anchors_t anchors, uint64_t computer_data_class_version, mobilesync_sync_type_t *sync_type, uint64_t *device_data_class_version) +mobilesync_error_t mobilesync_start(mobilesync_client_t client, const char *data_class, mobilesync_anchors_t anchors, uint64_t computer_data_class_version, mobilesync_sync_type_t *sync_type, uint64_t *device_data_class_version, char** error_description) { if (!client || client->data_class || !data_class || !anchors || !anchors->computer_anchor) { @@ -194,6 +146,8 @@ mobilesync_error_t mobilesync_start(mobilesync_client_t client, const char *data plist_t msg = NULL; plist_t response_type_node = NULL; + *error_description = NULL; + msg = plist_new_array(); plist_array_append_item(msg, plist_new_string("SDMessageSyncDataClassWithDevice")); plist_array_append_item(msg, plist_new_string(data_class)); @@ -233,23 +187,19 @@ mobilesync_error_t mobilesync_start(mobilesync_client_t client, const char *data goto out; } + // did the device refuse to sync with the computer? if (!strcmp(response_type, "SDMessageRefuseToSyncDataClassWithComputer")) { - char *reason = NULL; err = MOBILESYNC_E_SYNC_REFUSED; - plist_get_string_val(plist_array_get_item(msg, 2), &reason); - debug_info("Device refused sync: %s", reason); - free(reason); - reason = NULL; + plist_get_string_val(plist_array_get_item(msg, 2), error_description); + debug_info("Device refused sync: %s", error_description); goto out; } + // did the device cancel the session? if (!strcmp(response_type, "SDMessageCancelSession")) { - char *reason = NULL; err = MOBILESYNC_E_CANCELLED; - plist_get_string_val(plist_array_get_item(msg, 2), &reason); - debug_info("Device cancelled: %s", reason); - free(reason); - reason = NULL; + plist_get_string_val(plist_array_get_item(msg, 2), error_description); + debug_info("Device cancelled: %s", error_description); goto out; } @@ -309,17 +259,6 @@ mobilesync_error_t mobilesync_start(mobilesync_client_t client, const char *data return err; } -/** - * Finish a synchronization session of a data class on the device. - * A session must have previously been started using mobilesync_start(). - * - * @param client The mobilesync client - * - * @retval MOBILESYNC_E_SUCCESS on success - * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid - * @retval MOBILESYNC_E_PLIST_ERROR if the received plist is not of valid - * form - */ mobilesync_error_t mobilesync_finish(mobilesync_client_t client) { if (!client || !client->data_class) { @@ -395,7 +334,7 @@ static mobilesync_error_t mobilesync_get_records(mobilesync_client_t client, con msg = plist_new_array(); plist_array_append_item(msg, plist_new_string(operation)); plist_array_append_item(msg, plist_new_string(client->data_class)); - + err = mobilesync_send(client, msg); if (msg) { @@ -405,49 +344,16 @@ static mobilesync_error_t mobilesync_get_records(mobilesync_client_t client, con return err; } -/** - * Requests to receive all records of the currently set data class from the device. - * The actually changes are retrieved using mobilesync_receive_changes() after this - * request has been successful. - * - * @param client The mobilesync client - * - * @retval MOBILESYNC_E_SUCCESS on success - * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid - */ mobilesync_error_t mobilesync_get_all_records_from_device(mobilesync_client_t client) { return mobilesync_get_records(client, "SDMessageGetAllRecordsFromDevice"); } -/** - * Requests to receive only changed records of the currently set data class from the device. - * The actually changes are retrieved using mobilesync_receive_changes() after this - * request has been successful. - * - * @param client The mobilesync client - * - * @retval MOBILESYNC_E_SUCCESS on success - * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid - */ mobilesync_error_t mobilesync_get_changes_from_device(mobilesync_client_t client) { return mobilesync_get_records(client, "SDMessageGetChangesFromDevice"); } -/** - * Receives changed entitites of the currently set data class from the device - * - * @param client The mobilesync client - * @param entities A pointer to store the changed entity records as a PLIST_DICT - * @param is_last_record A pointer to store a flag indicating if this submission is the last one - * @param actions A pointer to additional flags the device is sending or NULL to ignore - * - * @retval MOBILESYNC_E_SUCCESS on success - * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid - * @retval MOBILESYNC_E_CANCELLED if the device explicitly cancelled the - * session - */ mobilesync_error_t mobilesync_receive_changes(mobilesync_client_t client, plist_t *entities, uint8_t *is_last_record, plist_t *actions) { if (!client || !client->data_class) { @@ -497,7 +403,7 @@ mobilesync_error_t mobilesync_receive_changes(mobilesync_client_t client, plist_ if (actions != NULL) { actions_node = plist_array_get_item(msg, 4); - if (plist_get_node_type(actions) == PLIST_DICT) + if (plist_get_node_type(actions_node) == PLIST_DICT) *actions = plist_copy(actions_node); else *actions = NULL; @@ -515,17 +421,6 @@ mobilesync_error_t mobilesync_receive_changes(mobilesync_client_t client, plist_ return err; } -/** - * Requests the device to delete all records of the current data class - * - * @note The operation must be called after starting synchronization. - * - * @param client The mobilesync client - * - * @retval MOBILESYNC_E_SUCCESS on success - * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid - * @retval MOBILESYNC_E_PLIST_ERROR if the received plist is not of valid form - */ mobilesync_error_t mobilesync_clear_all_records_on_device(mobilesync_client_t client) { if (!client || !client->data_class) { @@ -578,7 +473,7 @@ mobilesync_error_t mobilesync_clear_all_records_on_device(mobilesync_client_t cl goto out; } - if (strcmp(response_type, "SDMessageDeviceWillClearAllRecords")) { + if (strcmp(response_type, "SDMessageDeviceWillClearAllRecords") != 0) { err = MOBILESYNC_E_PLIST_ERROR; } @@ -595,14 +490,6 @@ mobilesync_error_t mobilesync_clear_all_records_on_device(mobilesync_client_t cl return err; } -/** - * Acknowledges to the device that the changes have been merged on the computer - * - * @param client The mobilesync client - * - * @retval MOBILESYNC_E_SUCCESS on success - * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid - */ mobilesync_error_t mobilesync_acknowledge_changes_from_device(mobilesync_client_t client) { if (!client || !client->data_class) { @@ -637,23 +524,6 @@ static plist_t create_process_changes_message(const char *data_class, plist_t en return msg; } -/** - * Verifies if the device is ready to receive changes from the computer. - * This call changes the synchronization direction so that mobilesync_send_changes() - * can be used to send changes to the device. - * - * @param client The mobilesync client - * - * @retval MOBILESYNC_E_SUCCESS on success - * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid - * @retval MOBILESYNC_E_PLIST_ERROR if the received plist is not of valid form - * @retval MOBILESYNC_E_WRONG_DIRECTION if the current sync direction does - * not permit this call - * @retval MOBILESYNC_E_CANCELLED if the device explicitly cancelled the - * session - * @retval MOBILESYNC_E_NOT_READY if the device is not ready to start - * receiving any changes - */ mobilesync_error_t mobilesync_ready_to_send_changes_from_computer(mobilesync_client_t client) { if (!client || !client->data_class) { @@ -721,20 +591,6 @@ mobilesync_error_t mobilesync_ready_to_send_changes_from_computer(mobilesync_cli return err; } -/** - * Sends changed entities of the currently set data class to the device - * - * @param client The mobilesync client - * @param entities The changed entity records as a PLIST_DICT - * @param is_last_record A flag indicating if this submission is the last one - * @param actions Additional actions for the device created with mobilesync_actions_new() - * or NULL if no actions should be passed - * - * @retval MOBILESYNC_E_SUCCESS on success - * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid, - * @retval MOBILESYNC_E_WRONG_DIRECTION if the current sync direction does - * not permit this call - */ mobilesync_error_t mobilesync_send_changes(mobilesync_client_t client, plist_t entities, uint8_t is_last_record, plist_t actions) { if (!client || !client->data_class || !entities) { @@ -763,21 +619,6 @@ mobilesync_error_t mobilesync_send_changes(mobilesync_client_t client, plist_t e return err; } -/** - * Receives any remapped identifiers reported after the device merged submitted changes. - * - * @param client The mobilesync client - * @param mapping A pointer to an array plist containing a dict of identifier remappings - * - * @retval MOBILESYNC_E_SUCCESS on success - * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid - * @retval MOBILESYNC_E_PLIST_ERROR if the received plist is not of valid - * form - * @retval MOBILESYNC_E_WRONG_DIRECTION if the current sync direction does - * not permit this call - * @retval MOBILESYNC_E_CANCELLED if the device explicitly cancelled the - * session - */ mobilesync_error_t mobilesync_remap_identifiers(mobilesync_client_t client, plist_t *mapping) { if (!client || !client->data_class) { @@ -847,15 +688,6 @@ mobilesync_error_t mobilesync_remap_identifiers(mobilesync_client_t client, plis return err; } -/** - * Cancels a running synchronization session with a device at any time. - * - * @param client The mobilesync client - * @param reason The reason to supply to the device for cancelling - * - * @retval MOBILESYNC_E_SUCCESS on success - * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid - */ mobilesync_error_t mobilesync_cancel(mobilesync_client_t client, const char* reason) { if (!client || !client->data_class || !reason) { @@ -882,18 +714,9 @@ mobilesync_error_t mobilesync_cancel(mobilesync_client_t client, const char* rea return err; } -/** - * Allocates memory for a new anchors struct initialized with the passed anchors. - * - * @param device_anchor An anchor the device reported the last time or NULL - * if none is known yet which for instance is true on first synchronization. - * @param computer_anchor An arbitrary string to use as anchor for the computer. - * - * @return A new #mobilesync_anchors_t struct. Must be freed using mobilesync_anchors_free(). - */ mobilesync_anchors_t mobilesync_anchors_new(const char *device_anchor, const char *computer_anchor) { - mobilesync_anchors_t anchors = (mobilesync_anchors_t) malloc(sizeof(mobilesync_anchors)); + mobilesync_anchors_t anchors = (mobilesync_anchors_t) malloc(sizeof(mobilesync_anchors)); if (device_anchor != NULL) { anchors->device_anchor = strdup(device_anchor); } else { @@ -908,11 +731,6 @@ mobilesync_anchors_t mobilesync_anchors_new(const char *device_anchor, const cha return anchors; } -/** - * Free memory used by anchors. - * - * @param anchors The anchors to free. - */ void mobilesync_anchors_free(mobilesync_anchors_t anchors) { if (anchors->device_anchor != NULL) { @@ -927,28 +745,11 @@ void mobilesync_anchors_free(mobilesync_anchors_t anchors) anchors = NULL; } -/** - * Create a new actions plist to use in mobilesync_send_changes(). - * - * @return A new plist_t of type PLIST_DICT. - */ -plist_t mobilesync_actions_new() +plist_t mobilesync_actions_new(void) { return plist_new_dict(); } -/** - * Add one or more new key:value pairs to the given actions plist. - * - * @param actions The actions to modify. - * @param ... KEY, VALUE, [KEY, VALUE], NULL - * - * @note The known keys so far are "SyncDeviceLinkEntityNamesKey" which expects - * an array of entity names, followed by a count paramter as well as - * "SyncDeviceLinkAllRecordsOfPulledEntityTypeSentKey" which expects an - * integer to use as a boolean value indicating that the device should - * link submitted changes and report remapped identifiers. - */ void mobilesync_actions_add(plist_t actions, ...) { if (!actions) @@ -969,10 +770,10 @@ void mobilesync_actions_add(plist_t actions, ...) plist_array_append_item(array, plist_new_string(entity_names[i])); } - plist_dict_insert_item(actions, key, array); + plist_dict_set_item(actions, key, array); } else if (!strcmp(key, "SyncDeviceLinkAllRecordsOfPulledEntityTypeSentKey")) { int link_records = va_arg(args, int); - plist_dict_insert_item(actions, key, plist_new_bool(link_records)); + plist_dict_set_item(actions, key, plist_new_bool(link_records)); } free(key); key = NULL; @@ -981,11 +782,6 @@ void mobilesync_actions_add(plist_t actions, ...) va_end(args); } -/** - * Free actions plist. - * - * @param actions The actions plist to free. Does nothing if NULL is passed. - */ void mobilesync_actions_free(plist_t actions) { if (actions) { |