public static bool Start(string device, IEmulationElement loggingParent) { #if !PLATFORM_LINUX throw new RecoverableException("Video capture is supported on Linux only!"); #else // stop any previous capturer Stop(); VideoCapturer.loggingParent = loggingParent; loggingParent.Log(LogLevel.Debug, "Opening device: {0}...", device); fd = LibCWrapper.Open(device, O_RDWR); if (fd == -1) { loggingParent.Log(LogLevel.Error, "Couldn't open device: {0}", device); return(false); } if (!CheckImageFormat()) { loggingParent.Log(LogLevel.Error, "Device does not support JPEG output: {0}", device); LibCWrapper.Close(fd); return(false); } started = true; return(RequestBuffer()); #endif }
private static int Open_TUNTAP(IntPtr dev, UInt16 flags, bool persistent) { var ifr = Marshal.AllocHGlobal(IFR_SIZE); // we need 40 bytes, but we allocate a bit more var fd = LibCWrapper.Open("/dev/net/tun", O_RDWR); if (fd < 0) { Console.Error.WriteLine("Could not open /dev/net/tun, error: {0}", Marshal.GetLastWin32Error()); return(fd); } var memory = new byte[IFR_SIZE]; Array.Clear(memory, 0, IFR_SIZE); var bytes = BitConverter.GetBytes(flags); Array.Copy(bytes, 0, memory, IFNAMSIZ, 2); if (dev != IntPtr.Zero) { var devBytes = Encoding.ASCII.GetBytes(Marshal.PtrToStringAnsi(dev)); Array.Copy(devBytes, memory, Math.Min(devBytes.Length, IFNAMSIZ)); } Marshal.Copy(memory, 0, ifr, IFR_SIZE); int err = 0; if ((err = LibCWrapper.Ioctl(fd, TUNSETIFF, ifr)) < 0) { Console.Error.WriteLine("Could not set TUNSETIFF, error: {0}", Marshal.GetLastWin32Error()); LibCWrapper.Close(fd); return(err); } if (persistent) { if ((err = LibCWrapper.Ioctl(fd, TUNSETPERSIST, 1)) < 0) { Console.Error.WriteLine("Could not set TUNSETPERSIST, error: {0}", Marshal.GetLastWin32Error()); LibCWrapper.Close(fd); return(err); } } LibCWrapper.Strcpy(dev, ifr); Marshal.FreeHGlobal(ifr); return(fd); }
public static void Stop() { #if !PLATFORM_LINUX throw new RecoverableException("Video capture is supported on Linux only!"); #else if (started) { started = false; FreeBuffer(); LibCWrapper.Close(fd); } #endif }
public void Dispose() { if (stream != null) { stream.Close(); } if (tapFileDescriptor != -1) { LibCWrapper.Close(tapFileDescriptor); tapFileDescriptor = -1; } }
private static bool DoIoctl(IoctlCode code, IntPtr data) { int err; if ((err = LibCWrapper.Ioctl(fd, (int)code, data)) < 0) { var lastErrorCode = Marshal.GetLastWin32Error(); var lastErrorMessage = LibCWrapper.Strerror(lastErrorCode); loggingParent.Log(LogLevel.Error, "There was an error when executing the {0} ioctl: {1} (0x{2:X})", Enum.GetName(typeof(IoctlCode), code), lastErrorMessage, lastErrorCode); LibCWrapper.Close(fd); return(false); } return(true); }
public void ReceiveFrame(EthernetFrame frame) { // TODO: non blocking if (stream == null) { return; } var handle = GCHandle.Alloc(frame.Bytes, GCHandleType.Pinned); try { var result = LibCWrapper.Write(stream.Handle, handle.AddrOfPinnedObject(), frame.Bytes.Length); if (!result) { this.Log(LogLevel.Error, "Error while writing to TUN interface: {0}.", result); } } finally { handle.Free(); } }
private void TransmitLoop(CancellationToken token) { while (true) { byte[] buffer = null; if (stream == null) { return; } try { buffer = LibCWrapper.Read(stream.Handle, MTU, 1000, () => token.IsCancellationRequested); } catch (ArgumentException) { // stream was closed return; } catch (ObjectDisposedException) { return; } if (token.IsCancellationRequested) { return; } if (buffer == null || buffer.Length == 0) { continue; } if (Misc.TryCreateFrameOrLogWarning(this, buffer, out var frame, addCrc: true)) { FrameReady?.Invoke(frame); } } }