Closed AiXanadu closed 1 year ago
it's missing version exchange, unless you filtered it out.
when you start mobilesync service you start with
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<string>DLMessageVersionExchange</string>
<integer>400</integer>
<integer>100</integer>
</array>
</plist>
and receive
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<string>DLMessageDeviceReady</string>
</array>
</plist>
then you start syncing
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<string>SDMessageSyncDataClassWithDevice</string>
<string>com.apple.Contacts</string>
<string>---</string>
<string>2023-05-09 17-32-06 +0100</string>
<integer>106</integer>
<string>___EmptyParameterString___</string>
</array>
</plist>
and response is like
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<string>SDMessageSyncDataClassWithComputer</string>
<string>com.apple.Contacts</string>
<string>2023-05-09 17-31-32 +0100</string>
<string>May 09 2023 17:32:06 +0200</string>
<string>SDSyncTypeSlow</string>
<integer>106</integer>
<string>___EmptyParameterString___</string>
</array>
</plist>
and then you continue
I think it has switched versions, because the version swap function has been executed when the client is created. `LIBIMOBILEDEVICE_API mobilesync_error_t mobilesync_client_new(idevice_t device, lockdownd_service_descriptor_t service, mobilesync_client_t 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, service, &dlclient));
if (ret != MOBILESYNC_E_SUCCESS) {
return ret;
}
mobilesync_client_t client_loc = (mobilesync_client_t) malloc(sizeof(struct mobilesync_client_private));
client_loc->parent = dlclient;
client_loc->direction = MOBILESYNC_SYNC_DIR_DEVICE_TO_COMPUTER;
client_loc->data_class = NULL;
/* perform handshake */
ret = mobilesync_error(device_link_service_version_exchange(dlclient, MSYNC_VERSION_INT1, MSYNC_VERSION_INT2));
if (ret != MOBILESYNC_E_SUCCESS) {
debug_info("version exchange failed, error %d", ret);
mobilesync_client_free(client_loc);
return ret;
}
*client = client_loc;
return ret;
} ` Do I need to manually add the SSL connection function interface?
service client connection is automatically set to ssl, if services start specifies it uses ssl, you don't need to to that explicitly.
and yes, you are right mobilesync_client_new sends the version exchange message
so if you go with functions (in mobilesync.h) proper order of functions should be mobilesync_client_new - create client mobilesync_anchors_new - create synchronization anchor mobilesync_start - start synchronization mobilesync_get_all_records_from_device - send command to receive all records mobilesync_receive_changes - receive record - this is called in cycle, pay attentio to is_last_record value mobilesync_finish
i don't use mobilesync function, since we have own implementation of sychronization and communicate with service directly.
Maybe that's how it goes. But when I call mobilesync_start the data returned is as I said above. DLMessageDisconnect
if you run it with debug output, do you see, that version exchange is processed?
or you might try just instead of mobilesync_client_new, try direct communication. i will try next week compile simple tool using mobilesync functions.
i'm testing on my ipad, which has 16.4.1(a) and iphone, also 16.4.1(a), and have no issues, but as i said, it's my own code, although it sends in most cases same stuff, as libimobile does. it's reverse engineered from usb capture.
hey, i just made simple code to retrieve contacts using mobilesync function, running on io 16.4.1(a) code will need some polishing, but i can retrieve contacts from internal memory without issues with it. it was compiled on windows, but should work on linux too.
#include <iostream>
#include "libimobiledevice/mobilesync.h"
#include "libimobiledevice/libimobiledevice.h"
#include <sys/timeb.h>
int main()
{
idevice_set_debug_level(1);
idevice_t device = nullptr;
auto ret = idevice_new(&device, "00008030-000115A202F9802E");
if (ret == IDEVICE_E_SUCCESS && idevice_new)
{
lockdownd_client_t client = nullptr;
auto lret = lockdownd_client_new_with_handshake(device, &client, "synctest");
if (lret == LOCKDOWN_E_SUCCESS && client)
{
plist_t val = nullptr;
auto vret = lockdownd_get_value(client, "com.apple.mobile.tethered_sync", nullptr, &val);
if (vret == LOCKDOWN_E_SUCCESS && val)
{
char* plistbuf = nullptr;
uint32_t plistlen = 0;
auto pret = plist_to_xml(val, &plistbuf, &plistlen);
if (pret == PLIST_ERR_SUCCESS && plistlen)
{
printf(plistbuf);
free(plistbuf);
}
plist_free(val);
}
lockdownd_client_free(client);
}
mobilesync_client_t syncclient = nullptr;
auto mret = mobilesync_client_start_service(device, &syncclient, "synctest");
if (mret == MOBILESYNC_E_SUCCESS && syncclient)
{
char anchor[200];
__time64_t ltime;
struct tm* ltm;
_time64(<ime);
ltm = _localtime64(<ime);
strftime(anchor, 200 - 1, "%Y-%m-%d %H-%M-%S", ltm);
char buffertz[20];
struct __timeb64 ltmz;
_ftime64(<mz);
sprintf(buffertz, " %c%02d%02d", ltmz.timezone > 0 ? '-' : '+', abs(ltmz.timezone / 60), abs(ltmz.timezone % 60));
strcat(anchor, buffertz);
mobilesync_sync_type_t synctype = MOBILESYNC_SYNC_TYPE_SLOW;
uint64_t syncversion = 0;
char* errormsg = nullptr;
auto anchors = mobilesync_anchors_new(nullptr, anchor);
if ((mret = mobilesync_start(syncclient, "com.apple.Contacts", anchors, 106, &synctype, &syncversion, &errormsg)) == MOBILESYNC_E_SUCCESS)
{
if (mobilesync_get_all_records_from_device(syncclient) == MOBILESYNC_E_SUCCESS)
{
plist_t entities = nullptr;
uint8_t islast = 0;
while (mobilesync_receive_changes(syncclient, &entities, &islast, nullptr) == MOBILESYNC_E_SUCCESS)
{
if (entities)
{
char* plistbuf = nullptr;
uint32_t plistlen = 0;
auto pret = plist_to_xml(entities, &plistbuf, &plistlen);
if (pret == PLIST_ERR_SUCCESS && plistlen)
{
printf(plistbuf);
free(plistbuf);
}
plist_free(entities);
}
mobilesync_acknowledge_changes_from_device(syncclient);
if (islast)
break;
}
}
}
else
printf("error %d, %s", mret, errormsg);
mobilesync_anchors_free(anchors);
mobilesync_client_free(syncclient);
}
idevice_free(device);
}
}
@mexmer Thank you very much, I used your code and successfully read the contacts!
i think there should be disconnect message, or cancel at end, and other stuff, to avoid leaving phone in udesired state. so take it just as concept.
I have an iPhone13 Pro (iOS16.4.1) device, I want to get the contact list in the device, how should I do it?
The ideviceinfo command shows the following: ideviceinfo.exe -q com.apple.mobile.tethered_sync -x
I start by callingmobilesync_start:
then it sends:
device returned:
How can I synchronize this operation?