samdmarshall / SDMMobileDevice

MobileDevice Implementation
BSD 3-Clause "New" or "Revised" License
574 stars 97 forks source link

sdmmd_return_t SDMMD_ServiceSend(SocketConnection, CFDataRef): Incomplete length #102

Closed kapil0408 closed 7 years ago

kapil0408 commented 7 years ago

When i try to take backup then it show this error in SDMMD_ServiceSendMessage function.

Please see code: -(void)getMobileBackup { sdmmd_return_t result1 = kAMDInvalidArgumentError; CFDictionaryRef dict = NULL; SDMMD_AMConnectionRef conn = NULL; conn = SDMMD_AMDServiceConnectionCreate(0, NULL, dict); result1 = SDMMD_AMDeviceStartService(device, CFSTR(AMSVC_BACKUP2), NULL, &conn);

if (SDM_MD_CallSuccessful(result1))
{
    CFMutableDictionaryRef responset = NULL;

    /*
     Open connection

     recieve from device

     <CFArray>=[
     <CFStringRef>={DLMessageVersionExchange}
     <CFNumberRef>=(kCFNumberSInt64Type){300} // major version
     <CFNumberRef>=(kCFNumberSInt64Type){0} // minor version
     ]

     respond with sending

     <CFArray>=[
     <CFStringRef>={DLMessageProcessMessage}
     <CFDictionary>={
     ]
     SupportedProtocolVersions: <CFArray>=[
     <CFNumberRef>=(kCFNumberFloat64Type){2.100000}
     MessageName: <CFStringRef>={Hello}
     }
     ]

     if successful, now receive

     <CFArray>=[
     <CFStringRef>={DLMessageDeviceReady}
     ]

     it seems that for doing a restore, you need to parse the mbdb

     // for files that are not on the host system
     Received:
     <CFArray>=[
     <CFStringRef>={DLMessageDownloadFiles}
     <CFArray>=[
     <CFStringRef>={435f770a03b4ff48d7540f3d85851f845e6e14ac/Info.plist}
     ]
     <CFDictionary>={
     }
     <CFNumberRef>=(kCFNumberFloat64Type){0.000000}
     <CFNumberRef>=(kCFNumberSInt64Type){0}
     ]

     If file doesn't exist...

     Send: (length + 0x06)
     0000 0001 06

     Send: (four zeros raw)
     0000 0000

     Send Message:
     <CFArray>=[
     <CFStringRef>={DLMessageStatusResponse}
     <CFNumberRef>=(kCFNumberSInt64Type){-13}   // magic error number :P
     <CFStringRef>={Multi status}
     <CFDictionary>={
     <CFStringRef>={435f770a03b4ff48d7540f3d85851f845e6e14ac/Info.plist}: <CFDictionary>={
     <CFStringRef>={DLFileErrorString}: <CFStringRef>=Invalid object referenced in backup image // this is just an example
     <CFStringRef>={DLFileErrorCode}: <CFNumberRef>=(kCFNumberSInt64Type){-6}   // this is the error code I've seen for file not found
     }
     }
     ]
     */

    CFMutableArrayRef arrVesrions = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
    Float64 code_value1 = 2.0;
    CFNumberRef code1 = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloat64Type, &code_value1);
    CFArrayAppendValue(arrVesrions, code1);

    Float64 code_value2 = 2.1;
    CFNumberRef code2 = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloat64Type, &code_value2);
    CFArrayAppendValue(arrVesrions, code2);

    CFMutableDictionaryRef dictVersion = SDMMD_create_dict();
    CFDictionarySetValue(dictVersion, CFSTR("SupportedProtocolVersions"), arrVesrions);
    CFDictionarySetValue(dictVersion, CFSTR("MessageName"), CFSTR("Hello"));

    CFMutableArrayRef status_response = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
    CFArrayAppendValue(status_response, CFSTR("DLMessageProcessMessage"));
    CFArrayAppendValue(status_response, dictVersion);

    result1 = SDMMD_ServiceSendMessage(SDMMD_TranslateConnectionToSocket(conn), status_response, kCFPropertyListXMLFormat_v1_0);
    if (SDM_MD_CallSuccessful(result1))
    {
        result1 = SDMMD_ServiceReceiveMessage(SDMMD_TranslateConnectionToSocket(conn), (CFPropertyListRef *)&responset);

    }
    if (SDM_MD_CallSuccessful(result1))
    {
        NSMutableDictionary *dictResponse = (__bridge NSMutableDictionary *)(responset);
        NSLog(@"dictResponse=%@",dictResponse);

        CFMutableArrayRef arrDeviceReady = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
        CFArrayAppendValue(arrDeviceReady, CFSTR("DLMessageVersionExchange"));
        CFArrayAppendValue(arrDeviceReady, CFSTR("DLVersionsOk"));
        uint32_t code_value3 = 300;
        CFNumberRef code3 = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &code_value3);
        CFArrayAppendValue(arrDeviceReady, code3);

        **result1 = SDMMD_ServiceSendMessage(SDMMD_TranslateConnectionToSocket(conn), arrDeviceReady, kCFPropertyListXMLFormat_v1_0);**

        if (SDM_MD_CallSuccessful(result1))
        {
            result1 = SDMMD_ServiceReceiveMessage(SDMMD_TranslateConnectionToSocket(conn), (CFPropertyListRef *)&responset);

        }
        if (SDM_MD_CallSuccessful(result1))
        {
            NSMutableDictionary *dictResponse = (__bridge NSMutableDictionary *)(responset);
            NSLog(@"dictResponse=%@",dictResponse);

        }
    }
}

}

I am facing problem in this line: " result1 = SDMMD_ServiceSendMessage(SDMMD_TranslateConnectionToSocket(conn), arrDeviceReady, kCFPropertyListXMLFormat_v1_0); " Please suggest any solution.

samdmarshall commented 7 years ago

Again, I am not answering questions about usage of the framework if they go beyond the realm of "does it work as intended" if you are having trouble implementing something on your own with it, I don't have time to help you with this, sorry.