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