public SCHBurst(GSMParameters Parameters) { Name = "SCH"; ShortName = "SC "; CreateSequence(Parameters); }
public eSuccessState ParseFACCHData(GSMParameters param, bool[] burstBufferC) { /* decode */ if (Deconvolution(burstBufferC) == eCorrectionResult.Failed) { ErrorMessage = "(FACCH: Error in ConvolutionalCoder, maybe encrypted)"; CryptedFrames++; return(eSuccessState.Unknown); } /* CRC check/fix */ switch (CRCCheck()) { case eCorrectionResult.Fixed: StatusMessage = "(FACCH: CRC Error recovered)"; break; case eCorrectionResult.Failed: ErrorMessage = "(FACCH: CRC Error)"; return(eSuccessState.Failed); } /* convert u[] to d[] bytes */ PackBytes(); DataBursts++; L2.Handle(param, this, L3, BurstBufferD); return(eSuccessState.Succeeded); }
public override eSuccessState ParseRawBurst(GSMParameters Parameters, double[] rawBurst, double[] rawBurstStrength) { double startOffset = Parameters.SampleStartPosition; int bitTolerance = 5; /* only the first SCH has to be searched in a much higher range */ if (Parameters.FirstSCH) { bitTolerance = 16; Parameters.FirstSCH = false; } /* skip the number of data bits defined in SCHBurst */ int sequencePos = (int)(startOffset + Parameters.Oversampling * (SyncOffset + 2)); /* locate the training sequence over two bits */ int position = SignalPower.Locate(rawBurst, sequencePos, TrainingSequence, (int)(Parameters.Oversampling * bitTolerance)); if (position == int.MinValue) { ErrorMessage = "(Error in SignalPower.Locate)" + Environment.NewLine; return(eSuccessState.Failed); } /* calculate the offset between guessed position and real */ Parameters.SampleOffset += position - sequencePos; Parameters.SubSampleOffset = 0; //Log.AddMessage("Offset: " + Parameters.SampleOffset + " SCH: " + (position - sequencePos)); return(eSuccessState.Succeeded); }
public GsmTapWriter(GSMParameters param) { Parameters = param; Endpoint = new IPEndPoint(IPAddress.Parse("255.255.255.255"), (int)GSMTAP_UDP_PORT); Header.version = GSMTAP_VERSION; Header.hdr_len = 4; Header.type = GSMTAP_TYPE_UM; }
private void CreateSequence(GSMParameters Parameters) { /* create training sequence ... */ double[] tmpTrainingSequence = new SequenceGenerator(Parameters.Oversampling, Parameters.BT).GenerateDiffEncoded(TrainingCode); /* ... and skip the first and last two samples since these are affected by the bits before */ TrainingSequence = new double[(int)(tmpTrainingSequence.Length - 4 * Parameters.Oversampling)]; Array.Copy(tmpTrainingSequence, (int)(2 * Parameters.Oversampling), TrainingSequence, 0, TrainingSequence.Length); }
private void btnBoolGadConvert_Click(object sender, EventArgs e) { bool inputError = false; bool dirBoolToGad = radioBoolToGad.Checked; if (dirBoolToGad) { if (textBool0.Text.Length != 114 || textBool1.Text.Length != 114 || textBool2.Text.Length != 114 || textBool3.Text.Length != 114) { inputError = true; } MessageBox.Show("not supported yet!"); return; } else { byte[] byteBuf = new byte[19]; GSMParameters param = new GSMParameters(); SDCCHBurst sdcch = new SDCCHBurst(); ByteUtil.BytesFromString(textGad0.Text, ref byteBuf); sdcch.ParseData(param, ByteUtil.BitsFromBytes(byteBuf), 0); ByteUtil.BytesFromString(textGad1.Text, ref byteBuf); sdcch.ParseData(param, ByteUtil.BitsFromBytes(byteBuf), 1); ByteUtil.BytesFromString(textGad2.Text, ref byteBuf); sdcch.ParseData(param, ByteUtil.BitsFromBytes(byteBuf), 2); ByteUtil.BytesFromString(textGad3.Text, ref byteBuf); sdcch.ParseData(param, ByteUtil.BitsFromBytes(byteBuf), 3); bool[][] boolBuf = new bool[4][]; for (int i = 0; i < boolBuf.Length; i++) { boolBuf[i] = new bool[114]; } sdcch.L1BurstEGet(ref boolBuf); if (boolBuf == null) { MessageBox.Show("error reading bits"); return; } textBool0.Text = ByteUtil.BitsToString(boolBuf[0]); textBool1.Text = ByteUtil.BitsToString(boolBuf[1]); textBool2.Text = ByteUtil.BitsToString(boolBuf[2]); textBool3.Text = ByteUtil.BitsToString(boolBuf[3]); } }
public GsmAnalyzerDumpWriter(GSMParameters param, string fileName) { FileName = fileName; Parameters = param; StartTime = DateTime.Now; LastTaggedTime = DateTime.Now; try { WriteFile = File.Open(FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); DumpFile = new StreamWriter(WriteFile); } catch (Exception e) { } }
public override eSuccessState ParseRawBurst(GSMParameters Parameters, double[] rawBurst, double[] rawBurstStrength) { double startOffset = Parameters.SampleStartPosition; /* dont use all bits. skip 4 bits at the start and 4 at the end */ int bits = (int)PayloadBits - 8; int startPos = (int)(Parameters.Oversampling * 4); int samples = (int)(Parameters.Oversampling * bits); double avgPhase = 0; double avgPower = 0; for (int pos = startPos; pos < samples + startPos; pos++) { avgPhase += rawBurst[(int)(startOffset + pos)]; avgPower += Math.Sqrt(rawBurstStrength[(int)(startOffset + pos)]); } double avgIdlePower = 0; for (int pos = 1; pos < startOffset / 4 + 1; pos++) { avgIdlePower += Math.Sqrt(rawBurstStrength[pos]); } avgPhase /= bits; avgPower /= samples; avgIdlePower /= (startOffset / 4); /* should have +PI/2 per high bit. calculate phase correction value per sample */ double phaseOffset = (Math.PI / 2 - avgPhase) / Parameters.Oversampling; /* set offset */ if (Parameters.PhaseAutoOffset) { Parameters.PhaseOffsetValue += phaseOffset; } int ratio = 10; Parameters.CurrentPower = avgPower; Parameters.AveragePower = ((ratio - 1) * Parameters.AveragePower + avgPower) / ratio; Parameters.AverageIdlePower = ((ratio - 1) * Parameters.AverageIdlePower + avgIdlePower) / ratio; return(eSuccessState.Unknown); }
public GsmAnalyzerDumpReader(GSMParameters param, string fileName) { DumpFileName = fileName; Parameters = param; ByteUtil.BitsFromBytes(GsmAnalyzerDumpWriter.DummyData, DummyBits, 8, 0, 148); try { FileIsBeingUpdated = IsBeingUpdated(); DumpFile = File.Open(DumpFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); DumpStream = new StreamReader(DumpFile); ReadNextRecord(); } catch (Exception e) { } }
public override eSuccessState ParseData(GSMParameters param, bool[] decodedBurst, int sequence) { if (IsDummy(decodedBurst)) { DummyBursts++; if (DumpRawData) { StatusMessage = "Dummy Burst"; } return(eSuccessState.Succeeded); } StoreBurstContext(param, decodedBurst, sequence); /* if FNs are consecutive */ if (AllBurstsReceived()) { /* clean up */ ClearBurstContext(); /* get all e[] bits and place in i[] */ CopyEToI(); /* deinterleave the 4 bursts. the result is a 456 bit block. i[] to c[] */ Deinterleave(); DataBursts++; if (Deconvolution() == eCorrectionResult.Failed) { ErrorMessage = "(Error in ConvolutionalCoder)"; return(eSuccessState.Failed); } /* CRC check/fix */ switch (CRCCheck()) { case eCorrectionResult.Fixed: StatusMessage = "(CRC Error recovered)"; break; case eCorrectionResult.Failed: ErrorMessage = "(CRC Error)"; return(eSuccessState.Failed); } /* convert u[] to d[] bytes */ PackBytes(); /* BCCH and CCCH have L2 Pseudo Length */ if ((BurstBufferD[0] & 3) != 1) { ErrorMessage = "(Error in L2 Pseudo Length)"; return(eSuccessState.Failed); } L2.Handle(param, this, L3, BurstBufferD); return(eSuccessState.Succeeded); } else { StatusMessage = null; } return(eSuccessState.Unknown); }
private void btnEncryptToL1_Click(object sender, EventArgs e) { bool error = false; if (textL2Data.Text.Length != 23 * 2 && textL2Data.Text.Length != 23 * 3 - 1) { MessageBox.Show(this, "Supply 23 bytes L2 data ..."); error = true; } if (textKc.Text.Length != 8 * 2) { MessageBox.Show(this, "Supply 8 bytes Kc ..."); error = true; } if (textFN.Text.Length == 0) { MessageBox.Show(this, "Supply frame number ..."); error = true; } if (error) { textL1crypt0.Text = ""; textL1crypt1.Text = ""; textL1crypt2.Text = ""; textL1crypt3.Text = ""; return; } byte[] l2data = new byte[23]; ByteUtil.BytesFromString(textL2Data.Text, ref l2data); bool[][] l1bursts = new bool[4][]; for (int i = 0; i < l1bursts.Length; i++) { l1bursts[i] = new bool[114]; } SDCCHBurst sdcch = new SDCCHBurst(); sdcch.L2DataAdd(l2data); sdcch.L2ToL1Convert(); sdcch.L1BurstIGet(ref l1bursts); /* crypt it */ byte[] kc = new byte[8]; ByteUtil.BytesFromString(textKc.Text, ref kc); GSMParameters param = new GSMParameters(); param.FN = uint.Parse(textFN.Text); CryptA5 A5Algo = new CryptA5(kc); if (radioSameFN.Checked) { A5Algo.CryptDownlink(l1bursts[0], param.Count); A5Algo.CryptDownlink(l1bursts[1], param.Count); A5Algo.CryptDownlink(l1bursts[2], param.Count); A5Algo.CryptDownlink(l1bursts[3], param.Count); } else { A5Algo.CryptDownlink(l1bursts[0], param.Count); param.FN++; A5Algo.CryptDownlink(l1bursts[1], param.Count); param.FN++; A5Algo.CryptDownlink(l1bursts[2], param.Count); param.FN++; A5Algo.CryptDownlink(l1bursts[3], param.Count); } textL1crypt0.Text = ByteUtil.BitsToString(l1bursts[0]); textL1crypt1.Text = ByteUtil.BitsToString(l1bursts[1]); textL1crypt2.Text = ByteUtil.BitsToString(l1bursts[2]); textL1crypt3.Text = ByteUtil.BitsToString(l1bursts[3]); }
private void krakenWorker_DoWork(object sender, DoWorkEventArgs e) { bool[] key1 = null; bool[] key2 = null; uint count1, count2; uint testCount, burstPerTest; uint success = 0, bursts = 0, kc_diff = 0; testCount = uint.Parse(textTestCount.Text); burstPerTest = uint.Parse(textBursts.Text); GSMParameters param = new GSMParameters(); byte[] kc, kc_calculated = null; kc = new byte[8]; Random rand = new Random(); KrakenClient kraken = new KrakenClient(Analyzer.KrakenHostAddress); if (!kraken.Connect()) { MessageBox.Show("Could not connect to kraken."); return; } for (uint i = 0; i < testCount; i++) { /* get new Kc */ rand.NextBytes(kc); kc_calculated = null; /* set framenumber for first burst */ param.FN = (uint)rand.Next(2715648); for (uint j = 0; j < burstPerTest && kc_calculated == null; j++) { count1 = param.Count; param.FN += 1; count2 = param.Count; key1 = generateStream(kc, count1); key2 = generateStream(kc, count2); kc_calculated = kraken.RequestResult(key1, count1, key2, count2); if (kc_calculated != null) { /* check if Kc are the same */ for (int k = 0; k < kc.Length; k++) { if (kc[k] != kc_calculated[k]) { kc_diff++; break; } if (k == 7) { success++; } } } bursts++; krakenWorker.ReportProgress(((int)i * (int)burstPerTest + (int)j + 1) * 100 / ((int)burstPerTest * (int)testCount)); } krakenWorker.ReportProgress(((int)(i + 1) * (int)burstPerTest) * 100 / ((int)burstPerTest * (int)testCount)); } MessageBox.Show("Cracking stats\n" + "\tburst crack tries: " + bursts + "\n" + "\tKc recovered: " + success + "/" + testCount + "\n" + "\tCoverage: " + (success * 100 / testCount) + "%\n" + "\tAvg. bursts needed to crack: " + ((float)(bursts - (testCount - success) * burstPerTest) / success)); }
private void DecryptA5(GSMParameters param, bool[] BurstBufferE) { }
public override eSuccessState ParseData(GSMParameters param, bool[] decodedBurst, int sequence) { eSuccessState success = eSuccessState.Unknown; if (IsDummy(decodedBurst)) { State = eBurstState.Idle; DummyBursts++; //CloseFiles(); /* don't treat TCHs as a reliable source for end-of-connection detection */ //DummyBurstReceived(param); if (DumpRawData) { StatusMessage = "Dummy Burst"; } return(eSuccessState.Succeeded); } EncryptionType = AssociatedSACCH.EncryptionType; ChannelEncrypted = AssociatedSACCH.ChannelEncrypted; StoreBurstContext(param, decodedBurst, TCHSeq); /* GSM 05.03 Ch 2.1 */ /* when we got 8 TCH bursts */ if (++TCHSeq == 8) { TCHSeq = 0; /* try to decrypt buffer if this is enabled, but do not try to crack the key */ if (!HandleEncryption(param, false)) { State = eBurstState.CryptedTraffic; /* encrypted but no decryptor available, silently return */ return(eSuccessState.Unknown); } /* deinterleave the 8 TCH bursts. the result is a 456 bit block. i[] to c[] */ Deinterleave(); /* * GSM-05.03 4.2.5 * was this burst stolen for a FACCH? hl(B) (in e[]) is set for the last 4 bursts */ if (IsHL(decodedBurst)) { /* pass encryption information to FACCH */ FACCH.A5Algorithm = A5Algorithm; FACCH.A5CipherKey = A5CipherKey; FACCH.ChannelEncrypted = ChannelEncrypted; /* pass c[] to FACCH handler */ success = FACCH.ParseFACCHData(param, BurstBufferC); StatusMessage = FACCH.StatusMessage; ErrorMessage = FACCH.ErrorMessage; FACCH.StatusMessage = null; FACCH.ErrorMessage = null; } else { /* TCH speech/data (data not supported yet) */ /* split up the class 1... */ Array.Copy(BurstBufferC, Class1DataConv, Class1DataConv.Length); /* ... and class 2 bits */ Array.Copy(BurstBufferC, 378, GSMFrameBufferD, 182, 78); /* use an own convolutional coder buffer for these 188 bits */ if (ConvolutionalCoder.Decode(Class1DataConv, ref Class1Data) == 0) { bool[] parityBits = new bool[53]; for (int pos = 0; pos < 91; pos++) { GSMFrameBufferD[2 * pos] = Class1Data[pos]; GSMFrameBufferD[2 * pos + 1] = Class1Data[184 - pos]; } /* calculate parity */ Array.Copy(GSMFrameBufferD, 0, parityBits, 0, 50); Array.Copy(Class1Data, 91, parityBits, 50, 3); bool[] crc = CRC.Calc(parityBits, 0, 53, CRC.PolynomialTCHFR); if (CRC.Matches(crc)) { DataBursts++; success = eSuccessState.Succeeded; if (ChannelEncrypted) { State = eBurstState.DecryptedTraffic; } else { State = eBurstState.PlainTraffic; } #if false #region Microsoft WAV49 GSM Format if (WAV49First) { BitMapping.Unmap(GSMFrameBufferD, 0, WAV49FrameBool, 0, BitMapping.g610BitOrder); } else { /* directly unmap into boolean WAV49 frame buffer */ BitMapping.Unmap(GSMFrameBufferD, 0, WAV49FrameBool, 260, BitMapping.g610BitOrder); /* convert that WAV49 frame to byte[] */ ByteUtil.BitsToBytes(WAV49FrameBool, WAV49FrameByte); try { if (OutFile == null) { string name = ("GSM_" + Name + "_" + param.FN + ".wav").Replace("/", "_"); OutFile = new FileStream(name, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); WriteHeader(OutFile); } /* and write it */ WriteBuffer(OutFile, WAV49FrameByte); WriteHeader(OutFile); StatusMessage = "GSM 06.10 Voice data (" + OutFile.Name + ")"; } catch (Exception e) { StatusMessage = "GSM 06.10 Voice data (Writing file failed, " + e.GetType() + ")"; } } WAV49First = !WAV49First; #endregion #endif if (ChannelMode != 33) { #region write audio dump in RTP A/V Format /* GSM frame magic */ RTPFrameBool[0] = true; RTPFrameBool[1] = true; RTPFrameBool[2] = false; RTPFrameBool[3] = true; /* directly unmap into boolean RTP frame buffer */ BitMapping.Unmap(GSMFrameBufferD, 0, RTPFrameBool, 4, BitMapping.g610BitOrder); /* convert that RTP frame to byte[] */ ByteUtil.BitsToBytes(RTPFrameBool, RTPFrameByte); StatusMessage = ""; if (ChannelEncrypted) { StatusMessage += "======= encrypted =======" + Environment.NewLine; } try { if (OutFile == null) { string name = ("GSM_" + Name + "_" + param.FN).Replace("/", "_"); OutFile = new FileStream(name + ".gsm", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); //OutFileRaw = new FileStream(name + ".raw", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); StatusMessage += "Created file: '" + name + "'" + Environment.NewLine; } /* and write it */ OutFile.Write(RTPFrameByte, 0, RTPFrameByte.Length); OutFile.Flush(); /* * Array.Copy(GSMFrameBufferD, 0, RTPFrameBool, 4, GSMFrameBufferD.Length); * RTPFrameBool[0] = false; * RTPFrameBool[1] = false; * RTPFrameBool[2] = false; * RTPFrameBool[3] = false; * ByteUtil.BitsToBytes(RTPFrameBool, RTPFrameByte); * OutFileRaw.Write(RTPFrameByte, 0, RTPFrameByte.Length); */ StatusMessage += "GSM 06.10 Voice data (" + OutFile.Name + ")"; } catch (Exception e) { StatusMessage += "GSM 06.10 Voice data (Writing file failed, " + e.GetType() + ")"; } #endregion } else { #region write audio dump in AMR Format (assume 12.2kbit/s) UnmapDToW(); UnmapWToS(); /* convert that AMR frame to byte[] */ ByteUtil.BitsToBytes(BurstBufferSpeechBits, RTPFrameByte); StatusMessage = ""; if (ChannelEncrypted) { StatusMessage += "======= encrypted =======" + Environment.NewLine; } try { if (OutFile == null) { byte[] fileHeader = new byte[] { 0x23, 0x21, 0x41, 0x4D, 0x52, 0x0A }; string name = ("GSM_" + Name + "_" + param.FN).Replace("/", "_"); OutFile = new FileStream(name + ".amr", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); OutFile.Write(fileHeader, 0, fileHeader.Length); } /* and write it */ OutFile.WriteByte(0x3C); OutFile.Write(RTPFrameByte, 0, 31); OutFile.Flush(); StatusMessage += "GSM 06.90 Voice data (" + OutFile.Name + ")"; } catch (Exception e) { StatusMessage += "GSM 06.90 Voice data (Writing file failed, " + e.GetType() + ")"; } #endregion } } else { State = eBurstState.Failed; CryptedFrames++; ErrorMessage = "(TCH/F Class Ia: CRC Error)"; } } else { State = eBurstState.Failed; CryptedFrames++; ErrorMessage = "(TCH/F Class I: Error in ConvolutionalCoder)"; } } /* trick: * first use the last 8 bursts until one block was successfully decoded. * then use the last 4 bursts as we normally would do. * this will help in finding the correct alignment within the 4 frames. */ if (success == eSuccessState.Succeeded) { BurstShiftCount = 4; } else { BurstShiftCount = 7; } /* save the last n bursts for the next block */ for (int pos = 0; pos < BurstShiftCount; pos++) { BurstData src = BurstBlock[(8 - BurstShiftCount) + pos]; BurstData dst = BurstBlock[pos]; dst.FN = src.FN; dst.Count = src.Count; Array.Copy(src.BurstBufferI, 0, dst.BurstBufferI, 0, dst.BurstBufferI.Length); Array.Copy(src.BurstBufferE, 0, dst.BurstBufferE, 0, dst.BurstBufferE.Length); } /* and continue at position n (so we will read another 8-n bursts) */ TCHSeq = BurstShiftCount; /* only when in sync, return error flag */ if (BurstShiftCount == 4) { return(success); } } return(eSuccessState.Unknown); }
public override eSuccessState ParseData(GSMParameters param, bool[] decodedBurst, int sequence) { if (IsDummy(decodedBurst)) { State = eBurstState.Idle; DummyBursts++; /* don't treat SACCHs as a reliable source for end-of-connection detection */ //DummyBurstReceived(param); if (DumpRawData) { StatusMessage = "Dummy Burst"; } TCHSeq = 0; return(eSuccessState.Succeeded); } bool isComplete; /* decide between normal SACCH and SACCH/TCH */ if (!TCHType) { /* thats a SACCH */ /* use the normal sequence parameter */ StoreBurstContext(param, decodedBurst, sequence); /* the block is complete when 4 bursts of 4 consecutive FN were buffered */ isComplete = AllBurstsReceived(); } else { /* thats a SACCH/TCH */ /* use an own counter */ StoreBurstContext(param, decodedBurst, TCHSeq); /* when we caught four bursts, the block is complete */ TCHSeq++; isComplete = TCHSeq > 3; } if (isComplete) { /* clean up */ TCHSeq = 0; ClearBurstContext(); /* try to decrypt buffer if this is enabled */ if (!HandleEncryption(param)) { State = eBurstState.CryptedTraffic; if (param.ReportL1EncryptionErrors) { StatusMessage = "(Error in decryption)"; } /* encrypted but no decryptor available, silently return */ return(eSuccessState.Unknown); } /* deinterleave the 4 bursts. the result is a 456 bit block. i[] to c[] */ Deinterleave(); if (Deconvolution() == eCorrectionResult.Failed) { if (param.ReportL1EncryptionErrors) { if (!ChannelEncrypted) { StatusMessage = "(Error in ConvolutionalCoder - not encrypted)"; } else { StatusMessage = "(Error in ConvolutionalCoder - encrypted, wrong keystream?)"; } } State = eBurstState.Failed; return(eSuccessState.Unknown); } /* CRC check/fix */ switch (CRCCheck()) { case eCorrectionResult.Fixed: StatusMessage = "(CRC Error recovered)"; break; case eCorrectionResult.Failed: State = eBurstState.Failed; ErrorMessage = "(CRC Error)"; return(eSuccessState.Failed); } if (ChannelEncrypted) { State = eBurstState.DecryptedTraffic; } else { State = eBurstState.PlainTraffic; } if (ChannelEncrypted && DumpEncryptedMessageBits) { if (StatusMessage != null) { StatusMessage += EncryptionBitString; } else { StatusMessage = EncryptionBitString; } } /* convert u[] to d[] bytes */ PackBytes(); DataBursts++; /* payload starts at octet 3 (GSM 04.04 7.1) */ L2.Handle(param, this, L3, BurstBufferD, 2); return(eSuccessState.Succeeded); } else { StatusMessage = null; } return(eSuccessState.Unknown); }
public override eSuccessState ParseData(GSMParameters param, bool[] decodedBurst, int sequence) { if (IsDummy(decodedBurst)) { /* this may happen with dumps that do not contain SCH/BCCH anymore. simply accept it. */ return(eSuccessState.Unknown); } Array.Copy(decodedBurst, 3, SCHData, 0, 39); Array.Copy(decodedBurst, 106, SCHData, 39, 39); if (Deconvolution() == eCorrectionResult.Failed) { ErrorMessage = "(Error in ConvolutionalCoder)"; return(eSuccessState.Failed); } bool[] crc = CRC.Calc(SCHDataDecoded, 0, 35, CRC.PolynomialSCH); if (!CRC.Matches(crc)) { ErrorMessage = "(Error in CRC)"; return(eSuccessState.Failed); } byte BSIC = (byte)ByteUtil.BitsToLongRev(SCHDataDecoded, 2, 6); long T1 = ByteUtil.BitsToLongRev(SCHDataDecoded, new[] { new[] { 0, 2 }, new[] { 8, 8 }, new[] { 23, 1 } }); long T2 = ByteUtil.BitsToLongRev(SCHDataDecoded, 18, 5); long T3M = ByteUtil.BitsToLongRev(SCHDataDecoded, new[] { new[] { 16, 2 }, new[] { 24, 1 } }); long T3 = (10 * T3M) + 1; long FN; if (T2 <= T3) { FN = 51 * ((T3 - T2) % 26) + T3 + 51 * 26 * T1; } else { FN = 51 * (26 - ((T2 - T3) % 26)) + T3 + 51 * 26 * T1; } if (param.FN != FN) { param.FN = FN; } param.TN = 0; param.BSIC = BSIC; if (DumpData) { StatusMessage = "BSIC: " + String.Format("{0,3}", BSIC) + " T1: " + String.Format("{0,5}", T1) + " T2: " + String.Format("{0,3}", T2) + " T3: " + String.Format("{0,3}", T3) + " FN: " + String.Format("{0,8}", FN) + " TrainOffs: " + String.Format("{0,3}", param.SampleOffset); } return(eSuccessState.Succeeded); }
public override eSuccessState ParseData(GSMParameters param, bool[] decodedBurst) { return(ParseData(param, decodedBurst, 0)); }
public void Handle(GSMParameters param, NormalBurst source, L3Handler l3, byte[] l2Data) { Handle(param, source, l3, l2Data, 0); }
public void Handle(GSMParameters param, NormalBurst source, L3Handler l3, byte[] l2Data, int startOffset) { if (param.PacketDumper != null) { param.PacketDumper.WriteL2Data(l2Data); } Builder.Length = 0; /* BCCH and CCCH packets have pseudo L2 headers (GSM 04.07 11.3.1) */ if (source.GetType() == typeof(BCCHBurst) || source.GetType() == typeof(CCCHBurst)) { Builder.Append("Pseudo L2 Header").Append(Environment.NewLine); if (source.ChannelEncrypted) { Builder.Append("======= encrypted =======").Append(Environment.NewLine); } /* call LUA script */ if (param.LuaVm != null) { LuaHelpers.CallFunction(param.LuaVm, "L2DataReceived", true, source, null, param); } /* pass to L3 handler if not empty and skip pseudo length */ if (!PacketIsEmpty(l2Data, 1)) { l3.Handle(l2Data, 1, param); } } else { /* always show empty/multiframe messages if requested */ ShowMessage = ShowAllMessages; /* show if encrypted */ if (source.ChannelEncrypted) { ShowMessage |= ShowCryptedMessages; Builder.Append("======= encrypted =======").Append(Environment.NewLine); } L2Data.Payload = l2Data; L2Data.StartOffset = startOffset; /* call LUA script */ if (param.LuaVm != null) { LuaHelpers.CallFunction(param.LuaVm, "L2DataReceived", true, source, L2Data, param); } if (L3Handler.ExceptFieldsEnabled || ShowMessage) { Builder.Append("SAPI: ").Append(L2Data.SAPI).Append(" C/R: ").Append((L2Data.CR ? "1" : "0")).Append(" EA: ").Append((L2Data.EA ? "1" : "0")).Append(" "); Builder.Append("M: ").Append((L2Data.M ? "1" : "0")).Append(" "); Builder.Append("EL: ").Append((L2Data.EL ? "1" : "0")).Append(" "); Builder.Append("L: ").Append(L2Data.Length).Append(" "); switch (L2Data.FrameFormat) { case eFrameFormat.S_Format: Builder.Append("S Format, N(R)=").Append(L2Data.NR).Append(" S=").Append(L2Data.S).Append(" ").Append((eSupervisory)L2Data.S); break; case eFrameFormat.U_Format: Builder.Append("U Format, U=").Append(L2Data.U).Append(" ").Append((eUnnumbered)L2Data.U); break; case eFrameFormat.I_Format: Builder.Append("I Format, N(R)=").Append(L2Data.NR).Append(" N(S)=").Append(L2Data.NS).Append(" "); break; } } /* check if there is enough space in the buffer */ if (L2Data.Length + packetBufferOffset <= packetBuffer.Length && L2Data.Length + L2Data.DataStart <= L2Data.Payload.Length) { /* dont buffer when its the same frame number (retransmission) */ if (!L2Data.M || LastNS < L2Data.NS) { Array.Copy(L2Data.Payload, L2Data.DataStart, packetBuffer, packetBufferOffset, L2Data.Length); packetBufferOffset += L2Data.Length; LastNS = L2Data.NS; } else { if (L3Handler.ExceptFieldsEnabled || ShowMessage) { Builder.Append("!! Retransmission !! "); } } } else { if (DumpFaulty) { Builder.Append("Faulty length?! Length = ").Append((packetBufferOffset + L2Data.Length)).Append(Environment.NewLine); Builder.Append("Raw L2 data").Append(Environment.NewLine); Builder.Append(" ").Append(DumpBytes(l2Data)).Append(Environment.NewLine); ShowMessage = true; } } /* that counter is just for convinience */ NumPackets++; /* when reached the last packet, pass it to L3 handler */ if (!L2Data.M) { if (L3Handler.ExceptFieldsEnabled || ShowMessage) { if (NumPackets > 1) { Builder.Append("(packet ").Append(NumPackets).Append(", total ").Append(packetBufferOffset).Append(" bytes)").Append(Environment.NewLine); } else { Builder.Append(Environment.NewLine); } } /* but only pass it through when there is any data */ if (packetBufferOffset > 0) { /* allocate a new array with the correct size */ byte[] buf = new byte[packetBufferOffset]; Array.Copy(packetBuffer, buf, buf.Length); if (!PacketIsEmpty(buf)) { l3.Handle(buf, 0, param); } } /* reset the buffer etc */ packetBufferOffset = 0; for (int pos = 0; pos < packetBuffer.Length; pos++) { packetBuffer[pos] = 0xCC; } NumPackets = 0; LastNS = -1; } else if (L3Handler.ExceptFieldsEnabled || ShowMessage) { Builder.Append("(packet ").Append(NumPackets).Append(")").Append(Environment.NewLine); } } if (DumpRawData && (L3Handler.ExceptFieldsEnabled || ShowMessage)) { Builder.Append("Raw L2 data").Append(Environment.NewLine); Builder.Append(" ").Append(DumpBytes(l2Data)).Append(Environment.NewLine); } StatusMessage = Builder.ToString(); }
public override eSuccessState ParseData(GSMParameters param, bool[] decodedBurst, int sequence) { return(eSuccessState.Unknown); }
public FCHBurst(GSMParameters Parameters) { Name = "FCH"; ShortName = "FC "; }
public override eSuccessState ParseData(GSMParameters param, bool[] decodedBurst, int sequence) { /* ignore uplink to check if kraken still working */ if (param.Dir == eLinkDirection.Uplink) { return(eSuccessState.Succeeded); } if (IsDummy(decodedBurst)) { State = eBurstState.Idle; DummyBursts++; DummyBurstReceived(param); if (DumpRawData) { StatusMessage = "Dummy Burst"; } return(eSuccessState.Succeeded); } StoreBurstContext(param, decodedBurst, sequence); /* if FNs are consecutive */ if (AllBurstsReceived()) { ClearBurstContext(); /* try to decrypt buffer if this is enabled */ if (!HandleEncryption(param)) { State = eBurstState.CryptedTraffic; if (param.ReportL1EncryptionErrors) { StatusMessage = "(Error in decryption)"; } /* encrypted but no decryptor available, silently return */ return(eSuccessState.Unknown); } /* deinterleave the 4 bursts. the result is a 456 bit block. i[] to c[] */ Deinterleave(); /* undo convolutional coding c[] to u[] */ if (Deconvolution() == eCorrectionResult.Failed) { if (param.ReportL1EncryptionErrors) { if (!ChannelEncrypted) { StatusMessage = "(Error in ConvolutionalCoder - not encrypted)"; } else { StatusMessage = "(Error in ConvolutionalCoder - encrypted, wrong keystream?)"; } } State = eBurstState.Failed; return(eSuccessState.Unknown); } /* CRC check/fix */ switch (CRCCheck()) { case eCorrectionResult.Fixed: StatusMessage = "(CRC Error recovered)"; break; case eCorrectionResult.Failed: State = eBurstState.Failed; ErrorMessage = "(CRC Error)"; return(eSuccessState.Failed); } if (ChannelEncrypted) { State = eBurstState.DecryptedTraffic; } else { State = eBurstState.PlainTraffic; } if (ChannelEncrypted && DumpEncryptedMessageBits) { if (StatusMessage != null) { StatusMessage += EncryptionBitString; } else { StatusMessage = EncryptionBitString; } } EncryptionBitString = ""; /* convert u[] to d[] bytes */ PackBytes(); DataBursts++; L2.Handle(param, this, L3, BurstBufferD); return(eSuccessState.Succeeded); } else { StatusMessage = null; } return(eSuccessState.Unknown); }
/* parse the raw samples */ public virtual eSuccessState ParseRawBurst(GSMParameters Parameters, double[] rawBurst, double[] rawBurstStrength) { return(eSuccessState.Unknown); }