public static void startBootloader(Smc device) { Console.WriteLine("Entering bootloader mode..."); string serialNumber = device.getSerialNumber(); device.startBootloader(); device.Dispose(); Console.WriteLine("Waiting for bootloader to connect..."); int msElapsed = 0; while (true) { foreach (DeviceListItem dli in Smc.getConnectedBootloaders()) { if (dli.serialNumber.Replace("-", "") == serialNumber.Replace("-", "")) { Console.WriteLine("Successfully entered bootloader mode."); return; } } System.Threading.Thread.Sleep(20); msElapsed += 20; if (msElapsed > 8000) { throw new Exception("Failed to enter bootloader mode: timeout elapsed."); } } }
/// <summary> /// This funnction does all the real work. It will /// throw an exception if anything goes wrong. /// </summary> static void MainWithExceptions(string[] args) { // Parse all the command-line arguments, turning them in to a list of // actions to be taken. No actions on the device will occur until // all the arguments have been processed and validated. List <Action> actions = new List <Action>(); List <ActionOnDevice> actionsOnDevice = new List <ActionOnDevice>(); // If the user specifies a device serial number, it will be stored here. String specifiedSerialNumber = null; // Create a list object because it is easier to work with. List <String> argList = new List <String>(args); // Search for the -f option. This must be done ahead of time so that // it can be any place in the command line. forceOption = argList.Contains("-f"); argEnumerator = argList.GetEnumerator(); while (argEnumerator.MoveNext()) { // Read the next argument and decide what to do. switch (argEnumerator.Current) { case "-f": // Ignore, because we already searched for "-f". break; case "-l": case "--list": actions.Add(listDevices); break; case "-d": case "--device": if (specifiedSerialNumber != null) { throw new Exception("Only one -d/--device argument is alllowed."); } // Remove the leading # sign. It is not standard to put it there, // but if someone writes it, this program should still work. specifiedSerialNumber = nextArgument().TrimStart('#'); break; case "-s": case "--status": actionsOnDevice.Add(printStatus); break; case "--stop": actionsOnDevice.Add(stop); break; case "--resume": actionsOnDevice.Add(resume); break; case "--speed": actionsOnDevice.Add(laterSetSpeed()); break; case "--brake": actionsOnDevice.Add(laterSetBrake()); break; case "--restoredefaults": actionsOnDevice.Add(restoreDefaults); break; case "--configure": actionsOnDevice.Add(laterConfigure()); break; case "--getconf": actionsOnDevice.Add(laterGetConf()); break; case "--bootloader": actionsOnDevice.Add(startBootloader); break; case "--max-speed": actionsOnDevice.Add(laterSetMotorLimit(SmcMotorLimit.MaxSpeed)); break; case "--max-accel": actionsOnDevice.Add(laterSetMotorLimit(SmcMotorLimit.MaxAcceleration)); break; case "--max-decel": actionsOnDevice.Add(laterSetMotorLimit(SmcMotorLimit.MaxDeceleration)); break; case "--brake-dur": actionsOnDevice.Add(laterSetMotorLimit(SmcMotorLimit.BrakeDuration)); break; case "--max-speed-forward": actionsOnDevice.Add(laterSetMotorLimit(SmcMotorLimit.MaxSpeed | SmcMotorLimit.ForwardOnly)); break; case "--max-accel-forward": actionsOnDevice.Add(laterSetMotorLimit(SmcMotorLimit.MaxAcceleration | SmcMotorLimit.ForwardOnly)); break; case "--max-decel-forward": actionsOnDevice.Add(laterSetMotorLimit(SmcMotorLimit.MaxDeceleration | SmcMotorLimit.ForwardOnly)); break; case "--brake-dur-forward": actionsOnDevice.Add(laterSetMotorLimit(SmcMotorLimit.BrakeDuration | SmcMotorLimit.ForwardOnly)); break; case "--max-speed-reverse": actionsOnDevice.Add(laterSetMotorLimit(SmcMotorLimit.MaxSpeed | SmcMotorLimit.ReverseOnly)); break; case "--max-accel-reverse": actionsOnDevice.Add(laterSetMotorLimit(SmcMotorLimit.MaxAcceleration | SmcMotorLimit.ReverseOnly)); break; case "--max-decel-reverse": actionsOnDevice.Add(laterSetMotorLimit(SmcMotorLimit.MaxDeceleration | SmcMotorLimit.ReverseOnly)); break; case "--brake-dur-reverse": actionsOnDevice.Add(laterSetMotorLimit(SmcMotorLimit.BrakeDuration | SmcMotorLimit.ReverseOnly)); break; default: throw new ArgumentException("Unrecognized argument \"" + argEnumerator.Current + "\"."); } } if (actions.Count == 0 && actionsOnDevice.Count == 0) { throw new ArgumentException("No actions specified."); } // Perform all actions that don't require being connected to a device. foreach (Action action in actions) { action(); } if (actionsOnDevice.Count == 0) { // There are no actions that require a device, so exit successfully. return; } // Find the right device to connect to. List <DeviceListItem> list = Smc.getConnectedDevices(); DeviceListItem item = null; if (specifiedSerialNumber == null) { // No serial number specified: connect to the first item in the list. if (list.Count > 0) { item = list[0]; } } else { // Find the device with the specified serial number. foreach (DeviceListItem checkItem in list) { if (checkItem.serialNumber == specifiedSerialNumber) { item = checkItem; break; } } } if (item == null && actionsOnDevice.Count == 1 && actionsOnDevice[0] == startBootloader) { // The correct device was not found, but all the user wanted to do was enter // bootloader mode so we should see if the device is connected in bootloader // mode and report success if that is true. List <DeviceListItem> bootloaders = Smc.getConnectedBootloaders(); if (specifiedSerialNumber == null) { if (bootloaders.Count > 0) { item = bootloaders[0]; } } else { // Find the device with the specified serial number. foreach (DeviceListItem checkItem in bootloaders) { if (checkItem.serialNumber.Replace("-", "") == specifiedSerialNumber.Replace("-", "")) { item = checkItem; break; } } } if (item == null) { if (specifiedSerialNumber == null) { throw new Exception("No " + Smc.namePlural + " (or bootloaders) found."); } else { throw new Exception("Could not find a device or bootloader with serial number " + specifiedSerialNumber + ".\n" + "To list devices, use the --list option."); } } Console.WriteLine("The device is already in bootloader mode."); return; } if (item == null) { if (specifiedSerialNumber == null) { throw new Exception("No " + Smc.namePlural + " found."); } else { throw new Exception("Could not find a device with serial number " + specifiedSerialNumber + ".\n" + "To list device, use the --list option."); } } // All the command-line arguments were good and a matching device was found, so // connect to it. Smc device = new Smc(item); // Perform all the previously computed actions on the device. foreach (ActionOnDevice action in actionsOnDevice) { action(device); } }