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); }
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))); }