示例#1
0
文件: LinkLayer.cs 项目: dozack/rps
        /// <summary>
        /// Build packet and transmit it on bus
        /// </summary>
        /// <param name="msg">Message to be transmitted</param>
        /// <returns>true if success, false if error</returns>
        public bool Send(LinkMessage msg)
        {
            int len = msg.Data.Length;

            if (len > 9)
            {
                len = 9;
            }
            string raw = '#' + len.ToString() + msg.Data;

            byte[] data = Encoding.ASCII.GetBytes(raw);
            if (phy.Transmit(data) == true)
            {
                return(true);
            }
            return(false);
        }
示例#2
0
 /// <summary>
 /// Event handler for OnMessageReceived event of link
 /// </summary>
 /// <param name="sender">Link layer instance</param>
 /// <param name="msg">Event parameters</param>
 private void Link_OnMessageReceived(LinkLayer sender, LinkMessage msg)
 {
     if (!IsServer)
     {
         char addr = msg.Data[0];
         if (value_tracker.Keys.Contains(addr))
         {
             ApplicationPdu pdu = new ApplicationPdu()
             {
                 Address = addr,
                 Value   = Convert.ToInt32(msg.Data.Substring(1))
             };
             value_tracker[pdu.Address] = pdu.Value;
             Debug.WriteLine("APP-ADDR:" + pdu.Address + "-VAL:" + msg.Data.Substring(1));
             TriggerApplicationUpdate(pdu);
         }
     }
 }
示例#3
0
 /// <summary>
 /// Send application protocol data unit to lower layer
 /// </summary>
 /// <param name="pdu">Application protocol data unit to send</param>
 /// <returns>true if success, false if error</returns>
 private bool ServerBroadcastValue(ApplicationPdu pdu)
 {
     if (IsServer)
     {
         try
         {
             LinkMessage msg = new LinkMessage()
             {
                 Data = pdu.Address + pdu.Value.ToString()
             };
             link.Send(msg);
         }
         catch
         {
             return(false);
         }
         return(true);
     }
     else
     {
         return(false);
     }
 }
示例#4
0
文件: LinkLayer.cs 项目: dozack/rps
 /// <summary>
 /// Handler for timers Elapsed event
 /// </summary>
 /// <param name="sender">Timer instance that triggered event</param>
 /// <param name="e">Arguments</param>
 private void TimeoutHandler(object sender, System.Timers.ElapsedEventArgs e)
 {
     if (status == LinkStatus.IDLE)
     {
         // Timeout occured but bus is idle (message processed) should not happen
         Debug.WriteLine("LINK-IDLE_TIMEOUT");
         return;
     }
     if (actl_message_id != tkick_message_id)
     {
         // Timeout occured but link is already handling another message - should not happen
         Debug.WriteLine("LINK-BUSY_TIMEOUT");
         return;
     }
     // Timeout occured and link is stuck, reset (required transport layer for handling possible data loss)
     Debug.WriteLine("LINK-STUCK_TIMEOUT");
     actl_message     = new LinkMessage();
     rx_counter       = 0;
     actl_message_id  = 0;
     tkick_message_id = 0;
     status           = LinkStatus.IDLE;
     return;
 }
示例#5
0
文件: LinkLayer.cs 项目: dozack/rps
 /// <summary>
 /// Method for triggering OnMessageReceived event
 /// </summary>
 /// <param name="msg">Received message</param>
 protected virtual void TriggerMessageReceived(LinkMessage msg)
 {
     OnMessageReceived?.Invoke(this, msg);
 }
示例#6
0
文件: LinkLayer.cs 项目: dozack/rps
        /// <summary>
        /// Task for processing received data running in thread
        /// </summary>
        private void LinkThreadTask()
        {
            while (true)
            {
                // Sleep delay
                Thread.Sleep(1);
                // Pop byte from receive ring buffer
                int value = phy.Receive();
                if (value != -1)
                {
                    char rx = Convert.ToChar(value);
                    switch (status)
                    {
                    // Bus is idle and waiting for start character
                    case LinkStatus.IDLE:
                        if (rx == '#')
                        {
                            // Save actual message id and start timeout timer
                            tkick_message_id = actl_message_id;
                            timer.Start();
                            // Proceed to length reception
                            status = LinkStatus.GET_LEN;
                        }
                        break;

                    // Receiving message length
                    case LinkStatus.GET_LEN:
                        uint length = (uint)(rx - '0');
                        actl_message = new LinkMessage()
                        {
                            Length = length
                        };
                        // Reset data counter
                        rx_counter = 0;
                        // Set link status to data reception
                        status = LinkStatus.GET_DATA;
                        break;

                    // Receiving message data
                    case LinkStatus.GET_DATA:
                        // Save data and increment counter
                        actl_message.Data += rx;
                        rx_counter++;
                        if (rx_counter == actl_message.Length)
                        {
                            // Message length achieved, assign id to next message
                            actl_message_id++;
                            // Stop timeout timer
                            timer.Stop();
                            // Log received data to output window
                            Debug.WriteLine("LINK-" + actl_message.ToString());
                            // Trigger OnMessageReceived event
                            TriggerMessageReceived(actl_message);
                            // Return link status back to idle state so next message can be processed
                            status = LinkStatus.IDLE;
                        }
                        break;

                    // Should not get there
                    default:
                        break;
                    }
                }
            }
        }