static void Main() { CallField call1 = Ax25Frame.DecodeCallsign(StringToByteArray("9A 60 98 A8 8A 40 EA")); CallField call2 = Ax25Frame.DecodeCallsign(StringToByteArray("9A 60 98 A8 8A 40 6A")); //byte b = (byte)'M'; //BitArray ba = new BitArray(new[] { b }); //Console.WriteLine(ba.ToOnesAndZeroes()); //string frame = "C0 00 AA A2 A4 AC AA A2 60 9A 60 98 A8 8A 40 E0 AE 92 88 8A 62 40 62 AE 92 88 8A 64 40 65 03 F0 27 77 59 44 6C 20 1C 5B 2F 3E 0D C0"; string frame = "C0 00 AA A2 A4 AC AA A2 60 9A 60 98 A8 8A 40 EA AE 92 88 8A 62 40 62 AE 92 88 8A 64 40 65 03 F0 27 77 59 44 6C 20 1C 5B 2F 3E 0D C0"; // C0 00 AA A2 A4 AC AA A2 60 9A 60 98 A8 8A 40 EA AE 92 88 8A 62 40 62 AE 92 88 8A 64 40 65 03 F0 27 77 59 44 6C 20 1C 5B 2F 3E 0D C0 // C0 00 AA A2 A4 AC AA A2 60 9A 60 98 A8 8A 40 6A AE 92 88 8A 62 40 62 AE 92 88 8A 64 40 64 9A 60 98 A8 8A 40 73 03 F0 27 77 59 44 6C 20 1C 5B 2F 3E 0D C0 // M0LTE-5 ** ** // C0 00 AA A2 A4 AC AA A2 E0 9A 60 98 A8 8A 40 EA AE 92 88 8A 62 40 E2 AE 92 88 8A 64 40 E4 9A 60 98 A8 8A 40 F3 03 F0 27 77 59 44 6C 20 1C 5B 2F 3E 0D C0 byte[] frameBytes = StringToByteArray(frame); Ax25Frame.TryParse(frameBytes, out Ax25Frame f); byte[] kf = f.ToKissFrame(); string s2 = kf.ToHexString(); Ax25Frame.TryParse(StringToByteArray(s2), out Ax25Frame f2); //Process(frameBytes); Debugger.Break(); }
internal static CallField DecodeCallsign(byte[] addressField) { var result = new CallField(); var sb = new StringBuilder(); for (int i = 0; i < 6; i++) { char c = (char)(addressField[i] >> 1); sb.Append(c); } string call = sb.ToString().Trim(); byte ssidByte = addressField[6]; // bits numbered from the right, per fig 3.5 of http://www.tapr.org/pdf/AX25.2.2.pdf // bit 0 (rightmost) is the HDLC address extension bit, set to zero on all but the last octet in the address field, where it is set to one. result.IsLast = ssidByte.GetBit(0); // ssid is next, it's just a 4-bit number, 0-15 int ssid = GetSsid(ssidByte); // reserved bits, set to 1 when not implemented bool reserved1 = ssidByte.GetBit(5); bool reserved2 = ssidByte.GetBit(6); // command/response bit of an LA PA frame, see section 6.1.2 of http://www.tapr.org/pdf/AX25.2.2.pdf result.CHBit = ssidByte.GetBit(7); if (ssid == 0) { result.Call = call; } else { result.Call = String.Format("{0}-{1}", call, ssid); } return(result); }
public static ParseResult TryParse(byte[] kissFrame, out Ax25Frame ax25Frame) { ax25Frame = null; if (kissFrame[0] != 0xc0 || kissFrame[1] != 0x00) { return(new ParseResult { FailReason = String.Format("Not a KISS frame, expected c0 00, got {0:X2} {1:X2}", kissFrame[0], kissFrame[1]) }); } if (kissFrame.Last() != 0xc0) { return(new ParseResult { FailReason = String.Format("Frame looks incomplete, expected c0 at end, got {0:X2}", kissFrame.Last()) }); } ax25Frame = new Ax25Frame(); ax25Frame.Source = DecodeCallsign(getSourceBytes(kissFrame)); ax25Frame.Dest = DecodeCallsign(getDestBytes(kissFrame)); byte[][] digis = getDigis(kissFrame); foreach (byte[] digiField in digis) { CallField call = DecodeCallsign(digiField); Debug.WriteLine(call); ax25Frame.Digis.Add(call); } ax25Frame.InfoBytes = getInfo(kissFrame); ax25Frame.Info = Encoding.ASCII.GetString(ax25Frame.InfoBytes); return(new ParseResult { Result = true }); }
static byte[] EncodeCallsign(CallField cf) { string callAndSsid = cf.Call; var parts = (callAndSsid ?? "").Trim().Split('-'); if (parts.Length != 1 && parts.Length != 2) { throw new ArgumentException($"Invalid callsign {callAndSsid}"); } if (string.IsNullOrWhiteSpace(parts[0])) { throw new ArgumentException($"Invalid callsign {parts[0]}"); } int ssid; if (parts.Length == 1) { ssid = 0; } else { ssid = int.Parse(parts[1]); } if (ssid < 0 || ssid > 15) { throw new ArgumentException($"Invalid SSID {ssid} in {callAndSsid}"); } string call = parts[0].Trim(); while (call.Length < 6) { call += " "; } // callsign bytes var result = new byte[7]; for (int i = 0; i < 6; i++) { result[i] = (byte)(call[i] << 1); } // ssid byte // bits numbered from the right, per fig 3.5 of http://www.tapr.org/pdf/AX25.2.2.pdf // bit 0 (rightmost) is the HDLC address extension bit, set to zero on all but the last octet in the address field, where it is set to one. result[6] = result[6].SetBit(0, cf.IsLast); // ssid is next, it's just a 4-bit number, 0-15 result[6] = SetSsid(result[6], ssid); // reserved bits, set to 1 when not implemented result[6] = result[6].SetBit(5, cf.Bit5Reserved); result[6] = result[6].SetBit(6, cf.Bit6Reserved); // command/response bit of an LA PA frame, see section 6.1.2 of http://www.tapr.org/pdf/AX25.2.2.pdf result[6] = result[6].SetBit(7, cf.CHBit); return(result); }