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); } } }
/// <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())); }