def set_motes_to_simulation(simfile, motes): """ This function replaces motes data from a list of motes (formatted as dictionaries with 'id', 'x', 'y' and 'motetype_identifier' keys) into a simulation file (.csc). :param simfile: path to the simulation file :param motes: list or dictionary of motes """ if isinstance(motes, list): motes = {int(m['id']): (float(m['x']), float(m['y'])) for m in motes} tmp = simfile + '.tmp' with open(simfile) as of: content = of.read() for m in finditer(r'^\s*<mote>(?P<block>.*?)</mote>\s*$', content, DOTALL | MULTILINE): block = m.groups('block')[0] idmatch = search(r'^\s*<id>(?P<mote_id>\d+?)</id>\s*$', block, MULTILINE) if idmatch is None: continue mote_id = int(idmatch.groups('mote_id')[0]) # e.g. occurs when modifying the simulation without malicious and the simulation with malicious has to be # update ; id of malicious mote is found in the simulation file but not in the dictionary of motes if mote_id not in motes.keys(): continue mote_pos = motes[mote_id] block = sub(r'<x>(.*?)</x>', '<x>{}</x>'.format(mote_pos[0]), block, flags=MULTILINE) block = sub(r'<y>(.*?)</y>', '<y>{}</y>'.format(mote_pos[1]), block, flags=MULTILINE) content = content.replace(m.groups('block')[0], block) with open(tmp, 'w+') as nf: nf.write(content) move_files('', '', (tmp, simfile))
def __run(name, **kwargs): """ Run an experiment. :param name: experiment name :param path: expanded path of the experiment (dynamically filled in through 'command' decorator with 'expand' """ path = kwargs['path'] check_structure(path, remove=True) with hide(*HIDDEN_ALL): for sim in ["without", "with"]: sim_path = join(path, "{}-malicious".format(sim)) data, results = join(sim_path, 'data'), join(sim_path, 'results') # the Makefile is at experiment's root ('path') with lcd(sim_path): logger.debug(" > Running simulation {} the malicious mote...".format(sim)) local("make run", capture=True) # simulations are in their respective folders ('sim_path') remove_files(sim_path, 'COOJA.log', 'COOJA.testlog') # once the execution is over, gather the screenshots into a single GIF and keep the first and # the last screenshots ; move these to the results folder with lcd(data): local('convert -delay 10 -loop 0 network*.png wsn-{}-malicious.gif'.format(sim)) network_images = {int(fn.split('.')[0].split('_')[-1]): fn for fn in listdir(data) if fn.startswith('network_')} move_files(data, results, 'wsn-{}-malicious.gif'.format(sim)) net_start_old = network_images[min(network_images.keys())] net_start, ext = splitext(net_start_old) net_start_new = 'wsn-{}-malicious_start{}'.format(sim, ext) net_end_old = network_images[max(network_images.keys())] net_end, ext = splitext(net_end_old) net_end_new = 'wsn-{}-malicious_end{}'.format(sim, ext) move_files(data, results, (net_start_old, net_start_new), (net_end_old, net_end_new)) remove_files(data, *network_images.values()) parsing_chain(sim_path)
def __run(name, **kwargs): """ Run an experiment. :param name: experiment name :param path: expanded path of the experiment (dynamically filled in through 'command' decorator with 'expand' """ path = kwargs['path'] check_structure(path, remove=True) with hide(*HIDDEN_ALL): for sim in ["without", "with"]: sim_path = join(path, "{}-malicious".format(sim)) data, results = join(sim_path, 'data'), join(sim_path, 'results') # the Makefile is at experiment's root ('path') with lcd(sim_path): logger.debug( " > Running simulation {} the malicious mote...".format( sim)) local("make run", capture=True) # simulations are in their respective folders ('sim_path') remove_files(sim_path, 'COOJA.log', 'COOJA.testlog') # once the execution is over, gather the screenshots into a single GIF and keep the first and # the last screenshots ; move these to the results folder with lcd(data): local( 'convert -delay 10 -loop 0 network*.png wsn-{}-malicious.gif' .format(sim)) network_images = { int(fn.split('.')[0].split('_')[-1]): fn for fn in listdir(data) if fn.startswith('network_') } move_files(data, results, 'wsn-{}-malicious.gif'.format(sim)) net_start_old = network_images[min(network_images.keys())] net_start, ext = splitext(net_start_old) net_start_new = 'wsn-{}-malicious_start{}'.format(sim, ext) net_end_old = network_images[max(network_images.keys())] net_end, ext = splitext(net_end_old) net_end_new = 'wsn-{}-malicious_end{}'.format(sim, ext) move_files(data, results, (net_start_old, net_start_new), (net_end_old, net_end_new)) remove_files(data, *network_images.values()) parsing_chain(sim_path)
def __remake(name, build=False, **kwargs): """ Remake the malicious mote of an experiment. (meaning that it lets all simulation's files unchanged except ./motes/malicious.[target]) :param name: experiment name :param path: expanded path of the experiment (dynamically filled in through 'command' decorator with 'expand' """ path = kwargs['path'] logger.debug(" > Retrieving parameters...") params = read_config(path) ext_lib = params.get("ext_lib") if ext_lib and not exists(ext_lib): logger.error("External library does not exist !") logger.critical("Make aborted.") return False logger.debug(" > Recompiling malicious mote...") # remove former compiled malicious mote and prepare the template templates = get_path(path, 'templates', create=True) get_path(templates, 'motes', create=True) copy_files((TEMPLATES_FOLDER, 'experiment'), templates, ('motes/{}.c'.format(params["mtype_malicious"]), 'motes/malicious.c')) # recreate malicious C file from template and clean the temporary template replacements = render_templates(path, only_malicious=True, **params) # then clean the temporary folder with templates remove_folder(templates) # now recompile with settings(hide(*HIDDEN_ALL), warn_only=True): with_malicious = join(path, 'with-malicious', 'motes') without_malicious = join(path, 'without-malicious', 'motes') contiki = join(with_malicious, 'contiki') contiki_rpl = join(contiki, 'core', 'net', 'rpl') with lcd(with_malicious): malicious = 'malicious.{}'.format(params["malicious_target"]) croot, csensor = 'root.{}'.format(params["target"]), 'sensor.{}'.format(params["target"]) # handle the malicious mote recompilation copy_folder(CONTIKI_FOLDER, with_malicious, includes=get_contiki_includes(params["malicious_target"])) if ext_lib is not None: remove_folder(contiki_rpl) copy_folder(ext_lib, contiki_rpl) apply_replacements(contiki_rpl, replacements) logger.debug(" > Making '{}'...".format(malicious)) stderr(local)("make malicious{} CONTIKI={}" .format(['', '.upload'][build], contiki), capture=True) if build: build = get_path(path, 'build', create=True) move_files(with_malicious, build, 'tmpimage.ihex') copy_files(with_malicious, build, malicious) move_files(with_malicious, without_malicious, malicious) local('make clean') remove_files(with_malicious, 'malicious.c') move_files(without_malicious, with_malicious, malicious) copy_files(without_malicious, with_malicious, croot, csensor) remove_folder(contiki)
def __make(name, ask=True, **kwargs): """ Make a new experiment. :param name: experiment name (or path to the experiment, if expanded in the 'command' decorator) :param ask: ask confirmation :param path: expanded path of the experiment (dynamically filled in through 'command' decorator with 'expand' :param kwargs: simulation keyword arguments (see the documentation for more information) """ global reuse_bin_path path = kwargs['path'] logger.debug(" > Validating parameters...") params = validated_parameters(kwargs) ext_lib = params.get("ext_lib") if ext_lib and not exists(ext_lib): logger.error("External library does not exist !") logger.critical("Make aborded.") return False logger.debug(" > Creating simulation...") # create experiment's directories check_structure(path, create=True, remove=True) templates = get_path(path, 'templates', create=True) get_path(templates, 'motes', create=True) # select the right malicious mote template and duplicate the simulation file copy_files((TEMPLATES_FOLDER, 'experiment'), templates, ('motes/{}.c'.format(params["mtype_root"]), 'motes/root.c'), ('motes/{}.c'.format(params["mtype_sensor"]), 'motes/sensor.c'), ('motes/{}.c'.format(params["mtype_malicious"]), 'motes/malicious.c'), 'motes/Makefile', 'Makefile', 'simulation.csc', 'script.js') # create experiment's files from templates then clean the templates folder replacements = render_templates(path, **params) remove_folder(templates) # now, write the config file without the list of motes del params['motes'] write_config(path, params) # now compile with settings(hide(*HIDDEN_ALL), warn_only=True): with_malicious = join(path, 'with-malicious', 'motes') without_malicious = join(path, 'without-malicious', 'motes') contiki = join(with_malicious, 'contiki') contiki_rpl = join(contiki, 'core', 'net', 'rpl') # copy a reduced version of Contiki where the debug flags can be set for RPL files set in DEBUG_FILES copy_folder(CONTIKI_FOLDER, with_malicious, includes=get_contiki_includes(params["target"], params["malicious_target"])) apply_debug_flags(contiki_rpl, debug=['NONE', 'PRINT'][params["debug"]]) with lcd(with_malicious): # first, compile root and sensor mote types croot, csensor = 'root.{}'.format(params["target"]), 'sensor.{}'.format(params["target"]) if reuse_bin_path is None or reuse_bin_path == with_malicious: logger.debug(" > Making '{}'...".format(croot)) stderr(local)("make root CONTIKI={}".format(contiki), capture=True) logger.debug(" > Making '{}'...".format(csensor)) stderr(local)("make sensor CONTIKI={}".format(contiki), capture=True) # here, files are moved ; otherwise, 'make clean' would also remove *.z1 move_files(with_malicious, without_malicious, croot, csensor) # after compiling, clean artifacts local('make clean') remove_files(with_malicious, 'root.c', 'sensor.c') else: copy_files(reuse_bin_path, without_malicious, croot, csensor) # second, handle the malicious mote compilation malicious = 'malicious.{}'.format(params["malicious_target"]) if ext_lib is not None: remove_folder(contiki_rpl) copy_folder(ext_lib, contiki_rpl) apply_replacements(contiki_rpl, replacements) logger.debug(" > Making '{}'...".format(malicious)) stderr(local)("make malicious CONTIKI={} TARGET={}" .format(contiki, params["malicious_target"]), capture=True) # temporary move compiled malicious mote, clean the compilation artifacts, move the malicious mote back # from the temporary location and copy compiled root and sensor motes move_files(with_malicious, without_malicious, malicious) local('make clean') move_files(without_malicious, with_malicious, malicious) copy_files(without_malicious, with_malicious, croot, csensor) # finally, remove compilation sources remove_files(with_malicious, 'malicious.c') remove_folder(contiki)
def __run(name, **kwargs): """ Run an experiment. :param name: experiment name :param path: expanded path of the experiment (dynamically filled in through 'command' decorator with 'expand' """ set_logging(kwargs.get('loglevel')) path = kwargs['path'] check_structure(path, remove=True) with settings(hide(*HIDDEN_ALL), warn_only=True): for sim in ["without", "with"]: sim_path = join(path, "{}-malicious".format(sim)) data, results = join(sim_path, 'data'), join(sim_path, 'results') # the Makefile is at experiment's root ('path') logger.debug( " > Running simulation {} the malicious mote...".format(sim)) with lcd(sim_path): output = local("make run TASK={}".format(kwargs['task']), capture=True) remove_files(sim_path, '.{}'.format(kwargs['task'])) error, interrupt, error_buffer = False, False, [] for line in output.split('\n'): if line.strip().startswith("FATAL") or line.strip().startswith( "ERROR"): error, interrupt = True, True elif line.strip().startswith("INFO"): error = False if len(error_buffer) > 0: logger.error('Cooja error:\n' + '\n'.join(error_buffer)) error_buffer = [] if error: error_buffer.append(line) if interrupt: logger.warn( "Cooja failed to execute ; 'run' interrupted (no parsing done)" ) raise Exception("Cooja failed to execute") # once the execution is over, gather the screenshots into a single GIF and keep the first and # the last screenshots ; move these to the results folder logger.debug(" > Gathering screenshots in an animated GIF...") with lcd(data): local( 'convert -delay 10 -loop 0 network*.png wsn-{}-malicious.gif' .format(sim), capture=True) network_images = { int(fn.split('.')[0].split('_')[-1]): fn for fn in listdir(data) if fn.startswith('network_') } move_files(data, results, 'wsn-{}-malicious.gif'.format(sim)) net_start_old = network_images[min(network_images.keys())] net_start, ext = splitext(net_start_old) net_start_new = 'wsn-{}-malicious_start{}'.format(sim, ext) net_end_old = network_images[max(network_images.keys())] net_end, ext = splitext(net_end_old) net_end_new = 'wsn-{}-malicious_end{}'.format(sim, ext) move_files(data, results, (net_start_old, net_start_new), (net_end_old, net_end_new)) remove_files(data, *network_images.values()) # then start the parsing functions to derive more results logger.debug(" > Parsing simulation results...") parsing_chain(sim_path) move_files(sim_path, results, 'COOJA.log')
def __remake(name, build=False, **kwargs): """ Remake the malicious mote of an experiment. (meaning that it lets all simulation's files unchanged except ./motes/malicious.[target]) :param name: experiment name :param path: expanded path of the experiment (dynamically filled in through 'command' decorator with 'expand' """ set_logging(kwargs.get('loglevel')) path = kwargs['path'] logger.debug(" > Retrieving parameters...") params = read_config(path) ext_lib = params.get("ext_lib") if ext_lib and not exists(ext_lib): logger.error("External library does not exist !") logger.critical("Make aborted.") return False logger.debug(" > Recompiling malicious mote...") # remove former compiled malicious mote and prepare the template templates = get_path(path, 'templates', create=True) get_path(templates, 'motes', create=True) copy_files( (TEMPLATES_FOLDER, 'experiment'), templates, ('motes/{}.c'.format(params["mtype_malicious"]), 'motes/malicious.c')) # recreate malicious C file from template and clean the temporary template replacements = render_templates(path, only_malicious=True, **params) # then clean the temporary folder with templates remove_folder(templates) # now recompile with settings(hide(*HIDDEN_ALL), warn_only=True): with_malicious = join(path, 'with-malicious', 'motes') without_malicious = join(path, 'without-malicious', 'motes') contiki = join(with_malicious, split(CONTIKI_FOLDER)[-1]) contiki_rpl = join(contiki, 'core', 'net', 'rpl') with lcd(with_malicious): malicious = 'malicious.{}'.format(params["malicious_target"]) croot, csensor = 'root.{}'.format( params["target"]), 'sensor.{}'.format(params["target"]) # handle the malicious mote recompilation copy_folder(CONTIKI_FOLDER, with_malicious, includes=get_contiki_includes( params["malicious_target"])) if ext_lib is not None: remove_folder(contiki_rpl) copy_folder(ext_lib, contiki_rpl) apply_replacements(contiki_rpl, replacements) if build: logger.debug(" > Building '{}'...".format(malicious)) stderr(local)( "sudo make malicious.upload CONTIKI={} TARGET={}".format( contiki, params["malicious_target"])) build = get_path(path, 'build', create=True) move_files(with_malicious, build, 'tmpimage.ihex') copy_files(with_malicious, build, malicious) else: logger.debug(" > Making '{}'...".format(malicious)) stderr(local)("make malicious CONTIKI={} TARGET={}".format( contiki, params["malicious_target"]), capture=True) move_files(with_malicious, without_malicious, malicious) local('make clean') remove_files(with_malicious, 'malicious.c') move_files(without_malicious, with_malicious, malicious) copy_files(without_malicious, with_malicious, croot, csensor) remove_folder(contiki)
def __make(name, ask=True, **kwargs): """ Make a new experiment. :param name: experiment name (or path to the experiment, if expanded in the 'command' decorator) :param ask: ask confirmation :param path: expanded path of the experiment (dynamically filled in through 'command' decorator with 'expand' :param kwargs: simulation keyword arguments (see the documentation for more information) """ global reuse_bin_path set_logging(kwargs.get('loglevel')) path = kwargs['path'] logger.debug(" > Validating parameters...") params = validated_parameters(kwargs) ext_lib = params.get("ext_lib") if ext_lib and not exists(ext_lib): logger.error("External library does not exist !") logger.critical("Make aborded.") return False logger.debug(" > Creating simulation...") # create experiment's directories check_structure(path, create=True, remove=True) templates = get_path(path, 'templates', create=True) get_path(templates, 'motes', create=True) # select the right malicious mote template and duplicate the simulation file copy_files( (TEMPLATES_FOLDER, 'experiment'), templates, ('motes/{}.c'.format(params["mtype_root"]), 'motes/root.c'), ('motes/{}.c'.format(params["mtype_sensor"]), 'motes/sensor.c'), ('motes/{}.c'.format(params["mtype_malicious"]), 'motes/malicious.c'), 'motes/Makefile', 'Makefile', 'simulation.csc', 'script.js') # create experiment's files from templates then clean the templates folder replacements = render_templates(path, **params) remove_folder(templates) # now, write the config file without the list of motes del params['motes'] write_config(path, params) # now compile with settings(hide(*HIDDEN_ALL), warn_only=True): with_malicious = join(path, 'with-malicious', 'motes') without_malicious = join(path, 'without-malicious', 'motes') contiki = join(with_malicious, split(CONTIKI_FOLDER)[-1]) contiki_rpl = join(contiki, 'core', 'net', 'rpl') # copy a reduced version of Contiki where the debug flags can be set for RPL files set in DEBUG_FILES copy_folder(CONTIKI_FOLDER, with_malicious, includes=get_contiki_includes(params["target"], params["malicious_target"])) apply_debug_flags(contiki_rpl, debug=['NONE', 'PRINT'][params["debug"]]) with lcd(with_malicious): # first, compile root and sensor mote types croot, csensor = 'root.{}'.format( params["target"]), 'sensor.{}'.format(params["target"]) if reuse_bin_path is None or reuse_bin_path == with_malicious: logger.debug(" > Making '{}'...".format(croot)) stderr(local)("make root CONTIKI={}".format(contiki), capture=True) logger.debug(" > Making '{}'...".format(csensor)) stderr(local)("make sensor CONTIKI={}".format(contiki), capture=True) # here, files are moved ; otherwise, 'make clean' would also remove *.z1 move_files(with_malicious, without_malicious, croot, csensor) # after compiling, clean artifacts local('make clean') remove_files(with_malicious, 'root.c', 'sensor.c') else: copy_files(reuse_bin_path, without_malicious, croot, csensor) # second, handle the malicious mote compilation malicious = 'malicious.{}'.format(params["malicious_target"]) if ext_lib is not None: remove_folder(contiki_rpl) copy_folder(ext_lib, contiki_rpl) apply_replacements(contiki_rpl, replacements) logger.debug(" > Making '{}'...".format(malicious)) stderr(local)("make malicious CONTIKI={} TARGET={}".format( contiki, params["malicious_target"]), capture=True) # temporary move compiled malicious mote, clean the compilation artifacts, move the malicious mote back # from the temporary location and copy compiled root and sensor motes move_files(with_malicious, without_malicious, malicious) local('make clean') move_files(without_malicious, with_malicious, malicious) copy_files(without_malicious, with_malicious, croot, csensor) # finally, remove compilation sources remove_files(with_malicious, 'malicious.c') remove_folder(contiki)