示例#1
0
        /// <summary>
        /// Called by ProcessResponseForXXX in order to respond to Status returned by server
        /// </summary>
        /// <param name="status">SyncMLStatus object which is part of syncml.</param>
        protected override void HandleServerStatus(SyncMLStatus status)
        {
            string statusCode = status.Data.Content;

            switch (statusCode)
            {
            case "207":      //The user updated the same record on more than 1 devices
                if (status.SourceRefCollection.Count > 0)
                {
                    string localID     = status.SourceRefCollection[0].Content;
                    string contactName = Facade.LocalDataSource.GetItemName(localID);
                    string m           = String.Format("When updating for {0}, the sync server found conflicts. Though the conflicts were resolved by the sync server through data merge, please manually check to ensure everything is OK.", contactName);
                    Facade.DisplayOperationMessage(m);
                }
                break;

            case "402":
                Facade.DisplayOperationMessage("The server requires payment.");
                Facade.SoFarOK = false;
                break;

            case "511":     // this is with the status for Hdr
                Facade.DisplayOperationMessage("Serious error with SyncHdr.");
                Facade.SoFarOK = false;
                break;

            default:
                break;
            }
            Debug.WriteLine("Status " + statusCode + ": " + GetStatusReport(status));
        }
示例#2
0
        public void TestStatus()
        {
            XElement nav = XElement.Load(CaseFile("Status.xml"));

            SyncMLStatus f = SyncMLStatus.Create(nav);

            Assert.IsTrue(CompareXml(nav, f.Xml), f.Xml.ToString());
        }
示例#3
0
        /// <summary>
        /// Called by ProcessResponseForXXX in order to create status for Alert returned by server.
        /// </summary>
        /// <param name="alert"></param>
        protected void PrepareStatusForReturnedAlert(SyncMLAlert alert)
        {
            switch (alert.Data.Content)
            {
            case "200":
            case "201":
            case "202":
            case "203":
            case "204":
            case "205":
                SyncMLStatus responseStatus = SyncMLStatus.Create();
                //status.CmdID is not defined here, but only defined right before sending next message
                responseStatus.MsgRef.Content = ServerSyncML.Hdr.MsgID.Content;
                responseStatus.Data.Content   = "200";
                responseStatus.Cmd.Content    = "Alert";
                responseStatus.CmdRef.Content = alert.CmdID.Content;
                responseStatus.TargetRefCollection.Add(SyncMLSimpleElementFactory.Create <SyncMLTargetRef>(Facade.ContactDataSourceAtServer));
                responseStatus.SourceRefCollection.Add(SyncMLSimpleElementFactory.Create <SyncMLSourceRef>(Facade.LocalDataSource.DataSourceName));

                //Get alert anchor next
                SyncMLItem alertItem       = alert.ItemCollection[0]; //assuming there's always one.
                SyncMLMeta alertItemMeta   = alertItem.Meta;          // assuming there's always one.
                MetaParser metaParser      = new MetaParser(alertItemMeta.Xml);
                MetaAnchor alertAnchor     = metaParser.GetMetaAnchor();
                string     alertAnchorNext = alertAnchor.Next.Content;

                SyncMLItem statusItem   = SyncMLItem.Create();
                MetaAnchor statusAnchor = MetaAnchor.Create();
                statusAnchor.Next = SyncMLSimpleElementFactory.Create <MetaNext>(alertAnchorNext);
                statusItem.Data.Xml.Add(statusAnchor.Xml);

                responseStatus.ItemCollection.Add(statusItem);

                Facade.ResponseCommandPool.Add(responseStatus);
                break;

            case "100":
                //Show. The Data element type contains content information that should be processed and displayed through the user agent.
                string serverStatusMessage = alert.ItemCollection[0].Data.Content;
                Facade.DisplayOperationMessage(serverStatusMessage);

                SyncMLStatus statusFor100 = SyncMLStatus.Create();
                statusFor100.MsgRef.Content = ServerSyncML.Hdr.MsgID.Content;
                statusFor100.Data.Content   = "200";
                statusFor100.Cmd.Content    = "Alert";
                statusFor100.CmdRef.Content = alert.CmdID.Content;
                Facade.ResponseCommandPool.Add(statusFor100);

                break;

            default:
                Trace.TraceInformation("Do not know what to do in PrepareStatusForReturnedAlert:");
                Trace.TraceInformation(alert.Xml.ToString());
                break;
            }
        }
示例#4
0
        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;
            }
        }
示例#5
0
 protected string GetStatusReport(SyncMLStatus status)
 {
     return(String.Format("Status: {0}  CmdRef: {1}  Cmd: {2} " + Environment.NewLine + "{3}",
                          status.Data.Content, status.CmdRef.Content, status.Cmd.Content,
                          Facade.StatusMessages.GetMessage(status.Data.Content)));
 }
示例#6
0
 /// <summary>
 /// Called by ProcessResponseForXXX in order to respond to some Status returned by server
 /// </summary>
 /// <param name="status">SyncMLStatus object which is part of syncml.</param>
 protected abstract void HandleServerStatus(SyncMLStatus status);
示例#7
0
        /// <summary>
        /// Generate status commands for received Sync command, and put the commands into the pool.
        /// </summary>
        /// <param name="syncCommand">Sync command from the server.</param>
        private void GenerateStatusCommandsForSyncCommand(SyncMLSync syncCommand)
        {
            SyncMLStatus syncStatus = SyncMLStatus.Create();

            syncStatus.Cmd.Content    = "Sync";
            syncStatus.CmdRef.Content = syncCommand.CmdID.Content;
            syncStatus.Data.Content   = "200";
            syncStatus.MsgRef.Content = ServerSyncML.Hdr.MsgID.Content;
            syncStatus.TargetRefCollection.Add(SyncMLSimpleElementFactory.Create <SyncMLTargetRef>(syncCommand.Target.LocURI.Content));
            syncStatus.SourceRefCollection.Add(SyncMLSimpleElementFactory.Create <SyncMLSourceRef>(syncCommand.Source.LocURI.Content));
            Facade.ResponseCommandPool.Add(syncStatus);

            Collection <SyncMLCommand> commands = syncCommand.Commands;

            if (commands != null)
            {
                foreach (SyncMLCommand command in commands)
                {
                    SyncMLAdd addCommand = command as SyncMLAdd;
                    if (addCommand != null)
                    {
                        SyncMLStatus addStatus = SyncMLStatus.Create();
                        addStatus.Cmd.Content    = "Add";
                        addStatus.CmdRef.Content = command.CmdID.Content;
                        addStatus.Data.Content   = "200";
                        addStatus.MsgRef.Content = syncStatus.MsgRef.Content;
                        addStatus.SourceRefCollection.Add(SyncMLSimpleElementFactory.Create <SyncMLSourceRef>(addCommand.ItemCollection[0].Source.LocURI.Content));
                        Facade.ResponseCommandPool.Add(addStatus);

                        continue;
                    }

                    SyncMLReplace replaceCommand = command as SyncMLReplace;
                    if (replaceCommand != null)
                    {
                        SyncMLStatus replaceStatus = SyncMLStatus.Create();
                        replaceStatus.Cmd.Content    = "Replace";
                        replaceStatus.CmdRef.Content = command.CmdID.Content;
                        replaceStatus.Data.Content   = "200";
                        replaceStatus.MsgRef.Content = syncStatus.MsgRef.Content;
                        replaceStatus.TargetRefCollection.Add(SyncMLSimpleElementFactory.Create <SyncMLTargetRef>(replaceCommand.ItemCollection[0].Target.LocURI.Content));
                        Facade.ResponseCommandPool.Add(replaceStatus);

                        continue;
                    }

                    SyncMLDelete deleteCommand = command as SyncMLDelete;
                    if (deleteCommand != null)
                    {
                        SyncMLStatus deleteStatus = SyncMLStatus.Create();
                        deleteStatus.Cmd.Content    = "Delete";
                        deleteStatus.CmdRef.Content = command.CmdID.Content;
                        deleteStatus.Data.Content   = "200";
                        deleteStatus.MsgRef.Content = syncStatus.MsgRef.Content;
                        deleteStatus.SourceRefCollection.Add(SyncMLSimpleElementFactory.Create <SyncMLSourceRef>(deleteCommand.ItemCollection[0].Target.LocURI.Content));
                        Facade.ResponseCommandPool.Add(deleteStatus);

                        continue;
                    }
                }
            }
        }
示例#8
0
        protected override bool ProcessResponse(string text)
        {
            if (!base.ProcessResponse(text))
            {
                return(false);
            }

            // So now syncml model is created from text
            UpdateCurrentURI(ServerSyncML);

            //0: Always have a status response to the SyncHdr of the server message. However, this status may not be sent back if it is the only one in the queue.
            SyncMLStatus responseStatus = SyncMLStatus.Create();

            responseStatus.MsgRef.Content = ServerSyncML.Hdr.MsgID.Content;
            responseStatus.Data.Content   = "200";
            responseStatus.Cmd.Content    = "SyncHdr";
            responseStatus.CmdRef.Content = "0";
            responseStatus.TargetRefCollection.Add(SyncMLSimpleElementFactory.Create <SyncMLTargetRef>(ServerSyncML.Hdr.Target.LocURI.Content));
            responseStatus.SourceRefCollection.Add(SyncMLSimpleElementFactory.Create <SyncMLSourceRef>(ServerSyncML.Hdr.Source.LocURI.Content));
            Facade.ResponseCommandPool.Add(responseStatus);//respond in next request.

            //1: Handle returned status commands
            Collection <SyncMLStatus> serverStatusCommands = AccessBody.GetStatusCommands(ServerSyncML);

            foreach (SyncMLStatus status in serverStatusCommands)
            {
                CommandAndStatusRegister.RegisterStatus(status.CmdRef.Content, status.Data.Content);
                HandleServerStatus(status); //this fn is still abstract here. Derived classes have different ways of handling.
            }

            //2: Prepare status commands for returned Alert commands. Derived classes then handle the alerts all the same way.
            Collection <SyncMLAlert> serverAlertCommands = AccessBody.GetAlertCommands(ServerSyncML);

            foreach (SyncMLAlert alert in serverAlertCommands)
            {
                Debug.WriteLine("Alert:" + alert.Xml.ToString());
                PrepareStatusForReturnedAlert(alert);
            }

            //3: Handle returned Sync command. Derived classes handle sync commands the same way.
            SyncMLSync serverSyncCommand = AccessBody.GetSyncCommand(ServerSyncML);

            if (serverSyncCommand != null)
            {
                string numberOfChangesStr = serverSyncCommand.NumberOfChanges.Content;
                if (!String.IsNullOrEmpty(numberOfChangesStr))
                {//where numberOfChanges > 0, display progress bar in GUI.
                    Facade.totalNumberOfChangesReceiving = Convert.ToInt32(numberOfChangesStr);
                    if (Facade.totalNumberOfChangesReceiving > 0)
                    {
                        Facade.DisplayOperationMessage(String.Format("Total number of changes received from the server: {0}", numberOfChangesStr));
                        Facade.InitProgressBarReceiving(0, Facade.totalNumberOfChangesReceiving, 1);
                        Facade.DisplayStageMessageReceiving(String.Format("Receiving {0} updates ...", Facade.totalNumberOfChangesReceiving));
                    }
                }

                int numbersOfChangesThisMessage = serverSyncCommand.Commands.Count; // the server might send in multiple messages
                Facade.numberOfChangesReceived += numbersOfChangesThisMessage;
                if (Facade.numberOfChangesReceived == Facade.totalNumberOfChangesReceiving)
                {
                    Facade.DisplayStageMessageReceiving("Receiving Done");
                }


                GenerateStatusCommandsForSyncCommand(serverSyncCommand);

                if (Facade.GracefulStop)
                {
                    return(true); // simply return, ture of false is meaningless.
                }
                Facade.IncrementProgressBarReceiving(numbersOfChangesThisMessage);

                ApplySyncCommandToLocal(serverSyncCommand);
            }

            //4: Verify if the server return all status codes to commands sent
            if (!CommandAndStatusRegister.IsAllCommandsReturnedWithStatus())
            {
                Trace.TraceInformation("!!!! Not all commands got status code. Please check the log for details.");
                Trace.TraceInformation("Commands without status: " + CommandAndStatusRegister.CommandsXmlWithoutStatus);
                //It is expected CommandAndStatusRegister is not used any more, otherwise, should clear it here.
            }

            //5: At the end, do what the server ask to do, likely a new SyncML message to be sent
            ProcessServerAlertCommands(serverAlertCommands);

            return(true);
        }
示例#9
0
 protected override void HandleServerStatus(SyncMLStatus status)
 {
     //do nothing, as not more work needs to be done.
 }