Advertisement
Guest User

Untitled

a guest
Apr 5th, 2020
638
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 22.98 KB | None | 0 0
  1. // TsDescrambler.cpp: TSデスクランブルデコーダ
  2. //
  3. /////////////////////////////////////////////////////////////////////////////
  4.  
  5. #include "StdAfx.h"
  6. #include "BonSDK.h"
  7. #include "TsDescrambler.h"
  8. #include "TsTable.h"
  9. #include "TsPacket.h"
  10.  
  11.  
  12. /////////////////////////////////////////////////////////////////////////////
  13. // ファイルローカル定数設定
  14. /////////////////////////////////////////////////////////////////////////////
  15.  
  16. // EMM処理有効期間
  17. #define EMM_VALID_PERIOD            7UL         // 7day
  18.  
  19. // B-CASカード再初期化ガードインターバル
  20. #define BCAS_REFRESH_INTERVAL       1000UL      // 1s
  21.  
  22. // PMT待ちパケットカウント数
  23. #define PMT_WAIT_PACKET_COUNT       (3250 *  200 / TS_PACKET_SIZE)  //  200ms @ 26Mbps
  24. #define ECM_WAIT_PACKET_COUNT       (3250 * 2000 / TS_PACKET_SIZE)  // 2000ms @ 26Mbps
  25.  
  26. // クリップ付きインクリメントマクロ
  27. #define CLIPED_INCREMENT(V)         {if((V) < 0xFFFFFFFFUL)(V)++;}
  28.  
  29.  
  30. /////////////////////////////////////////////////////////////////////////////
  31. // TSデスクランブルデコーダ
  32. /////////////////////////////////////////////////////////////////////////////
  33.  
  34. const bool CTsDescrambler::InputMedia(IMediaData *pMediaData, const DWORD dwInputIndex)
  35. {
  36.     // 入力パラメータチェック
  37.     ITsPacket * const pPacket = dynamic_cast<ITsPacket *>(pMediaData);
  38.     if(!pPacket || (dwInputIndex >= GetInputNum()))return false;
  39.  
  40.     // PS処理
  41.     InputPacket(pPacket);
  42.  
  43.     if(!m_bEnableBuffering || (m_DecBufState == BDS_RUNNING)){
  44.         // パケット復号
  45.         OutputPacket(pPacket);
  46.         }
  47.     else{
  48.         // 未処理パケットバッファリング
  49.         PushUnprocPacket(pPacket);
  50.  
  51.         // バッファリング制御
  52.         BufManagement(pPacket);
  53.         }
  54.  
  55.     return true;
  56. }
  57.  
  58. const bool CTsDescrambler::OpenDescrambler(LPCTSTR lpszBCId)
  59. {
  60.     // 一旦クローズ
  61.     CloseDescrambler();
  62.  
  63.     IHalDevice *pHalDevice = NULL;
  64.  
  65.     try{
  66.         // B-CASカードのインスタンスを生成する
  67.         if(!(pHalDevice = ::BON_SAFE_CREATE<IHalDevice *>(lpszBCId)))throw __LINE__;
  68.  
  69.         // デバイスタイプをチェック
  70.         if(pHalDevice->GetDeviceType() != ::BON_NAME_TO_GUID(TEXT("IHalBcasCard")))throw __LINE__;
  71.  
  72.         // デバイスの存在をチェック
  73.         if(!pHalDevice->GetTotalDeviceNum())throw __LINE__;
  74.  
  75.         // デバイスの空きをチェック
  76.         if(pHalDevice->GetActiveDeviceNum() >= pHalDevice->GetTotalDeviceNum())throw __LINE__;
  77.    
  78.         // IHalBcasCardインタフェース取得
  79.         if(!(m_pHalBcasCard = dynamic_cast<IHalBcasCard *>(pHalDevice)))throw __LINE__;
  80.  
  81.         // B-CASカードをオープン
  82.         if(!m_pHalBcasCard->OpenCard())throw __LINE__;
  83.        
  84.         // 全状態リセット
  85.         OnReset();
  86.         }
  87.     catch(...){
  88.         // エラー発生
  89.         BON_SAFE_RELEASE(pHalDevice);
  90.         m_pHalBcasCard = NULL;
  91.        
  92.         CloseDescrambler();
  93.         return false;
  94.         }
  95.  
  96.     return true;
  97. }
  98.  
  99. const bool CTsDescrambler::CloseDescrambler(void)
  100. {
  101.     // B-CASカードをクローズ
  102.     BON_SAFE_RELEASE(m_pHalBcasCard);
  103.  
  104.     return true;
  105. }
  106.  
  107. void CTsDescrambler::DiscardScramblePacket(const bool bEnable)
  108. {
  109.     // スクランブル解除漏れパケットを破棄するか設定
  110.     m_bDiscardScramblePacket = (bEnable)? true : false;
  111. }
  112.  
  113. void CTsDescrambler::EnableEmmProcess(const bool bEnable)
  114. {
  115.     // EMMを処理するか設定
  116.     m_bEnableEmmProcess = (bEnable)? true : false;
  117. }
  118.  
  119. void CTsDescrambler::EnableBuffering(const bool bEnable)
  120. {
  121.     // バッファリングするか設定
  122.     m_bEnableBuffering = (bEnable)? true : false;
  123. }
  124.  
  125. void CTsDescrambler::ResetStatistics(void)
  126. {
  127.     // 統計データをリセットする
  128.     m_dwInputPacketNum = 0UL;
  129.     m_dwOutputPacketNum = 0UL;
  130.     m_dwScramblePacketNum = 0UL;
  131.     m_dwEcmProcessNum = 0UL;
  132.     m_dwEmmProcessNum = 0UL;
  133.    
  134.     ::ZeroMemory(m_adwInputPacketNum, sizeof(m_adwInputPacketNum));
  135.     ::ZeroMemory(m_adwOutputPacketNum, sizeof(m_adwOutputPacketNum));
  136.     ::ZeroMemory(m_adwScramblePacketNum, sizeof(m_adwScramblePacketNum));
  137. }
  138.  
  139. const DWORD CTsDescrambler::GetDescramblingState(const WORD wProgramID)
  140. {
  141.     // PATテーブルを取得
  142.     const IPatTable *pPatTable = dynamic_cast<const IPatTable *>(m_TsInputMap.GetMapTarget(0x0000U));
  143.     if(!pPatTable)return IHalBcasCard::EC_BADARGUMENT;
  144.        
  145.     // 引数に一致するPMTのPIDを検索
  146.     for(WORD wIndex = 0U ; wIndex < pPatTable->GetProgramNum() ; wIndex++){
  147.         if(pPatTable->GetProgramID(wIndex) == wProgramID){
  148.            
  149.             // PMTテーブルを取得
  150.             const IPmtTable *pPmtTable = dynamic_cast<const IPmtTable *>(m_TsInputMap.GetMapTarget(pPatTable->GetPmtPID(wIndex)));
  151.             if(!pPmtTable)return IHalBcasCard::EC_BADARGUMENT;
  152.            
  153.             // ECMのPIDを取得
  154.             const IDescBlock * const pDescBlock = pPmtTable->GetPmtDesc();
  155.             if(!pDescBlock)return IHalBcasCard::EC_BADARGUMENT;
  156.    
  157.             const ICaMethodDesc * pCaMethodDesc = NULL;
  158.  
  159.             // TRMP ではない B-CAS の CA descriptor を取得
  160.             for (DWORD dwDescIndex=0;dwDescIndex<pDescBlock->GetDescNum();dwDescIndex++) {
  161.                
  162.                 pCaMethodDesc = dynamic_cast<const ICaMethodDesc *>(pDescBlock->GetDescByTag(ICaMethodDesc::DESC_TAG, dwDescIndex));
  163.                 if(!pCaMethodDesc) break;
  164.  
  165.                 const WORD wCaMethodID = pCaMethodDesc->GetCaMethodID();
  166.                 if (wCaMethodID != 0x0005) {
  167.                     // ca_system_id が B-CAS (0x0005) と不一致
  168.                     pCaMethodDesc = NULL;
  169.                     continue;
  170.                 }
  171.  
  172.                 // B-CAS (0x0005) と一致する CA descriptor が見つかった
  173.                 break;
  174.             }
  175.  
  176.             // 適合する CA Descriptor が発見できなかった
  177.             if(!pCaMethodDesc)return IHalBcasCard::EC_BADARGUMENT;
  178.            
  179.             const WORD wEcmPID = pCaMethodDesc->GetCaPID();
  180.             if(wEcmPID >= TS_INVALID_PID)return IHalBcasCard::EC_NO_ERROR;
  181.  
  182.             // ECMプロセッサを取得
  183.             const CEcmProcessor *pEcmProcessor = dynamic_cast<const CEcmProcessor *>(m_TsInputMap.GetMapTarget(pPatTable->GetPmtPID(wEcmPID)));
  184.             if(!pEcmProcessor)return IHalBcasCard::EC_BADARGUMENT;
  185.            
  186.             // 復号状態を返す
  187.             return pEcmProcessor->m_dwDescramblingState;
  188.             }      
  189.         }
  190.  
  191.     return IHalBcasCard::EC_BADARGUMENT;
  192. }
  193.  
  194. const DWORD CTsDescrambler::GetInputPacketNum(const WORD wPID)
  195. {
  196.     // 入力パケット数を返す
  197.     return (wPID < 0x2000U)? m_adwInputPacketNum[wPID] : m_dwInputPacketNum;
  198. }
  199.  
  200. const DWORD CTsDescrambler::GetOutputPacketNum(const WORD wPID)
  201. {
  202.     // 出力パケット数を返す
  203.     return (wPID < 0x2000U)? m_adwOutputPacketNum[wPID] : m_dwOutputPacketNum;
  204. }
  205.  
  206. const DWORD CTsDescrambler::GetScramblePacketNum(const WORD wPID)
  207. {
  208.     // 復号漏れパケット数を返す
  209.     return (wPID < 0x2000U)? m_adwScramblePacketNum[wPID] : m_dwScramblePacketNum;
  210. }
  211.  
  212. const DWORD CTsDescrambler::GetEcmProcessNum(void)
  213. {
  214.     // ECM処理回数を返す
  215.     return m_dwEcmProcessNum;
  216. }
  217.  
  218. const DWORD CTsDescrambler::GetEmmProcessNum(void)
  219. {
  220.     // EMM処理回数を返す
  221.     return m_dwEmmProcessNum;
  222. }
  223.  
  224. IHalBcasCard * CTsDescrambler::GetHalBcasCard(void)
  225. {
  226.     // B-CASカードリーダデバイスを返す
  227.     return m_pHalBcasCard;
  228. }
  229.  
  230. CTsDescrambler::CTsDescrambler(IBonObject *pOwner)
  231.     : CMediaDecoder(pOwner, 1UL, 1UL)
  232.     , m_TsInputMap(NULL)
  233.     , m_TsOutputMap(NULL)
  234.     , m_pHalBcasCard(NULL)
  235.     , m_bDiscardScramblePacket(false)
  236.     , m_bEnableEmmProcess(false)
  237.     , m_wLastTsID(TS_INVALID_PID)
  238.     , m_bEnableBuffering(false)
  239.     , m_DecBufState(BDS_INITIAL)
  240.     , m_dwPmtWaitCount(0UL)
  241. {
  242.     // 統計データを初期化する
  243.     ResetStatistics();
  244.  
  245.     // PATテーブルをPIDマップに追加
  246.     m_TsInputMap.MapPid(0x0000U, dynamic_cast<ITsPidMapTarget *>(CPatTable::CreateInstance(dynamic_cast<IPatTable::IHandler *>(this))));
  247.  
  248.     // CATテーブルをPIDマップに追加
  249.     m_TsInputMap.MapPid(0x0001U, dynamic_cast<ITsPidMapTarget *>(CCatTable::CreateInstance(dynamic_cast<ICatTable::IHandler *>(this))));
  250.  
  251.     // TOTテーブルをPIDマップに追加
  252.     m_TsInputMap.MapPid(0x0014U, dynamic_cast<ITsPidMapTarget *>(CTotTable::CreateInstance(dynamic_cast<ITotTable::IHandler *>(this))));
  253. }
  254.  
  255. CTsDescrambler::~CTsDescrambler(void)
  256. {
  257.     // B-CASカードクローズ
  258.     CloseDescrambler();
  259.    
  260.     // バッファ開放
  261.     ClearUnprocPacket();
  262. }
  263.  
  264. const bool CTsDescrambler::OnPlay(void)
  265. {
  266.     // 内部状態を初期化する
  267.     return OnReset();
  268. }
  269.  
  270. const bool CTsDescrambler::OnStop(void)
  271. {
  272.     // 未処理パケットをフラッシュする
  273.     FlushUnprocPacket();
  274.  
  275.     return CMediaDecoder::OnStop();
  276. }
  277.  
  278. const bool CTsDescrambler::OnReset(void)
  279. {
  280.     // PIDマップリセット
  281.     ResetPidMap();
  282.  
  283.     // TSIDリセット
  284.     m_wLastTsID = TS_INVALID_PID;
  285.  
  286.     // PATリセット
  287.     m_TsInputMap.ResetPid(0x0000U);
  288.  
  289.     // バッファリング状態リセット
  290.     m_DecBufState = BDS_INITIAL;
  291.     m_dwPmtWaitCount = 0UL;
  292.     ClearUnprocPacket();
  293.  
  294.     // 統計データリセット
  295.     ResetStatistics();
  296.  
  297.     return true;
  298. }
  299.  
  300. void CTsDescrambler::OnPatTable(const IPatTable *pPatTable)
  301. {
  302.     // TSID更新確認
  303.     if(m_bEnableBuffering && (m_wLastTsID != pPatTable->GetTsID())){
  304.         if(m_wLastTsID != TS_INVALID_PID){
  305.             // 未処理パケットをフラッシュする
  306.             FlushUnprocPacket();
  307.             m_DecBufState = BDS_INITIAL;
  308.             m_dwPmtWaitCount = 0UL;
  309.            
  310.             // PIDマップリセット
  311.             ResetPidMap();
  312.             }
  313.         m_wLastTsID = pPatTable->GetTsID();
  314.         }
  315.  
  316.     // PMTテーブルPIDマップ追加
  317.     for(WORD wIndex = 0U ; wIndex < pPatTable->GetProgramNum() ; wIndex++){
  318.         m_TsInputMap.MapPid(pPatTable->GetPmtPID(wIndex), dynamic_cast<ITsPidMapTarget *>(CPmtTable::CreateInstance(dynamic_cast<IPmtTable::IHandler *>(this))));
  319.         }
  320.  
  321.     // バッファリング状態状態更新
  322.     if(m_DecBufState == BDS_INITIAL){
  323.         m_DecBufState = BDS_STORING_PMT;
  324.         m_dwPmtWaitCount = 0UL;
  325.         }
  326. }
  327.  
  328. void CTsDescrambler::OnCatTable(const ICatTable *pCatTable)
  329. {
  330.     // EMMのPIDを取得する
  331.     const IDescBlock * const pDescBlock = pCatTable->GetCatDesc();
  332.     if(!pDescBlock)return;
  333.    
  334.     const ICaMethodDesc * pCaMethodDesc = NULL;
  335.  
  336.     // TRMP ではない B-CAS の CA descriptor を取得
  337.     for (DWORD dwDescIndex=0;dwDescIndex<pDescBlock->GetDescNum();dwDescIndex++) {
  338.                
  339.         pCaMethodDesc = dynamic_cast<const ICaMethodDesc *>(pDescBlock->GetDescByTag(ICaMethodDesc::DESC_TAG, dwDescIndex));
  340.         if(!pCaMethodDesc) break;
  341.  
  342.         const WORD wCaMethodID = pCaMethodDesc->GetCaMethodID();
  343.         if (wCaMethodID != 0x0005) {
  344.             // ca_system_id が B-CAS (0x0005) と不一致
  345.             pCaMethodDesc = NULL;
  346.             continue;
  347.         }
  348.  
  349.         // B-CAS (0x0005) と一致する CA descriptor が見つかった
  350.         break;
  351.     }
  352.    
  353.     // 適合する CA Descriptor が発見できなかった
  354.     if(!pCaMethodDesc)return;
  355.  
  356.     const WORD wEmmPID = pCaMethodDesc->GetCaPID();
  357.     if(wEmmPID >= TS_INVALID_PID)return;
  358.     // 難視観た後にch変えるとEnableB25Decoderの設定無視るバグ
  359.     if(wEmmPID == 0x0000)return;
  360.  
  361.     // EMMプロセッサをPIDマップに追加
  362.     m_TsInputMap.MapPid(wEmmPID, dynamic_cast<ITsPidMapTarget *>(CEmmProcessor::CreateInstance(dynamic_cast<ITsDescrambler *>(this))));
  363. }
  364.  
  365. void CTsDescrambler::OnPmtTable(const IPmtTable *pPmtTable)
  366. {
  367.     // ECMのPIDを取得する
  368.     const IDescBlock * const pDescBlock = pPmtTable->GetPmtDesc();
  369.     if(!pDescBlock)return;
  370.    
  371.     const ICaMethodDesc * pCaMethodDesc = NULL;
  372.  
  373.     dynamic_cast<const ICaMethodDesc *>(pDescBlock->GetDescByTag(ICaMethodDesc::DESC_TAG));
  374.     // TRMP ではない B-CAS の CA descriptor を取得
  375.     for (DWORD dwDescIndex=0;dwDescIndex<pDescBlock->GetDescNum();dwDescIndex++) {
  376.                
  377.         pCaMethodDesc = dynamic_cast<const ICaMethodDesc *>(pDescBlock->GetDescByTag(ICaMethodDesc::DESC_TAG, dwDescIndex));
  378.         if(!pCaMethodDesc) break;
  379.  
  380.         const WORD wCaMethodID = pCaMethodDesc->GetCaMethodID();
  381.         if (wCaMethodID != 0x0005) {
  382.             // ca_system_id が B-CAS (0x0005) と不一致
  383.             pCaMethodDesc = NULL;
  384.             continue;
  385.         }
  386.  
  387.         // B-CAS (0x0005) と一致する CA descriptor が見つかった
  388.         break;
  389.     }
  390.    
  391.     // 適合する CA Descriptor が発見できなかった
  392.     if(!pCaMethodDesc)return;
  393.  
  394.     const WORD wEcmPID = pCaMethodDesc->GetCaPID();
  395.     if(wEcmPID >= TS_INVALID_PID)return;
  396.  
  397.     // 既存のECMプロセッサを確認
  398.     if(!dynamic_cast<CEcmProcessor *>(m_TsInputMap.GetMapTarget(wEcmPID))){
  399.         // ECMプロセッサをPIDマップに追加
  400.         m_TsInputMap.MapPid(wEcmPID, dynamic_cast<ITsPidMapTarget *>(CEcmProcessor::CreateInstance(dynamic_cast<ITsDescrambler *>(this))));
  401.         }
  402.  
  403.     // ESプロセッサをPIDマップに追加
  404.     for(WORD wIndex = 0U ; wIndex < pPmtTable->GetEsNum() ; wIndex++){
  405.         m_TsOutputMap.MapPid(pPmtTable->GetEsPID(wIndex), dynamic_cast<ITsPidMapTarget *>(CEsProcessor::CreateInstance(m_TsInputMap.GetMapTarget(wEcmPID))));
  406.         }
  407. }
  408.  
  409. void CTsDescrambler::OnTotTable(const ITotTable *pTotTable)
  410. {
  411.     // 何もしない
  412. }
  413.  
  414. void CTsDescrambler::InputPacket(ITsPacket * const pPacket)
  415. {
  416.     // PIDマップに入力
  417.     if(m_pHalBcasCard)m_TsInputMap.StorePacket(pPacket);
  418.  
  419.     // 入力パケット数インクリメント
  420.     CLIPED_INCREMENT(m_dwInputPacketNum);
  421.     CLIPED_INCREMENT(m_adwInputPacketNum[pPacket->GetPID()]);
  422. }
  423.  
  424. void CTsDescrambler::BufManagement(ITsPacket * const pPacket)
  425. {
  426.     if(m_PacketBuf.size() >= ECM_WAIT_PACKET_COUNT){
  427.         // バッファリングリミット超過
  428.         FlushUnprocPacket();
  429.         m_DecBufState = BDS_RUNNING;
  430.         }
  431.     else if(m_DecBufState == BDS_STORING_PMT){
  432.         // PMT待ちカウンタインクリメント
  433.         if(++m_dwPmtWaitCount >= PMT_WAIT_PACKET_COUNT){
  434.             m_DecBufState = BDS_STORING_ECM;
  435.             }
  436.         }
  437.     else if(m_DecBufState == BDS_STORING_ECM){
  438.         // ECMストア状態モニタ
  439.         if(dynamic_cast<CEcmProcessor *>(m_TsInputMap.GetMapTarget(pPacket->GetPID()))){
  440.             bool bNotStored = false;
  441.        
  442.             for(WORD wPID = 0x0000U ; wPID < 0x2000U ; wPID++){
  443.                 const CEcmProcessor *pEcmProcessor = dynamic_cast<CEcmProcessor *>(m_TsInputMap.GetMapTarget(wPID));
  444.                 if(pEcmProcessor){
  445.                     if(!pEcmProcessor->IsEcmReceived()){
  446.                         // ECM未受信
  447.                         bNotStored = true;
  448.                         }
  449.                     }
  450.                 }
  451.  
  452.             if(!bNotStored){
  453.                 m_DecBufState = BDS_RUNNING;
  454.            
  455.                 // 未処理パケット出力
  456.                 FlushUnprocPacket();
  457.                 }
  458.             }
  459.         }
  460. }
  461.  
  462. void CTsDescrambler::OutputPacket(ITsPacket * const pPacket)
  463. {
  464.     const WORD wPID = pPacket->GetPID();
  465.  
  466.     // ESプロセッサに入力
  467.     m_TsOutputMap.StorePacket(pPacket);
  468.  
  469.     if(pPacket->IsScrambled()){
  470.         // 復号漏れパケット数インクリメント
  471.         CLIPED_INCREMENT(m_dwScramblePacketNum);
  472.         CLIPED_INCREMENT(m_adwScramblePacketNum[wPID]);
  473.  
  474.         SendDecoderEvent(EID_CANT_DESCRAMBLE, reinterpret_cast<PVOID>(m_dwScramblePacketNum));
  475.        
  476.         // 復号漏れパケット破棄有効時は下位デコーダに出力しない
  477.         if(m_bDiscardScramblePacket)return;
  478.         }
  479.  
  480.     // 出力パケット数インクリメント
  481.     CLIPED_INCREMENT(m_dwOutputPacketNum);
  482.     CLIPED_INCREMENT(m_adwOutputPacketNum[wPID]);
  483.  
  484.     // 下位デコーダにデータ出力
  485.     OutputMedia(dynamic_cast<IMediaData *>(pPacket));
  486. }
  487.  
  488. void CTsDescrambler::ResetPidMap(void)
  489. {
  490.     // PAT/CAT/TOT以外アンマップ
  491.     for(WORD wPID = 0x0002U ; wPID < 0x2000U ; wPID++){
  492.         if(wPID != 0x0014U){
  493.             m_TsInputMap.UnmapPid(wPID);
  494.             }  
  495.         }
  496.  
  497.     // CATリセット
  498.     m_TsInputMap.ResetPid(0x0001U);
  499.  
  500.     // TOTリセット
  501.     m_TsInputMap.ResetPid(0x0014U);
  502.    
  503.     // ESプロセッサリセット
  504.     m_TsOutputMap.ClearPid();
  505. }
  506.  
  507. void CTsDescrambler::FlushUnprocPacket(void)
  508. {
  509.     // 未処理パケットをフラッシュする
  510.     for(DWORD dwIndex = 0UL ; dwIndex < m_PacketBuf.size() ; dwIndex++){
  511.         OutputPacket(m_PacketBuf[dwIndex]);
  512.         }
  513.  
  514.     // バッファをクリア
  515.     ClearUnprocPacket();
  516. }
  517.  
  518. void CTsDescrambler::PushUnprocPacket(const ITsPacket *pPacket)
  519. {
  520.     // 未処理パケットをバッファにプッシュする
  521.     CTsPacket * const pNewPacket = new CTsPacket(NULL);
  522.     ::BON_ASSERT(pNewPacket);
  523.  
  524.     if(pNewPacket->CopyPacket(pPacket)){   
  525.         m_PacketBuf.push_back(pNewPacket);
  526.         }
  527. }
  528.  
  529. void CTsDescrambler::ClearUnprocPacket(void)
  530. {
  531.     // 未処理パケットをクリア
  532.     for(DWORD dwIndex = 0UL ; dwIndex < m_PacketBuf.size() ; dwIndex++){
  533.         BON_SAFE_RELEASE(m_PacketBuf[dwIndex]);
  534.         }
  535.    
  536.     m_PacketBuf.clear();
  537. }
  538.  
  539.  
  540. /////////////////////////////////////////////////////////////////////////////
  541. // ECM処理内部クラス
  542. /////////////////////////////////////////////////////////////////////////////
  543.  
  544. void CTsDescrambler::CEcmProcessor::OnPidReset(ITsPidMapper *pTsPidMapper, const WORD wPID)
  545. {
  546.     // キークリアする(誤ったキーによる破損を防止するため)
  547.     m_Multi2Decoder.SetScrambleKey(NULL);
  548.     m_dwDescramblingState = IHalBcasCard::EC_NO_ERROR;
  549.    
  550.     CPsiTableBase::OnPidReset(pTsPidMapper, wPID);
  551. }
  552.  
  553. void CTsDescrambler::CEcmProcessor::Reset(void)
  554. {
  555.     m_bIsEcmReceived = false;
  556.    
  557.     CPsiTableBase::Reset();
  558. }
  559.  
  560. CTsDescrambler::CEcmProcessor::CEcmProcessor(IBonObject *pOwner)
  561.     : CPsiTableBase(NULL)
  562.     , m_pTsDescrambler(dynamic_cast<CTsDescrambler *>(pOwner))
  563.     , m_pHalBcasCard(m_pTsDescrambler->m_pHalBcasCard)
  564.     , m_dwLastRetryTime(::GetTickCount() - BCAS_REFRESH_INTERVAL)
  565.     , m_dwDescramblingState(IHalBcasCard::EC_NO_ERROR)
  566. {
  567.     // MULTI2デコーダを初期化
  568.     m_Multi2Decoder.Initialize(m_pHalBcasCard->GetSystemKey(), m_pHalBcasCard->GetInitialCbc());
  569. }
  570.  
  571. CTsDescrambler::CEcmProcessor::~CEcmProcessor(void)
  572. {
  573.     // このインスタンスを参照しているCEsProcessorをアンマップする
  574.     CEsProcessor *pEsProcessor;
  575.    
  576.     for(WORD wPID = 0x0000U ; wPID < 0x2000U ; wPID++){
  577.         if(pEsProcessor = dynamic_cast<CEsProcessor *>(m_pTsDescrambler->m_TsOutputMap.GetMapTarget(wPID))){
  578.             if(pEsProcessor->m_pEcmProcessor == this){
  579.                 m_pTsDescrambler->m_TsOutputMap.UnmapPid(wPID);
  580.                 }
  581.             }
  582.         }
  583. }
  584.  
  585. const bool CTsDescrambler::CEcmProcessor::IsEcmReceived(void) const
  586. {
  587.     // ECMの受信有無を返す
  588.     return m_bIsEcmReceived;
  589. }
  590.  
  591. const bool CTsDescrambler::CEcmProcessor::DescramblePacket(ITsPacket * const pTsPacket)
  592. {
  593.     // IMediaDataインタフェース問い合わせ
  594.     IMediaData *pMediaData = dynamic_cast<IMediaData *>(pTsPacket);
  595.  
  596.     // スクランブル解除
  597.     if(pMediaData){
  598.         if(m_Multi2Decoder.Decode(pTsPacket->GetPayloadData(), (DWORD)pTsPacket->GetPayloadSize(), pTsPacket->m_Header.byTransportScramblingCtrl)){
  599.             // トランスポートスクランブル制御再設定
  600.             pMediaData->SetAt(3UL, pMediaData->GetAt(3UL) & 0x3FU);
  601.             pTsPacket->m_Header.byTransportScramblingCtrl = 0U;
  602.  
  603.             return true;
  604.             }
  605.         }
  606.    
  607.     return false;
  608. }
  609.  
  610. const bool CTsDescrambler::CEcmProcessor::OnTableUpdate(const IPsiSection *pNewSection, const IPsiSection *pLastSection)
  611. {
  612.     // テーブルIDをチェック
  613.     if(pNewSection->GetTableID() != TABLE_ID)return false;
  614.  
  615.     // ECMをB-CASカードに渡してキー取得
  616.     const BYTE *pKsData = m_pHalBcasCard->GetKsFromEcm(pNewSection->GetPayloadData(), pNewSection->GetPayloadSize());
  617.  
  618.     // ECM処理失敗時は一度だけB-CASカードを再初期化する
  619.     if(!pKsData && (m_pHalBcasCard->GetEcmError() != IHalBcasCard::EC_NOT_CONTRACTED)){
  620.         if((::GetTickCount() - m_dwLastRetryTime) >= BCAS_REFRESH_INTERVAL){
  621.             // 再初期化ガードインターバル経過なら         
  622.             if(m_pHalBcasCard->OpenCard()){
  623.                 pKsData = m_pHalBcasCard->GetKsFromEcm(pNewSection->GetPayloadData(), pNewSection->GetPayloadSize());
  624.                 }
  625.                
  626.             // 最終リトライ時間更新
  627.             m_dwLastRetryTime = ::GetTickCount();
  628.             }
  629.         }
  630.  
  631.     // スクランブルキー更新
  632.     m_Multi2Decoder.SetScrambleKey(pKsData);
  633.  
  634.     // イベント通知
  635.     if(pKsData)CLIPED_INCREMENT(m_pTsDescrambler->m_dwEcmProcessNum);
  636.     m_pTsDescrambler->SendDecoderEvent(EID_ECM_PROCESSED, reinterpret_cast<PVOID>(m_pHalBcasCard->GetEcmError()));
  637.  
  638.     // 復号状態更新
  639.     m_dwDescramblingState = m_pHalBcasCard->GetEcmError();
  640.     m_bIsEcmReceived = true;
  641.  
  642.     return true;
  643. }
  644.  
  645.  
  646. /////////////////////////////////////////////////////////////////////////////
  647. // EMM処理内部クラス
  648. /////////////////////////////////////////////////////////////////////////////
  649.  
  650. CTsDescrambler::CEmmProcessor::CEmmProcessor(IBonObject *pOwner)
  651.     : CPsiTableBase(NULL)
  652.     , m_pTsDescrambler(dynamic_cast<CTsDescrambler *>(pOwner))
  653.     , m_pHalBcasCard(m_pTsDescrambler->m_pHalBcasCard)
  654. {
  655.     // 何もしない
  656. }
  657.  
  658. CTsDescrambler::CEmmProcessor::~CEmmProcessor(void)
  659. {
  660.     // 何もしない
  661. }
  662.  
  663. const bool CTsDescrambler::CEmmProcessor::OnTableUpdate(const IPsiSection *pNewSection, const IPsiSection *pLastSection)
  664. {
  665.     // テーブルIDをチェック
  666.     if(pNewSection->GetTableID() != SECTION_TABLE_ID)return false;
  667.  
  668.     // EMM処理が無効のときは何もしない
  669.     if(!m_pTsDescrambler->m_bEnableEmmProcess)return true;
  670.  
  671.     // セクションを解析
  672.     const WORD wDataSize = pNewSection->GetPayloadSize();
  673.     const BYTE *pHexData = pNewSection->GetPayloadData();
  674.    
  675.     WORD wPos = 0U;
  676.    
  677.     while((wDataSize - wPos) >= 17U){
  678.         // EMMサイズをチェック
  679.         const WORD wEmmSize = (WORD)pHexData[wPos + 6U] + 7U;
  680.         if(((wDataSize - wPos) < wEmmSize) || (wEmmSize < 17U))break;
  681.  
  682.         // ハンドラ呼び出し
  683.         if(OnEmmBody(&pHexData[wPos], wEmmSize))break;
  684.        
  685.         // 解析位置更新
  686.         wPos += wEmmSize;
  687.         }
  688.  
  689.     return true;
  690. }
  691.  
  692. const bool CTsDescrambler::CEmmProcessor::OnEmmBody(const BYTE *pEmmData, const WORD wEmmSize)
  693. {
  694.     // 自B-CASカードID取得
  695.     const BYTE * const pCardID = m_pHalBcasCard->GetBcasCardID();
  696.  
  697.     // 自B-CASカードIDと照合
  698.     for(DWORD dwPos = 0UL ; dwPos < 6UL ; dwPos++){
  699.         if(pCardID[dwPos] != pEmmData[dwPos])return false;
  700.         }
  701.  
  702.     // ストリームの時間を確認する
  703.     CTsTime ValidTime;
  704.     ValidTime.SetNowTime();                                 // 現在時刻を取得
  705.     ValidTime -= EMM_VALID_PERIOD * 24UL * 60UL * 60UL;     // 有効期間だけ過去に戻す
  706.    
  707.     const ITotTable *pTotTable = dynamic_cast<const ITotTable *>(m_pTsDescrambler->m_TsInputMap.GetMapTarget(0x0014U));
  708.     if(!pTotTable)return true;
  709.     CTsTime EmmTime = pTotTable->GetDateTime();             // TOTから時刻を取得
  710.    
  711.     // 有効期間より過去のEMMデータは処理しない
  712.     if(EmmTime < ValidTime)return true;
  713.    
  714.     // B-CASカードにEMMデータ送信
  715.     if(!m_pHalBcasCard->SendEmmSection(pEmmData, wEmmSize)){
  716.         // リトライ
  717.         if(!m_pHalBcasCard->SendEmmSection(pEmmData, wEmmSize)){
  718.             // EMM処理失敗
  719.             m_pTsDescrambler->SendDecoderEvent(EID_EMM_PROCESSED, reinterpret_cast<PVOID>(false));
  720.             return true;
  721.             }
  722.         }
  723.  
  724.     // イベント通知
  725.     CLIPED_INCREMENT(m_pTsDescrambler->m_dwEmmProcessNum);
  726.     m_pTsDescrambler->SendDecoderEvent(EID_EMM_PROCESSED, reinterpret_cast<PVOID>(true));
  727.  
  728.     return true;
  729. }
  730.  
  731.  
  732. /////////////////////////////////////////////////////////////////////////////
  733. // ES処理内部クラス
  734. /////////////////////////////////////////////////////////////////////////////
  735.  
  736. CTsDescrambler::CEsProcessor::CEsProcessor(IBonObject *pOwner)
  737.     : CBonObject(NULL)
  738.     , m_pEcmProcessor(dynamic_cast<CEcmProcessor *>(pOwner))
  739. {
  740.     // 何もしない
  741. }
  742.  
  743. CTsDescrambler::CEsProcessor::~CEsProcessor(void)
  744. {
  745.     // 何もしない
  746. }
  747.  
  748. const bool CTsDescrambler::CEsProcessor::StorePacket(const ITsPacket *pTsPacket)
  749. {
  750.     // スクランブル解除
  751.     return m_pEcmProcessor->DescramblePacket(const_cast<ITsPacket *>(pTsPacket));
  752. }
  753.  
  754. void CTsDescrambler::CEsProcessor::OnPidReset(ITsPidMapper *pTsPidMapper, const WORD wPID)
  755. {
  756.     // 何もしない
  757. }
  758.  
  759. void CTsDescrambler::CEsProcessor::OnPidMapped(ITsPidMapper *pTsPidMapper, const WORD wPID)
  760. {
  761.     // 何もしない
  762. }
  763.  
  764. void CTsDescrambler::CEsProcessor::OnPidUnmapped(ITsPidMapper *pTsPidMapper, const WORD wPID)
  765. {
  766.     // インスタンス開放
  767.     Release();
  768. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement