//public string HwAddress { get; set; } public MessageEventArgs(Message message, int port) { Message = message; Port = port; //HwAddress = hwAddress; }
public static Message Parse(byte[] data, ref int length, ref int index) { //-------------------------------- //Check length //-------------------------------- if ((data == null) || (data.Length < MinLength)) return null; //-------------------------------- //Check start //-------------------------------- if (data[index] != StartByte) return null; Message msg; try { msg = new Message(data, ref length, ref index); } catch (Exception) { return null; } //-------------------------------- //return message //-------------------------------- return msg; }
/// <summary> /// Process message according to following rules: /// 1) message for other nodes => retransmit to other port /// 2) message for this node => process message /// 3) message in broadcast => process message and if result is false retransmit /// </summary> /// <param name="sender">Source of message (Port)</param> /// <param name="eventArgs">Message received + port number</param> private void MessageReceived(object sender, MessageEventArgs eventArgs) { ResetError(); try { RxMutex.WaitOne(); var message = eventArgs.Message; var port = eventArgs.Port; //Throw message received event if (OnMessageReceived != null) OnMessageReceived(this, message); //Use address ? var noAddress = (message.Flags & 0x0c) == 0; //Message in broadcast var broadcast = message.Destination.Equals(Address.BroadcastAddress); //Message is for this node var forMe = message.Destination.Equals(Address) || noAddress; var fromMe = message.Source.Equals(Address); //Message no requires ack/nack var immediate = message.MessageType == MessageTypes.Immediate; //Message is ack/nack response var isAck = (message.MessageType == MessageTypes.AckResponse) || (message.MessageType == MessageTypes.NackResponse); //Get port var conn = _ports[port]; //Command from expected source => OK Log.Debug(string.Format("{0} received from node: {1}", message, message.Source)); //return true if message is processed from this node var processed = false; //Round check (abort message from myself) if (fromMe & IgnoreOwnMessages) { Log.Warn(string.Format("Message {0} originated from this node", message)); return; } //Check message for me or in broadcast if (forMe || broadcast) if (isAck) { if (forMe) if (conn.CheckAck(message)) { lock (message) { if (AckReceived != null) processed = AckReceived(this, message, port); //Thread.Sleep(100); } } else { LastError = HBusErrors.ERR_ACK_LOST; //Check ack failed Log.Error(string.Format("Check ack from node {0} failed", message.Source)); } } else { //Process command on Node processed = (CommandReceived != null) && CommandReceived(this, message, port); } //Default response action send ack if not broadcast var result = ProcessActionTypes.DoNothing; if (forMe && !broadcast && !immediate && !isAck) { //Processed without errors => ACK result = processed && (LastError == 0) ? ProcessActionTypes.SendAck : ProcessActionTypes.SendNack; } else { if (!fromMe && ((!forMe && !broadcast) || (!processed && broadcast)) && ((message.Destination != Address.Empty) || noAddress)) //if (broadcast && !processed) result = Ports > 1 ? ProcessActionTypes.ForwardMessage : ProcessActionTypes.DoNothing; } switch (result) { case ProcessActionTypes.DoNothing: break; case ProcessActionTypes.SendAck: //Send back ack to same port SendAck(message.Command, message.Source, Payload); break; case ProcessActionTypes.SendNack: //Send back nack to same port SendNack(message.Command, message.Source, LastError); break; case ProcessActionTypes.ForwardMessage: SendMessage(message, port); break; case ProcessActionTypes.ForwardMessageWithPayload: //If new payload recreate the message if (Payload != null) message = new Message(message.MessageType, message.Destination, message.Source, message.Command, Payload); //Forward message to other ports SendMessage(message, port); break; } Log.Debug(string.Format("message {0} processed", message)); } catch (Exception ex) { SetError(MethodBase.GetCurrentMethod().Name, ex); } finally { RxMutex.ReleaseMutex(); Status = BusStatus.Ready; } }
public bool Equals(Message other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return (other.Start == Start) && (other.Flags == Flags) && other.Source.Equals(Source) && other.Destination.Equals(Destination) && (other.Command == Command) && Equals(other.Data, Data); }
/// <summary> /// Send HBus message to specific port /// or broadcast to all available ports /// </summary> /// <param name="msg"></param> /// <param name="sourceport">Skip this port if value is passed</param> private void SendMessage(Message msg, int sourceport = -1) { if (Status == BusStatus.Reset) // || Status == BusStatus.Send) { Log.Warn(string.Format("SendMessage not possibile with status {0}", Status)); return; } try { Status = BusStatus.Send; var buffer = msg.ToArray(); if ((buffer == null) || (buffer.Length < HBusSettings.MessageLength)) { LastError = HBusErrors.ERR_MESSAGE_CORRUPTED; Log.Error("SendMessage: wrong message size"); return; } //Send message to all available ports foreach (var port in _ports.Where(p => p.Number != sourceport)) { port.SendMessage(buffer); Log.Debug(string.Format("Message {0} sent on port {1}", msg, port.Number)); } //Throw specific events if ((CommandSent != null) && ((msg.MessageType == MessageTypes.Immediate) || (msg.MessageType == MessageTypes.Normal))) CommandSent(this, msg); if ((AckSent != null) && ((msg.MessageType == MessageTypes.AckResponse) || (msg.MessageType == MessageTypes.NackResponse))) AckSent(this, msg); Thread.Sleep(CommandDelay); Status = msg.MessageType == MessageTypes.Normal ? BusStatus.WaitAck : BusStatus.Ready; //Throw message transmitted event if (OnMessageTransmited != null) OnMessageTransmited(this, msg); } catch (Exception ex) { SetError(MethodBase.GetCurrentMethod().Name, ex); } }