using System; using System.Collections.Generic; using System.Linq; using System.Reflection.Metadata.Ecma335; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using skyscraper5.Skyscraper.IO.CrazycatStreamReader; namespace skyscraper5.IO.StreamReader { public partial class LocalStreamReader { private static class UnsafeStreamReaderMethods { /// /// Checks whether any sort of tuner is present in this system. /// /// Whether a tuner is present. [DllImport("StreamReader.dll", EntryPoint = "CheckForDVB")] internal static extern bool CheckForDVB(); /// /// Checks whether one or more tuner is present in the system. /// /// A method which will be called for each tuner found. /// Whether a tuner was found [DllImport("StreamReader.dll", EntryPoint = "CheckForDVBEx")] internal static extern bool CheckForDVBEx([MarshalAs(UnmanagedType.FunctionPtr)] DvbEnumCallback func); /// /// Checks whether one or more tuner is present in the system. /// /// A method which will be called for each tuner found. /// Whether a tuner was found [DllImport("StreamReader.dll", EntryPoint = "CheckForDVBExEx")] public static extern bool CheckForDVBExEx([MarshalAs(UnmanagedType.FunctionPtr)] DvbEnumCallbackEx func); /// /// Boots the first system tuner and sets it as the currently active tuner. Note that /// only one tuner can be active at the same time. /// /// Whether a tuner was booted sucessfully. [DllImport("StreamReader.dll", EntryPoint = "StartDVB")] internal static extern bool StartDVB(); /// /// Boots a tuner and makes it the currently active tuner. Note that only one tuner /// can be active at the same time. /// /// The ID of the tuner to boot /// Whether the turner booted sucessfully. [DllImport("StreamReader.dll", EntryPoint = "StartDVBEx")] public static extern bool StartDvbEx(int index); /// /// Shuts down the currently active tuner. /// /// Whether the tuner was shut down sucessfully [DllImport("StreamReader.dll", EntryPoint = "StopDVB")] public static extern bool StopDVB(); /// /// Retrieves the tuner standard. /// /// A Pointer in which the tuner type will be put into. /// Whether the tuner reports a standard [DllImport("StreamReader.dll", EntryPoint = "GetTunerType")] internal static extern bool GetTunerType(ref STD_TYPE type); /// /// Sends a raw command to a DiSEqC switch with up to four positions. /// /// 0 for disabling DiSEqc, 1 for a tone-burst, 2 for enabling DiSEqC 1.0 /// The opcode to send. /// Whether the command was sent [DllImport("StreamReader.dll", EntryPoint = "SendDiSEqC")] public static extern bool SendDiSEqC(uint diseqcType, DiSEqC_Opcode data); /// /// Send a raw command to a DiSEqC-Motor, ignoring any potential responses. /// /// The buffer containing the raw command /// The length of the command /// Whether the command was sent [DllImport("StreamReader.dll", EntryPoint = "SendDiseqCmd")] internal static extern bool SendDiseqCmd(byte[] buffer, int length); /// /// Supposed to send a raw command to a DiSEqC-Motor and awaits a response. /// Since I couldn't test this - (I don't have a motor on my dish!) this will merely /// throw a NotImplementedException /// /// The command to send to the motor /// The length of the command to send to the motor. /// A byte array to store the motor's response in. /// Expected length of the motor's response /// Throws a NotImplementedException internal static bool SendDiseqCmdEx(IntPtr pCmd, int length, IntPtr reply, int replyLength) { //I have no rotor to test this with. //Also, I'm not sure whether this method head is correct. throw new NotImplementedException(nameof(SendDiseqCmdEx)); } /// /// Set the tuner to a satellite frequency /// /// The frequency in kHz. /// The symbol rate in Sym/s. (e.g. 27500 * 1000 = 27500000) /// 0 for horizontal, 1 for vertical. /// The error correction method used by the channel. /// Local Oscillator Frequency 1 of the LNB in kHz. (9750000 for Ku-Band) /// Local Oscillator Frequency 2 of the LNB in kHz. (10600000 for Ku-Band) /// Border Frequency for switching between Low Band and High Band in kHz (11700000 for Ku-Band) /// Whether the tuner complied with the request [DllImport("StreamReader.dll", EntryPoint = "SetChannel")] public static extern bool SetChannel(int freq, int symbrate, int pol, VITERBIRATE_TYPE fec, int lof1, int lof2, int lofsw); /// /// Set the tuner to a satellite frequency /// /// The frequency in kHz. /// The symbol rate in Sym/s. (e.g. 27500 * 1000 = 27500000) /// 0 for horizontal, 1 for vertical. /// The error correction method used by the channel. /// Local Oscillator Frequency 1 of the LNB in kHz. (9750000 for Ku-Band) /// Local Oscillator Frequency 2 of the LNB in kHz. (10600000 for Ku-Band) /// Border Frequency for switching between Low Band and High Band in kHz (11700000 for Ku-Band) /// The modulation type used by the channel. /// Whether the tuner complied with the request. [DllImport("StreamReader.dll", EntryPoint = "SetChannelEx")] internal static extern bool SetChannelEx(int freq, int symbrate, int pol, VITERBIRATE_TYPE fec, int lof1, int lof2, int lofsw, MOD_TYPE mod); /// /// Set the tuner to a satellite frequency /// /// The frequency in kHz. /// The symbol rate in Sym/s. (e.g. 27500 * 1000 = 27500000) /// 0 for horizontal, 1 for vertical. /// The error correction method used by the channel. /// Local Oscillator Frequency 1 of the LNB in kHz. (9750000 for Ku-Band) /// Local Oscillator Frequency 2 of the LNB in kHz. (10600000 for Ku-Band) /// Border Frequency for switching between Low Band and High Band in kHz (11700000 for Ku-Band) /// The modulation type used by the channel. /// Spectral inversion: 0 for autodetection, 1 for no spectral inversion, 2 for spectral inversion. /// S2 Pilot Symbols: 0 for autodetection, 1 for no pilot symbols, 2 for pilot symbols /// /// [DllImport("StreamReader.dll", EntryPoint = "SetChannelExEx")] internal static extern bool SetChannelExEx(int freq, int symbrate, int pol, VITERBIRATE_TYPE fec, int lof1, int lof2, int lofsw, MOD_TYPE mod, int inv, int pilot, ROLLOFF_TYPE rolloff); /// /// Starts receiving data from the tuner. /// /// The PID you want to receive. Set this to 8192 if you want ALL pids. /// The function to call when a packet was received. /// Set this to 0x02 for all that is holy. Others might cause blue-screens. /// Set this to 1 to receive single packets, or 2 to receive (a varying amount of) multiple packets. /// The pointer you can use with DelFilter. /// Whether the filter was started sucesfully. [DllImport("StreamReader.dll", EntryPoint = "SetFilter")] public static extern bool SetFilter(int pid, [MarshalAs(UnmanagedType.FunctionPtr)] StdcallDvbCallback func, int callbackType, int size, ref IntPtr lpFilterNum); /// /// Starts receiving data from the tuner. /// /// The PID you want to receive. Set this to 8192 if you want ALL pids. /// The function to call when a packet was received. /// Set this to 0x02 for all that is holy. Others might cause blue-screens. /// Set this to 1 to receive single packets, or 2 to receive (a varying amount of) multiple packets. /// The pointer you can use with DelFilter. /// Whether the filter was started sucesfully. [DllImport("StreamReader.dll", EntryPoint = "SetFilterEx")] internal static extern bool SetFilterEx(int pid, [MarshalAs(UnmanagedType.FunctionPtr)] StdcallDvbCallbackEx lpFunc, int callbackType, int size, ref IntPtr lpFilterNum); [DllImport("StreamReader.dll", EntryPoint = "SetBitFilter")] internal static extern bool SetBitFilter(int pid, IntPtr filterData, IntPtr filterMask, byte filterLength, [MarshalAs(UnmanagedType.FunctionPtr)] StdcallDvbCallback lpFunc, ref IntPtr lpFilterNum); /// /// Creates a filter to read data from the virtual IR Channel of the tuner. /// /// The remote control type. 0x00 works for all remote types. /// The adress of the remote control. Set to -1 for all remotes. /// The function to call when an IR Command was received. /// A pointer to the filter to use with DelFilter. /// Whether the listening to a remote command is working. [DllImport("StreamReader.dll", EntryPoint = "SetRemoteControl")] internal static extern bool SetRemoteControl(int irtype, short devAddr, [MarshalAs(UnmanagedType.FunctionPtr)] StdcallDvbCallback func, ref IntPtr lpFilterNum); /// /// Stops reading data. /// /// The pointer to the filter which should be stopped. /// Whether the filter could be stopped. [DllImport("StreamReader.dll", EntryPoint = "DelFilter")] public static extern bool DelFilter(IntPtr filterNum); /// /// Reports the signal strength and quality. For some tuners you'll need GetSignalStrength instead. /// /// A float pointer which will be set to the signal strength. /// A float pointer which will be set to the signal quality. /// Whether these information could be reported. [DllImport("StreamReader.dll", EntryPoint = "GetSignal")] internal static extern bool GetSignal(ref int pStrength, ref int pQuality); /// /// An alternative method to read the signal strength and quality. /// /// A float pointer which will be set to the signal strength. /// A float pointer which will be set to the signal quality. /// Whether these information could be reported. [DllImport("StreamReader.dll", EntryPoint = "GetSignalStrength")] internal static extern bool GetSignalStrength(ref float pStrength, ref float pQuality); /// /// Gets information about the current signal. /// /// Pointer to a float which will be set to the Signal-to-Noise ratio. /// Pointer to a float which will be set to the biterror rate. /// Whether the data could be reported. [DllImport("StreamReader.dll", EntryPoint = "GetSignalEx")] internal static extern bool GetSignalEx(ref float pSNR, ref float pBER); /// /// Gets information about the current signal. /// /// Pointer to a boolean which will be set to true if a signal is present. /// Pointer to a boolean which will be set to true if a signal lock is available. /// Pointer to an integer which will be set to the RF Level. /// Pointer to a float which will be set to the Signal-to-Noise ratio. /// Pointer to a float which will be set to the biterror rate. /// Whether the data could be reported. [DllImport("StreamReader.dll", EntryPoint = "GetSignalExEx")] internal static extern bool GetSignalExEx(ref bool pPresent, ref bool pLock, ref int pRFLevel, ref float pSNR, ref float pBER); /// /// Read signal statistics into an integer array. /// /// Pointer to an array which will receive the following elements: Locked?, Signal Quality, Signal Present?, Signal Strength /// Whether the statistics could be reported. [DllImport("StreamReader.dll", EntryPoint = "Statistic")] internal static extern bool Statistic(int[] pStat); /// /// Reads the MAC Adress of a tuner. /// /// A byte array to put the MAC into. /// Whether the MAC was sucessfully read. [DllImport("StreamReader.dll", EntryPoint = "GetMAC")] public static extern bool GetMAC(byte[] pMac); /// /// Gets the TunerMetadata capabilities. /// /// A bitmask containing all the tuner capabilities. [DllImport("StreamReader.dll", EntryPoint = "GetCaps")] public static extern Caps GetCaps(); /// /// Gets the RF Strength of a satellite frequency. /// /// An approximate channel frequency in kHz /// 0 for horizontal, 1 for vertical /// Local Oscillator Frequency 1 of the LNB in kHz. (9750000 for Ku-Band) /// Local Oscillator Frequency 2 of the LNB in kHz. (10600000 for Ku-Band) /// Border Frequency for switching between Low Band and High Band in kHz (11700000 for Ku-Band) /// The pointer to put the result in. /// Whether the probe was sucessful. [DllImport("StreamReader.dll", EntryPoint = "RFScan")] internal static extern bool RFScan(int freq, int pol, int lof1, int lof2, int lofsw, out double pRFLevel); [DllImport("StreamReader.dll", EntryPoint = "FFTInit")] internal static extern bool FFTInit(); internal static bool FFTScan(int freq, int pol, int lof1, int lof2, int lofsw, uint range, byte mode, byte nb_acc, IntPtr pTab, IntPtr pBegin, IntPtr pNum) { //I don't have a tuner that supports this... throw new NotImplementedException(); } /// /// Given an approximate satellite frequency, tune to the nearest channel. /// /// An approximate channel frequency in kHz /// The range where to look for in kHz /// 0 for horizontal, 1 for vertical /// Local Oscillator Frequency 1 of the LNB in kHz. (9750000 for Ku-Band) /// Local Oscillator Frequency 2 of the LNB in kHz. (10600000 for Ku-Band) /// Border Frequency for switching between Low Band and High Band in kHz (11700000 for Ku-Band) /// The minimum acceptable symbol rate. Depending on your tuner you either want 200 or 1000. /// The exact tuning data /// Whether a channel could be found [DllImport("StreamReader.dll", EntryPoint = "BLScan")] internal static extern bool BLScan(int freq, int freq_range, int pol, int lof1, int lof2, int lofsw, int minsr, ref SearchResult pSearchResult); /// /// Given an approximate satellite frequency, tune to the nearest channel. /// /// An approximate channel frequency in kHz /// The range where to look for in kHz /// 0 for horizontal, 1 for vertical /// Local Oscillator Frequency 1 of the LNB in kHz. (9750000 for Ku-Band) /// Local Oscillator Frequency 2 of the LNB in kHz. (10600000 for Ku-Band) /// Border Frequency for switching between Low Band and High Band in kHz (11700000 for Ku-Band) /// The minimum acceptable symbol rate. Depending on your tuner you either want 200 or 1000. /// The network type /// The exact tuning data /// Whether a channel could be found [DllImport("StreamReader.dll", EntryPoint = "BLScanEx")] internal static extern bool BLScanEx(int freq, int freq_range, int pol, int lof1, int lof2, int lofsw, int minsr, STD_TYPE std, ref SearchResult pSearchResult); /// /// Performs a blind scan on a satellite network. /// This method blocks until the scan is complete. /// /// The frequency to the start the scan on in kHz (10700000 for Ku-Band) /// The frequency to end the scan on in kHz (12750000 for Ku-Band) /// 0 for horizontal, 1 for vertical. /// Local Oscillator Frequency 1 of the LNB in kHz. (9750000 for Ku-Band) /// Local Oscillator Frequency 2 of the LNB in kHz. (10600000 for Ku-Band) /// Border Frequency for switching between Low Band and High Band in kHz (11700000 for Ku-Band) /// The struct to put the last found channel in. /// Number of channels found. /// The function to call when a channel was found. /// Whether the blind scan was performed sucessfully. [DllImport("StreamReader.dll", EntryPoint = "BLScan2")] public static extern bool BLScan2(int freq_start, int freq_stop, int pol, int lof1, int lof2, int lofsw, IntPtr pSearchResult, ref int pTpNum, [MarshalAs(UnmanagedType.FunctionPtr)] BlScanCallback lpFunc); /// /// Retrieve extended carrier info after lock for a sattelite signal. /// /// Struct to output the data to /// Whether the carrier info could be read. [DllImport("StreamReader.dll", EntryPoint = "SignalInfo")] public static extern bool SignalInfo(ref SearchResult pSearchResult); /// /// Read constellation data for a satellite signal. /// /// Type of constellation data to read. You probably want 0. /// Output Array /// Number of Constellation points to read. Must be (pIQ.Length / 2) /// Whether the constellation data was read [DllImport("StreamReader.dll", EntryPoint = "IQScan")] internal static extern bool IQScan(uint input, sbyte[] pIQ, uint num); /// /// Read constellation data for a non-satellite signal. /// /// Type of constellation data to read. You probably want 0. /// Output Array /// Number of Constellation points to read. Must be (pIQ.Length / 2) /// Whether the constellation data was read [DllImport("StreamReader.dll", EntryPoint = "IQScan2")] internal static extern bool IQScan2(uint point, short[] pIQ, uint num); [DllImport("StreamReader.dll", EntryPoint = "IQScan2Range")] internal static extern bool IQScan2Range(byte input, ref ushort pMinPoint, ref ushort pMaxPoint); [DllImport("StreamReader.dll", EntryPoint = "CIRScanRange")] internal static extern bool CIRScanRange(bool bHiRes, ref ushort pMinCnum, ref ushort pMaxCnum, ref int pMinDelayNs, ref int pMaxDelayNs); [DllImport("StreamReader.dll", EntryPoint = "CIRScan")] internal static extern bool CIRScan(bool bHiRes, int[] pPowers, int[] pDelays); [DllImport("StreamReader.dll", EntryPoint = "CarRange")] internal static extern bool CarRange(ref ushort pMinCnum, ref ushort pMaxCnum); [DllImport("StreamReader.dll", EntryPoint = "CarEsNo")] internal static extern bool CarEsNo(ref ushort cnum, ref double pEsNo); [DllImport("StreamReader.dll", EntryPoint = "MISSel")] public static extern bool MISSel(bool bEnable, byte misFilter, byte misFilterMask); /// /// Sets the Physical Layer Scrambling credentials. /// /// The PLS mode. /// The PLS key. /// Whether the tuner complied. [DllImport("StreamReader.dll", EntryPoint = "PLSSel")] internal static extern bool PLSSel(byte plsMode, uint code); /// /// Gets the current Physical Layer Scrambling key. /// /// The pointer to write the PLS Mode in. /// The pointer to write the PLS Key in. /// Whether the tuner sent valid PLS credentials. [DllImport("StreamReader.dll", EntryPoint = "PLSGet")] internal static extern bool PLSGet(byte pMode, ref uint pCode); [DllImport("StreamReader.dll", EntryPoint = "ModSel")] internal static extern bool ModSel(ref S2Mode ps2Modes, uint num); [DllImport("StreamReader.dll", EntryPoint = "ModInv")] internal static extern bool ModInv(uint WaitMs, ref S2Mode pS2Modes, ref uint pNum); /// /// Tune to DVB-T2 / DVB-C Channel /// /// Frequency in kHz /// Channel Bandwidth in kHz (usually 8000) /// Whether the tuner complied with the request. [DllImport("StreamReader.dll", EntryPoint = "SetChannel2")] public static extern bool SetChannel2(uint freq, uint bandwidth); /// /// Tune to DVB-T2 / DVB-C channel. /// /// Frequency in kH /// Channel Bandwidth in kHz (usually 8000) /// Type of network /// ??? (Setting this to 0 works.) /// Whether the tuner complied with the request. [DllImport("StreamReader.dll", EntryPoint = "SetChannel2Ex")] internal static extern bool SetChannel2Ex(uint freq, uint bandwidth, STD_TYPE std, int stream); /// /// Tune to DVB-T2 / DVB-C Channel. Beware, will freeze for a minute when SymbolRate is wrong. /// /// Frequency in kHz /// Channel Bandwidth in kHz (usually 8000) /// Sybol Rate in kiloSymbols (6900000 for Vodafone) /// Type of network /// ??? Setting this to 0 works. /// Whether the tuner complied with the request. [DllImport("StreamReader.dll", EntryPoint = "SetChannel2ExEx")] internal static extern bool SetChannel2ExEx(uint freq, uint bandwidth, uint symbrate, STD_TYPE std, int stream); /// /// Retrieve extended carrier info after lock for a non-sattelite signal. /// /// Outputs the Signal information /// Whether the signal information was read sucessfully [DllImport("StreamReader.dll", EntryPoint = "SignalInfo2")] public static extern bool SignalInfo2(ref SearchResult2 si2); /// /// Get RF Level from FM / UHF / VHF Frequency /// /// Frequency in kHz /// TunerMetadata standard /// Output pointer /// whether the operation completed sucessfully [DllImport("StreamReader.dll", EntryPoint = "RFScan2")] internal static extern bool RFScan2(uint freq, STD_TYPE std, ref double pRFLevel); /// /// Performs a blind scan on non-satellite networks. /// This method blocks until the scan is complete! /// /// Starting Frequency in kHz /// End Frequency in kHz /// Frequency increment in kHz (3000 is usually a safe choice here) /// System bandwidth (usually 8000) /// Type of Network /// Outputs the final channel. Not really necessary. /// Outputs the number of channels. /// Function to call when a channel was found. /// Whether the scan was performed sucessfully [DllImport("StreamReader.dll", EntryPoint = "AirScan")] public static extern bool AirScan(int freq_start, int freq_stop, uint step, uint bandwidth, int std, IntPtr pSearchResult, ref int pTpNum, [MarshalAs(UnmanagedType.FunctionPtr)] AirScanCallback lpFunc); /// /// Reads from the EEPROM of the tuner. /// /// Buffer to put the read data in. /// Offset from where to start reading from the EEPROM /// How many bytes to read /// Wheter the reading operation was sucessful. [DllImport("StreamReader.dll", EntryPoint = "GetEEPROM")] internal static extern bool GetEEPROM(byte[] buffer, int offset, int len); /// /// Supposed to write data to the device's EEPROM. /// This method is not implemented on purpose because I neither have the balls to try /// this, nor the money to replace my tuner in case I mess up. /// This will throw a NotSupportedException when calling this. /// /// Buffer of data to write to the EEPROM. /// Offset in the EEPROM to start writing. /// How many bytes to write to the EEPROM /// Throws NotSupportedException internal static bool SetEEPROM(byte[] buffer, int offset, int len) { //I'm not willing to try this out. TBS Tuners are way too expensive for me than to //mess with their firmware. throw new NotSupportedException(); } } } }