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