/// <summary>
        /// Send a message.
        /// </summary>
        /// <param name="controller">Concerned controller.</param>
        /// <param name="message">Message to send.</param>
        internal static bool Send(ControllerDto controller, MessageToDto message)
        {
            // get serial message
            MessageDto serialMessage;
            using (var ctx = new MessageProcessDtoFactory())
            {
                serialMessage = ctx.Convert(message);
            }

            // wait for sending turn & request process
            Queue.WaitMessageSending.WaitOne(DeviceConstants.WaitEventTimeout);
            Queue.WaitMessageReception.WaitOne(DeviceConstants.WaitEventTimeout);

            // set processed message
            Queue.MessageTo = message;

            // send message
            var result = PortBusiness.Send(Queue.Controller.Port, serialMessage);

            Queue.WaitMessageReception.Set();

            // wait round time trip
            Thread.Sleep(MessageConstants.WaitForRoundTimeTrip);
            return result;
        }
        /// <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();
            }
        }