sdmmd_return_t SDMMD_ServiceSendMessage(SocketConnection handle, CFPropertyListRef data, CFPropertyListFormat format) {
	CFErrorRef error;
	CFDataRef xmlData = CFPropertyListCreateData(kCFAllocatorDefault, data, format, 0, &error);
	sdmmd_return_t result = ((data) ? SDMMD_ServiceSend(handle, xmlData) : kAMDInvalidArgumentError);
	if (xmlData)
		CFRelease(xmlData);
	return result;
}
sdmmd_return_t SDMMD_MB2SendFileStream(SDMMD_AMConnectionRef conn, CFStringRef path, CFDataRef file) {
	sdmmd_return_t result = kAMDSuccess;
	
	CFDataRef file_path = CFStringCreateExternalRepresentation(kCFAllocatorDefault, path, kCFStringEncodingUTF8, 0);
	result = SDMMD_ServiceSend(SDMMD_TranslateConnectionToSocket(conn), file_path);
	CFSafeRelease(file_path);
	
	char data_chunk[1] = { 0x0C };
	CFMutableDataRef data_separator = CFDataCreateMutable(kCFAllocatorDefault, 0);
	CFDataAppendBytes(data_separator, (const UInt8 *)data_chunk, sizeof(uint8_t));
	CFDataAppendBytes(data_separator, CFDataGetBytePtr(file), CFDataGetLength(file));
	result = SDMMD_ServiceSend(SDMMD_TranslateConnectionToSocket(conn), data_separator);
	CFSafeRelease(data_separator);
	
	char zero_chunk[1] = { 0x0 };
	CFDataRef data_end = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)zero_chunk, sizeof(uint8_t));
	result = SDMMD_ServiceSend(SDMMD_TranslateConnectionToSocket(conn), data_end);
	CFSafeRelease(data_end);
	
	return result;
}
sdmmd_return_t SDMMD_ServiceSendStream(SocketConnection handle, CFPropertyListRef data, CFPropertyListFormat format) {
	CFStringRef errStr;
	CFWriteStreamRef write = CFWriteStreamCreateWithAllocatedBuffers(kCFAllocatorDefault, kCFAllocatorDefault);
	CFWriteStreamOpen(write);
	uint32_t length = CFPropertyListWriteToStream(data, write, format, &errStr);
	CFDataRef xmlData = CFWriteStreamCopyProperty(write, kCFStreamPropertyDataWritten);
	sdmmd_return_t result = kAMDInvalidArgumentError;
	if (length == CFDataGetLength(xmlData)) {
		result = ((data) ? SDMMD_ServiceSend(handle, xmlData) : kAMDInvalidArgumentError);
	}
	if (xmlData)
		CFRelease(xmlData);
	CFWriteStreamClose(write);
	if (write)
		CFRelease(write);
	return result;
}