private async void button1_Click(object sender, EventArgs e)
        {
            var operation = OperationMessage.MACRead(0x0002);

            float       priotity = 0;
            List <Task> tasks    = new List <Task>();

            for (int i = 0; i < 8; i++)
            {
                var task = new Task(async() =>
                {
                    Debug.WriteLine("Message " + priotity + " enqueued");
                    OutputHeader outputMessage = new OutputHeader(priotity)
                    {
                        SecurityEnabled = true,
                        RoutingEnabled  = true,
                        EndPoint        = 1,
                        Retries         = 3,
                        Content         = operation
                    };
                    priotity += 0.1f;
                    Debug.WriteLine(outputMessage.Priority + " Response: " + (await CommunicationManager.Instance.SendMessage(outputMessage)).ToString() + " " + DateTime.Now.Millisecond);
                });

                task.Start();

                tasks.Add(task);
            }

            await Task.WhenAll(tasks);
        }
        public async Task <bool> SendMessage(IMessage message)
        {
            OutputHeader outputMessage = new OutputHeader(this.OutputParameters.Priority)
            {
                EndPoint = this.OutputParameters.Endpoint,
                Retries  = this.OutputParameters.MaxRetries,
                Content  = message,
            };

            return(await this.communicationManager.SendMessage(outputMessage));
        }
Exemple #3
0
        private Task <bool> EnqueueMessage(OutputHeader message, NodeConnection connection)
        {
            ushort connectionAddress = connection.NodeAddress;

            TaskCompletionSource <bool> result = new TaskCompletionSource <bool>();

            lock (thisLock)
            {
                var            currentQueue = this.pendingMessagesQueue[connectionAddress];
                PendingMessage newMsg       = new PendingMessage(result, message);
                int            index        = 0;
                foreach (PendingMessage pendingMsg in currentQueue)
                {
                    if (newMsg.Message.Priority > pendingMsg.Message.Priority)
                    {
                        currentQueue.Insert(index, newMsg);
                        break;
                    }
                    index++;
                }
                if (index == currentQueue.Count)
                {
                    currentQueue.Add(newMsg);
                }

                // If the new message is alone in the queue
                if (currentQueue.Count == 1)
                {
                    // Connection is bussy. We need to wait
                    if (!this.CheckForSend(connectionAddress))
                    {
                        Debug.Print(newMsg.Id + " waiting (1)...");
                    }
                }
                else
                {
                    Debug.Print(newMsg.Id + " waiting (" + (index + 1) + ")...");
                }
            }

            return(result.Task);
        }
Exemple #4
0
        public async Task <bool> SendMessage(OutputHeader message)
        {
            if (this.pendingConfirmationTask != null && !this.pendingConfirmationTask.Task.IsCompleted)
            {
                throw new InvalidOperationException("Sending in progress");
            }

            this.pendingConfirmationTask = new TaskCompletionSource <bool>();

            this.currentMessageId = (currentMessageId + 1) % 254; //255 is reserved for internal messages
            message.MessageId     = this.currentMessageId;

            if (message.Content is OperationMessage)
            {
                Debug.WriteLine(this.PortName + " UART SEND OPCODE " + ((OperationMessage)message.Content).OpCode.ToString());
            }

            if (!this.SendData(message.ToBinary()))
            {
                return(false);
            }
            else
            {
                //Await for a confirmation with timeout
                Task delayTask = Task.Delay(this.ConfirmationTimeout);
                Task firstTask = await Task.WhenAny(this.pendingConfirmationTask.Task, delayTask);

                if (firstTask == delayTask)
                {
                    //Timeout
                    Debug.WriteLine(this.PortName + " Confirmation response aborted TIMEOUT!");
                    this.pendingConfirmationTask.SetCanceled();
                    return(false);
                }
                else
                {
                    return(pendingConfirmationTask.Task.Result);
                }
            }
        }
Exemple #5
0
        public async Task <bool> SendMessage(OutputHeader message)
        {
            ushort destinationAddress = message.Content.DestinationAddress;

            if (destinationAddress == 0)
            {
                throw new InvalidOperationException("The destination address can not be zero");
            }

            NodeConnection connection;

            lock (this)
            {
                // Try to use a cached direct connection to the destination address.
                if (connectionsInUse.ContainsKey(destinationAddress))
                {
                    connection = connectionsInUse[destinationAddress];
                    message.Content.DestinationAddress = 0;
                }
                else if ((connection = this.serialManager.GetNodeConnection(destinationAddress)) != null)
                {
                    this.StoreConnection(connection);
                    message.Content.DestinationAddress = 0;
                }
                else if (masterConnection != null)
                {
                    // If not posible send to the master
                    connection = masterConnection;
                }
                else
                {
                    // If the master is not connected return false...
                    return(false);
                }
            }

            //Enqueue the message
            return(await EnqueueMessage(message, connection));
        }
Exemple #6
0
        /// <summary>
        /// Sends the an message to the node physically connected.
        /// </summary>
        /// <param name="operation">The message to be sent.</param>
        /// <returns></returns>
        private bool SendInternalMessage(IMessage message)
        {
            if (message.DestinationAddress != 0 && message.DestinationAddress != this.NodeAddress)
            {
                throw new InvalidOperationException("This method can be used only to send internal messages");
            }

            OutputHeader outputMessage = new OutputHeader()
            {
                MessageId       = 255, // Internal use only
                SecurityEnabled = true,
                RoutingEnabled  = true,
                EndPoint        = 1,
                Retries         = 3,
                Content         = message
            };

            if (message is OperationMessage)
            {
                Debug.WriteLine(this.PortName + " UART SEND OPCODE " + ((OperationMessage)message).OpCode.ToString());
            }

            return(this.SendData(outputMessage.ToBinary()));
        }
Exemple #7
0
 public PendingMessage(TaskCompletionSource <bool> taskSource, OutputHeader message)
 {
     this.Id         = instanceCounter++;
     this.TaskSource = taskSource;
     this.Message    = message;
 }