Esempio n. 1
0
        /* define our own since we want to use private bool[] for c[] bits */
        internal new eCorrectionResult Deconvolution()
        {
            int failures = ConvolutionalCoder.Decode(SCHData, ref SCHDataDecoded);

            if (failures == 0)
            {
                return(eCorrectionResult.Correct);
            }
            else if (failures < 10)
            {
                return(eCorrectionResult.Fixed);
            }
            else
            {
                return(eCorrectionResult.Failed);
            }
        }
Esempio n. 2
0
        /* define our own since we want to use private bool[] for c[] bits */
        internal new eCorrectionResult Deconvolution(bool[] burstBufferC)
        {
            int failures = ConvolutionalCoder.Decode(burstBufferC, ref BurstBufferU);

            if (failures == 0)
            {
                return(eCorrectionResult.Correct);
            }
            else if (failures < 10)
            {
                return(eCorrectionResult.Fixed);
            }
            else
            {
                return(eCorrectionResult.Failed);
            }
        }
Esempio n. 3
0
        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);
        }