Exemple #1
0
        /// <summary>
        /// Sends the DiSEqC command.
        /// </summary>
        /// <param name="diSEqC">The DiSEqC command.</param>
        /// <returns>true if succeeded, otherwise false</returns>
        public bool SendDiSEqCCommand(byte[] diSEqC)
        {
            const int disEqcLen = 16;

            for (int i = 0; i < 12; ++i)
            {
                Marshal.WriteByte(_ptrDiseqc, 4 + i, 0);
            }
            Marshal.WriteInt32(_ptrDiseqc, 0, diSEqC.Length); //command len
            for (int i = 0; i < diSEqC.Length; ++i)
            {
                Marshal.WriteByte(_ptrDiseqc, 4 + i, diSEqC[i]);
            }

            DVB_MMI.DumpBinary(_ptrDiseqc, 0, disEqcLen);
            InitStructure((int)THBDA_IOCTL_SET_DiSEqC, _ptrDiseqc, disEqcLen, IntPtr.Zero, 0);
            bool success = false;

            if (propertySet != null)
            {
                int hr = propertySet.Set(THBDA_TUNER, 0, _ptrOutBuffer2, 0x18, _thbdaBuf, thbdaLen);
                if (hr != 0)
                {
                    Log.Log.WriteFile("TwinHan DiSEqC failed 0x{1:X8}", hr);
                }
                else
                {
                    Log.Log.WriteFile("TwinHan DiSEqC succeeded");
                    success = true;
                }
                //Release.ComObject(propertySet);
            }
            return(success);
        }
Exemple #2
0
 /// <summary>
 /// Gets the answer from the CAM after sending the PMT .
 /// </summary>
 /// <returns>string containing the CAM answer</returns>
 public string GetPmtReply()
 {
     if (IsCamPresent() == false)
     {
         return("");
     }
     for (int i = 0; i < 1024; ++i)
     {
         Marshal.WriteByte(_ptrPmt, i, 0);
     }
     InitStructure((int)THBDA_IOCTL_CI_GET_PMT_REPLY, IntPtr.Zero, 0, _ptrPmt, 1024);
     if (propertySet != null)
     {
         int hr   = propertySet.Set(THBDA_TUNER, 0, _ptrOutBuffer2, 0x18, _thbdaBuf, thbdaLen);
         int back = Marshal.ReadInt32(_ptrDwBytesReturned);
         if (hr != 0)
         {
             Log.Log.WriteFile("Twinhan:  GetPmtReply() failed 0x{0:X}", hr);
         }
         Log.Log.WriteFile("Twinhan:  GetPmtReply() returned {0} bytes", back);
         DVB_MMI.DumpBinary(_ptrPmt, 0, back);
         //Release.ComObject(propertySet);
     }
     return("");
 }
 /// <summary>
 /// Selects a CI menu entry
 /// </summary>
 /// <param name="choice"></param>
 /// <returns></returns>
 public bool SelectMenu(byte choice)
 {
     Log.Log.Debug("WinTvCi: Select CI Menu entry {0}", choice);
     byte[] uData = new byte[5];    // default answer length
     DVB_MMI.CreateMMISelect(choice, ref uData);
     SendAPDU(uData, uData.Length); // send to cam
     return(true);
 }
 /// <summary>
 /// Closes the CI menu of KNC1 card
 /// </summary>
 /// <returns></returns>
 public bool CloseCIMenu()
 {
     Log.Log.Debug("WinTvCi: Close CI Menu");
     byte[] uData = new byte[5];    // default answer length
     DVB_MMI.CreateMMIClose(ref uData);
     SendAPDU(uData, uData.Length); // send to cam
     return(true);
 }
Exemple #5
0
        /// <summary>
        /// Sends the PMT to the CAM/CI module
        /// </summary>
        /// <param name="caPMT">The caPMT structure.</param>
        /// <param name="caPMTLen">The caPMT lenght</param>
        /// <returns>false on failure to send PMT</returns>
        public bool SendPMT(byte[] caPMT, int caPMTLen)
        {
            if (IsCamPresent() == false)
            {
                return(true); // Nothing to do
            }
            Log.Log.WriteFile("Twinhan: Send PMT, len: {0}", caPMTLen);
            if (caPMT.Length == 0)
            {
                return(false);
            }

            Log.Log.WriteFile(" capmt:");
            DVB_MMI.DumpBinary(caPMT, 0, caPMTLen);


            bool suceeded = false;

            Marshal.Copy(caPMT, 0, _ptrPmt, caPMTLen);

            InitStructure((int)THBDA_IOCTL_CI_SEND_PMT, _ptrPmt, caPMTLen, IntPtr.Zero, 0);
            if (propertySet != null)
            {
                int failedAttempts = 0;
                while (true)
                {
                    int hr = propertySet.Set(THBDA_TUNER, 0, _ptrOutBuffer2, 0x18, _thbdaBuf, thbdaLen);
                    if (hr != 0)
                    {
                        failedAttempts++;
                        Log.Log.WriteFile("Twinhan:  CAM failed 0x{0:X}", hr);
                        if (((uint)hr) == (0x8007001F) && failedAttempts < 10)
                        {
                            Log.Log.Debug(" sleep and then retry again, failedAttempts: {0}", failedAttempts);
                            System.Threading.Thread.Sleep(100);
                            continue;
                        }
                    }
                    else
                    {
                        Log.Log.WriteFile("Twinhan:  CAM returned ok 0x{0:X}", hr);
                        suceeded = true;
                    }
                    break;
                }
                //Release.ComObject(propertySet);
            }
            return(suceeded);
        }
        /// <summary>
        /// Sends an answer after CI request
        /// </summary>
        /// <param name="Cancel"></param>
        /// <param name="Answer"></param>
        /// <returns></returns>
        public bool SendMenuAnswer(bool Cancel, String Answer)
        {
            if (Answer == null)
            {
                Answer = "";
            }
            Log.Log.Debug("WinTvCi: Send Menu Answer: {0}, Cancel: {1}", Answer, Cancel);
            byte[] uData    = new byte[1024];
            byte   uLength1 = 0;
            byte   uLength2 = 0;

            DVB_MMI.CreateMMIAnswer(Cancel, Answer, ref uData, ref uLength1, ref uLength2);
            SendAPDU(uData, uLength1); // send to cam
            return(true);
        }
Exemple #7
0
        /// <summary>
        /// Sends a diseqc command and reads a reply
        /// </summary>
        /// <param name="reply">The reply.</param>
        /// <returns>true if succeeded, otherwise false</returns>
        public bool ReadDiSEqCCommand(out byte[] reply)
        {
            reply    = new byte[1];
            reply[0] = 0;
            const int disEqcLen = 16;

            for (int i = 0; i < 16; ++i)
            {
                Marshal.WriteByte(_ptrDiseqc, i, 0);
            }

            bool success = false;

            InitStructure((int)THBDA_IOCTL_GET_DiSEqC, IntPtr.Zero, 0, _ptrDiseqc, disEqcLen);
            if (propertySet != null)
            {
                int hr = propertySet.Set(THBDA_TUNER, 0, _ptrOutBuffer2, 0x18, _thbdaBuf, thbdaLen);
                if (hr != 0)
                {
                    Log.Log.WriteFile("TwinHan get DiSEqC failed 0x{0:X}", hr);
                }
                else
                {
                    Log.Log.WriteFile("TwinHan get DiSEqC ok 0x{0:X}", hr);
                }
                Log.Log.Write("ReadDiSEqCCommand");
                DVB_MMI.DumpBinary(_ptrDiseqc, 0, 16);

                success = true;
                int bytesReturned = Marshal.ReadInt32(_ptrDiseqc);
                if (bytesReturned > 0)
                {
                    reply = new byte[bytesReturned];
                    for (int i = 0; i < bytesReturned; ++i)
                    {
                        reply[i] = Marshal.ReadByte(_ptrDiseqc, 4 + i);
                    }
                }
                //Release.ComObject(propertySet);
            }
            return(success);
        }
        /// <summary>
        /// On APDU callback
        /// </summary>
        /// <param name="pUSBCIFilter">CI filter</param>
        /// <param name="APDU">APDU</param>
        /// <param name="SizeOfAPDU">Size of APDU</param>
        /// <returns></returns>
        public Int32 OnAPDU(IBaseFilter pUSBCIFilter, IntPtr APDU, long SizeOfAPDU)
        {
            Int32 MMI_length = (Int32)SizeOfAPDU;

            Log.Log.Info("WinTvCi OnAPDU: SizeOfAPDU={0}", MMI_length);
            byte[] bMMI = DVB_MMI.IntPtrToByteArray(APDU, 0, MMI_length);
#if DEBUG
            DVB_MMI.DumpBinary(bMMI, 0, MMI_length);
#endif
            try
            {
                MMI.HandleMMI(bMMI, MMI_length);
            }
            catch (Exception e)
            {
                Log.Log.Write("WinTvCI error:");
                Log.Log.Write(e);
            }
            return(0);
        }
Exemple #9
0
        /// <summary>
        /// Sends a MMI object with answer back
        /// </summary>
        /// <param name="MMI"></param>
        /// <returns></returns>
        private bool SendMMI(MMIInfoStruct MMI)
        {
            Marshal.StructureToPtr(MMI, _ptrMMIBuffer, true);
            int sizeMMI = Marshal.SizeOf(MMI);

            Log.Log.Debug("SendMMI: size {0}", sizeMMI);
            DVB_MMI.DumpBinary(_ptrMMIBuffer, 0, sizeMMI);
            InitStructure((int)THBDA_IOCTL_CI_ANSWER, IntPtr.Zero, 0, _ptrMMIBuffer, sizeMMI);
            if (propertySet != null)
            {
                int hr = propertySet.Set(THBDA_TUNER, 0, _ptrOutBuffer2, 0x18, _thbdaBuf, thbdaLen);
                if (hr == 0)
                {
                    Log.Log.Debug("TwinHan: SendMMI successful");
                    return(true);
                }

                Log.Log.Debug("TwinHan: SendMMI failed 0x{0:X}", hr);
            }
            return(false);
        }
Exemple #10
0
        /// <summary>
        /// Reads a MMI object
        /// </summary>
        /// <returns></returns>
        private MMIInfoStruct ReadMMI()
        {
            Int32         bytesReturned;
            MMIInfoStruct MMI;

            // clear buffer first
            for (int i = 0; i < 8192; i += 4)
            {
                Marshal.WriteInt32(_ptrMMIBuffer, i, 0);
            }
            InitStructure((int)THBDA_IOCTL_CI_GET_MMI, IntPtr.Zero, 0, _ptrMMIBuffer, 8192);
            if (propertySet != null)
            {
                int hr = propertySet.Set(THBDA_TUNER, 0, _ptrOutBuffer2, 0x18, _thbdaBuf, thbdaLen);
                if (hr == 0)
                {
                    bytesReturned = Marshal.ReadInt32(_ptrDwBytesReturned);
                    Log.Log.Debug("TwinHan: ReadMMI successful, bytes {0}", bytesReturned);
                    DVB_MMI.DumpBinary(_ptrMMIBuffer, 0, bytesReturned);
                    try
                    {
                        MMI = (MMIInfoStruct)Marshal.PtrToStructure(_ptrMMIBuffer, typeof(MMIInfoStruct));
                    }
                    catch (Exception e)
                    {
                        Log.Log.Write(e);
                        return(null);
                    }

                    return(MMI);
                }

                Log.Log.Debug("TwinHan: ReadMMI failed 0x{0:X}", hr);
            }
            return(null);
        }
Exemple #11
0
        /// <summary>
        /// Handles APDU (MMI) objects and perform callbacks
        /// </summary>
        /// <param name="MMI">MMI byte[]</param>
        /// <param name="MMI_length">length</param>
        public void HandleMMI(byte[] MMI, int MMI_length)
        {
            // parse starting 3 bytes == tag
            DVB_MMI.MMI_TAGS uMMITag = DVB_MMI.ToMMITag(MMI, 0);

            // dumping binary APDU
#if DEBUG
            DVB_MMI.DumpBinary(MMI, 0, MMI_length);
#endif

            // calculate length and offset
            int countLengthBytes;
            int mmiLength = DVB_MMI.GetLength(MMI, 3 /* bytes for mmi_tag */, out countLengthBytes);
            int mmiOffset = 3 + countLengthBytes; // 3 bytes mmi tag + 1 byte length field ?

#if DEBUG
            Log.Log.Debug("{0}: MMITag:{1}, MMIObjectLength: {2} ({2:X2}), mmiOffset: {3}", m_cardName, uMMITag, mmiLength,
                          mmiOffset);
#endif
            int offset = 0; // starting with 0; reading whole struct from start
            if (uMMITag == DVB_MMI.MMI_TAGS.CLOSE)
            {
                // Close menu
                byte nDelay   = 0;
                byte CloseCmd = MMI[mmiOffset + 0];
                if (CloseCmd != 0)
                {
                    nDelay = MMI[mmiOffset + 1];
                }
                if (m_ciMenuCallback != null)
                {
                    Log.Log.Debug("{0}: OnCiClose()", m_cardName);
                    m_ciMenuCallback.OnCiCloseDisplay(nDelay);
                }
                else
                {
                    Log.Log.Debug("{0}: OnCiCloseDisplay: cannot do callback!", m_cardName);
                }
            }
            if (uMMITag == DVB_MMI.MMI_TAGS.ENQUIRY)
            {
                // request input
                bool   bPasswordMode      = false;
                byte   answer_text_length = MMI[mmiOffset + 1];
                string strText            = "";

                if ((MMI[mmiOffset + 0] & 0x01) != 0)
                {
                    bPasswordMode = true;
                }

                // mmioffset +4 because there a 2 other bytes before text starts
                // length is these 2 bytes shorter
                strText = DVB_MMI.BytesToString(MMI, mmiOffset + 4, mmiLength - mmiOffset - 2);
                if (m_ciMenuCallback != null)
                {
                    Log.Log.Debug("{0}: OnCiRequest: bPasswordMode:{1}, answer_text_length:{2}, strText:{3}", m_cardName,
                                  bPasswordMode, answer_text_length, strText);
                    m_ciMenuCallback.OnCiRequest(bPasswordMode, answer_text_length, strText);
                }
                else
                {
                    Log.Log.Debug("{0}: OnCiRequest: cannot do callback!", m_cardName);
                }
            }
            if (uMMITag == DVB_MMI.MMI_TAGS.LIST_LAST || uMMITag == DVB_MMI.MMI_TAGS.MENU_LAST ||
                uMMITag == DVB_MMI.MMI_TAGS.MENU_MORE || uMMITag == DVB_MMI.MMI_TAGS.LIST_MORE)
            {
                // step forward; begin with offset+1; stop when 0x9F reached
                // should be modified to offset + mmioffset+1 ?
                offset++;
                while (MMI[offset] != (byte)0x9F)
                {
                    //Log.Log.Debug("Skip to offset {0} value {1:X2}", offset, MMI[offset]);
                    offset++;
                }
                uMMITag = DVB_MMI.ToMMITag(MMI, offset); // get next MMI tag
                Log.Log.Debug("{0}: MMI Parse: Got MENU_LAST, skipped to next block on index: {1}; new Tag {2}", m_cardName,
                              offset, uMMITag);

                int           nChoices = 0;
                List <string> Choices  = new List <string>();
                // Always three line with menu info (DVB Standard)
                // Title Text
                offset += DVB_MMI.GetCIText(MMI, offset, ref Choices);
                // Subtitle Text
                offset += DVB_MMI.GetCIText(MMI, offset, ref Choices);
                // Bottom Text
                offset += DVB_MMI.GetCIText(MMI, offset, ref Choices);

                // first step through the choices, to get info and count them
                int max = 20;
                while (max-- > 0)
                {
                    // if the offset gets to mmi object length then end here
                    if (offset >= mmiLength - 1)
                    {
                        break;
                    }

                    offset += DVB_MMI.GetCIText(MMI, offset, ref Choices);
                    nChoices++;
                }
                // when title and choices are ready now, send to client
#if DEBUG
                for (int c = 0; c < Choices.Count; c++)
                {
                    Log.Log.Debug("{0}: {1} : {2}", m_cardName, c, Choices[c]);
                }
#endif
                if (m_ciMenuCallback != null)
                {
                    m_ciMenuCallback.OnCiMenu(Choices[0], Choices[1], Choices[2], nChoices);
                    for (int c = 3; c < Choices.Count; c++)
                    {
                        m_ciMenuCallback.OnCiMenuChoice(c - 3, Choices[c]);
                    }
                }
                else
                {
                    Log.Log.Debug("{0}: OnCiMenu: cannot do callback!", m_cardName);
                }
            }
        }