private static bool DetectNonsense(MechatrolinkPacket packet)
        {
            byte command = packet.Command.ParsedFields[(byte)MechatrolinkCommand.Fields.Code][0];

            if (command == 0x0D || command == 0x0E || command == 0x0F)
            {
                return(false);
            }
            byte addr = packet.ParsedData[(int)MechatrolinkPacket.Fields.Address][0];

            if (addr == 0x00)
            {
                return(true);
            }
            if (addr == MechatrolinkCommandDatabase.SyncFrameAddress)
            {
                return(false);
            }
            byte control = packet.ParsedData[(int)MechatrolinkPacket.Fields.Control][0];

            if (control != MechatrolinkCommandDatabase.RequestControlCode && control != MechatrolinkCommandDatabase.ResponseControlCode)
            {
                return(true);
            }
            return(false);
        }
Пример #2
0
 public static string GetReport(MechatrolinkPacket packet)
 {
     try
     {
         if (packet.ParsedData[(int)MechatrolinkPacket.Fields.Address][0] == SyncFrameAddress)
         {
             return(SyncFrameReport);
         }
         var info = Database[packet.Command.ParsedFields[(int)MechatrolinkCommand.Fields.Code][0]];
         return(info.GetReport(packet.Command.ParsedFields[(int)MechatrolinkCommand.Fields.Data],
                               packet.ParsedData[(int)MechatrolinkPacket.Fields.Control][0] == ResponseControlCode));
     }
     catch (KeyNotFoundException) { }
     catch (Exception e)
     {
         ErrorListener.Add(new Exception("Error during database search. Operation aborted.", e));
     }
     return("");
 }
        /// <summary>
        /// Sorts packet's bytes into easily accessible structures. Manipulates endianess.
        /// </summary>
        /// <param name="data">Expects bytes, composed of fully decoded bits (Decode, then SeparatePackets, then DestuffZeros, then PackIntoBytes).</param>
        /// <param name="time">x10nS</param>
        /// <param name="littleEndian">See Communications.Parse</param>
        /// <returns></returns>
        public static MechatrolinkPacket Parse(byte[] data, int time, bool littleEndian = false)
        {
            bool containsSub = data.Length > OrdinaryPacketLength;

            byte[][]    result  = new byte[FieldLength.Count][];
            List <byte> fcs     = new List <byte>(data.Length - FieldLength[Fields.FCS]);
            int         current = 0;

            for (int i = 0; i < FieldLength.Count; i++)
            {
                if (OrdinaryPacketFieldsToExclude.Any(x => x == (Fields)i))
                {
                    continue;
                }
                int l = FieldLength[(Fields)i];
                result[i] = new byte[l];
                //Multibyte fields may be little-endian at physical layer (in fact they should be, but it turns out they're not...)
                //All in all, we'd better implement a switch
                for (int j = 0; j < l; j++)
                {
                    result[i][j] = data[current + (littleEndian ? (l - j - 1) : (j))];
                    if ((Fields)i != Fields.FCS)
                    {
                        fcs.Add(result[i][j]);
                    }
                }
                current += l;
            }
            var toParse = result[(int)Fields.CommandData];

            if (containsSub)
            {
                toParse = toParse.Concat(result[(int)Fields.SubcommandData]).ToArray();
            }
            var packet = new MechatrolinkPacket(result, MechatrolinkCommand.Parse(toParse), time);

            packet.ComputedFCS    = HDLCManchesterDecoder.ComputeFCS(fcs.ToArray());
            packet.FCSError       = !packet.ComputedFCS.SequenceEqual(packet.ParsedData[(int)Fields.FCS]);
            packet.DatabaseReport = MechatrolinkCommandDatabase.GetReport(packet);
            return(packet);
        }
        /// <summary>
        /// Gets raw logic analyzer data (edges) and does complete decoding.
        /// </summary>
        /// <param name="list">Edge list</param>
        /// <param name="frequency">Communication frequency (equal to speed, 4Mbps = 4MHz for Mechatrolink-I and 10MHz for M-II)</param>
        /// <param name="littleEndian">Publicly available bits of docs are confusing on the subject of command body endianess.
        /// Experience suggests that body bytes on their own are transmitted as big-endian,
        /// though multibyte data pieces inside the body might be encoded as little-endian.</param>
        /// <returns></returns>
        public static MechatrolinkCommunication Parse(SortedList <int, bool> list, int frequency, bool littleEndian = false)
        {
            var tempDecoded = HDLCManchesterDecoder.Decode(list, frequency, 0.25);
            //DataReporter.ReportProgress("Manchester layer decoded...");
            var packets = HDLCManchesterDecoder.SeparatePackets(tempDecoded);

            tempDecoded.Clear(); //Not needed anymore
            tempDecoded.TrimExcess();
            GC.Collect();
            DataReporter.ReportProgress("HDLC layer decoded...");
            MechatrolinkPacket[] decoded = new MechatrolinkPacket[packets.Length];
            for (int i = 0; i < packets.Length; i++)
            {
                byte[] temp = HDLCManchesterDecoder.PackIntoBytes(
                    HDLCManchesterDecoder.DestuffZeroes(packets[i])).Values.ToArray();
                //DataReporter.ReportProgress(string.Format("Packet {0} out of {1} packed...", i + 1, packets.Length));
                decoded[i] = MechatrolinkPacket.Parse(temp, packets[i].Keys.First(), littleEndian);
                //DataReporter.ReportProgress(string.Format("Packet {0} out of {1} decoded...", i + 1, packets.Length));
            }
            DataReporter.ReportProgress("Packets parsed...");
            return(new MechatrolinkCommunication(decoded, (int)Math.Round(1E8 / frequency)));
        }