示例#1
0
        /// <summary>
        /// Acknowledgment received.
        /// </summary>
        /// <param name="messageProcessing">Message processing.</param>
        internal static void AcknowledgmentReceived(MessageProcessDto messageProcessing)
        {
            IDevice iDevice = null;

            if (messageProcessing.MessageTo != null)
            {
                // configuration command
                if (messageProcessing.MessageTo.IsConfiguration)
                {
                    iDevice = new ConfigurationBusiness();
                }
                // constructor command
                else if (messageProcessing.MessageTo.IsConstructor)
                {
                    iDevice = new ConstructorBusiness();
                }
                // generic response
                else
                {
                    var processAttr = ReflectionHelper.GetEnumValueAttribute<DeviceClassGeneric, DataReceivedAttribute>(messageProcessing.MessageTo.Node.DeviceClassGeneric);
                    if (processAttr != null) iDevice = ReflectionHelper.CreateInstance<IDevice>(processAttr.ClassType);
                }

                // execute
                iDevice?.AcknowlegmentReceived(messageProcessing.MessageFrom);
            }
        }
        /// <summary>
        /// Connect to a port.
        /// </summary>
        /// <param name="controller">Controller to connect.</param>
        /// <returns>Connected controller.</returns>
        internal static ControllerDto Connect(ControllerDto controller)
        {
            // close existing port
            Close(controller.Port);

            // connect port
            controller.Port = PortBusiness.Connect(controller.Port);

            // initialize queue
            Queue = new MessageProcessDto { Controller = controller };

            // start listener
            if (Queue.TaskReceive == null)
            {
                Queue.TaskContinue = true;
                Queue.TaskReceive = new Task(() => ReceiveTask(Queue));
                Queue.TaskReceive.Start();
            }

            return controller;
        }
 /// <summary>
 /// Send an acknowledgment.
 /// </summary>
 /// <param name="messageProcess">Message processing to use.</param>
 private static void SendAcknowledgment(MessageProcessDto messageProcess)
 {
     Thread.Sleep(MessageConstants.WaitForRoundTimeTrip);
     var message = new MessageDto
     {
         Content = new List<byte>
         {
             messageProcess.MessageFrom.IsValid ? (byte) MessageHeader.Acknowledgment : (byte) MessageHeader.NotAcknowledgment
         }
     };
     PortBusiness.Send(messageProcess.Controller.Port, message);
 }
        /// <summary>
        /// Process a start of frame (SOF).
        /// </summary>
        /// <param name="messageProcess">Message processing.</param>
        private static void ProcessFrame(MessageProcessDto messageProcess)
        {
            // special request
            if (messageProcess.MessageFrom.Type == MessageType.Request && messageProcess.MessageFrom.Content.Count > 1)
            {
                messageProcess.MessageFrom.Node = messageProcess.Controller.Nodes.FirstOrDefault(x => x.ZIdentifier == messageProcess.MessageFrom.ZIdentifier);
            }
            // complete received message if it's a response (SOF and ACK)
            else if (messageProcess.MessageTo != null)
            {
                messageProcess.MessageFrom.Node = messageProcess.MessageTo.Node;
                messageProcess.MessageFrom.ZIdentifier = messageProcess.MessageTo.ZIdentifier;
            }

            // Data frame (SOF)
            if (messageProcess.MessageFrom.Header == MessageHeader.StartOfFrame && messageProcess.MessageFrom.Node != null)
            {
                // process response
                if (messageProcess.MessageTo != null && messageProcess.MessageFrom.Type == MessageType.Response &&
                    messageProcess.MessageTo.Command == messageProcess.MessageFrom.Command)
                {
                    DevicesBusiness.ResponseReceived(messageProcess);
                    messageProcess.WaitMessageSending.Set(); // release message sending lock
                }
                // process request
                else if (messageProcess.MessageFrom.Type == MessageType.Request && 
                         messageProcess.MessageFrom.RequestCommand != RequestCommandClass.None)
                {
                    DevicesBusiness.RequestReceived(messageProcess.MessageFrom);
                }
            }
            // ACK
            else
            {
                DevicesBusiness.AcknowledgmentReceived(messageProcess);
            }
        }
        /// <summary>
        /// Called when a message is received.
        /// </summary>
        /// <param name="messageProcess">Concerned queue.</param>
        private static async void ReceiveTask(MessageProcessDto messageProcess)
        {
            while (messageProcess.TaskContinue)
            {
                // get reception lock
                messageProcess.WaitMessageReception.WaitOne(DeviceConstants.WaitEventTimeout);

                // get message
                var serialMessage = PortBusiness.Receive(messageProcess.Controller.Port);

                // process
                if (serialMessage.IsComplete)
                {
                    // get message
                    using (var ctx = new MessageProcessDtoFactory())
                    {
                        messageProcess.MessageFrom = ctx.Convert(serialMessage);
                    }

                    // send ACK
                    if (messageProcess.MessageFrom.Header == MessageHeader.StartOfFrame) SendAcknowledgment(messageProcess);

                    // process received message
                    if(messageProcess.MessageFrom.IsValid) ProcessFrame(messageProcess);
                }

                // round trip time
                if (serialMessage.Content.Count == 0) await Task.Delay(MessageConstants.WaitReceiveTask);


                // release reception & request lock
                messageProcess.WaitMessageReception.Set();
            }
        }