public abstract void ProcessReceivedMessage(IMessage inputMessage);
        public override void ProcessReceivedMessage(IMessage message)
        {
            OperationMessage operation = (OperationMessage)message;

            if (operation.OpCode == OperationMessage.OPCodes.JoinRequest)
            {
                Debug.WriteLine(String.Format("JOIN REQUEST RECEIVED FROM 0x{0:X4}", operation.SourceAddress));
                this.SendJoinRequestResponse(operation.SourceAddress).Wait();
            }
            else if (operation.OpCode == OperationMessage.OPCodes.JoinAbort)
            {
                Debug.WriteLine(String.Format("JOIN ABORT RECEIVED FROM 0x{0:X4} -> NUMBER OF RESPONSES: {1}", operation.SourceAddress, operation.Args[0]));
            }
            else if (operation.OpCode == OperationMessage.OPCodes.JoinAccept)
            {
                byte[] macAddress = operation.Args.Take(6).ToArray();
                byte baseModel = operation.Args[6];
                byte shieldModel = operation.Args[7];
                byte[] aesKey = operation.Args.Skip(8).ToArray();

                StringBuilder sb = new StringBuilder();
                sb.AppendFormat("JOIN ACCEPT RECEIVED FROM 0x{0:X4} -> MAC: ", operation.SourceAddress);

                foreach (byte b in macAddress)
                {
                    sb.AppendFormat("0x{0:X2} ", b);
                }

                sb.AppendFormat("  BASE-MODEL: {0}  SHIELD-MODEL: {1}", baseModel, shieldModel);

                sb.Append("  AES-KEY: ");

                foreach (byte b in aesKey)
                {
                    sb.AppendFormat("0x{0:X2} ", b);
                }

                Debug.WriteLine(sb.ToString());

                string macString = macAddress.ToStrigMac();

                PendingNodeInfo info = this.PendingNodes.FirstOrDefault(n => n.MacAddress == macString);

                if (info == null)
                {
                    this.PendingNodes.Add(new PendingNodeInfo()
                        {
                            MacAddress = macString,
                            BaseType = baseModel,
                            ShieldType = shieldModel,
                            TemporalAddress = operation.SourceAddress,
                            TemporalAESKey = aesKey,
                        });

                    if (NetworkJoinReceived != null)
                        NetworkJoinReceived(this, macString);
                }else{
                    //Refresh params
                    info.BaseType = baseModel;
                    info.ShieldType = shieldModel;
                    info.TemporalAddress = operation.SourceAddress;
                    info.TemporalAESKey = aesKey;
                }
            }
        }
        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);
        }
        /// <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());
        }