示例#1
0
        static void Main(string[] args)
        {
            VicarDevice vicar = null;

              try
              {
            /* Parse command-line arguments */

            //Get specified demo
            Demo demo;
            var raw = _GetCommandArgumentValue("demo");
            if (!Enum.TryParse(raw, out demo))
            {
              throw new ArgumentException("No or invalid demo specified: " + raw);
            }

            //Get preferred operating mode
            VicarDevice.OperatingMode mode;
            if (!Enum.TryParse(_GetCommandArgumentValue("mode"), out mode))
            {
              //Custom is default/preferred mode, which can be faster
              mode = VicarDevice.OperatingMode.Custom;
            }

            //Get preferred device configurations
            VicarDevice.AdditionalCustomInterface? configs = null;
            raw = _GetCommandArgumentValue("configs");
            if (!string.IsNullOrEmpty(raw))
            {
              foreach (var r in raw.Split(new char[] { '|' }))
              {
            VicarDevice.AdditionalCustomInterface c;
            if (Enum.TryParse<VicarDevice.AdditionalCustomInterface>(r, out c))
            {
              if (!configs.HasValue)
              {
                configs = VicarDevice.AdditionalCustomInterface.None;
              }

              configs |= c;
            }
              }
            }

            //Get logging verbosity
            Settings.UseVerboseLogging = args.Any(t => t.ToLower() == "/verbose");

            bool sentConfig = false;
            Console.WriteLine(string.Format("Waiting for '{0}' device connection...", mode));
            while (true)
            {
              var devicePaths = VicarDevice.GetDevicePaths();
              if (devicePaths.Any())
              {
            //Go with the first mode found (preferably the one specified)
            var paths = devicePaths.OrderByDescending(t => t.Key == mode).First();

            //Pass no more than 2 interfaces (which HID would use)
            if (vicar != null)
            {
              vicar.Close();
            }

            try
            {
              vicar = new VicarDevice(paths.Key, paths.Value.Take(Math.Min(paths.Value.Count, 2)).ToArray());
              vicar.Open();

              if (vicar.Mode != mode)
              {
                Console.WriteLine(string.Format("'{0}' mode detected, switching to '{1}'...",
                  vicar.Mode, mode));
                vicar.SetOperatingMode(mode);
                vicar.Close();

                //Wait a little bit for things to re-enumerate
                Thread.Sleep(3000);
              }
              else if (!sentConfig && configs.HasValue && vicar.Configurations != configs.Value)
              {
                sentConfig = true;
                Console.WriteLine(string.Format("Setting specified device configuration..."));
                vicar.SetDeviceConfiguration(configs.Value);

                //Wait a little bit for things to re-enumerate
                Thread.Sleep(3000);
              }
              else
              {
                break;
              }
            }
            catch
            {
              //Eat it...
            }
              }

              if (Console.KeyAvailable)
              {
            if (Console.ReadKey(true).Key == ConsoleKey.Escape)
            {
              Console.WriteLine("[ESC] pressed; aborting...");
              if (vicar != null)
              {
                vicar.Close();
                vicar = null;
              }
            }
              }

              //Don't hog the CPU while we wait
              Thread.Sleep(100);
            }

            if (vicar != null)
            {
              Console.WriteLine("Device detected, allowing peripheral detection...");
              vicar.AllowPeripheralDetection(true);
              Console.WriteLine("Waiting for peripheral to become attached...");
              vicar.WaitUntilPeripheralConnected();
              Console.WriteLine("Peripheral is attached. Moving on...");

              //Get the first 8 bytes of the device descriptor
              byte address = 0x00;
              var m = vicar.SendControlRequest(address, 0x80, 0x06, 0x0100, 0x0000, 0x0008, null);

              //Set the address
              vicar.SendControlRequest(address, 0x00, 0x05, ++address, 0x0000, 0x0000);

              //Set the control endpoint's maximum packet size (or just assume 0x08 if we can't)
              //This is necessary to enable large control transfers on this address
              var bMaxPacketSize0 = (byte)(m.Length >= 8 ? m[7] : 0x08); //just stick with 0x08, I guess
              vicar.ConfigureEndpoint(address, 0x00, bMaxPacketSize0, true);

              //Get the configuration descriptor (once to get the size, and again to get the whole thing)
              //  (or just assume 0xFF if we can't)
              var configDescriptor = vicar.SendControlRequest(address, 0x80, 0x06, 0x0200, 0x0000, 4);
              var length = configDescriptor.Length >= 4 ? Utilities.ToLittleEndianUshort(configDescriptor, 2)
            : (ushort)0xFF;
              configDescriptor = vicar.SendControlRequest(address, 0x80, 0x06, 0x0200, 0x0000, length);

              //Get the incoming and outgoing endpoints from any endpoint descriptors
              int i = 0;
              while (i < configDescriptor.Length)
              {
            if (configDescriptor[i + 1] == 0x05)
            {
              //Endpoint descriptor
              var ep = configDescriptor[i + 2];
              var maxPacketSize = Utilities.ToLittleEndianUshort(configDescriptor, i + 4);
              if ((ep & 0x80) > 0)
              {
                //Incoming endpoint
                if (!IncomingEndpoint.HasValue)
                {
                  IncomingEndpoint = ep;
                  IncomingEndpointMaxPacketSize = maxPacketSize;
                }
              }
              else
              {
                //Outgoing endpoint
                if (!OutgoingEndpoint.HasValue)
                {
                  OutgoingEndpoint = ep;
                  OutgoingEndpointMaxPacketSize = maxPacketSize;
                }
              }
            }

            i += configDescriptor[i];
              }

              //Set the device configuration (assuming 1)
              vicar.SendControlRequest(address, 0x00, 0x09, 0x0001, 0x0000, 0x0000);

              //Get the max LUN
              //vicar.SendControlRequest(address, 0xA1, 0xFE, 0x0000, 0x0000, 0x0001);

              //Configure the two endpoints
              //The device will auto-poll them and alert us of any new data (if not using URBs)

              if (IncomingEndpoint.HasValue)
              {
            vicar.ConfigureEndpoint(0x01, IncomingEndpoint.Value, IncomingEndpointMaxPacketSize,
              demo == Demo.MassStorageForwarding || !UseUrbs);
              }

              if (OutgoingEndpoint.HasValue)
              {
            vicar.ConfigureEndpoint(0x01, OutgoingEndpoint.Value, OutgoingEndpointMaxPacketSize, true);
              }

              switch (demo)
              {
            case Demo.MassStorage:
              {
                _DoMassStorageDemo(vicar);

                break;
              }

            case Demo.MassStorageForwarding:
              {
                vicar.EnableInterfaceForwarding(true, 0x01, IncomingEndpoint.GetValueOrDefault(),
                  OutgoingEndpoint.GetValueOrDefault());
                Console.WriteLine("Forwarding is enabled. Press any key to quit.");
                Console.ReadKey(true);

                break;
              }

            case Demo.SimulateKeyboard:
              {
                while (true)
                {
                  Console.WriteLine("Enter a string and press enter. It will be echoed back to you in 5 seconds.");
                  Console.WriteLine("Enter a blank line to quit.");
                  Console.Write("> ");
                  var line = Console.ReadLine();
                  if (string.IsNullOrEmpty(line))
                  {
                    break;
                  }

                  Thread.Sleep(5000);
                  _SendString(vicar, line);
                  _SendKey(vicar, 0x00, 0x28);
                }

                break;
              }

            default:
              {
                break;
              }
              }

              vicar.Close();
            }
            else
            {
              Console.WriteLine("No device detected; exiting.");
            }
              }
              catch (Exception ex)
              {
            Console.WriteLine("FATAL: " + ex.ToString());
              }
              finally
              {
            if (Debugger.IsAttached)
            {
              Console.WriteLine("Press any key to exit the application.");
              Console.ReadKey(true);
            }
              }
        }