[parrot] factorize Parrot tools

This commit is contained in:
Gautier Hattenberger
2017-07-05 18:43:41 +02:00
parent 6b128d296d
commit 4b65a35b99
4 changed files with 669 additions and 864 deletions
File diff suppressed because it is too large Load Diff
+29 -185
View File
@@ -1,6 +1,8 @@
#!/usr/bin/env python
#
# Copyright (C) 2012-2014 The Paparazzi Team
# 2015 Freek van Tienen <freek.v.tienen@gmail.com>
# 2017 Gautier Hattenberger <gautier.hattenberger@enac.fr>
#
# This file is part of Paparazzi.
#
@@ -20,192 +22,34 @@
#
from __future__ import print_function
import re
import argparse
import os
from time import sleep
from parrot_utils import ParrotUtils
import parrot_utils
class Bebop(ParrotUtils):
uav_name = 'Bebop'
address = '192.168.42.1'
version_file = '/version.txt'
upload_path = '/data/ftp/'
check_version_before_run = True
update_time_before_run = True
def uav_status(self):
print('Parrot version:\t\t' + self.check_version())
def init_extra_parser(self):
# Parse the extra arguments
self.parser.add_argument('--min_version', metavar='MIN', default='3.3.0',
help='force minimum version allowed')
self.parser.add_argument('--max_version', metavar='MAX', default='4.0.5',
help='force maximum version allowed')
def parse_extra_args(self, args):
# nothing here
pass
# Read from config.ini TODO
def read_from_config(name, config=''):
if config == '':
config = parrot_utils.execute_command('cat /data/config.ini')
search = re.search(name + '[^=]+=[\r\n\t ]([^\r\n\t ]+)', config)
if search is None:
return ''
else:
return search.group(1)
if __name__ == "__main__":
bebop = Bebop()
bebop.parse_args()
exit(0)
# Write to config TODO
def write_to_config(name, value):
if read_from_config(name) == '':
parrot_utils.execute_command('echo "' + name + ' = ' + value + '\" >> /data/config.ini')
else:
parrot_utils.execute_command('sed -i "s/\(' + name + ' *= *\).*/\\1' + value + '/g" /data/config.ini')
def bebop_status():
#config_ini = parrot_utils.execute_command(tn, 'cat /data/config.ini')
print('======================== Bebop Status ========================')
print('Version:\t\t' + str(parrot_utils.check_version(tn, '')))
# Request the filesystem status
print('\n=================== Filesystem Status =======================')
print(parrot_utils.check_filesystem(tn))
# Parse the arguments
parser = argparse.ArgumentParser(description='Bebop helper tool. Use bebop.py -h for help')
parser.add_argument('--host', metavar='HOST', default='192.168.42.1',
help='the ip address of bebop')
parser.add_argument('--min_version', metavar='MIN', default='3.3.0',
help='force minimum version allowed')
parser.add_argument('--max_version', metavar='MAX', default='4.0.5',
help='force maximum version allowed')
subparsers = parser.add_subparsers(title='Command to execute', metavar='command', dest='command')
# All the subcommands and arguments
subparsers.add_parser('status', help='Request the status of the Bebop')
subparsers.add_parser('reboot', help='Reboot the Bebop')
subparser_upload_and_run = subparsers.add_parser('upload_file_and_run', help='Upload and run software (for instance the Paparazzi autopilot)')
subparser_upload_and_run.add_argument('file', help='Filename of an executable')
subparser_upload_and_run.add_argument('folder', help='Destination subfolder (raw for Paparazzi autopilot)')
subparser_upload = subparsers.add_parser('upload_file', help='Upload a file to the Bebop')
subparser_upload.add_argument('file', help='Filename')
subparser_upload.add_argument('folder', help='Destination subfolder (base destination folder is /data/ftp)')
subparser_download = subparsers.add_parser('download_file', help='Download a file from the Bebop')
subparser_download.add_argument('file', help='Filename (with the path on the local machine)')
subparser_download.add_argument('folder', help='Remote subfolder (base folder is /data/ftp)')
subparser_download_dir = subparsers.add_parser('download_dir', help='Download all files from a folder from the Bebop')
subparser_download_dir.add_argument('dest', help='destination folder (on the local machine)')
subparser_download_dir.add_argument('folder', help='Remote subfolder (base folder is /data/ftp)')
subparser_rm_dir = subparsers.add_parser('rm_dir', help='Remove a directory and all its files from the Bebop')
subparser_rm_dir.add_argument('folder', help='Remote subfolder (base folder is /data/ftp)')
subparser_insmod = subparsers.add_parser('insmod', help='Upload and insert kernel module')
subparser_insmod.add_argument('file', help='Filename of *.ko kernel module')
subparser_start = subparsers.add_parser('start', help='Start a program on the Bebop')
subparser_start.add_argument('program', help='the program to start')
subparser_kill = subparsers.add_parser('kill', help='Kill a program on the Bebop')
subparser_kill.add_argument('program', help='the program to kill')
args = parser.parse_args()
# Connect with telnet and ftp
tn, ftp = parrot_utils.connect(args.host)
# Check the Bebop status
if args.command == 'status':
print("Connected to Bebop at " + args.host)
bebop_status()
# Reboot the drone
elif args.command == 'reboot':
parrot_utils.reboot(tn)
print('The Bebop is rebooting...')
# Kill a program
elif args.command == 'kill':
parrot_utils.execute_command(tn, 'killall -9 ' + args.program)
print('Program "' + args.program + '" is now killed')
# Start a program
elif args.command == 'start':
parrot_utils.execute_command(tn, args.start + ' &')
print('Program "' + args.start + '" is now started')
elif args.command == 'insmod':
modfile = parrot_utils.split_into_path_and_file(args.file)
print('Uploading \'' + modfile[1])
parrot_utils.uploadfile(ftp, modfile[1], file(args.file, "rb"))
print(parrot_utils.execute_command(tn, "insmod /data/ftp/" + modfile[1]))
elif args.command == 'upload_file_and_run':
# Split filename and path
f = parrot_utils.split_into_path_and_file(args.file)
#check firmware version
v = parrot_utils.check_version(tn, '')
print("Checking Bebop firmware version... " + str(v) )
if ((v < parrot_utils.ParrotVersion(args.min_version)) or (v > parrot_utils.ParrotVersion(args.max_version))):
print("Error: please upgrade your Bebop firmware to version between " + args.min_version + " and " + args.max_version + "!")
else:
print("Kill running " + f[1] + " and make folder " + args.folder)
parrot_utils.execute_command(tn,"killall -9 " + f[1])
sleep(1)
parrot_utils.execute_command(tn, "mkdir -p /data/ftp/" + args.folder)
print('Uploading \'' + f[1] + "\' from " + f[0] + " to " + args.folder)
parrot_utils.uploadfile(ftp, args.folder + "/" + f[1], file(args.file, "rb"))
sleep(0.5)
from datetime import datetime
parrot_utils.execute_command(tn, "date --set '" + datetime.now().strftime('%Y-%m-%d %H:%M:%S') + "'")
print("Set date on Bebop to " + datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
parrot_utils.execute_command(tn, "chmod 777 /data/ftp/" + args.folder + "/" + f[1])
parrot_utils.execute_command(tn, "/data/ftp/" + args.folder + "/" + f[1] + " > /dev/null 2>&1 &")
print("#pragma message: Upload and Start of ap.elf to Bebop succesful !")
elif args.command == 'upload_file':
# Split filename and path
f = parrot_utils.split_into_path_and_file(args.file)
parrot_utils.execute_command(tn, "mkdir -p /data/ftp/" + args.folder)
print('Uploading \'' + f[1] + "\' from " + f[0] + " to /data/ftp/" + args.folder)
parrot_utils.uploadfile(ftp, args.folder + "/" + f[1], file(args.file, "rb"))
print("#pragma message: Upload of " + f[1] + " to Bebop succesful !")
elif args.command == 'download_file':
# Split filename and path
f = parrot_utils.split_into_path_and_file(args.file)
# Open file and download
try:
fd = open(args.file, 'wb')
print('Downloading \'' + f[1] + "\' from " + args.folder + " to " + f[0])
ftp.retrbinary("RETR " + args.folder + "/" + f[1], fd.write)
print("#pragma message: Download of " + f[1] + " from Bebop Succes!")
except IOError:
print("#pragma message: Fail to open file " + args.file)
except:
os.remove(args.file)
print("#pragma message: Download of " + f[1] + " from Bebop Failed!")
else:
fd.close()
elif args.command == 'download_dir':
# Split filename and path
files = parrot_utils.execute_command(tn, 'find /data/ftp/' + args.folder + ' -name \'*.*\'')
# Create dest dir if needed
if not os.path.exists(args.dest):
os.mkdir(args.dest)
# Open file and download
for f in files.split():
file_name = parrot_utils.split_into_path_and_file(f)
file_source = args.folder + '/' + file_name[1]
file_dest = args.dest + '/' + file_name[1]
try:
fd = open(file_dest, 'wb')
print('Downloading \'' + f + "\' to " + file_dest)
ftp.retrbinary("RETR " + file_source, fd.write)
except IOError:
print("#pragma message: Fail to open file " + file_dest)
except:
os.remove(file_dest)
print("#pragma message: Download of " + f + " from Bebop Failed!")
else:
fd.close()
print("#pragma message: End download of folder " + args.folder + " from Bebop")
elif args.command == 'rm_dir':
# Split filename and path
print("Deleting folder /data/ftp/" + args.folder + " from Bebop")
print(parrot_utils.execute_command(tn, 'rm -r /data/ftp/' + args.folder))
# Close the telnet and python script
parrot_utils.disconnect(tn, ftp)
exit(0)
+304 -66
View File
@@ -1,5 +1,7 @@
#
# Copyright (C) 2012-2014 The Paparazzi Team
# 2015 Freek van Tienen <freek.v.tienen@gmail.com>
# 2017 Gautier Hattenberger <gautier.hattenberger@enac.fr>
#
# This file is part of Paparazzi.
#
@@ -21,9 +23,13 @@
from __future__ import print_function
import socket
import telnetlib
import os
import sys
from ftplib import FTP
from time import sleep
import ftplib
import argparse
import re
class ParrotVersion(object):
def __init__(self):
@@ -69,84 +75,316 @@ class ParrotVersion(object):
def __ge__(self, other):
return self.version() >= other.version()
class ParrotUtils:
# Check if IP is valid
def is_ip(address):
try:
socket.inet_aton(address)
ip = True
except socket.error:
ip = False
return ip
# Programs that could be running on the drone
runnable_programs = [
('program.elf', 'Parrot native UAV application'),
('dragon-prog', 'Parrot native UAV application'),
('ap.elf', 'Paparazzi'),
('gst-launch', 'GStreamer')
]
# Helper function
def split_into_path_and_file(name):
if name.count('/') <= 0:
return ["./", name]
return name.rsplit('/', 1)
# Default values
version_file = '/update/version.txt'
upload_path = '/data/video/'
uav_name = 'Parrot UAV'
address = '192.168.1.1'
prompt = '# '
check_version_before_run = False
update_time_before_run = False
# Execute a command
def execute_command(tn, command, prompt='#'):
tn.write(command + '\n')
return tn.read_until(prompt+' ')[len(command) + 2:-4]
# Initialize defaults
def __init__(self):
self.config_content = ''
self.init_parser()
self.init_extra_parser()
# Check the version
def check_version(tn, directory, prompt='#'):
return ParrotVersion(execute_command(tn, 'cat ' + directory + '/version.txt', prompt).strip())
# Connect with telnet and ftp, wait until login
def connect(self):
try:
self.tn = telnetlib.Telnet(self.address, timeout=3)
self.ftp = FTP(self.address)
self.ftp.login()
self.tn.read_until(self.prompt)
return True
except:
print('Could not connect to the ' + self.uav_name + ' (address: ' + self.address + ')')
print('Check if the ' + self.uav_name + ' is turned on and the computer is connected over wifi or bluetooth.')
if self.address == '192.168.42.1':
print("If you are using Bebop 1 or 2, don't forget pressing the power button 4 times after the Bebop has booted!")
exit(2)
# Check what currently is running on the drone
def check_running(tn, prompt='#'):
ps_aux = execute_command(tn, 'ps', prompt)
running = ""
# Close the telnet and ftp
def disconnect(self):
self.tn.close()
self.ftp.close()
# Execute a command
def execute_command(self, command):
self.tn.write(command + '\n')
s = self.tn.read_until(self.prompt)
if s.endswith('[JS] $ '):
s = s[len(command) + 2:-8]
elif s.endswith('[RS.edu] $ '):
s = s[len(command) + 2:-12]
else:
s = s[len(command) + 2:-4]
return s
# Upload ftp and catch memory-full error
def upload(self, filename, content):
try:
self.ftp.storbinary("STOR " + filename, content)
except ftplib.error_temp:
print('FTP UPLOAD ERROR: Uploading the file to the ' + self.uav_name + ' failed!')
print('Check if the Filesystem of the ' + self.uav_name + ' isn\'t full:')
print(self.check_filesystem())
sys.exit()
except:
print('FTP UPLOAD ERROR: Uploading the file to the ' + self.uav_name + ' failed!')
print('FTP uploading failed with the following error: ', sys.exc_info()[0])
print('Check if the Filesystem of the ' + self.uav_name + ' isn\'t full:')
print(self.check_filesystem())
sys.exit()
# Download a file from the drone
def download(self, filename, folder):
# Split filename and path
f = self.split_into_path_and_file(filename)
# Open file and download
try:
fd = open(filename, 'wb')
print('Downloading \'' + f[1] + "\' from " + folder + " to " + f[0])
self.ftp.retrbinary("RETR " + folder + "/" + f[1], fd.write)
print('#pragma message: Download of "' + f[1] + '" from the ' + self.uav_name + ' success!')
except IOError:
print('#error: Fail to open local file "' + filename + '"')
except:
os.remove(filename)
print('#error: Download of "' + filename + '" from ' + self.uav_name + ' Failed!')
else:
fd.close()
# Download a folder from the drone
def download_folder(self, dest, folder):
# find files
files = self.execute_command('find ' + self.upload_path + folder + ' -name \'*.*\'')
# Create dest dir if needed
if not os.path.exists(dest):
os.mkdir(dest)
# Open file and download
for f in files.split():
file_dest = dest + '/' + file_name[1]
self.download(file_dest, folder)
print("#pragma message: End download of folder " + args.folder + " from " + self.uav_name)
if 'dragon-prog' in ps_aux:
running += ' Native (dragon-prog),'
if 'ap.elf' in ps_aux:
running += ' Paparazzi (ap.elf),'
if 'program.elf' in ps_aux:
running += ' Native (program.elf),'
if 'gst-launch' in ps_aux:
running += ' GStreamer (gst-launch)'
return running[1:]
# helper function to split file name and path
def split_into_path_and_file(self, name):
if name.count('/') <= 0:
return ["./", name]
return name.rsplit('/', 1)
# Check the filesystem
def check_filesystem(tn, prompt='#'):
return execute_command(tn, 'df -h', prompt)
def is_ip(address):
try:
socket.inet_aton(address)
ip = True
except socket.error:
ip = False
return ip
# Reboot the drone
def reboot(tn, prompt='#'):
execute_command(tn, 'reboot', prompt)
# Check what currently is running on the drone
def check_running(self):
ps_aux = self.execute_command('ps')
running = ""
# Upload ftp and catch memory-full error
def uploadfile(ftp, filename, content):
try:
ftp.storbinary("STOR " + filename, content)
except ftplib.error_temp:
print("FTP UPLOAD ERROR: Uploading FAILED: Probably your drone onboard storage memory is full. Remove old JPG or other data?")
sys.exit()
except:
print("FTP UPLOAD ERROR: Maybe your drone onboard storage memory is full? Remove old JPG or other data?)", sys.exc_info()[0])
sys.exit()
# Go trough all programings
for prog in self.runnable_programs:
if prog[0] in ps_aux:
running += ' '+prog[1]+' ('+prog[0]+')'
# Don't print the first space
return running[1:]
# Check the filesystem
def check_filesystem(self):
return self.execute_command('df -h')
# Get the version of the drone
def check_version(self):
if self.version_file is not None:
return ParrotVersion(execute_command('cat ' + self.version_file).strip())
else:
return "Unknown version"
# Default status
def status(self):
print('======================== ' + self.uav_name + ' Status ========================')
self.uav_status()
print('\n======================== Filesystem Status ========================')
print(self.check_filesystem())
# Reboot the drone
def reboot(self):
self.execute_command('reboot')
print('The ' + self.uav_name + ' is now rebooting')
# Kill a running program
def kill_program(self, name):
self.execute_command('killall -9 ' + name)
print('Program "' + name + '" is now killed')
# Start a new program
def start_program(self, name):
self.execute_command('chmod 777 ' + name)
self.execute_command(name + ' > /dev/null 2>&1 &')
print('Program "' + name + '" is now started')
# Create a new directory
def create_directory(self, name):
self.execute_command('mkdir -p ' + name)
print('Created new directory "' + name + '"')
# Remove a directory
def remove_directory(self, name):
self.sexecute_command('rm -r ' + name)
print('Removed directory "' + name + '"')
# Upload a new file
def upload_file(self, name, folder=""):
f = self.split_into_path_and_file(name)
# First kill the running program
self.kill_program(f[1])
sleep(1)
# Make the upload directory and upload the file
self.create_directory(self.upload_path + folder)
if len(folder) > 0:
self.upload(folder + '/' + f[1], file(name, "rb"))
else:
self.upload(f[1], file(name, "rb"))
sleep(0.5)
print('Succesfully uploaded "' + name + '" to folder "' + folder + '"')
# Upload and run a new program
def upload_and_run(self, name, folder, min_ver=None, max_ver=None):
if self.check_version_before_run and min_ver is not None and max_ver is not None:
v = self.check_version()
print("Checking " + self.uav_name + " firmware version... " + str(v) )
if ((v < self.ParrotVersion(min_ver)) or (v > self.ParrotVersion(max_ver))):
print("Error: please upgrade your " + self.uav_name + " firmware to version between " + min_ver + " and " + max_ver + "!")
return
f = self.split_into_path_and_file(name)
# Upload the file
self.upload_file(name, folder)
if self.update_time_before_run:
from datetime import datetime
self.execute_command("date --set '" + datetime.now().strftime('%Y-%m-%d %H:%M:%S') + "'")
print("Set date on " + self.uav_name + " to " + datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
# Make the file executable and execute it
self.start_program(self.upload_path + folder + '/' + f[1])
print('#pragma message: Succesfully started "' + f[1] + '" on ' + self.uav_name)
def insmod(self, modname):
f = parrot_utils.split_into_path_and_file(modname)
print('Uploading \'' + f[1])
self.upload_file(modname)
print(self.execute_command("insmod " + self.upload_path + '/' + modfile[1]))
#####################################################################
# Main argument parser setup
def init_parser(self):
self.parser = argparse.ArgumentParser(description=self.uav_name + ' python helper. Use ' + sys.argv[0] + ' -h for help')
self.parser.add_argument('--host', metavar='HOST', default=self.address,
help='the ip address of ' + self.uav_name)
self.subparsers = self.parser.add_subparsers(title='Command to execute', metavar='command', dest='command')
# Add commands
self.subparsers.add_parser('status', help='Request the status of the ' + self.uav_name)
self.subparsers.add_parser('reboot', help='Reboot the ' + self.uav_name)
ss = self.subparsers.add_parser('kill', help='Kill a program on the ' + self.uav_name)
ss.add_argument('program', help='The program to kill')
ss = self.subparsers.add_parser('start', help='Start a program on the ' + self.uav_name)
ss.add_argument('program', help='The program to start (base folder is the ftp folder)')
ss = self.subparsers.add_parser('upload', help='Upload a file to the ' + self.uav_name)
ss.add_argument('file', help='Filename')
ss.add_argument('folder', help='Destination subfolder (base folder is the ftp folder)')
ss = self.subparsers.add_parser('download', help='Download a file from the ' + self.uav_name)
ss.add_argument('file', help='Remote filename (could include folder)')
ss.add_argument('save_file', help='Destination file on local computer')
ss = self.subparsers.add_parser('download_dir', help='Download all files from a folder from the ' + self.uav_name)
ss.add_argument('dest', help='destination folder (on the local machine)')
ss.add_argument('folder', help='Remote subfolder (base folder is the ftp folder)')
ss = self.subparsers.add_parser('upload_file_and_run', help='Upload and run software (for instance the Paparazzi autopilot)')
ss.add_argument('file', help='Filename of an executable')
ss.add_argument('folder', help='Remote destination folder (base folder is the ftp folder)')
ss = self.subparsers.add_parser('mkdir', help='Make a new directory on the ' + self.uav_name)
ss.add_argument('folder', help='Remote subfolder (base folder is the ftp folder)')
ss = self.subparsers.add_parser('rmdir', help='Remove a directory and all its files from the ' + self.uav_name)
ss.add_argument('folder', help='Remote subfolder (base folder is the ftp folder)')
ss = self.subparsers.add_parser('insmod', help='Upload and insert kernel module')
ss.add_argument('file', help='Filename of *.ko kernel module')
# Connect with telnet and ftp, wait until login
def connect(host, prompt='#'):
try:
tn = telnetlib.Telnet(host, timeout=3)
ftp = FTP(host)
ftp.login()
tn.read_until(prompt+' ')
return tn, ftp
except:
print('Could not connect to Parrot UAV (host: ' + host + ')')
if host == '192.168.42.1':
print("Check whether your WiFi is connected and don't forget pressing the power button 4 times after the Bebop has booted!")
exit(2)
# Main function to parse arguments
def parse_args(self):
args = self.parser.parse_args()
# First connect to the drone
self.address = args.host
if self.connect() == False:
return False
# Parse the command line arguments
if args.command == 'status':
self.status()
elif args.command == 'reboot':
self.reboot()
elif args.command == 'kill':
self.kill_program(args.program)
elif args.command == 'start':
self.start_program(self.upload_path + args.program)
elif args.command == 'upload':
self.upload_file(args.file, args.folder)
elif args.command == 'download':
self.download(args.file, args.save_file)
elif args.command == 'upload_file_and_run':
if hasattr(args, 'min_version') and hasattr(args, 'max_version'):
self.upload_and_run(args.file, args.folder, args.min_version, args.max_version)
else:
self.upload_and_run(args.file, args.folder)
elif args.command == 'mkdir':
self.create_directory(self.upload_path + args.folder)
elif args.command == 'rmdir':
self.remove_directory(self.upload_path + args.folder)
elif args.command == 'insmod':
self.insmod(args.file)
else:
if self.parse_extra_args(args) == False:
self.disconnect()
return False
# Disconnect
self.disconnect()
return True
# Close the telnet and ftp
def disconnect(tn, ftp):
tn.close()
ftp.close()
+21 -171
View File
@@ -20,179 +20,29 @@
#
from __future__ import print_function
import re
import argparse
import os
from time import sleep
from parrot_utils import ParrotUtils
import parrot_utils
class Swing(ParrotUtils):
uav_name = 'Swing'
address = '192.168.4.1'
version_file = None
upload_path = '/data/edu/'
prompt = '$ '
PROMPT = '$'
FTP_ROOT = '/data/edu/'
def uav_status(self):
print('Parrot version:\t\t' + self.check_version())
def init_extra_parser(self):
# nothing here
pass
def parse_extra_args(self, args):
# nothing here
pass
# Read from config.ini TODO
def read_from_config(name, config=''):
if config == '':
config = parrot_utils.execute_command('cat /data/config.ini', prompt=PROMPT)
search = re.search(name + '[^=]+=[\r\n\t ]([^\r\n\t ]+)', config)
if search is None:
return ''
else:
return search.group(1)
if __name__ == "__main__":
swing = Swing()
swing.parse_args()
exit(0)
# Write to config TODO
def write_to_config(name, value):
if read_from_config(name) == '':
parrot_utils.execute_command('echo "' + name + ' = ' + value + '\" >> /data/config.ini', prompt=PROMPT)
else:
parrot_utils.execute_command('sed -i "s/\(' + name + ' *= *\).*/\\1' + value + '/g" /data/config.ini', prompt=PROMPT)
def swing_status():
#config_ini = parrot_utils.execute_command(tn, 'cat /data/config.ini', prompt=PROMPT)
#print('==================== Swing Status ====================')
#print('Version:\t\t' + str(parrot_utils.check_version(tn, '', prompt=PROMPT)))
# Request the filesystem status
print('\n=================== Filesystem Status =======================')
print(parrot_utils.check_filesystem(tn, prompt=PROMPT))
# Parse the arguments
parser = argparse.ArgumentParser(description='Swing python helper. Use swing.py -h for help')
parser.add_argument('--host', metavar='HOST', default='192.168.4.1',
help='the ip address of Swing')
subparsers = parser.add_subparsers(title='Command to execute', metavar='command', dest='command')
# All the subcommands and arguments
subparsers.add_parser('status', help='Request the status of the Swing')
subparsers.add_parser('reboot', help='Reboot the Swing')
subparser_upload_and_run = subparsers.add_parser('upload_file_and_run', help='Upload and run software (for instance the Paparazzi autopilot)')
subparser_upload_and_run.add_argument('file', help='Filename of an executable')
subparser_upload_and_run.add_argument('folder', help='Destination subfolder (raw or sdk for Paparazzi autopilot)')
subparser_upload = subparsers.add_parser('upload_file', help='Upload a file to the Swing')
subparser_upload.add_argument('file', help='Filename')
subparser_upload.add_argument('folder', help='Destination subfolder (base destination folder is '+FTP_ROOT+')')
subparser_download = subparsers.add_parser('download_file', help='Download a file from the Swing')
subparser_download.add_argument('file', help='Filename (with the path on the local machine)')
subparser_download.add_argument('folder', help='Remote subfolder (base folder is '+FTP_ROOT+')')
subparser_download_dir = subparsers.add_parser('download_dir', help='Download all files from a folder from the Swing')
subparser_download_dir.add_argument('dest', help='destination folder (on the local machine)')
subparser_download_dir.add_argument('folder', help='Remote subfolder (base folder is '+FTP_ROOT+')')
subparser_rm_dir = subparsers.add_parser('rm_dir', help='Remove a directory and all its files from the Swing')
subparser_rm_dir.add_argument('folder', help='Remote subfolder (base folder is '+FTP_ROOT+')')
subparser_insmod = subparsers.add_parser('insmod', help='Upload and insert kernel module')
subparser_insmod.add_argument('file', help='Filename of *.ko kernel module')
subparser_start = subparsers.add_parser('start', help='Start a program on the Swing')
subparser_start.add_argument('program', help='the program to start')
subparser_kill = subparsers.add_parser('kill', help='Kill a program on the Swing')
subparser_kill.add_argument('program', help='the program to kill')
args = parser.parse_args()
# Connect with telnet and ftp
tn, ftp = parrot_utils.connect(args.host, prompt=PROMPT)
# Check the Swing status
if args.command == 'status':
print("Connected to Swing at " + args.host)
swing_status()
# Reboot the drone
elif args.command == 'reboot':
parrot_utils.reboot(tn, prompt=PROMPT)
print('The Swing is rebooting...')
# Kill a program
elif args.command == 'kill':
parrot_utils.execute_command(tn, 'killall -9 ' + args.program, prompt=PROMPT)
print('Program "' + args.program + '" is now killed')
# Start a program
elif args.command == 'start':
parrot_utils.execute_command(tn, args.start + ' &', prompt=PROMPT)
print('Program "' + args.start + '" is now started')
elif args.command == 'insmod':
modfile = parrot_utils.split_into_path_and_file(args.file)
print('Uploading \'' + modfile[1])
parrot_utils.uploadfile(ftp, modfile[1], file(args.file, "rb"))
print(parrot_utils.execute_command(tn, "insmod "+ FTP_ROOT + modfile[1], prompt=PROMPT))
elif args.command == 'upload_file_and_run':
# Split filename and path
f = parrot_utils.split_into_path_and_file(args.file)
print("Kill running " + f[1] + " and make folder " + args.folder)
parrot_utils.execute_command(tn,"killall -9 " + f[1], prompt=PROMPT)
sleep(1)
parrot_utils.execute_command(tn, "mkdir -p " + FTP_ROOT + args.folder, prompt=PROMPT)
print('Uploading \'' + f[1] + "\' from " + f[0] + " to " + args.folder)
parrot_utils.uploadfile(ftp, args.folder + "/" + f[1], file(args.file, "rb"))
sleep(0.5)
parrot_utils.execute_command(tn, "chmod 777 " + FTP_ROOT + args.folder + "/" + f[1], prompt=PROMPT)
parrot_utils.execute_command(tn, FTP_ROOT + args.folder + "/" + f[1] + " > /dev/null 2>&1 &", prompt=PROMPT)
print("#pragma message: Upload and Start of ap.elf to Swing Succes!")
elif args.command == 'upload_file':
# Split filename and path
f = parrot_utils.split_into_path_and_file(args.file)
parrot_utils.execute_command(tn, "mkdir -p " + FTP_ROOT + args.folder, prompt=PROMPT)
print('Uploading \'' + f[1] + "\' from " + f[0] + " to " + FTP_ROOT + args.folder)
parrot_utils.uploadfile(ftp, args.folder + "/" + f[1], file(args.file, "rb"))
print("#pragma message: Upload of " + f[1] + " to Swing Succes!")
elif args.command == 'download_file':
# Split filename and path
f = parrot_utils.split_into_path_and_file(args.file)
# Open file and download
try:
fd = open(args.file, 'wb')
print('Downloading \'' + f[1] + "\' from " + args.folder + " to " + f[0])
ftp.retrbinary("RETR " + args.folder + "/" + f[1], fd.write)
print("#pragma message: Download of " + f[1] + " from Swing Succes!")
except IOError:
print("#pragma message: Fail to open file " + args.file)
except:
os.remove(args.file)
print("#pragma message: Download of " + f[1] + " from Swing Failed!")
else:
fd.close()
elif args.command == 'download_dir':
# Split filename and path
files = parrot_utils.execute_command(tn, 'find ' + FTP_ROOT + args.folder + ' -name \'*.*\'', prompt=PROMPT)
# Create dest dir if needed
if not os.path.exists(args.dest):
os.mkdir(args.dest)
# Open file and download
for f in files.split():
file_name = parrot_utils.split_into_path_and_file(f)
file_source = args.folder + '/' + file_name[1]
file_dest = args.dest + '/' + file_name[1]
try:
fd = open(file_dest, 'wb')
print('Downloading \'' + f + "\' to " + file_dest)
ftp.retrbinary("RETR " + file_source, fd.write)
except IOError:
print("#pragma message: Fail to open file " + file_dest)
except:
os.remove(file_dest)
print("#pragma message: Download of " + f + " from Swing Failed!")
else:
fd.close()
print("#pragma message: End download of folder " + args.folder + " from Swing")
elif args.command == 'rm_dir':
# Split filename and path
print("Deleting folder " + FTP_ROOT + args.folder + " from Swing")
print(parrot_utils.execute_command(tn, 'rm -r ' + FTP_ROOT + args.folder, prompt=PROMPT))
# Close the telnet and python script
parrot_utils.disconnect(tn, ftp)
exit(0)