DecodePmt() public method

Decodes the PMT supplied in buf and fills the pid table with all pids found
public DecodePmt ( byte buf ) : void
buf byte The buf.
return void
    /// <summary>
    /// Sends the PMT to the CI module
    /// </summary>
    /// <param name="subChannel">The sub channel.</param>
    /// <param name="channel">channel on which we are tuned</param>
    /// <param name="PMT">byte array containing the PMT</param>
    /// <param name="pmtLength">length of the pmt array</param>
    /// <param name="audioPid">pid of the current audio stream</param>
    /// <returns></returns>
    public bool SendPMT(int subChannel, DVBBaseChannel channel, byte[] PMT, int pmtLength, int audioPid)
    {
      try
      {
        if (!_useCam)
          return true;
        if (channel.FreeToAir)
          return true; //no need to descramble this one...

        AddSubChannel(subChannel, channel);
        ConditionalAccessContext context = _mapSubChannels[subChannel];
        context.CamType = _CamType;
        context.Channel = channel;
        if (_CamType == CamType.Astoncrypt2)
        {
          int newLength;
          context.PMT = PatchPMT_AstonCrypt2(PMT, pmtLength, out newLength);
          context.PMTLength = newLength;
        }
        else
        {
          context.PMT = PMT;
          context.PMTLength = pmtLength;
        }
        context.AudioPid = audioPid;
        context.ServiceId = channel.ServiceId;

        if (_winTvCiModule != null)
        {
          int hr = _winTvCiModule.SendPMT(PMT, pmtLength);
          if (hr != 0)
          {
            Log.Log.Info("Conditional Access:  sendPMT to WinTVCI failed");
            return false;
          }
          Log.Log.Info("Conditional Access:  sendPMT to WinTVCI succeeded");
          return true;
        }
        if (_knc != null)
        {
          ChannelInfo info = new ChannelInfo();
          info.DecodePmt(PMT);
          int caPmtLen;
          byte[] caPmt = info.caPMT.CaPmtStruct(out caPmtLen);
          return _knc.SendPMT(caPmt, caPmtLen);
        }
        if (_DigitalDevices != null)
        {
          return _DigitalDevices.SendServiceIdToCam(channel.ServiceId);
        }
        if (_digitalEveryWhere != null)
        {
          return _digitalEveryWhere.SendPMTToFireDTV(_mapSubChannels);
        }
        if (_technoTrend != null)
        {
          return _technoTrend.DescrambleMultiple(_mapSubChannels);
          // return _technoTrend.SendPMT(PMT, pmtLength);
        }
        if (_twinhan != null)
        {
          ChannelInfo info = new ChannelInfo();
          info.DecodePmt(PMT);

          int caPmtLen;
          byte[] caPmt = info.caPMT.CaPmtStruct(out caPmtLen);
          return _twinhan.SendPMT(caPmt, caPmtLen);
        }
      }
      catch (Exception ex)
      {
        Log.Log.Write(ex);
      }
      return true;
    }
示例#2
0
    private bool HandlePmt()
    {
      IntPtr pmtMem = Marshal.AllocCoTaskMem(4096); // max. size for pmt
      try
      {
        _pmtLength = _tsFilterInterface.PmtGetPMTData(_subChannelIndex, pmtMem);
        if (_pmtLength < 6)
        {
          return false;
        }

        // Check the program number.
        _pmtData = new byte[_pmtLength];
        Marshal.Copy(pmtMem, _pmtData, 0, _pmtLength);
        int version = ((_pmtData[5] >> 1) & 0x1F);
        int pmtProgramNumber = (_pmtData[3] << 8) + _pmtData[4];
        Log.Log.Info("HDPVR: PMT sid=0x{0:X} pid=0x{1:X} version=0x{2:X}", pmtProgramNumber, _pmtPid, version);
        if (pmtProgramNumber != SERVICE_ID)
        {
          throw new TvException("HDPVRChannel: PMT program number doesn't match expected service ID");
        }

        // Get the program PIDs.
        _pmtVersion = version;
        _channelInfo = new ChannelInfo();
        _channelInfo.DecodePmt(_pmtData);
        _channelInfo.serviceID = pmtProgramNumber;
        _channelInfo.network_pmt_PID = _pmtPid;
        SetMpegPidMapping(_channelInfo);
        return true;
      }
      finally
      {
        Marshal.FreeCoTaskMem(pmtMem);
      }
    }
    /// <summary>
    /// Decodes the PMT and sends the PMT to cam.
    /// </summary>
    protected virtual bool SendPmtToCam(out bool updatePids, out int waitInterval)
    {
      ThrowExceptionIfTuneCancelled();
      lock (this)
      {
        DVBBaseChannel channel = _currentChannel as DVBBaseChannel;
        updatePids = false;
        waitInterval = 100;
        bool foundCA = false;
        if (_mdplugs != null)
        {
          if (channel != null)
          {
            //HACK: Currently Premiere Direkt Feeds (nid=133) have the free_ca flag in SDT set to true (means not scrambled), so we have to override this
            if ((!channel.FreeToAir) || (channel.NetworkId == 133 && !channel.Provider.Equals("BetaDigital")))
            {
              DateTime dtNow = DateTime.Now;
              foundCA = false;
              //Log.Log.Info("subch:{0} listen for CA", _listenCA);
              if (!_eventCA.WaitOne(10000, true)) //wait 10 sec for CA to arrive.
              {
                TimeSpan ts = DateTime.Now - dtNow;
                Log.Log.Info("subch:{0} SendPmt:no CA found after {1} seconds", _subChannelId, ts.TotalSeconds);
                return false;
              }
              else
              {
                ThrowExceptionIfTuneCancelled();
                foundCA = true;
                TimeSpan ts = DateTime.Now - dtNow;
                Log.Log.Info("subch:{0} SendPmt:CA found after {1} seconds", _subChannelId, ts.TotalSeconds);
              }              
            }
          }
        }

        if (channel == null)
        {
          Log.Log.Info("subch:{0} SendPmt:no channel set", _subChannelId);
          return true;
        }
        IntPtr pmtMem = Marshal.AllocCoTaskMem(4096); // max. size for pmt
        IntPtr catMem = Marshal.AllocCoTaskMem(4096); // max. size for cat
        try
        {
          _pmtLength = _tsFilterInterface.PmtGetPMTData(_subChannelIndex, pmtMem);
          if (_pmtLength > 6)
          {
            _pmtData = new byte[_pmtLength];
            Marshal.Copy(pmtMem, _pmtData, 0, _pmtLength);
            int version = ((_pmtData[5] >> 1) & 0x1F);
            int pmtProgramNumber = (_pmtData[3] << 8) + _pmtData[4];
            Log.Log.Info("subch:{0} SendPmt:{1:X} {2:X} {3:X} {4:X}", _subChannelId, pmtProgramNumber, channel.ServiceId,
                         _pmtVersion, version);
            if (pmtProgramNumber == channel.ServiceId)
            {
              if (_pmtVersion == version) //already received this pmt
                return true;

              _pmtVersion = version;

              _channelInfo = new ChannelInfo();
              _channelInfo.DecodePmt(_pmtData);
              _channelInfo.network_pmt_PID = channel.PmtPid;
              _channelInfo.serviceID = channel.ServiceId;

              // update any service scrambled / unscambled changes
              if (_channelInfo.scrambled == channel.FreeToAir)
              {
                channel.FreeToAir = !_channelInfo.scrambled;
                Log.Log.Info("subch:{0} SendPMT: Channel FTA information changed to {1} according to CAIDs in PMT.",
                             _subChannelId, channel.FreeToAir);
              }
              if ((_mdplugs != null) && (foundCA))
              {
                try
                {
                  int catLength = _tsFilterInterface.CaGetCaData(_subChannelIndex, catMem);
                  if (catLength > 0)
                  {
                    byte[] cat = new byte[catLength];
                    Marshal.Copy(catMem, cat, 0, catLength);
                    _channelInfo.DecodeCat(cat, catLength);
                  }
                }
                catch (Exception ex)
                {
                  Log.Log.Write(ex);
                }
              }

              updatePids = true;

              if (_conditionalAccess == null)
              {
                Log.Log.Info("subch:{0} SendPMT: No cam in use, nothing to do.", _subChannelId);
                return true;
              }
              if (channel.FreeToAir)
              {
                Log.Log.Info("subch:{0} SendPMT: Channel is FTA, nothing to do.", _subChannelId);
                return true;
              }
              Log.Log.WriteFile("subch:{0} SendPMT version:{1} len:{2} {3}", _subChannelId, version, _pmtLength,
                                _channelInfo.caPMT.ProgramNumber);

              int audioPid = -1;
              if (_currentAudioStream != null)
              {
                audioPid = _currentAudioStream.Pid;
              }

              if (_conditionalAccess.SendPMT(_subChannelId, channel, _pmtData, _pmtLength,
                                             audioPid))
              {
                Log.Log.WriteFile("subch:{0} cam flags:{1}", _subChannelId, _conditionalAccess.IsCamReady());
                return true;
              }
              else
              {
                //cam is not ready yet
                Log.Log.WriteFile("subch:{0} SendPmt failed cam flags:{1}", _subChannelId,
                                  _conditionalAccess.IsCamReady());
                _pmtVersion = -1;
                waitInterval = 3000;
                return false;
              }
            }
          }
        }
        catch (Exception ex)
        {
          Log.Log.Write(ex);
        }
        finally
        {
          Marshal.FreeCoTaskMem(pmtMem);
          Marshal.FreeCoTaskMem(catMem);
        }
      }
      return false;
    }