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();
}
}
}
}