/// <summary> /// /// </summary> /// <param name="command"></param> /// <returns>localId=serverId pair</returns> private string ApplyAddOrReplaceCommand(SyncMLUpdateBase command) { if (command == null) { return(null); } bool isBase64 = false; bool isAddCommand = false; SyncMLMeta commandMeta = command.Meta; SyncMLItem commandItem = command.ItemCollection[0]; //assuming there is always one item. if (String.IsNullOrEmpty(commandMeta.Content) && (!commandMeta.Xml.HasElements)) { commandMeta = commandItem.Meta; } MetaParser metaParser = new MetaParser(commandMeta.Xml); MetaFormat metaFormat = metaParser.GetMetaFormat(); if (metaFormat != null) { isBase64 = metaFormat.Content == "b64"; } MetaType metaType = metaParser.GetMetaType(); if (metaType == null) { return(null); //the meta element may be empty, so no need to proceed. } // if (contentType == ContactExchangeType.Unknown) //todo: add some exception throw new LocalDataSourceException("expected data is Base64 encoded SIF-C or vCard"); isAddCommand = command is SyncMLAdd; //Assuming there will be only one item. string serverId; string localId = null; serverId = commandItem.Source.LocURI.Content; //id of remote one if (!isAddCommand) { localId = commandItem.Target.LocURI.Content; // entryId of existing contact } string text = GetTextFromContent(isBase64, metaType.Content, commandItem.Data.Content); if (text != null) { localId = isAddCommand ? sifAgent.AddItem(text) : sifAgent.ReplaceItem(text, localId); return(isAddCommand ? localId + "=" + serverId : null); } else { return(null); } }
protected override void HandleServerStatus(SyncMLStatus status) { string statusCode = status.Data.Content; Debug.WriteLine("Status " + statusCode + ": " + GetStatusReport(status)); switch (status.CmdRef.Content) { case "0": //Handle header authentication switch (statusCode) { case "212": Facade.DisplayOperationMessage("Log on to SyncML server successfully."); LoggedOn = true; AuthenticationStatus = SyncMLAuthenticationStatus.LoggedOn; MetaParser parser2 = new MetaParser(status.Chal.Meta.Xml); MetaType metaType2 = parser2.GetMetaType(); if (metaType2 != null) { if (metaType2.Content == "syncml:auth-basic") { AuthenticationStatus = SyncMLAuthenticationStatus.Base64Chal; Facade.AuthenticationTypeOfNextMessage = SyncMLAuthenticationType.Base64; } else if (metaType2.Content == "syncml:auth-md5") { AuthenticationStatus = SyncMLAuthenticationStatus.MD5Chal; MetaNextNonce nextNonce = parser2.GetMetaNextNonce(); Facade.Md5NextNonceFromServer = Convert.FromBase64String(nextNonce.Content); Facade.AuthenticationTypeOfNextMessage = SyncMLAuthenticationType.MD5; } else { AuthenticationStatus = SyncMLAuthenticationStatus.UnknownChal; } } break; case "407": case "401": MetaParser parser = new MetaParser(status.Chal.Meta.Xml); MetaType metaType = parser.GetMetaType(); if (metaType != null) { if (metaType.Content == "syncml:auth-basic") { AuthenticationStatus = SyncMLAuthenticationStatus.Base64Chal; } else if (metaType.Content == "syncml:auth-md5") { AuthenticationStatus = SyncMLAuthenticationStatus.MD5Chal; MetaNextNonce nextNonce = parser.GetMetaNextNonce(); Facade.Md5NextNonceFromServer = Convert.FromBase64String(nextNonce.Content); } else { AuthenticationStatus = SyncMLAuthenticationStatus.UnknownChal; } } else { AuthenticationStatus = SyncMLAuthenticationStatus.FailedID; } Facade.DisplayOperationMessage("Authentication rejected. Please check user name and password."); break; default: AuthenticationStatus = SyncMLAuthenticationStatus.UnknownStatus; Facade.DisplayOperationMessage("The server sent back unexpected status code: " + statusCode); Facade.SoFarOK = false; break; } break; case "1": //server status to the sync alert command switch (statusCode) { case "508": Trace.TraceInformation("Server wants slown sync."); // Facade.ResponseCommandPool.Add(CreateSyncAlert(SyncType.Slow)); break; case "200": break; default: if (statusCode == "404") { Trace.TraceInformation("The server does not have requested data store."); Facade.DisplayOperationMessage("The server does not have requested data store."); } Trace.TraceInformation(String.Format("Sync request is rejected. The server said: {0}", Facade.StatusMessages.GetMessage(statusCode))); Facade.SoFarOK = false; break; } break; case "2": // Handle response to previous Get if (statusCode == "200") { Trace.TraceInformation("Received server device information successfully."); } else { Facade.SoFarOK = false; } break; case "3": // Handle response to previous Put. if (statusCode == "200") { Trace.TraceInformation("The server received local device information successfully."); } else { Facade.SoFarOK = false; } break; default: Trace.TraceInformation("Unexpected CmdRef in Status."); Facade.SoFarOK = false; break; } }
} // using xmlWriter /// <summary> /// /// </summary> /// <param name="topElement">the 'Changes' element, to be manipulated</param> /// <param name="command"></param> private static void WriteAddOrReplaceCommandToXml(XElement topElement, SyncMLUpdateBase command) { if (command == null) { return; } bool isBase64 = false; ContactExchangeType contentType = ContactExchangeType.Unknown; bool isAddCommand = false; string commandTypeStr; SyncMLMeta commandMeta = command.Meta; SyncMLItem commandItem = command.ItemCollection[0]; //assuming there is always one item. if (String.IsNullOrEmpty(commandMeta.Content) && (!commandMeta.Xml.HasElements)) { commandMeta = commandItem.Meta; } MetaParser metaParser = new MetaParser(commandMeta.Xml); MetaFormat metaFormat = metaParser.GetMetaFormat(); if (metaFormat != null) { isBase64 = metaFormat.Content == "b64"; } MetaType metaType = metaParser.GetMetaType(); if (metaType == null) { return; //the meta element may be empty, so no need to proceed. } if (metaType.Content == "text/x-s4j-sifc") { contentType = ContactExchangeType.Sifc; } else if ((metaType.Content == "text/x-vcard") || (metaType.Content == "text/vcard")) { contentType = ContactExchangeType.Vcard21; } if (contentType == ContactExchangeType.Unknown) { throw new LocalDataSourceException("expected data is Base64 encoded SIF-C or vCard"); } isAddCommand = command is SyncMLAdd; commandTypeStr = isAddCommand ? "New" : "Update"; //Assuming there will be only one item. string id; if (isAddCommand) { id = commandItem.Source.LocURI.Content; } else { id = commandItem.Target.LocURI.Content; } XElement cItem = new XElement("C", new XAttribute("ID", id)); XElement changItem = new XElement(commandTypeStr, cItem); topElement.Add(changItem); switch (contentType) { case ContactExchangeType.Sifc: // do not need to check isBase64, because it must be cItem.Add(XElement.Parse(Utility.ConvertFromBase64(commandItem.Data.Content))); break; case ContactExchangeType.Vcard21: XElement sifcXml; if (isBase64) { sifcXml = VCardSIFC.ConvertVCardToSifCXml(VCardReader.ParseText( Utility.ConvertFromBase64(commandItem.Data.Content))); } else { sifcXml = VCardSIFC.ConvertVCardToSifCXml(VCardReader.ParseText(commandItem.Data.Content)); } cItem.Add(sifcXml); break; default: throw new LocalDataSourceException("Can not create stream from command Data."); } }