public static void StartAccessoryMode(USBH_RawDevice openedDevice)
 {
     openedDevice.SendSetupTransfer(
         (byte)(UsbRequestType.Vendor),
         (byte)AndroidAccessoryUsbCommands.StartAccessoryMode,
         0,
         0
         );
 }
 public static void SetAllStrings(USBH_RawDevice openedDevice, AndroidAccessoryStrings strings)
 {
     SetStringIfNotNull(openedDevice, AndroidAccessoryStringTypes.Description, strings.Description);
     SetStringIfNotNull(openedDevice, AndroidAccessoryStringTypes.ManufacturerName, strings.ManufacturerName);
     SetStringIfNotNull(openedDevice, AndroidAccessoryStringTypes.ModelName, strings.ModelName);
     SetStringIfNotNull(openedDevice, AndroidAccessoryStringTypes.SerialNumber, strings.SerialNumber);
     SetStringIfNotNull(openedDevice, AndroidAccessoryStringTypes.Uri, strings.Uri);
     SetStringIfNotNull(openedDevice, AndroidAccessoryStringTypes.Version, strings.Version);
 }
 public static void StartAccessoryMode(USBH_RawDevice openedDevice)
 {
     openedDevice.SendSetupTransfer(
         (byte)(UsbRequestType.Vendor),
         (byte)AndroidAccessoryUsbCommands.StartAccessoryMode,
         0,
         0
         );
 }
 public static void SetAllStrings(USBH_RawDevice openedDevice, AndroidAccessoryStrings strings)
 {
     SetStringIfNotNull(openedDevice, AndroidAccessoryStringTypes.Description, strings.Description);
     SetStringIfNotNull(openedDevice, AndroidAccessoryStringTypes.ManufacturerName, strings.ManufacturerName);
     SetStringIfNotNull(openedDevice, AndroidAccessoryStringTypes.ModelName, strings.ModelName);
     SetStringIfNotNull(openedDevice, AndroidAccessoryStringTypes.SerialNumber, strings.SerialNumber);
     SetStringIfNotNull(openedDevice, AndroidAccessoryStringTypes.Uri, strings.Uri);
     SetStringIfNotNull(openedDevice, AndroidAccessoryStringTypes.Version, strings.Version);
 }
Example #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="UsbShuttlePro"/> class.
        /// </summary>
        /// <param name="device">USB Host RAW Device</param>
        public UsbShuttlePro(USBH_Device device)
        {
            jogWheel = new USBH_RawDevice(device);
            var cd = jogWheel.GetConfigurationDescriptors(0);

            jogWheel.SendSetupTransfer(0x00, 0x09, cd.bConfigurationValue, 0x00);
            var jogWheelEp = cd.interfaces[0].endpoints[0];

            jogWheelPipe = jogWheel.OpenPipe(jogWheelEp);
            jogWheelPipe.TransferTimeout = 0;

            jogWheelThread = ThreadFactory.CreateThread(JogReaderMonitor, ThreadPriority.Highest);
            jogWheelThread.Start();
        }
 static void SetStringIfNotNull(USBH_RawDevice openedDevice, AndroidAccessoryStringTypes stringType, string value)
 {
     if (value != null)
     {
         var utf8Bytes = StringToUtf8NulTerminatedByteArray(value);
         openedDevice.SendSetupTransfer(
             (byte)(UsbRequestType.Vendor),
             (byte)AndroidAccessoryUsbCommands.SetString,
             0,
             (ushort)stringType,
             utf8Bytes,
             0,
             utf8Bytes.Length
             );
     }
 }
        public PS3Controller(USBH_Device device)
        {
            if (device.VENDOR_ID != PS3_VENDOR_ID || device.PRODUCT_ID != PS3_PRODUCT_ID)
            {
                throw new InvalidOperationException();
            }

            raw = new USBH_RawDevice(device);
            USBH_Descriptors.Configuration cd = raw.GetConfigurationDescriptors(0);

            readPipe = raw.OpenPipe(cd.interfaces[0].endpoints[1]); // to read buttons
            readPipe.TransferTimeout = 0;
            //Set configuration
            raw.SendSetupTransfer(0x00, 0x09, cd.bConfigurationValue, 0x00);

            //Set the BD address automatically
            SetBD_Addr(Bluetooth.BDaddr);

            try
            {
                //request the PS3 controller to send button presses etc back
                //Host to device (0x00) | Class (0x20) | Interface (0x01), Set Report (0x09), Report Type (Feature 0x03) - Report ID (0xF4), Host to device (0x00) - Endpoint 0 (0x00), data, dataoffset, datalength
                raw.SendSetupTransfer(0x21, 0x09, 0x03F4, 0x0000, enableUSB, 0x00, 0x04);
            }
            catch (Exception ex)
            {
                Debug.Print("==============================");
                Debug.Print(DateTime.Now.ToString());
                Debug.Print(ex.Message);
                Debug.Print(ex.StackTrace);
                if (ex.InnerException != null)
                {
                    Debug.Print("Inner Exception: " + ex.InnerException.Message);
                }
            }

            for (int i = 0; i < OUTPUT_REPORT_BUFFER.Length; i++)
            {
                writeBuffer[i] = OUTPUT_REPORT_BUFFER[i];
            }

            PS3Thread          = new Thread(ReaderThread); // create the polling thread
            PS3Thread.Priority = ThreadPriority.Highest;   // we should read as fast as possible
            PS3Thread.Start();
        }
Example #8
0
        Thread PS3ReadThread;//The LED and rumble values, has to be written again and again, for it to stay turned on

        public PS3Navigation(USBH_Device device)
        {
            if (device.VENDOR_ID != PS3NAVIGATION_VENDOR_ID || device.PRODUCT_ID != PS3NAVIGATION_PRODUCT_ID)
            {
                throw new InvalidOperationException();
            }

            raw = new USBH_RawDevice(device);
            USBH_Descriptors.Configuration cd = raw.GetConfigurationDescriptors(0);

            readPipe = raw.OpenPipe(cd.interfaces[0].endpoints[1]);
            readPipe.TransferTimeout = 0;

            //Set configuration
            raw.SendSetupTransfer(0x00, 0x09, cd.bConfigurationValue, 0x00);

            //Set the BD address automatically
            SetBD_Addr(Bluetooth.BDaddr);

            try
            {
                //request the PS3 controller to send button presses etc back
                //Host to device (0x00) | Class (0x20) | Interface (0x01), Set Report (0x09), Report Type (Feature 0x03) - Report ID (0xF4), Host to device (0x00) - Endpoint 0 (0x00), data, dataoffset, datalength
                raw.SendSetupTransfer(0x21, 0x09, 0x03F4, 0x0000, PS3Controller.enableUSB, 0x00, 0x04);
            }
            catch (Exception ex)
            {
                Debug.Print("==============================");
                Debug.Print(DateTime.Now.ToString());
                Debug.Print(ex.Message);
                Debug.Print(ex.StackTrace);
                if (ex.InnerException != null)
                {
                    Debug.Print("Inner Exception: " + ex.InnerException.Message);
                }
            }

            PS3NavigationConnected = true;
            PS3ReadThread          = new Thread(ReaderThread);// create the write thread - needed for the LED's and rumble to stay turned on
            PS3ReadThread.Priority = ThreadPriority.Highest;
            PS3ReadThread.Start();
        }
        public static int GetProtocol(USBH_RawDevice openedDevice)
        {
            var dataBytes = new byte[2];

            try
            {
                openedDevice.SendSetupTransfer(
                    (byte)(UsbRequestType.DeviceToHost | UsbRequestType.Vendor),
                    (byte)AndroidAccessoryUsbCommands.GetProtocol,
                    0,
                    1,
                    dataBytes,
                    0,
                    dataBytes.Length
                    );
            }
            catch (Exception)
            {
                // SendSetupTransfer will just blow a generic Exception if it
                // fails. If this gets changed, catch the more specific
                // Exception instead. Right now the USB host code always
                // throws Exception when anything goes wrong, and then you use
                // USBHostController.GetLastError to see what happened.
                //
                // See http://www.tinyclr.com/forum/2/3367/ for details.

                if (USBHostController.GetLastError() == USBH_ERROR.NoError)
                {
                    // Some other kind of Exception -- let it fly
                    throw;
                }

                // Fake a nonsensical protocol version to signal to the caller
                // that it's not gonna happen. dataBytes should still be 0
                // but just to make sure I'll reset it.

                dataBytes[0] = 0;
                dataBytes[1] = 0;
            }
            return((dataBytes[1] << 8) | dataBytes[0]);
        }
        public PS3Navigation(USBH_Device device)
        {
            if (device.VENDOR_ID != PS3NAVIGATION_VENDOR_ID || device.PRODUCT_ID != PS3NAVIGATION_PRODUCT_ID)
                throw new InvalidOperationException();

            raw = new USBH_RawDevice(device);
            USBH_Descriptors.Configuration cd = raw.GetConfigurationDescriptors(0);

            readPipe = raw.OpenPipe(cd.interfaces[0].endpoints[1]);
            readPipe.TransferTimeout = 0;

            //Set configuration
            raw.SendSetupTransfer(0x00, 0x09, cd.bConfigurationValue, 0x00);

            //Set the BD address automatically
            SetBD_Addr(Bluetooth.BDaddr);

            try
            {
                //request the PS3 controller to send button presses etc back
                //Host to device (0x00) | Class (0x20) | Interface (0x01), Set Report (0x09), Report Type (Feature 0x03) - Report ID (0xF4), Host to device (0x00) - Endpoint 0 (0x00), data, dataoffset, datalength
                raw.SendSetupTransfer(0x21, 0x09, 0x03F4, 0x0000, PS3Controller.enableUSB, 0x00, 0x04);
            }
            catch (Exception ex)
            {
                Debug.Print("==============================");
                Debug.Print(DateTime.Now.ToString());
                Debug.Print(ex.Message);
                Debug.Print(ex.StackTrace);
                if (ex.InnerException != null)
                {
                    Debug.Print("Inner Exception: " + ex.InnerException.Message);
                }
            }

            PS3NavigationConnected = true;
            PS3ReadThread = new Thread(ReaderThread);// create the write thread - needed for the LED's and rumble to stay turned on
            PS3ReadThread.Priority = ThreadPriority.Highest;
            PS3ReadThread.Start();
        }
        public static int GetProtocol(USBH_RawDevice openedDevice)
        {
            var dataBytes = new byte[2];
            try
            {
                openedDevice.SendSetupTransfer(
                    (byte)(UsbRequestType.DeviceToHost | UsbRequestType.Vendor),
                    (byte)AndroidAccessoryUsbCommands.GetProtocol,
                    0,
                    1,
                    dataBytes,
                    0,
                    dataBytes.Length
                    );
            }
            catch (Exception)
            {
                // SendSetupTransfer will just blow a generic Exception if it
                // fails. If this gets changed, catch the more specific
                // Exception instead. Right now the USB host code always
                // throws Exception when anything goes wrong, and then you use
                // USBHostController.GetLastError to see what happened.
                //
                // See http://www.tinyclr.com/forum/2/3367/ for details.

                if (USBHostController.GetLastError() == USBH_ERROR.NoError)
                {
                    // Some other kind of Exception -- let it fly
                    throw;
                }

                // Fake a nonsensical protocol version to signal to the caller
                // that it's not gonna happen. dataBytes should still be 0
                // but just to make sure I'll reset it.

                dataBytes[0] = 0;
                dataBytes[1] = 0;
            }
            return (dataBytes[1] << 8) | dataBytes[0];
        }
        public PS3Move(USBH_Device device)
        {
            if (device.VENDOR_ID != PS3MOVE_VENDOR_ID || device.PRODUCT_ID != PS3MOVE_PRODUCT_ID)
                throw new InvalidOperationException();

            raw = new USBH_RawDevice(device);
            USBH_Descriptors.Configuration cd = raw.GetConfigurationDescriptors(0);

            writePipe = raw.OpenPipe(cd.interfaces[0].endpoints[0]); // to write settings (LEDs, rumble...)
            writePipe.TransferTimeout = 0;

            //Set configuration
            raw.SendSetupTransfer(0x00, 0x09, cd.bConfigurationValue, 0x00);

            //Set the BD address automatically
            SetBD_Addr(Bluetooth.BDaddr);

            SetLed(Bluetooth.Colors.Green);//Indicate that it's connected

            PS3MoveWriteThread = new Thread(WriteThread);// create the write thread - needed for the LED's and rumble to stay turned on
            PS3MoveWriteThread.Start();
        }
Example #13
0
        Thread PS3MoveWriteThread;                   //The LED and rumble values, has to be written again and again, for it to stay turned on

        public PS3Move(USBH_Device device)
        {
            if (device.VENDOR_ID != PS3MOVE_VENDOR_ID || device.PRODUCT_ID != PS3MOVE_PRODUCT_ID)
            {
                throw new InvalidOperationException();
            }

            raw = new USBH_RawDevice(device);
            USBH_Descriptors.Configuration cd = raw.GetConfigurationDescriptors(0);

            writePipe = raw.OpenPipe(cd.interfaces[0].endpoints[0]); // to write settings (LEDs, rumble...)
            writePipe.TransferTimeout = 0;

            //Set configuration
            raw.SendSetupTransfer(0x00, 0x09, cd.bConfigurationValue, 0x00);

            //Set the BD address automatically
            SetBD_Addr(Bluetooth.BDaddr);

            SetLed(Bluetooth.Colors.Green);               //Indicate that it's connected

            PS3MoveWriteThread = new Thread(WriteThread); // create the write thread - needed for the LED's and rumble to stay turned on
            PS3MoveWriteThread.Start();
        }
 static void SetStringIfNotNull(USBH_RawDevice openedDevice, AndroidAccessoryStringTypes stringType, string value)
 {
     if (value != null)
     {
         var utf8Bytes = StringToUtf8NulTerminatedByteArray(value);
         openedDevice.SendSetupTransfer(
             (byte)(UsbRequestType.Vendor),
             (byte)AndroidAccessoryUsbCommands.SetString,
             0,
             (ushort)stringType,
             utf8Bytes,
             0,
             utf8Bytes.Length
             );
     }
 }
Example #15
0
        private void DeviceConnectedEvent(USBH_Device device)
        {
            if (XBoxJoystickData != null)
            {
                //we already have one connected so we will ignore any new events
                return;
            }

            if (device.TYPE == USBH_DeviceType.Unknown && device.VENDOR_ID == vendorId && device.PRODUCT_ID == productId)
            {
#if DEBUG
                Debug.Print("XBox Controller Found");
#endif

                XBoxJoystick = new USBH_RawDevice(device);

                // Get descriptors
                USBH_Descriptors.Configuration cd = XBoxJoystick.GetConfigurationDescriptors(0);

                // communication endpoint
                USBH_Descriptors.Endpoint XBoxInputEndPoint  = null;
                USBH_Descriptors.Endpoint XboxOutputEndPoint = null;

                // look for HID class
                for (int i = 0; i < cd.interfaces.Length; i++)
                {
                    // found
                    if (cd.interfaces[i].bInterfaceSubclass == 0x5D && cd.interfaces[i].bInterfaceProtocol == 0x01)
                    {
                        if (cd.interfaces[i].endpoints.Length == 2)
                        {
                            int ep = 0;

                            // set configuration
                            XBoxJoystick.SendSetupTransfer(0x00, 0x09, cd.bConfigurationValue, 0x00);

                            XBoxInputEndPoint             = cd.interfaces[i].endpoints[ep];           // get endpoint
                            XBoxInputPipe                 = XBoxJoystick.OpenPipe(XBoxInputEndPoint); // open pipe
                            XBoxInputPipe.TransferTimeout = 0;                                        // recommended for interrupt transfers

                            ep++;

                            XboxOutputEndPoint             = cd.interfaces[i].endpoints[ep];
                            XBoxOutputPipe                 = XBoxJoystick.OpenPipe(XboxOutputEndPoint);
                            XBoxOutputPipe.TransferTimeout = 0;


                            XBoxThread = new Thread(ReaderThread)
                            {
                                Priority = ThreadPriority.Highest                                     /* we should read as fast as possible*/
                            };                                                                        // create the polling thread
                            XBoxThread.Start();


                            IsConnected = true;

                            if (ControllerConnected != null)
                            {
                                ControllerConnected(this);
                            }
                        }

                        //break;
                    }
                }
            }
        }
        long timerLEDRumble; // used to continuously set PS3 Move controller LED and rumble values

        #endregion Fields

        #region Constructors

        public Bluetooth(USBH_Device device)
        {
            if (device.VENDOR_ID != CSR_VENDOR_ID || device.PRODUCT_ID != CSR_PRODUCT_ID)//Check if the device is a Bluetooth dongle
                throw new InvalidOperationException();

            raw = new USBH_RawDevice(device);
            USBH_Descriptors.Configuration cd = raw.GetConfigurationDescriptors(0);

            IntInPipe = raw.OpenPipe(cd.interfaces[0].endpoints[0]); // Interrupt In
            BulkInPipe = raw.OpenPipe(cd.interfaces[0].endpoints[1]); // Bulk In
            BulkOutPipe = raw.OpenPipe(cd.interfaces[0].endpoints[2]); // Bulk Out

            //Add transfer timeout for better stability
            IntInPipe.TransferTimeout = 5;
            BulkInPipe.TransferTimeout = 5;

            //Set configuration
            raw.SendSetupTransfer(0x00, 0x09, cd.bConfigurationValue, 0x00);

            //Needed for PS3 Dualshock Controller to work
            for (int i = 0; i < PS3Controller.OUTPUT_REPORT_BUFFER.Length; i++)
                HIDBuffer[i + 2] = PS3Controller.OUTPUT_REPORT_BUFFER[i];//First two bytes reserved for report type and ID

            HIDBuffer[0] = 0x52;// HID BT Set_report (0x50) | Report Type (Output 0x02)
            HIDBuffer[1] = 0x01;// Report ID

            //Needed for PS3 Move Controller commands to work
            HIDMoveBuffer[0] = 0xA2;// HID BT DATA_request (0xA0) | Report Type (Output 0x02)
            HIDMoveBuffer[1] = 0x02;// Report ID

            IntInThread = new Thread(IntReadingThread);
            IntInThread.Start();

            BulkInThread = new Thread(BulkReadingThread);
            BulkInThread.Priority = ThreadPriority.Highest;
            BulkInThread.Start();

            WriteSerial("CSR Initialized");
        }
        public static void Main()
        {
            USBH_RawDevice openedDevice = null;
            var            deviceOpened = new ManualResetEvent(false);

            Debug.Print("Running");
            // Subscribe to USBH events.
            USBHostController.DeviceConnectedEvent += (device) => { Debug.Print("Device connected Vendor ID = " + device.VENDOR_ID + ", Product ID = " + device.PRODUCT_ID); openedDevice = new USBH_RawDevice(device); deviceOpened.Set(); };
            Debug.Print("Listening for events");

            deviceOpened.WaitOne();
            deviceOpened.Reset();
            Debug.Print("Got our raw device");

            Debug.Print("Vendor ID = " + openedDevice.VENDOR_ID + ", Product ID = " + openedDevice.PRODUCT_ID);

            Debug.Print("Protocol version = " + AndroidAccessoryUtil.GetProtocol(openedDevice));

            // !!! THIS Thread.Sleep IS A HACK
            // It's not clear what the problem is, but if you don't pause here
            // then the PID on restart is the old PID. I don't know if this is
            // something stupid in the USB stack (someone kept old device info
            // around) or if this is something stupid on the Android side or
            // if it's something stupid I'm doing. But this makes it feel
            // better in my environment. I would love if it went away.

            Thread.Sleep(375);
            var strings = new AndroidAccessoryStrings
            {
                Description      = "Prototype Engineering NETMF bridge",
                ManufacturerName = "Prototype Engineering, LLC",
                ModelName        = "Model 1 baby",
                SerialNumber     = "12345",
                Uri     = "http://prototype-eng.com/",
                Version = "1.2.3"
            };

            AndroidAccessoryUtil.SetAllStrings(openedDevice, strings);
            Debug.Print("Strings set");

            AndroidAccessoryUtil.StartAccessoryMode(openedDevice);

            Debug.Print("Waiting for re-enumeration");
            deviceOpened.WaitOne();
            deviceOpened.Reset();
            Debug.Print("Got our new device");

            Debug.Print("Vendor ID = " + openedDevice.VENDOR_ID + ", Product ID = " + openedDevice.PRODUCT_ID);

            // Now do the scavenger hunt for the IN / OUT endpoints

            var configurationDescriptor = openedDevice.GetConfigurationDescriptors(0);

            USBH_RawDevice.Pipe outPipe = null;
            USBH_RawDevice.Pipe inPipe  = null;

            // Set the configuration http://developer.android.com/guide/topics/usb/adk.html#establish
            openedDevice.SendSetupTransfer(0x00, 0x09, configurationDescriptor.bConfigurationValue, 0x00);

            var _interface = configurationDescriptor.interfaces[0];

            //foreach (var _interface in configurationDescriptor.interfaces)
            {
                Debug.Print("Interface class = " + _interface.bInterfaceClass + ", subclass = " + _interface.bInterfaceSubclass);

                foreach (var endpoint in _interface.endpoints)
                {
                    Debug.Print("Endpoint descriptor type = " + endpoint.bDescriptorType + ", address = " + endpoint.bEndpointAddress + ", attributes = " + endpoint.bmAttributes);
                    if ((endpoint.bEndpointAddress & 0x80) != 0)
                    {
                        Debug.Print("Opening inPipe");
                        inPipe = openedDevice.OpenPipe(endpoint);
                    }
                    else
                    {
                        Debug.Print("Opening outPipe");
                        outPipe = openedDevice.OpenPipe(endpoint);
                    }
                }
            }

            Debug.Print("Pipes opened");

            DoProtocol(inPipe, outPipe);
        }
Example #18
0
        static void DeviceConnectedEvent(USBH_Device device)
        {
            Debug.Print("Inside the DeviceConnectedEvent!");
            if (!initPhaseOneComplete)
            {
                usb = new USBH_RawDevice(device);
                USBH_Descriptors.Configuration cd    = usb.GetConfigurationDescriptors(0);
                USBH_Descriptors.Endpoint      adbEP = null;
                USBH_Descriptors.Interface     adbIF = null;

                Debug.Print("[Device, Port " + usb.PORT_NUMBER + "]");
                Debug.Print("Interface: " + usb.INTERFACE_INDEX);
                Debug.Print("ID: " + usb.ID);
                Debug.Print("Type: " + usb.TYPE);
                Debug.Print("VID: " + usb.VENDOR_ID);
                Debug.Print("PID: " + usb.PRODUCT_ID);

                // look for HID class
                for (int i = 0; i < cd.bNumInterfaces; i++)
                {
                    adbIF = cd.interfaces[i];
                    if (adbIF.bInterfaceClass == 255)
                    {
                        Debug.Print("  === Interface ===");
                        Debug.Print("  Class: " + cd.interfaces[i].bInterfaceClass);
                        Debug.Print("  SubClass: " + cd.interfaces[i].bInterfaceSubclass);
                        Debug.Print("  Number: " + cd.interfaces[i].bInterfaceNumber);
                        Debug.Print("  Protocol: " + cd.interfaces[i].bInterfaceProtocol);
                        Debug.Print("  Type: " + cd.interfaces[i].bDescriptorType);

                        for (int ep = 0; ep < adbIF.bNumberEndpoints; ep++)
                        {
                            adbEP = adbIF.endpoints[ep];

                            Debug.Print("   -- Endpoint --");
                            Debug.Print("    Attributes: " + adbIF.endpoints[ep].bmAttributes);
                            Debug.Print("    Address: " + adbIF.endpoints[ep].bEndpointAddress);
                            Debug.Print("    Type: " + adbIF.endpoints[ep].bDescriptorType);
                            Debug.Print("    Interval: " + adbIF.endpoints[ep].bInterval);
                            Debug.Print(" ");

                            string str = adbEP.bEndpointAddress.ToString();
                            Debug.Print(str);



                            switch (adbEP.bEndpointAddress)
                            {
                            case 133:                          // ADB data in , 129 = (Thunder Board)
                                adbInPipe = usb.OpenPipe(adbEP);
                                adbInPipe.TransferTimeout = 0; // recommended for interrupt transfers
                                Debug.Print("in case .133...");
                                break;

                            case 4: // ADB data out,  1 = (Thunder Board)
                                adbOutPipe = usb.OpenPipe(adbEP);
                                Debug.Print("in case 5...");
                                break;
                            }
                        }
                        initPhaseOneComplete = true;
                        Debug.Print("Phase One Complete = true!");
                    }
                }
            }
            //else
            //{
            initPhaseTwoComplete = true;
            Debug.Print("Phase Two Complete = true!");
            //}

            if (initPhaseTwoComplete)
            {
                initPhaseOneComplete = false;
                initPhaseTwoComplete = false;
                isReady = true;
                Debug.Print("isReady is true!");
            }

            if (isReady)
            {
                Debug.Print("AdbListening Thread initialised!");
                usb.SendSetupTransfer(0x00, 0x09, 0x0001, 0x0000);
                adbInThread          = new Thread(AdbListening); // create the polling thread
                adbInThread.Priority = ThreadPriority.Highest;
                adbInThread.Start();

                SendAdbMessage(A_CNXN, 16777216, 4096, hostName);
                //SendAdbMessage(A_CNXN, 16777216, 4096, hostName);
            }
        }
        private static void DoProtocol(USBH_RawDevice.Pipe inPipe, USBH_RawDevice.Pipe outPipe)
        {
            var inBuffer = new byte[inPipe.PipeEndpoint.wMaxPacketSize];
            var outBuffer = new byte[outPipe.PipeEndpoint.wMaxPacketSize];
            int bytesTransferred;
            OutputPort LED = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.LED, false);
            InputPort button = new InputPort((Cpu.Pin)FEZ_Pin.Digital.LDR, false, Port.ResistorMode.PullUp);

            while (true)
            {
                bytesTransferred = inPipe.TransferData(inBuffer, 0, 1);
                if (bytesTransferred > 0)
                {
                    Debug.Print("Received " + inBuffer[0]);
                    switch ((FezUsbCommands)inBuffer[0])
                    {
                        case FezUsbCommands.LedOff:
                            LED.Write(false);
                            break;
                        case FezUsbCommands.LedOn:
                            LED.Write(true);
                            break;
                        default:
                            break;
                    }
                    outBuffer[0] = (byte)((LED.Read() ? FezUsbResponse.LedOn : 0) | ((!button.Read()) ? FezUsbResponse.ButtonDown : 0));
                    outPipe.TransferData(outBuffer, 0, 1);
                }
            }
        }
        public static void Main()
        {
            USBH_RawDevice openedDevice = null;
            var deviceOpened = new ManualResetEvent(false);

            Debug.Print("Running");
            // Subscribe to USBH events.
            USBHostController.DeviceConnectedEvent += (device) => { Debug.Print("Device connected Vendor ID = " + device.VENDOR_ID + ", Product ID = " + device.PRODUCT_ID); openedDevice = new USBH_RawDevice(device); deviceOpened.Set(); };
            Debug.Print("Listening for events");

            deviceOpened.WaitOne();
            deviceOpened.Reset();
            Debug.Print("Got our raw device");

            Debug.Print("Vendor ID = " + openedDevice.VENDOR_ID + ", Product ID = " + openedDevice.PRODUCT_ID);

            Debug.Print("Protocol version = " + AndroidAccessoryUtil.GetProtocol(openedDevice));

            // !!! THIS Thread.Sleep IS A HACK
            // It's not clear what the problem is, but if you don't pause here
            // then the PID on restart is the old PID. I don't know if this is
            // something stupid in the USB stack (someone kept old device info
            // around) or if this is something stupid on the Android side or
            // if it's something stupid I'm doing. But this makes it feel
            // better in my environment. I would love if it went away.

            Thread.Sleep(375);
            var strings = new AndroidAccessoryStrings
            {
                Description = "Prototype Engineering NETMF bridge",
                ManufacturerName = "Prototype Engineering, LLC",
                ModelName = "Model 1 baby",
                SerialNumber = "12345",
                Uri = "http://prototype-eng.com/",
                Version = "1.2.3"
            };
            AndroidAccessoryUtil.SetAllStrings(openedDevice, strings);
            Debug.Print("Strings set");

            AndroidAccessoryUtil.StartAccessoryMode(openedDevice);

            Debug.Print("Waiting for re-enumeration");
            deviceOpened.WaitOne();
            deviceOpened.Reset();
            Debug.Print("Got our new device");

            Debug.Print("Vendor ID = " + openedDevice.VENDOR_ID + ", Product ID = " + openedDevice.PRODUCT_ID);

            // Now do the scavenger hunt for the IN / OUT endpoints

            var configurationDescriptor = openedDevice.GetConfigurationDescriptors(0);
            USBH_RawDevice.Pipe outPipe = null;
            USBH_RawDevice.Pipe inPipe = null;

            // Set the configuration http://developer.android.com/guide/topics/usb/adk.html#establish
            openedDevice.SendSetupTransfer(0x00, 0x09, configurationDescriptor.bConfigurationValue, 0x00);

            var _interface = configurationDescriptor.interfaces[0];
            //foreach (var _interface in configurationDescriptor.interfaces)
            {
                Debug.Print("Interface class = " + _interface.bInterfaceClass + ", subclass = " + _interface.bInterfaceSubclass);

                foreach (var endpoint in _interface.endpoints)
                {
                    Debug.Print("Endpoint descriptor type = " + endpoint.bDescriptorType + ", address = " + endpoint.bEndpointAddress + ", attributes = " + endpoint.bmAttributes);
                    if ((endpoint.bEndpointAddress & 0x80) != 0)
                    {
                        Debug.Print("Opening inPipe");
                        inPipe = openedDevice.OpenPipe(endpoint);
                    }
                    else
                    {
                        Debug.Print("Opening outPipe");
                        outPipe = openedDevice.OpenPipe(endpoint);
                    }
                }
            }

            Debug.Print("Pipes opened");

            DoProtocol(inPipe, outPipe);
        }