/// <summary> /// upload to Parrot boards /// </summary> /// <param name="filename"></param> public bool UploadParrot(string filename, BoardDetect.boards board) { string vehicleName = board.ToString().Substring(0, 1).ToUpper() + board.ToString().Substring(1).ToLower(); Ping ping = new Ping(); PingReply pingReply = pingParrotVehicle(ping); updateProgress(0, "Trying to connect to " + vehicleName); if (pingReply == null || pingReply.Status != IPStatus.Success) { bool ssidFound = isParrotWifiConnected(vehicleName); if (!ssidFound) { CustomMessageBox.Show("Please connect to " + vehicleName + " Wifi now and after that press OK", vehicleName, MessageBoxButtons.OK); ssidFound = isParrotWifiConnected(vehicleName); pingReply = pingParrotVehicle(ping); } while (pingReply == null || pingReply.Status != IPStatus.Success) { if (!ssidFound) { if (CustomMessageBox.Show("You don't seem connected to " + vehicleName + " Wifi. Please connect to it and press OK to try again", vehicleName, MessageBoxButtons.OKCancel) == DialogResult.Cancel) { return false; } } else if (CustomMessageBox.Show("You seem connected to " + vehicleName + " Wifi but it didn't answer our request. Do you want to try again?", vehicleName, MessageBoxButtons.OKCancel) == DialogResult.Cancel) { return false; } ssidFound = isParrotWifiConnected(vehicleName); pingReply = pingParrotVehicle(ping); } } try { AdbServer.Instance.StartServer("adb.exe", true); IAdbClient adbClient = AdbClient.Instance; string response = adbClient.Connect(new DnsEndPoint("192.168.42.1", 9050)); if (!response.Contains("connected to 192.168.42.1:9050")) { string ntimes = "four"; if (board == BoardDetect.boards.disco) { ntimes = "two"; } CustomMessageBox.Show("Please press " + vehicleName + " Power button " + ntimes + " times", vehicleName, MessageBoxButtons.OK); response = adbClient.Connect(new DnsEndPoint("192.168.42.1", 9050)); while (!response.Contains("connected to 192.168.42.1:9050")) { if (CustomMessageBox.Show("Couldn't contact " + vehicleName + ". Press the Power button " + ntimes + " times. Do you want to try to connect again?", vehicleName, MessageBoxButtons.OKCancel) == DialogResult.Cancel) { return false; } response = adbClient.Connect(new DnsEndPoint("192.168.42.1", 9050)); } } DeviceData device = adbClient.GetDevices().First(); ConsoleOutputReceiver consoleOut = new ConsoleOutputReceiver(); try { using (SyncService service = new SyncService(device)) { using (FileStream stream = File.OpenRead(filename)) { updateProgress(10, "Uploading software..."); service.Push(stream, "/data/ftp/internal_000/APM/" + (board == BoardDetect.boards.disco ? "apm-plane-disco" : "arducopter"), 777, DateTime.Now, CancellationToken.None); updateProgress(50, "Software uploaded"); } if (board != BoardDetect.boards.disco) { using (MemoryStream stream = new MemoryStream()) using (StreamReader sr = new StreamReader(stream)) { updateProgress(60, "Looking for need to update init scripts..."); service.Pull("/etc/init.d/rcS_mode_default", stream, CancellationToken.None); bool initChanged = false; List<string> initLines = new List<string>(); string[] initAPLines = { "if test -x /data/ftp/internal_000/APM/start_ardupilot.sh && test -x /data/ftp/internal_000/APM/arducopter; then", " /data/ftp/internal_000/APM/start_ardupilot.sh &", "else" }; int[] initAPLinesIndex = Enumerable.Repeat(-1, initAPLines.Length).ToArray(); int dragonLineIndex = -1; stream.Seek(0, SeekOrigin.Begin); while (!sr.EndOfStream) { string line = sr.ReadLine(); int dragonIndex = line.IndexOf("DragonStarter.sh"); bool acLine = line.ToLower().Trim().StartsWith("arducopter"); if (dragonIndex != -1) { int dragonCommentIndex = line.IndexOf('#'); if (dragonCommentIndex != -1 && dragonCommentIndex < dragonIndex) { line = line.Remove(dragonCommentIndex, 1); initChanged = true; } if (line.Substring(0, 2) != " ") { line = line.Insert(0, " "); initChanged = true; } dragonLineIndex = initLines.Count; } else if (acLine) { initChanged = true; continue; } else { foreach (int i in Enumerable.Range(0, initAPLines.Length)) { if (line == initAPLines[i]) { initAPLinesIndex[i] = initLines.Count; break; } } } initLines.Add(line); } if (initAPLinesIndex[0] == -1 || initAPLinesIndex[1] != (initAPLinesIndex[0] + 1) || initAPLinesIndex[2] != (initAPLinesIndex[1] + 1) || dragonLineIndex != (initAPLinesIndex[2] + 1)) { foreach(int i in initAPLinesIndex) { if(i != -1) { if (i < dragonLineIndex) dragonLineIndex--; initLines.RemoveAt(i); } } initLines.InsertRange(dragonLineIndex, initAPLines); if (initLines[dragonLineIndex + initAPLines.Length + 1] != "fi") { initLines.Insert(dragonLineIndex + initAPLines.Length + 1, "fi"); } initChanged = true; } string startAPText = "#!/bin/sh\n\n" + "# startup fan\n" + "echo 1 > /sys/devices/platform/user_gpio/FAN/value\n\n" + "while :; do\n" + " ulogger -t \"rcS_mode_default\" -p I \"Launching ArduPilot\"\n" + " /data/ftp/internal_000/APM/arducopter -A udp:192.168.42.255:14550:bcast -B /dev/ttyPA1 -C udp:192.168.42.255:14551:bcast -l /data/ftp/internal_000/APM/logs -t /data/ftp/internal_000/APM/terrain\n" + "done\n"; // if the above script is changed, change this date to a future date DateTime startAPDate = new DateTime(2016, 10, 21, 05, 10, 19); FileStatistics startAPStat = service.Stat("/data/ftp/internal_000/APM/start_ardupilot.sh"); if (startAPStat.FileMode == 0 || startAPStat.Time.CompareTo(startAPDate) < 0) { updateProgress(70, "Uploading ArduPilot startup script..."); using (MemoryStream startScriptStream = new MemoryStream(sr.CurrentEncoding.GetBytes(startAPText))) { service.Push(startScriptStream, "/data/ftp/internal_000/APM/start_ardupilot.sh", 777, startAPDate, CancellationToken.None); } } FileStatistics binaryStat = service.Stat("/usr/bin/arducopter"); if (initChanged || (binaryStat.FileMode.HasFlag(UnixFileMode.Regular))) { adbClient.ExecuteRemoteCommand("mount -o remount,rw /", device, consoleOut); if (binaryStat.FileMode.HasFlag(UnixFileMode.Regular)) { // remove old binary location adbClient.ExecuteRemoteCommand("rm -f /usr/bin/arducopter", device, consoleOut); } if (initChanged) { // only backup init file if a backup doesn't exist adbClient.ExecuteRemoteCommand("mv -n /etc/init.d/rcS_mode_default /etc/init.d/rcS_mode_default.backup", device, consoleOut); updateProgress(80, "Writing modified init script"); stream.SetLength(0); using (StreamWriter sw = new StreamWriter(stream, sr.CurrentEncoding)) { sw.NewLine = "\n"; initLines.ForEach(line => sw.WriteLine(line)); sw.Flush(); stream.Seek(0, SeekOrigin.Begin); service.Push(stream, "/etc/init.d/rcS_mode_default", 755, DateTime.Now, CancellationToken.None); // a bug in 'adb push' sets 'group' and 'other' permissions equal to 'owner' so we run chmod to have the correct original permissions adbClient.ExecuteRemoteCommand("chmod 755 /etc/init.d/rcS_mode_default", device, consoleOut); } } } updateProgress(90, "Scripts updated"); } } } } finally { updateProgress(100, "Rebooting..."); adbClient.ExecuteRemoteCommand("reboot.sh", device, consoleOut); } CustomMessageBox.Show("Firmware installed!"); updateProgress(-1, "Firmware installed"); } catch (Exception e) { log.Error(e); Console.WriteLine("An error occurred: " + e.ToString()); updateProgress(-1, "ERROR: " + e.Message); return false; } finally { AdbClient.Instance.KillAdb(); } return true; }
public void MkDir(string path, bool recursive = false) { var receiver = new adb.ConsoleOutputReceiver(); if (recursive) { var dir = "/"; foreach (string dirname in path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries)) { dir = dir.CombineFwdSlash(dirname); // adb.AdbClient.Instance.ExecuteRemoteCommand($"mkdir \"{dir}\"", _device, receiver); } } }