///<summary> /// WinTV CI control ///</summary> ///<param name="winTvUsbCIFilter">WinTV CI filter</param> public WinTvCiModule(IBaseFilter winTvUsbCIFilter) { _winTvUsbCIFilter = winTvUsbCIFilter; cbOnAPDU = OnAPDU; cbOnStatus = OnStatus; cbOnCamInfo = OnCamInfo; cbOnCloseMMI = OnMMIClosed; MMI = new DVB_MMI_Handler("WinTvCI"); // callbacks are set on first access }
///<summary> /// WinTV CI control ///</summary> ///<param name="winTvUsbCIFilter">WinTV CI filter</param> public WinTvCiModule(IBaseFilter winTvUsbCIFilter) { _winTvUsbCIFilter = winTvUsbCIFilter; cbOnAPDU = OnAPDU; cbOnStatus = OnStatus; cbOnCamInfo = OnCamInfo; cbOnCloseMMI = OnMMIClosed; MMI = new DVB_MMI_Handler("WinTvCI"); // callbacks are set on first access }
/// <summary> /// Thread that checks for CI menu /// </summary> private void CiMenuHandler() { Log.Log.Debug("FireDTV: CI handler thread start polling status"); int bytesReturned; int hr; DVB_MMI_Handler MMI = new DVB_MMI_Handler("FireDTV", ref m_ciMenuCallback); DE_CI_STATUS CiStatus; // Init CiStatus word to 0 Marshal.WriteInt16(_ptrDataCiHandler, 0); IKsPropertySet propertySet = _filterTuner as IKsPropertySet; if (propertySet == null) { Log.Log.Debug("FireDTV:CiMenuHandler() properySet=null"); return; } while (!StopThread) { try { // this code is equal to GetCAMStatus, but implemented separately to avoid memory / threading conflicts with used pointers! hr = propertySet.Get(KSPROPSETID_Firesat, KSPROPERTY_FIRESAT_GET_CI_STATUS, _ptrDataCiHandler, CA_DATA_SIZE, _ptrDataCiHandler, CA_DATA_SIZE, out bytesReturned); if (hr != 0) { Log.Log.Debug("FireDTV: error reading CI state."); } else { CiStatus = (DE_CI_STATUS)Marshal.ReadInt16(_ptrDataCiHandler); #if DEBUG Log.Log.Debug("FireDTV: CI iStatus:{0}", CiStatus); #endif if ((CiStatus & DE_CI_STATUS.CI_MMI_REQUEST) != 0) { Log.Log.Debug("FireDTV: CI menu object available!"); // Get the MMI object FIRESAT_CA_DATA caData = GET_FIRESAT_CA_DATA(5 /*CA_MMI*/, 0); Marshal.StructureToPtr(caData, _ptrDataInstance, true); Marshal.StructureToPtr(caData, _ptrDataCiHandler, true); hr = propertySet.Set(KSPROPSETID_Firesat, KSPROPERTY_FIRESAT_CA2HOST, _ptrDataInstance, CA_DATA_SIZE, _ptrDataCiHandler, CA_DATA_SIZE); if (hr != 0) { Log.Log.Debug("FireDTV: unable to set \"CA_MMI\""); } hr = propertySet.Get(KSPROPSETID_Firesat, KSPROPERTY_FIRESAT_CA2HOST, _ptrDataInstance, CA_DATA_SIZE, _ptrDataCiHandler, CA_DATA_SIZE, out bytesReturned); if (hr != 0) { Log.Log.Debug("FireDTV: unable to get \"CA_MMI\": hr {0:X}", hr); } else { // cast ptr back to struct and handle it in c# FIRESAT_CA_DATA caDataReturned = (FIRESAT_CA_DATA)Marshal.PtrToStructure(_ptrDataCiHandler, typeof (FIRESAT_CA_DATA)); Int32 caDataLength = caDataReturned.uLength2 << 8 | caDataReturned.uLength1; MMI.HandleMMI(caDataReturned.uData, caDataLength); } } } Thread.Sleep(500); } catch (ThreadAbortException) {} catch (Exception ex) { Log.Log.Debug("FireDTV: error in CiMenuHandler thread\r\n{0}", ex.ToString()); return; } } }