summaryrefslogtreecommitdiffstats
path: root/src/mobilesync.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mobilesync.c')
-rw-r--r--src/mobilesync.c286
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) {