Exemple #1
0
        public static byte[] Read(int fd, int count, int timeout, Func <bool> shouldCancel)
        {
#if !PLATFORM_LINUX
            throw new NotSupportedException("This API is available on Linux only!");
#else
            int pollResult;
            var pollData = new Pollfd {
                fd     = fd,
                events = PollEvents.POLLIN
            };

            do
            {
                pollResult = Syscall.poll(new [] { pollData }, timeout);
            }while(UnixMarshal.ShouldRetrySyscall(pollResult) && !shouldCancel());

            if (pollResult > 0)
            {
                return(Read(fd, count));
            }
            else
            {
                return(null);
            }
#endif
        }
Exemple #2
0
        public void Run()
        {
            Thread m_signalThread = new Thread(SignalThread);

            m_signalThread.Start();

            Pollfd[] fds = new Pollfd[2];

            while (m_exit == false)
            {
                fds[0].fd      = Mono.Unix.UnixStream.StandardInputFileDescriptor;
                fds[0].events  = PollEvents.POLLIN;
                fds[0].revents = 0;

                fds[1].fd      = m_netPipe.Reading.Handle;
                fds[1].events  = PollEvents.POLLIN;
                fds[1].revents = 0;

                int ret = Syscall.poll(fds, -1);

                if (ret == 0)
                {
                    //ChiConsole.Prompt = String.Format("pr{0}> ", z++);
                    ChiConsole.WriteLine("timeout");
                }
                else if (ret > 0)
                {
                    if (fds[0].revents != 0)
                    {
                        m_textConsole.ReadChars();

                        string str;
                        while ((str = m_textConsole.GetLine()) != null)
                        {
                            //m_textConsole.WriteLine("Tuli {0}", str);
                            HandleInput(str);
                        }
                    }

                    if (fds[1].revents != 0)
                    {
                        m_netPipe.Reading.ReadByte();
                        m_synchronizedInvoke.DispatchInvokes();
                    }
                }
            }

            Dbg.WriteLine("Exiting");

            m_sigThreadStop = true;
            if (m_signalThread.Join(1000) == false)
            {
                m_signalThread.Abort();
            }

            m_textConsole.UnInit();
        }
Exemple #3
0
        private bool IsDataAvailable(int timeout, out int pollResult)
        {
            var pollData = new Pollfd {
                fd     = master,
                events = PollEvents.POLLIN
            };

            do
            {
                pollResult = Syscall.poll(new [] { pollData }, timeout);
            }while(!disposed && UnixMarshal.ShouldRetrySyscall(pollResult));
            return(pollResult > 0);
        }
        private unsafe void waitInterrupt(int file)
        {
            var pfs = new Pollfd();

            pfs.fd      = file;
            pfs.events  = PollEvents.POLLPRI | PollEvents.POLLERR;
            pfs.revents = 0;

            var buf = new byte[2];

            fixed(byte *pb = buf)
            {
                var r = Syscall.poll(new[] { pfs }, -1);

                var res2 = (int)Syscall.pread(file, pb, (ulong)1, 0);
            }
        }
Exemple #5
0
        public static byte[] ReadDataWithTimeout(int fd, int count, int timeout, Func <bool> shouldCancel)
        {
            int pollResult;
            var pollData = new Pollfd {
                fd     = fd,
                events = PollEvents.POLLIN
            };

            do
            {
                pollResult = Syscall.poll(new [] { pollData }, timeout);
            }while(UnixMarshal.ShouldRetrySyscall(pollResult) && !shouldCancel());

            if (pollResult > 0)
            {
                return(ReadData(fd, count));
            }
            else
            {
                return(null);
            }
        }
Exemple #6
0
		public X11Display (IntPtr display)
		{
			if (display == IntPtr.Zero) {
				throw new ArgumentNullException("Display",
							"Could not open display (X-Server required. Check your DISPLAY environment variable)");
			}

			this.display = display;

			// Debugging support
			if (Environment.GetEnvironmentVariable ("MONO_XSYNC") != null) {
				Xlib.XSynchronize (display, true);
			}

			if (Environment.GetEnvironmentVariable ("MONO_XEXCEPTIONS") != null) {
				ErrorExceptions = true;
			}

			atoms = new X11Atoms (this);

			DoubleClickInterval = 500;

			HoverState.Interval = 500;
			HoverState.Timer = new Timer();
			HoverState.Timer.Enabled = false;
			HoverState.Timer.Interval = HoverState.Interval;
			HoverState.Timer.Tick += new EventHandler(MouseHover);
			HoverState.Size = new Size(4, 4);
			HoverState.X = -1;
			HoverState.Y = -1;

			ActiveWindow = null;
			FocusWindow = null;
			ModalWindows = new Stack(3);

			MouseState = MouseButtons.None;
			MousePosition = new Point(0, 0);

			Caret.Timer = new Timer();
			Caret.Timer.Interval = 500;		// FIXME - where should this number come from?
			Caret.Timer.Tick += new EventHandler(CaretCallback);

			// XXX multiscreen work here
			root_hwnd = new X11RootHwnd (this, Xlib.XRootWindow (display, DefaultScreen));

			// XXX do we need a per-screen foster parent?
			// Create the foster parent
			foster_hwnd = new X11Hwnd (this,
						   Xlib.XCreateSimpleWindow (display, root_hwnd.WholeWindow,
									     0, 0, 1, 1, 4, UIntPtr.Zero, UIntPtr.Zero));

			pollfds = new Pollfd [1];
			pollfds [0] = new Pollfd ();
			pollfds [0].fd = Xlib.XConnectionNumber (display);
			pollfds [0].events = PollEvents.POLLIN;

			Keyboard = new X11Keyboard(display, foster_hwnd.Handle);
			Dnd = new X11Dnd (display, Keyboard);

			ErrorExceptions = false;

			// Handle any upcoming errors
			ErrorHandler = new XErrorHandler (HandleError);
			Xlib.XSetErrorHandler (ErrorHandler);

			X11DesktopColors.Initialize(); // XXX we need to figure out how to make this display specific?

			// Disable keyboard autorepeat
			try {
				Xlib.XkbSetDetectableAutoRepeat (display, true, IntPtr.Zero);
				detectable_key_auto_repeat = true;
			} catch {
				Console.Error.WriteLine ("Could not disable keyboard auto repeat, will attempt to disable manually.");
				detectable_key_auto_repeat = false;
			}

			// we re-set our error handler here, X11DesktopColor stuff might have stolen it (gtk does)
			Xlib.XSetErrorHandler (ErrorHandler);

			// create our event thread (just sits on the X socket waiting for events)
			event_thread = new Thread (new ThreadStart (XEventThread));
			event_thread.IsBackground = true;
			event_thread.Start ();
		}
		public static bool TryCopy (IntPtr source, out Pollfd destination)
		{
			return ToPollfd (source, out destination) == 0;
		}
		private static extern int ToPollfd (IntPtr source, out Pollfd destination);
Exemple #9
0
		internal void SetDisplay(IntPtr display_handle)
		{
			if (display_handle != IntPtr.Zero) {
				Hwnd	hwnd;

				if ((DisplayHandle != IntPtr.Zero) && (FosterParent != IntPtr.Zero)) {
					hwnd = Hwnd.ObjectFromHandle(FosterParent);
					XDestroyWindow(DisplayHandle, FosterParent);
					hwnd.Dispose();
				}

				if (DisplayHandle != IntPtr.Zero) {
					XCloseDisplay(DisplayHandle);
				}

				DisplayHandle=display_handle;

				// We need to tell System.Drawing our DisplayHandle. FromHdcInternal has
				// been hacked to do this for us.
				Graphics.FromHdcInternal (DisplayHandle);

				// query for the render extension so
				// we can ignore the spurious
				// BadPicture errors that are
				// generated by cairo/render.
				XQueryExtension (DisplayHandle, "RENDER",
						 ref render_major_opcode, ref render_first_event, ref render_first_error);

				// Debugging support
				if (Environment.GetEnvironmentVariable ("MONO_XSYNC") != null) {
					XSynchronize(DisplayHandle, true);
				}

				if (Environment.GetEnvironmentVariable ("MONO_XEXCEPTIONS") != null) {
					ErrorExceptions = true;
				}

				// Generic X11 setup
				ScreenNo = XDefaultScreen(DisplayHandle);
				RootWindow = XRootWindow(DisplayHandle, ScreenNo);
				DefaultColormap = XDefaultColormap(DisplayHandle, ScreenNo);

				// Create the foster parent
				// it is important that border_width is kept in synch with the other XCreateWindow calls
				FosterParent=XCreateSimpleWindow(DisplayHandle, RootWindow, 0, 0, 1, 1, 0, UIntPtr.Zero, UIntPtr.Zero);
				if (FosterParent==IntPtr.Zero) {
					Console.WriteLine("XplatUIX11 Constructor failed to create FosterParent");
				}

				DebugHelper.WriteLine ("FosterParent created 0x{0:x}", FosterParent.ToInt32());

				hwnd = new Hwnd();
				hwnd.Queue = ThreadQueue(Thread.CurrentThread);
				hwnd.WholeWindow = FosterParent;
				hwnd.ClientWindow = FosterParent;

				// Create a HWND for RootWIndow as well, so our queue doesn't eat the events
				hwnd = new Hwnd();
				hwnd.Queue = ThreadQueue(Thread.CurrentThread);
				hwnd.whole_window = RootWindow;
				hwnd.ClientWindow = RootWindow;

				// For sleeping on the X11 socket
				listen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
				IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, 0);
				listen.Bind(ep);
				listen.Listen(1);

				// To wake up when a timer is ready
				network_buffer = new byte[10];

				wake = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
				wake.Connect(listen.LocalEndPoint);

				// Make this non-blocking, so it doesn't
				// deadlock if too many wakes are sent
				// before the wake_receive end is polled
				wake.Blocking = false;

				wake_receive = listen.Accept();

				#if __MonoCS__
				pollfds = new Pollfd [2];
				pollfds [0] = new Pollfd ();
				pollfds [0].fd = XConnectionNumber (DisplayHandle);
				pollfds [0].events = PollEvents.POLLIN;

				pollfds [1] = new Pollfd ();
				pollfds [1].fd = wake_receive.Handle.ToInt32 ();
				pollfds [1].events = PollEvents.POLLIN;
				#endif

				Keyboard = new X11Keyboard(DisplayHandle, FosterParent);
				Dnd = new X11Dnd (DisplayHandle, Keyboard);

				DoubleClickInterval = 500;

				HoverState.Interval = 500;
				HoverState.Timer = new Timer();
				HoverState.Timer.Enabled = false;
				HoverState.Timer.Interval = HoverState.Interval;
				HoverState.Timer.Tick += new EventHandler(MouseHover);
				HoverState.Size = new Size(4, 4);
				HoverState.X = -1;
				HoverState.Y = -1;

				ActiveWindow = IntPtr.Zero;
				FocusWindow = IntPtr.Zero;
				ModalWindows = new Stack(3);

				MouseState = MouseButtons.None;
				mouse_position = new Point(0, 0);

				Caret.Timer = new Timer();
				Caret.Timer.Interval = 500;		// FIXME - where should this number come from?
				Caret.Timer.Tick += new EventHandler(CaretCallback);

				SetupAtoms();

				// Grab atom changes off the root window to catch certain WM events
				XSelectInput(DisplayHandle, RootWindow, new IntPtr ((int) (EventMask.PropertyChangeMask | Keyboard.KeyEventMask)));

				// Handle any upcoming errors
				ErrorHandler = new XErrorHandler(HandleError);
				XSetErrorHandler(ErrorHandler);
			} else {
				throw new ArgumentNullException("Display", "Could not open display (X-Server required. Check your DISPLAY environment variable)");
			}
		}
Exemple #10
0
        protected override void OnInput()
        {
            System.Diagnostics.Debug.Assert(_socket != null);

            if (_recvBuffer == null || _recvBuffer.Capacity < _bufferSize)
            {
                _recvBuffer = new MemoryStream(_bufferSize);
            }

            _recvBuffer.Seek(0, SeekOrigin.Begin);
            _recvBuffer.SetLength(_recvBuffer.Capacity);

            byte[] buf    = _recvBuffer.GetBuffer();
            int    offset = (int)_recvBuffer.Position;
            int    size   = (int)_recvBuffer.Length;

            Pollfd[] fds = new Pollfd[1];
            fds[0].fd     = _socket.Handle;
            fds[0].events = PollEvents.POLLIN;

            int expires = Environment.TickCount + Timeout;
            int wait    = 0;

            for (;;)
            {
                try
                {
                    wait           = Math.Max(0, expires - Environment.TickCount);
                    fds[0].revents = 0;

                    int ret = Syscall.poll(fds, wait);

                    if (UnixMarshal.ShouldRetrySyscall(ret))
                    {
                        continue;
                    }

                    UnixMarshal.ThrowExceptionForLastErrorIf(ret);

                    if (ret == 0)
                    {
                        throw new TimeoutException();
                    }

                    if (ret != 1 || (fds[0].revents & PollEvents.POLLIN) == 0)
                    {
                        continue;
                    }

                    var rxLen = _socket.Read(buf, offset, size);

                    _recvBuffer.SetLength(rxLen);

                    if (Logger.IsDebugEnabled)
                    {
                        Logger.Debug("\n\n" + Utilities.HexDump(_recvBuffer));
                    }

                    // Got a valid packet
                    return;
                }
                catch (Exception ex)
                {
                    Logger.Error("Unable to receive CAN packet on {0}. {1}", Interface, ex.Message);

                    throw new SoftException(ex);
                }
            }
        }
		private static int FromPollfd (ref Pollfd source, IntPtr destination)
		{
			throw new System.NotImplementedException();
		}
        /// <summary>
        /// The capture thread
        /// </summary>
        protected virtual void CaptureThread()
        {
            if (!Opened)
            {
                throw new DeviceNotReadyException("Capture called before PcapDevice.Open()");
            }

            var usePoll = (this is LibPcapLiveDevice) &&
                          isLibPcap && MonoUnixFound;

            // unix specific code
            int captureFileDescriptor = 0;

            if (usePoll)
            {
                // retrieve the file descriptor of the adapter for use with poll()
                captureFileDescriptor = LibPcapSafeNativeMethods.pcap_fileno(PcapHandle);
                if (captureFileDescriptor == -1)
                {
                    SendCaptureStoppedEvent(CaptureStoppedEventStatus.ErrorWhileCapturing);
                    return;
                }
            }

            LibPcapSafeNativeMethods.pcap_handler Callback = new LibPcapSafeNativeMethods.pcap_handler(PacketHandler);

            // unix specific code
#if UseMonoUnixNativeDirectly
            Pollfd[] pollFds = new Pollfd[1];
#else
            System.Array pollFds        = null;
            object[]     PollParameters = null;
#endif

            // Timeout chosen to allow the capture thread to loop frequently enough
            // to enable it to properly exit when the user requests it to but
            // infrequently enough to cause any noticable performance overhead
            int millisecondTimeout = 500;

            if (usePoll)
            {
#if UseMonoUnixNativeDirectly
                pollFds[0].fd     = captureFileDescriptor;
                pollFds[0].events = PollEvents.POLLPRI | Mono.Unix.Native.PollEvents.POLLIN;
#else
                FieldInfo field;
                pollFds = Array.CreateInstance(PollfdType, 1);

                // create a PollFd struct instance
                var pollFd = Activator.CreateInstance(PollfdType);

                // set the descriptor field
                field = PollfdType.GetField("fd");
                field.SetValue(pollFd, captureFileDescriptor);

                // set the events field
                short eventValue = (short)(POLLIN | POLLPRI); // mask the two together
                field = PollfdType.GetField("events");
                field.SetValue(pollFd, eventValue);

                // set the Pollfd entry
                pollFds.SetValue(pollFd, 0);

                // setup the parameters we will pass to the poll() method
                PollParameters    = new object[2];
                PollParameters[0] = pollFds;
                PollParameters[1] = millisecondTimeout;
#endif
            }

            while (!shouldCaptureThreadStop)
            {
                // unix specific code, we want to poll for packets
                // otherwise if we call pcap_dispatch() the read() will block
                // and won't resume until a packet arrives OR until a signal
                // occurs
                if (usePoll)
                {
                    // block here
#if UseMonoUnixNativeDirectly
                    var result = Mono.Unix.Native.Syscall.poll(pollFds, millisecondTimeout);
#else
                    object o = SyscallType.InvokeMember("poll",
                                                        BindingFlags.InvokeMethod,
                                                        Type.DefaultBinder,
                                                        null,
                                                        PollParameters);
                    int result = (int)o;
#endif

                    // if we have no poll results, just loop
                    if (result <= 0)
                    {
                        continue;
                    }

                    // fall through here to the pcap_dispatch() call
                }

                int res = LibPcapSafeNativeMethods.pcap_dispatch(PcapHandle, m_pcapPacketCount, Callback, IntPtr.Zero);

                // pcap_dispatch() returns the number of packets read or, a status value if the value
                // is negative
                if (res <= 0)
                {
                    switch (res)                    // Check pcap loop status results and notify upstream.
                    {
                    case Pcap.LOOP_USER_TERMINATED: // User requsted loop termination with StopCapture()
                        SendCaptureStoppedEvent(CaptureStoppedEventStatus.CompletedWithoutError);
                        return;

                    case Pcap.LOOP_COUNT_EXHAUSTED:         // m_pcapPacketCount exceeded (successful exit)
                    {
                        // NOTE: pcap_dispatch() returns 0 when a timeout occurrs so to prevent timeouts
                        //       from causing premature exiting from the capture loop we only consider
                        //       exhausted events to cause an escape from the loop when they are from
                        //       offline devices, ie. files read from disk
                        if (this is CaptureFileReaderDevice)
                        {
                            SendCaptureStoppedEvent(CaptureStoppedEventStatus.CompletedWithoutError);
                            return;
                        }
                        break;
                    }

                    case Pcap.LOOP_EXIT_WITH_ERROR:         // An error occurred whilst capturing.
                        SendCaptureStoppedEvent(CaptureStoppedEventStatus.CompletedWithoutError);
                        return;

                    default:        // This can only be triggered by a bug in libpcap.
                        throw new PcapException("Unknown pcap_loop exit status.");
                    }
                }
                else   // res > 0
                {
                    // if we aren't capturing infinitely we need to account for
                    // the packets that we read
                    if (m_pcapPacketCount != Pcap.InfinitePacketCount)
                    {
                        // take away for the packets read
                        if (m_pcapPacketCount >= res)
                        {
                            m_pcapPacketCount -= res;
                        }
                        else
                        {
                            m_pcapPacketCount = 0;
                        }

                        // no more packets to capture, we are finished capturing
                        if (m_pcapPacketCount == 0)
                        {
                            SendCaptureStoppedEvent(CaptureStoppedEventStatus.CompletedWithoutError);
                            return;
                        }
                    }
                }
            }

            SendCaptureStoppedEvent(CaptureStoppedEventStatus.CompletedWithoutError);
        }
Exemple #13
0
	public static int poll (Pollfd [] fds, uint nfds, int timeout) {
		return -1;
	}
Exemple #14
0
		// native X display handle
		internal void SetDisplay (IntPtr display_handle)
		{
			if (display_handle != IntPtr.Zero) {
				Hwnd	hwnd;
				
				if ((GdkDisplayHandle != IntPtr.Zero) && (GdkFosterParent != IntPtr.Zero)) {
					hwnd = Hwnd.ObjectFromHandle (gdk_x11_drawable_get_xid (GdkFosterParent));
					gdk_window_destroy (GdkFosterParent);
					hwnd.Dispose ();
				}
				
				if (GdkDisplayHandle != IntPtr.Zero) {
					gdk_display_close (GdkDisplayHandle);
				}
				
				DisplayHandle = display_handle;
				GdkDisplayHandle = gdk_x11_lookup_xdisplay (display_handle);
				
				// We need to tell System.Drawing our DisplayHandle. FromHdcInternal has
				// been hacked to do this for us.
				Graphics.FromHdcInternal (DisplayHandle);
				
				// Debugging support
				if (Environment.GetEnvironmentVariable ("MONO_XSYNC") != null) {
					XSynchronize (DisplayHandle, true);					
				}
				
				if (Environment.GetEnvironmentVariable ("MONO_XEXCEPTIONS") != null) {
					ErrorExceptions = true;
				}
				
				// Generic X11 setup
				GdkScreen = gdk_screen_get_default ();
				// or gdk_x11_get_default_screen
				ScreenNo = gdk_screen_get_number (GdkScreen);
				GdkRootWindow = gdk_get_default_root_window ();
				RootWindow = gdk_x11_drawable_get_xid (GdkRootWindow);
				GdkDefaultColormap = gdk_colormap_get_system ();
				DefaultColormap = gdk_x11_colormap_get_xcolormap (GdkDefaultColormap);
				
				VisualBestDepth = gdk_visual_get_best_depth ();
				//Console.WriteLine (VisualBestDepth);
				
				// Create the foster parent
				FosterParent = XCreateSimpleWindow (DisplayHandle, RootWindow, 0, 0, 1, 1, 4, 0, 0);
				GdkFosterParent = gdk_window_foreign_new (FosterParent);
				
				if (GdkFosterParent == IntPtr.Zero) {
					Console.WriteLine ("XplatUIX11GTK Constructor failed to create FosterParent");
				}
				
				hwnd = new Hwnd ();
				
				hwnd.WholeWindow = FosterParent;
				hwnd.ClientWindow = FosterParent;
				
				// For sleeping on the X11 socket
				listen = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
				IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 0);
				listen.Bind (ep);
				listen.Listen (1);
				
				// To wake up when a timer is ready
				network_buffer = new byte [10];
				
				wake = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
				wake.Connect (listen.LocalEndPoint);
				wake_receive = listen.Accept ();
				
				pollfds = new Pollfd [2];
				pollfds [0] = new Pollfd ();
				pollfds [0].fd = XConnectionNumber (DisplayHandle);
				pollfds [0].events = PollEvents.POLLIN;

				pollfds [1] = new Pollfd ();
				pollfds [1].fd = wake_receive.Handle.ToInt32 ();
				pollfds [1].events = PollEvents.POLLIN;
				
				Keyboard = new X11Keyboard (DisplayHandle);
				Dnd = new X11Dnd (DisplayHandle);
				
				PostQuitState = false;
				
				DoubleClickInterval = 500;
				
				HoverState.Interval = 500;
				HoverState.Timer = new Timer ();
				HoverState.Timer.Enabled = false;
				HoverState.Timer.Interval = HoverState.Interval;
				HoverState.Timer.Tick += new EventHandler (MouseHover);
				HoverState.X = -1;
				HoverState.Y = -1;
				
				ActiveWindow = IntPtr.Zero;
				FocusWindow = IntPtr.Zero;
				ModalWindows = new Stack (3);
				
				MouseState = MouseButtons.None;
				MousePosition = new Point (0, 0);
				
				Caret.Timer = new Timer ();
				Caret.Timer.Interval = 500;		// FIXME - where should this number come from?
				Caret.Timer.Tick += new EventHandler (CaretCallback);
				
				SetupAtoms ();
				
				// Grab atom changes off the root window to catch certain WM events
				gdk_window_set_events (GdkRootWindow, (int)GdkEventMask.GDK_PROPERTY_CHANGE_MASK);
				
				// Handle any upcoming errors
				ErrorHandler = new XErrorHandler (HandleError);
				XSetErrorHandler (ErrorHandler);
			} else {
				throw new ArgumentNullException ("Display", "Could not open display (X-Server required. Check your DISPLAY environment variable)");
			}
		}
Exemple #15
0
        protected override void OnOutput(byte[] buf, int offset, int count)
        {
            int size = count;

            Pollfd[] fds = new Pollfd[1];
            fds[0].fd     = _socket.Handle;
            fds[0].events = PollEvents.POLLOUT;

            if (Logger.IsDebugEnabled)
            {
                Logger.Debug("\n\n" + Utilities.HexDump(buf, offset, count));
            }

            int expires = Environment.TickCount + Timeout;
            int wait    = 0;

            for (;;)
            {
                try
                {
                    wait           = Math.Max(0, expires - Environment.TickCount);
                    fds[0].revents = 0;

                    int ret = Syscall.poll(fds, wait);

                    if (UnixMarshal.ShouldRetrySyscall(ret))
                    {
                        continue;
                    }

                    UnixMarshal.ThrowExceptionForLastErrorIf(ret);

                    if (ret == 0)
                    {
                        throw new TimeoutException();
                    }

                    if (ret != 1 || (fds[0].revents & PollEvents.POLLOUT) == 0)
                    {
                        continue;
                    }

                    _socket.Write(buf, offset, size);

                    return;
                }
                catch (Exception ex)
                {
                    if (ex is TimeoutException)
                    {
                        Logger.Debug("Ethernet packet not sent to {0} in {1}ms, timing out.", Interface, Timeout);
                    }
                    else
                    {
                        Logger.Error("Unable to send ethernet packet to {0}. {1}", Interface, ex.Message);
                    }

                    throw new SoftException(ex);
                }
            }
        }
		private static int ToPollfd (IntPtr source, out Pollfd destination)
		{
			throw new System.NotImplementedException();
		}
		private static extern int FromPollfd (ref Pollfd source, IntPtr destination);
Exemple #18
0
        protected override void OnOutput(BitwiseStream data)
        {
            if (Logger.IsDebugEnabled)
            {
                Logger.Debug("\n\n" + Utilities.HexDump(data));
            }

            long count = data.Length;
            //var buffer = new byte[MaxMTU];
            var buffer = new byte[CAN_MTU];
            int size   = data.Read(buffer, 0, buffer.Length);

            Pollfd[] fds = new Pollfd[1];
            fds[0].fd     = _socket.Handle;
            fds[0].events = PollEvents.POLLOUT;

            int expires = Environment.TickCount + Timeout;
            int wait    = 0;

            for (;;)
            {
                try
                {
                    wait           = Math.Max(0, expires - Environment.TickCount);
                    fds[0].revents = 0;

                    int ret = Syscall.poll(fds, wait);

                    if (UnixMarshal.ShouldRetrySyscall(ret))
                    {
                        continue;
                    }

                    UnixMarshal.ThrowExceptionForLastErrorIf(ret);

                    if (ret == 0)
                    {
                        throw new TimeoutException();
                    }

                    if (ret != 1 || (fds[0].revents & PollEvents.POLLOUT) == 0)
                    {
                        continue;
                    }

                    //_socket.Write(buffer, 0, size);
                    _socket.Write(buffer, 0, CAN_MTU);

                    if (count != size)
                    {
                        throw new Exception(string.Format("Only sent {0} of {1} byte packet.", size, count));
                    }

                    return;
                }
                catch (Exception ex)
                {
                    Logger.Error("Unable to send CAN packet to {0}. {1}", Interface, ex.Message);

                    throw new SoftException(ex);
                }
            }
        }
		public static bool TryCopy (ref Pollfd source, IntPtr destination)
		{
			return FromPollfd (ref source, destination) == 0;
		}
        /// <summary>
        /// The capture thread
        /// </summary>
        protected virtual void CaptureThread()
        {
            if (!Opened)
                throw new DeviceNotReadyException("Capture called before PcapDevice.Open()");

            var usePoll = (this is LibPcapLiveDevice) &&
                          isLibPcap && MonoUnixFound;

            // unix specific code
            int captureFileDescriptor = 0;
            if(usePoll)
            {
                // retrieve the file descriptor of the adapter for use with poll()
                captureFileDescriptor = LibPcapSafeNativeMethods.pcap_fileno(PcapHandle);
                if(captureFileDescriptor == -1)
                {
                    SendCaptureStoppedEvent(CaptureStoppedEventStatus.ErrorWhileCapturing);
                    return;
                }
            }

            LibPcapSafeNativeMethods.pcap_handler Callback = new LibPcapSafeNativeMethods.pcap_handler(PacketHandler);

            // unix specific code
#if UseMonoUnixNativeDirectly
            Pollfd[] pollFds = new Pollfd[1];
#else
            System.Array pollFds = null;
            object[] PollParameters = null;
#endif

            // Timeout chosen to allow the capture thread to loop frequently enough
            // to enable it to properly exit when the user requests it to but
            // infrequently enough to cause any noticable performance overhead
            int millisecondTimeout = 500;

            if(usePoll)
            {
#if UseMonoUnixNativeDirectly
                pollFds[0].fd = captureFileDescriptor;
                pollFds[0].events = PollEvents.POLLPRI | Mono.Unix.Native.PollEvents.POLLIN;
#else
                FieldInfo field;
                pollFds = Array.CreateInstance(PollfdType, 1);

                // create a PollFd struct instance
                var pollFd = Activator.CreateInstance(PollfdType);

                // set the descriptor field
                field = PollfdType.GetField("fd");
                field.SetValue(pollFd, captureFileDescriptor);

                // set the events field
                short eventValue = (short)(POLLIN | POLLPRI); // mask the two together
                field = PollfdType.GetField("events");
                field.SetValue(pollFd, eventValue);

                // set the Pollfd entry
                pollFds.SetValue(pollFd, 0);

                // setup the parameters we will pass to the poll() method
                PollParameters = new object[2];
                PollParameters[0] = pollFds;
                PollParameters[1] = millisecondTimeout;
#endif
            }

            while(!shouldCaptureThreadStop)
            {
                // unix specific code, we want to poll for packets
                // otherwise if we call pcap_dispatch() the read() will block
                // and won't resume until a packet arrives OR until a signal
                // occurs
                if(usePoll)
                {
                    // block here
#if UseMonoUnixNativeDirectly
                    var result = Mono.Unix.Native.Syscall.poll(pollFds, millisecondTimeout);
#else
                    object o = SyscallType.InvokeMember("poll",
                                                        BindingFlags.InvokeMethod,
                                                        Type.DefaultBinder,
                                                        null,
                                                        PollParameters);
                    int result = (int)o;
#endif

                    // if we have no poll results, just loop
                    if(result <= 0)
                    {
                        continue;
                    }

                    // fall through here to the pcap_dispatch() call
                }

                int res = LibPcapSafeNativeMethods.pcap_dispatch(PcapHandle, m_pcapPacketCount, Callback, IntPtr.Zero);

                // pcap_dispatch() returns the number of packets read or, a status value if the value
                // is negative
                if(res <= 0)
                {
                    switch (res)    // Check pcap loop status results and notify upstream.
                    {
                        case Pcap.LOOP_USER_TERMINATED:     // User requsted loop termination with StopCapture()
                            SendCaptureStoppedEvent(CaptureStoppedEventStatus.CompletedWithoutError);
                            return;
                        case Pcap.LOOP_COUNT_EXHAUSTED:     // m_pcapPacketCount exceeded (successful exit)
                        {
                            // NOTE: pcap_dispatch() returns 0 when a timeout occurrs so to prevent timeouts
                            //       from causing premature exiting from the capture loop we only consider
                            //       exhausted events to cause an escape from the loop when they are from
                            //       offline devices, ie. files read from disk
                            if(this is CaptureFileReaderDevice)
                            {
                                SendCaptureStoppedEvent(CaptureStoppedEventStatus.CompletedWithoutError);
                                return;
                            }
                            break;
                        }
                        case Pcap.LOOP_EXIT_WITH_ERROR:     // An error occurred whilst capturing.
                            SendCaptureStoppedEvent(CaptureStoppedEventStatus.CompletedWithoutError);
                            return;
                        default:    // This can only be triggered by a bug in libpcap.
                            throw new PcapException("Unknown pcap_loop exit status.");
                    }
                } else // res > 0
                {
                    // if we aren't capturing infinitely we need to account for
                    // the packets that we read
                    if(m_pcapPacketCount != Pcap.InfinitePacketCount)
                    {
                        // take away for the packets read
                        if(m_pcapPacketCount >= res)
                            m_pcapPacketCount -= res;
                        else
                            m_pcapPacketCount = 0;

                        // no more packets to capture, we are finished capturing
                        if(m_pcapPacketCount == 0)
                        {
                            SendCaptureStoppedEvent(CaptureStoppedEventStatus.CompletedWithoutError);
                            return;
                        }
                    }
                }
            }

            SendCaptureStoppedEvent(CaptureStoppedEventStatus.CompletedWithoutError);
        }
        public IDisposable Connect()
        {
            if (monitor != null)
            {
                throw new InvalidOperationException("already connected");
            }
            monitor = new Monitor(udev);
            monitor.AddMatchSubsystem("hidraw");
            monitor.EnableReceiving();
            var tokenSource = new CancellationTokenSource();
            var token       = tokenSource.Token;

            Task.Run(() => {
                try {
                    var enumerator = new Enumerator(udev);
                    enumerator.AddMatchSubsystem("hidraw");
                    enumerator.ScanDevices();
                    foreach (var device in enumerator)
                    {
                        if (token.IsCancellationRequested)
                        {
                            break;
                        }
                        var hids = TryGetHidDevices(device);
                        if (hids == null)
                        {
                            continue;
                        }
                        foreach (var hid in hids)
                        {
                            subject.OnNext(hid);
                        }
                    }
                    var pollfds = new Pollfd[] {
                        new Pollfd {
                            fd = monitor.Fd, events = PollEvents.POLLIN
                        }
                    };
                    while (!token.IsCancellationRequested)
                    {
                        // FIXME: it would be nice if we didn't wake up every 100ms
                        // not sure how to interrupt a system call though
                        // pinvoke pthread_kill() maybe?
                        var ret = Syscall.poll(pollfds, 100);
                        if (ret == -1)
                        {
                            var err = Stdlib.GetLastError();
                            if (err == Errno.EINTR)
                            {
                                continue;
                            }
                            UnixMarshal.ThrowExceptionForError(err);
                        }
                        if (token.IsCancellationRequested)
                        {
                            break;
                        }
                        if (ret == 0)
                        {
                            // timed out
                            continue;
                        }
                        if (pollfds[0].revents.HasFlag(PollEvents.POLLNVAL))
                        {
                            // monitor file descriptor is closed, monitor must
                            // have been disposed, so complete gracefully
                            break;
                        }
                        var device = monitor.TryReceiveDevice();
                        var hids   = TryGetHidDevices(device);
                        if (hids == null)
                        {
                            continue;
                        }
                        foreach (var hid in hids)
                        {
                            subject.OnNext(hid);
                        }
                    }
                    subject.OnCompleted();
                }
                catch (Exception ex) {
                    subject.OnError(ex);
                }
                finally {
                    monitor.Dispose();
                    monitor = null;
                }
            }, token);

            return(Disposable.Create(() => tokenSource.Cancel()));
        }