コード例 #1
0
        /// <summary>
        /// Reading
        /// </summary>
        private void ReadReport()
        {
            byte[] buff = new byte[REPORT_LENGTH];

            uint             numberOfBytesRead = 0;
            NativeOverlapped overlapped        = new NativeOverlapped();

            overlapped.EventHandle = mre.SafeWaitHandle.DangerousGetHandle();
            overlapped.OffsetHigh  = 0;
            overlapped.OffsetLow   = 0;

            bool result = HIDImports.ReadFile(this.SafeFileHandle.DangerousGetHandle(), buff, (uint)buff.Length, out numberOfBytesRead, ref overlapped);

            //Log("ReadReport: " + result.ToString());

            // parse it
            if (buff != null && result)
            {
                if (ParseInputReport(buff))
                {
                    if (WiiControllerStateChanged != null)
                    {
                        WiiControllerStateChanged(this, new WiiControllerStateChangedEventArgs(this.WiiControllerState));
                    }
                }
            }
        }
コード例 #2
0
    // clear out the USB input buffer
    public void FlushReadUSB()
    {
        // note the starting time so we don't wait forever
        DateTime t0 = DateTime.Now;

        // wait until a read would block
        int rptLen = inputReportLength;

        while ((DateTime.Now - t0).TotalMilliseconds < 100)
        {
            // set up a non-blocking read
            IntPtr buf = Marshal.AllocHGlobal(rptLen);
            try
            {
                unsafe
                {
                    // set up the overlapped I/O descriptor
                    Overlapped        o  = new Overlapped(0, 0, evov.SafeWaitHandle.DangerousGetHandle(), null);
                    NativeOverlapped *no = o.Pack(null, null);

                    // start the non-blocking read
                    Marshal.WriteByte(buf, 0);
                    HIDImports.ReadFile(fp, buf, rptLen, IntPtr.Zero, no);

                    // check to see if it's ready immediately
                    bool ready = evov.WaitOne(0);
                    if (ready)
                    {
                        // it's ready - complete the read
                        UInt32 readLen;
                        int    result = HIDImports.GetOverlappedResult(fp, no, out readLen, 0);
                    }
                    else
                    {
                        // Not ready - we'd have to wait to do a read, so the
                        // buffer is empty.  Cancel the read.
                        HIDImports.CancelIo(fp);
                    }

                    // done with the overlapped I/O descriptor
                    Overlapped.Unpack(no);
                    Overlapped.Free(no);

                    // if there was nothing ready to read, we've cleared out buffered
                    // inputs, so we're done
                    if (!ready)
                    {
                        return;
                    }
                }
            }
            finally
            {
                Marshal.FreeHGlobal(buf);
            }
        }
    }
コード例 #3
0
    public byte[] ReadUSB()
    {
        // try reading a few times, in case we lose the connection briefly
        int rptLen = inputReportLength;

        for (int tries = 0; tries < 3; ++tries)
        {
            unsafe
            {
                // set up a non-blocking ("overlapped") read
                IntPtr buf = Marshal.AllocHGlobal((int)rptLen);
                try
                {
                    Marshal.WriteByte(buf, 0);
                    Overlapped        o  = new Overlapped(0, 0, evov.SafeWaitHandle.DangerousGetHandle(), null);
                    NativeOverlapped *no = o.Pack(null, null);
                    HIDImports.ReadFile(fp, buf, rptLen, IntPtr.Zero, no);

                    // Wait briefly for the read to complete.  But don't wait forever - we might
                    // be talking to a device interface that doesn't provide the type of status
                    // report we're looking for, in which case we don't want to get stuck waiting
                    // for something that will never happen.  If this is indeed the controller
                    // interface we're interested in, it will respond within a few milliseconds
                    // with our status report.
                    if (evov.WaitOne(100))
                    {
                        // The read completed successfully!  Get the result.
                        UInt32 readLen;
                        int    result = HIDImports.GetOverlappedResult(fp, no, out readLen, 0);

                        Overlapped.Unpack(no);
                        Overlapped.Free(no);

                        if (result == 0)
                        {
                            // The read failed.  Try re-opening the file handle in case we
                            // dropped the connection, then re-try the whole read.
                            TryReopenHandle();
                            continue;
                        }
                        else if (readLen != rptLen)
                        {
                            // The read length didn't match what we expected.  This might be
                            // a different device (not a Pinscape controller) or a different
                            // version that we don't know how to talk to.  In either case,
                            // return failure.
                            return(null);
                        }
                        else
                        {
                            // The read succeed and was the correct size.  Return the data.
                            byte[] retbuf = new byte[rptLen];
                            Marshal.Copy(buf, retbuf, 0, rptLen);
                            return(retbuf);
                        }
                    }
                    else
                    {
                        // The read timed out.  This must not be our control interface after
                        // all.  Cancel the read and try reopening the handle.
                        HIDImports.CancelIo(fp);
                        Overlapped.Unpack(no);
                        Overlapped.Free(no);
                        if (TryReopenHandle())
                        {
                            continue;
                        }
                        return(null);
                    }
                }
                finally
                {
                    Marshal.FreeHGlobal(buf);
                }
            }
        }

        // don't retry more than a few times
        return(null);
    }
コード例 #4
0
        /// <summary>
        /// Reading in another Thread
        /// </summary>
        private void OnReadData(object threadSleepTime)
        {
            Log("Read Thread started");

            try
            {
                int sleepTime = (int)threadSleepTime;
                while (readAsync)
                {
                    byte[] buff = new byte[REPORT_LENGTH];

                    uint             numberOfBytesRead = 0;
                    NativeOverlapped overlapped        = new NativeOverlapped();
                    overlapped.EventHandle = mre.SafeWaitHandle.DangerousGetHandle();
                    overlapped.OffsetHigh  = 0;
                    overlapped.OffsetLow   = 0;

                    bool result = HIDImports.ReadFile(this.SafeFileHandle.DangerousGetHandle(), buff, (uint)buff.Length, out numberOfBytesRead, ref overlapped);

                    Log("ReadReport: " + result.ToString());

                    if (!result)
                    {
                        uint lastError = HIDImports.GetLastError();
                        if (lastError != HIDImports.ERROR_IO_PENDING)
                        {
                            Log("Read failed: " + lastError.ToString("X"));
                            continue;
                        }
                        else
                        {
                            if (!HIDImports.GetOverlappedResult(this.SafeFileHandle.DangerousGetHandle(), ref overlapped, out numberOfBytesRead, true))
                            {
                                lastError = HIDImports.GetLastError();
                                Log("Read failed: " + lastError.ToString("X"));
                                continue;
                            }

                            if (overlapped.InternalHigh.ToInt32() == HIDImports.STATUS_PENDING || overlapped.InternalLow.ToInt32() == HIDImports.STATUS_PENDING)
                            {
                                Log("Read interrupted " + lastError.ToString("X"));
                                if (!HIDImports.CancelIo(this.SafeFileHandle.DangerousGetHandle()))
                                {
                                    lastError = HIDImports.GetLastError();
                                    Log("CancelIO failed: " + lastError.ToString("X"));
                                    continue;
                                }
                            }
                        }
                    }

                    // parse it
                    if (buff != null)
                    {
                        if (ParseInputReport(buff))
                        {
                            if (WiiControllerStateChanged != null)
                            {
                                WiiControllerStateChanged(this, new WiiControllerStateChangedEventArgs(this.WiiControllerState));
                            }
                        }
                    }

                    Thread.Sleep(sleepTime);
                }
            }
            catch (ThreadAbortException ex)
            {
                Log("Thread abort!: " + ex.Message);
            }
        }