Beispiel #1
0
    //public string HwAddress { get; set; }

    public MessageEventArgs(Message message, int port)
    {
      Message = message;
      Port = port;
      //HwAddress = hwAddress;
    }
Beispiel #2
0
    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;
    }
Beispiel #3
0
    /// <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;
      }
    }
Beispiel #4
0
 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);
 }
Beispiel #5
0
    /// <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);
      }
    }