Exemplo n.º 1
0
        public int Process(Burst burst, float *audioOut)
        {
            var trafficChannel = 0;

            BurstReceived = (burst.Type != BurstType.None);

            _timeCounter++;
            Ber = _averageBer;
            if (_timeCounter > 100)
            {
                Mer = (_badBurstCounter / _timeCounter) * 100.0f;

                _timeCounter     = 0;
                _badBurstCounter = 0;
            }

            _networkTime.AddTimeSlot();

            if (burst.Type == BurstType.None)
            {
                _haveErrors = true;
                if (TetraMode == Mode.TMO)
                {
                    _badBurstCounter++;
                    //Debug.WriteLine("burst err");
                    //Debug.Write(string.Format("ts:{0:0} fr:{1:00} Burst_Err", _networkTime.TimeSlot, _networkTime.Frame));
                }
                return(trafficChannel);
            }

            _haveErrors = false;

            //Debug.WriteLine("");
            //Debug.Write(string.Format("ts:{0:0} fr:{1:00}", _networkTime.TimeSlot, _networkTime.Frame));
            //Debug.Write(" " + burst.Type.ToString());

            _parse.ResetAACH();

            _data.Clear();
            _syncInfo.Clear();

            #region Sync burst

            if (burst.Type == BurstType.SYNC)
            {
                _phyLevel.ExtractSBChannels(burst, _sb1BufferPtr);

                _logicChannel     = _lowerMac.ExtractLogicChannelFromSB(_sb1BufferPtr, _sb1Buffer.Length);
                _badBurstCounter += _logicChannel.CrcIsOk ? 0.0f : 0.5f;
                _haveErrors      |= !_logicChannel.CrcIsOk;
                _averageBer       = _averageBer * 0.5f + _lowerMac.Ber * 0.5f;
                //Debug.Write(" slot 1:" + (_logicChannel.CrcIsOk ? " OK" : " Err"));
                if (_logicChannel.CrcIsOk)
                {
                    _parse.SyncPDU(_logicChannel, _syncInfo);

                    if (_syncInfo.Value(GlobalNames.SystemCode) < 8)
                    {
                        TetraMode = Mode.TMO;
                        _lowerMac.ScramblerCode = TetraUtils.CreateScramblerCode(_syncInfo.Value(GlobalNames.MCC), _syncInfo.Value(GlobalNames.MNC), _syncInfo.Value(GlobalNames.ColorCode));
                        _networkTime.Synchronize(_syncInfo.Value(GlobalNames.TimeSlot), _syncInfo.Value(GlobalNames.Frame), _syncInfo.Value(GlobalNames.MultiFrame));
                    }
                    else
                    {
                        TetraMode = Mode.DMO;

                        if (_syncInfo.Value(GlobalNames.SYNC_PDU_type) == 0)
                        {
                            //Debug.Write(_syncInfo.Value(GlobalNames.Master_slave_link_flag) == 1 ? " Master" : " Slave");

                            if (_syncInfo.Value(GlobalNames.Master_slave_link_flag) == 1 || _syncInfo.Value(GlobalNames.Communication_type) == 0)
                            {
                                _networkTime.SynchronizeMaster(_syncInfo.Value(GlobalNames.TimeSlot), _syncInfo.Value(GlobalNames.Frame));
                            }
                            else
                            {
                                _networkTime.SynchronizeSlave(_syncInfo.Value(GlobalNames.TimeSlot), _syncInfo.Value(GlobalNames.Frame));
                            }
                        }
                    }
                }
                else
                {
                    //Debug.WriteLine("Sync SB crc error");
                }

                _phyLevel.ExtractPhyChannels(TetraMode, burst, _bbBufferPtr, _bkn1BufferPtr, _bkn2BufferPtr);

                if (TetraMode == Mode.TMO)
                {
                    _logicChannel          = _lowerMac.ExtractLogicChannelFromBKN(_bkn2BufferPtr, _bkn2Buffer.Length);
                    _logicChannel.TimeSlot = _networkTime.TimeSlot;
                    _logicChannel.Frame    = _networkTime.Frame;

                    _badBurstCounter += _logicChannel.CrcIsOk ? 0.0f : 0.5f;
                    _haveErrors      |= !_logicChannel.CrcIsOk;
                    _averageBer       = _averageBer * 0.5f + _lowerMac.Ber * 0.5f;
                    //Debug.Write(" slot 2:" + (_logicChannel.CrcIsOk ? " OK" : " Err"));
                    if (_logicChannel.CrcIsOk)
                    {
                        _parse.TmoParseMacPDU(_logicChannel, _data);
                    }
                    else
                    {
                        //Debug.WriteLine("Sync BKN2 crc error");
                    }
                }
                else
                {
                    _logicChannel          = _lowerMac.ExtractLogicChannelFromBKN2(_bkn2BufferPtr, _bkn2Buffer.Length);
                    _logicChannel.TimeSlot = _networkTime.TimeSlot;
                    _logicChannel.Frame    = _networkTime.Frame;

                    _badBurstCounter += _logicChannel.CrcIsOk ? 0.0f : 0.5f;
                    _haveErrors      |= !_logicChannel.CrcIsOk;
                    _averageBer       = _averageBer * 0.5f + _lowerMac.Ber * 0.5f;
                    //Debug.Write(" slot 2:" + (_logicChannel.CrcIsOk ? " OK" : " Err"));
                    if (_logicChannel.CrcIsOk)
                    {
                        _parse.SyncPDUHalfSlot(_logicChannel, _syncInfo);

                        if (_syncInfo.Value(GlobalNames.Communication_type) == 0)
                        {
                            if (_syncInfo.Contains(GlobalNames.MNC) && _syncInfo.Contains(GlobalNames.Source_address))
                            {
                                _lowerMac.ScramblerCode = TetraUtils.CreateScramblerCode(_syncInfo.Value(GlobalNames.MNC), _syncInfo.Value(GlobalNames.Source_address));
                            }
                        }
                        else if (_syncInfo.Value(GlobalNames.Communication_type) == 1)
                        {
                            if (_syncInfo.Contains(GlobalNames.Repeater_address) && _syncInfo.Contains(GlobalNames.Source_address))
                            {
                                _lowerMac.ScramblerCode = TetraUtils.CreateScramblerCode(_syncInfo.Value(GlobalNames.Repeater_address), _syncInfo.Value(GlobalNames.Source_address));
                            }
                        }
                    }
                }

                UpdateSyncInfo(_syncInfo);
            }
            #endregion

            UpdatePublicProp();

            #region Other burst

            if (burst.Type != BurstType.SYNC)
            {
                _phyLevel.ExtractPhyChannels(TetraMode, burst, _bbBufferPtr, _bkn1BufferPtr, _bkn2BufferPtr);

                if (TetraMode == Mode.TMO)
                {
                    _logicChannel          = _lowerMac.ExtractLogicChannelFromBB(_bbBufferPtr, _bbBuffer.Length);
                    _logicChannel.TimeSlot = _networkTime.TimeSlot;
                    _logicChannel.Frame    = _networkTime.Frame;

                    _badBurstCounter += _logicChannel.CrcIsOk ? 0.0f : 0.2f;
                    _haveErrors      |= !_logicChannel.CrcIsOk;
                    //Debug.Write(_logicChannel.CrcIsOk ? " BB OK" : " BB Err");
                    if (_logicChannel.CrcIsOk)
                    {
                        _parse.AccessAsignPDU(_logicChannel);
                    }
                    else
                    {
                        //Debug.WriteLine("BB crc error");
                    }
                }

                switch (burst.Type)
                {
                case BurstType.NDB1:

                    if (((TetraMode == Mode.TMO) && (_parse.DownLinkChannelType == ChannelType.Traffic)) ||
                        ((TetraMode == Mode.DMO) && (!_networkTime.Frame18) && (_networkTime.TimeSlot == 1)) ||
                        ((TetraMode == Mode.DMO) && (!_networkTime.Frame18Slave) && (_networkTime.TimeSlotSlave == 1)))
                    {
                        //Debug.Write(" slot 12:voice");

                        _logicChannel = _lowerMac.ExtractVoiceDataFromBKN1BKN2(_bkn1BufferPtr, _bkn2BufferPtr, _bkn1Buffer.Length);
                        var itsAudio = DecodeAudio(audioOut, _logicChannel.Ptr, _logicChannel.Length, false, _networkTime.TimeSlot);
                        trafficChannel = itsAudio ? _networkTime.TimeSlot : 0;
                        break;
                    }
                    else
                    {
                        _logicChannel          = _lowerMac.ExtractLogicChannelFromBKN1BKN2(_bkn1BufferPtr, _bkn2BufferPtr, _bkn1Buffer.Length);
                        _logicChannel.TimeSlot = _networkTime.TimeSlot;
                        _logicChannel.Frame    = _networkTime.Frame;

                        _badBurstCounter += _logicChannel.CrcIsOk ? 0.0f : 0.8f;
                        _haveErrors      |= !_logicChannel.CrcIsOk;
                        _averageBer       = _averageBer * 0.5f + _lowerMac.Ber * 0.5f;
                        //Debug.Write(" slot 12:" + (_logicChannel.CrcIsOk ? " OK" : " Err"));
                        if (_logicChannel.CrcIsOk)
                        {
                            if (TetraMode == Mode.TMO)
                            {
                                _parse.TmoParseMacPDU(_logicChannel, _data);
                            }
                            else
                            {
                                _parse.DmoParseMacPDU(_logicChannel, _data);
                            }
                        }
                        else
                        {
                            //Debug.WriteLine("BKN1 BKN2 crc error");
                        }
                    }
                    break;

                case BurstType.NDB2:

                    _logicChannel          = _lowerMac.ExtractLogicChannelFromBKN(_bkn1BufferPtr, _bkn1Buffer.Length);
                    _logicChannel.TimeSlot = _networkTime.TimeSlot;
                    _logicChannel.Frame    = _networkTime.Frame;

                    _badBurstCounter += _logicChannel.CrcIsOk ? 0.0f : 0.4f;
                    _haveErrors      |= !_logicChannel.CrcIsOk;
                    _averageBer       = _averageBer * 0.5f + _lowerMac.Ber * 0.5f;
                    //Debug.Write(" slot 1:" + (_logicChannel.CrcIsOk ? " OK" : " Err"));
                    if (_logicChannel.CrcIsOk)
                    {
                        if (TetraMode == Mode.TMO)
                        {
                            _parse.TmoParseMacPDU(_logicChannel, _data);
                        }
                        else
                        {
                            _parse.DmoParseMacPDU(_logicChannel, _data);
                        }
                    }
                    else
                    {
                        //Debug.WriteLine("BKN1 crc error");
                    }

                    if ((_parse.DownLinkChannelType == ChannelType.Traffic && !_parse.HalfSlotStolen) ||
                        ((TetraMode == Mode.DMO) && (!_networkTime.Frame18) && (_networkTime.TimeSlot == 1) && (!_parse.HalfSlotStolen)) ||
                        ((TetraMode == Mode.DMO) && (!_networkTime.Frame18Slave) && (_networkTime.TimeSlotSlave == 1) && (!_parse.HalfSlotStolen)))
                    {
                        //Debug.Write(" slot 2:voice");
                        _logicChannel = _lowerMac.ExtractVoiceDataFromBKN2(_bkn2BufferPtr, _bkn2Buffer.Length);
                        var itsAudio = DecodeAudio(audioOut, _logicChannel.Ptr, _logicChannel.Length, true, _networkTime.TimeSlot);
                        trafficChannel = itsAudio ? _networkTime.TimeSlot : 0;
                        break;
                    }
                    else
                    {
                        _logicChannel          = _lowerMac.ExtractLogicChannelFromBKN(_bkn2BufferPtr, _bkn2Buffer.Length);
                        _logicChannel.TimeSlot = _networkTime.TimeSlot;
                        _logicChannel.Frame    = _networkTime.Frame;

                        _badBurstCounter += _logicChannel.CrcIsOk ? 0.0f : 0.4f;
                        _haveErrors      |= !_logicChannel.CrcIsOk;
                        _averageBer       = _averageBer * 0.5f + _lowerMac.Ber * 0.5f;
                        //Debug.Write(" slot 2:" + (_logicChannel.CrcIsOk ? " OK" : " Err"));
                        if (_logicChannel.CrcIsOk)
                        {
                            if (TetraMode == Mode.TMO)
                            {
                                _parse.TmoParseMacPDU(_logicChannel, _data);
                            }
                            else
                            {
                                _parse.DmoParseMacPDU(_logicChannel, _data);
                            }
                        }
                        else
                        {
                            //Debug.WriteLine("BKN2 crc error");
                        }
                    }
                    break;

                default:
                    break;
                }
            }

            if (_data.Count > 0)
            {
                UpdateData(_data);
            }

            #endregion

            return(trafficChannel);
        }