def check_radio(): try: Radio() except Exception as e: log_error(e) logger.error( "RADIO init Failed. Make sure radio/comms board connectors are correct" ) else: logger.info("RADIO initialization successful")
def check_nemo(): try: nemo = Nemo(port_id=3, reset_gpio_ch=16) nemo.self_test() except Exception as e: log_error(e) logger.error( "NEMO init failed. Check 'i2cdetect -y 3' for device address 0x13") else: logger.info("NEMO initialized successfully")
def check_mux(): try: mux = CameraMux() mux.selectCamera(1) except Exception as e: log_error(e) logger.error( "MUX init failed. Make sure it's pressed down fully onto GPIO connections, and that SDA/SCL is not grounded" ) else: logger.info("MUX initialized successfully")
def test_learn(args): machine = Machine("x86_64") # Compil tests log_info("Remove old files") os.system("make clean") log_info("Compile C files") status = os.system("make") assert status == 0 # Find test names c_files = [] for cur_dir, sub_dir, files in os.walk("."): c_files += [x[:-2] for x in files if x.endswith(".c")] for c_file in c_files: cont = Container.from_stream(open(c_file)) func_name = c_file main_addr = cont.symbol_pool["main"].offset func_addr = cont.symbol_pool[func_name].offset log_info("Learning " + func_name + " over " + func_name + ".c") cmd = [ "sibyl", "learn", "-t", "miasm", "-m", hex(main_addr), func_name, c_file ] sibyl = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = sibyl.communicate() assert sibyl.returncode == 0 log_info("Testing generated class") mod = imp.new_module("testclass") exec stdout in mod.__dict__ classTest = getattr(mod, "Test" + c_file) tl = TestLauncher(c_file, machine, ABI_AMD64_SYSTEMV, [classTest], "gcc") possible_funcs = tl.run(func_addr) if tl.possible_funcs: log_success("Generated class recognize the function " + func_name) else: log_error("Generated class failed to recognize the function " + func_name) log_info("Remove old files") os.system("make clean")
def check_gom(): try: gom = Gomspace() hk = gom.get_health_data(level="eps") except Exception as e: log_error(e) logger.error( f"GOM init failed. Is it charged above 7.0V? Check SDA/SCL (with an oscilloscope if need be)" ) else: logger.info( f"GOM initialization successful. Battery voltage: {hk.vbatt}")
def check_cams(): try: mux = CameraMux() mux.selectCamera(1) except Exception as e: log_error(e) logger.error("MUX init failed. Not attempting to init cameras") else: logger.info("MUX initialized successfully") camera = Camera() for i in [1, 2, 3]: try: mux.selectCamera(i) f, t = camera.rawObservation( f"initialization-{i}-{int(time())}") except Exception as e: log_error(e) logger.error(f"CAM{i} init failed") else: logger.info(f"CAM{i} initialized successfully: {f}: {t}")
def run(self): """This is the main loop of the Cislunar Explorers FSW and runs constantly during flight.""" try: while True: sleep(2) # TODO remove when flight modes execute real tasks self.poll_inputs() self.update_state() self.read_command_queue_from_file() self.execute_commands() # Set goal or execute command immediately self.run_mode() except Exception as e: log_error(e, exc_info=1) logger.error("Error in main loop. Transitioning to SAFE mode") finally: # TODO handle failure gracefully if FOR_FLIGHT is True: self.replace_flight_mode_by_id(FMEnum.Safety.value) self.run() else: self.shutdown()
def check_sensor_board(): try: gyro = GyroSensor() gyro_data = gyro.get_gyro() except Exception as e: log_error(e) gyro = None logger.error( "GYRO init failed. Check power, gnd, and SDA/SCL connections to sensor board" ) else: logger.info(f"Gyro initialization successful. Gyro rates: {gyro_data}") if gyro: try: adc = ADC(gyro) temp = adc.read_temperature() pressure = adc.read_pressure() except Exception as e: log_error(e) logger.error( "ADC init failed. Check power, gnd, and SDA/SCL connections to sensor board" ) else: logger.info( f"ADC initialization successful. Pressure:{pressure}, Thermocouple:{temp}" ) else: logger.warning("Not initializing ADC because Gyro failed") try: rtc = RTC() rtc_time = rtc.get_time() except Exception as e: log_error(e) logger.error( "RTC init failed. Check power, gnd, and SDA/SCL connections to sensor board" ) else: logger.info(f"RTC initialization successful. RTC time: {rtc_time}")
def test_learn(args): machine = Machine("x86_64") # Compil tests log_info("Remove old files") os.system("make clean") log_info("Compile C files") status = os.system("make") assert status == 0 # Find test names c_files = [] for cur_dir, sub_dir, files in os.walk("."): c_files += [x[:-2] for x in files if x.endswith(".c")] # Ways to invoke to_invoke = { "Miasm": invoke_miasm, } if args.pin_tracer: to_invoke["PIN"] = invoke_pin # Learn + test fail = False for filename in c_files: if filename in unsupported: log_error("Skip %s (unsupported)" % filename) continue with open(filename) as fdesc: cont = Container.from_stream(fdesc) func_name = filename func_addr = cont.loc_db.get_name_offset(func_name) header_filename = "%s.h" % filename for name, cb in to_invoke.iteritems(): log_info("Learning %s over %s with %s" % (func_name, filename, name)) cmdline = cb(filename, func_name, header_filename, cont) print " ".join(cmdline) sibyl = subprocess.Popen(cmdline, env=os.environ, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = sibyl.communicate() if sibyl.returncode != 0: log_error("Failed to learn with error:") print stderr fail = True continue log_info("Testing generated class") mod = imp.new_module("testclass") exec stdout in mod.__dict__ classTest = getattr(mod, "TESTS")[0] tl = TestLauncher(filename, machine, ABI_AMD64_SYSTEMV, [classTest], config.jit_engine) possible_funcs = tl.run(func_addr) if tl.possible_funcs and possible_funcs == [filename]: log_success("Generated class recognize the function " \ "'%s'" % func_name) else: log_error("Generated class failed to recognize the function " \ "'%s'" % func_name) fail = True # Clean log_info( "Remove old files" ) os.system("make clean") return fail
def test_find(args): if args.func_heuristic: get_funcs = get_funcs_heuristics else: get_funcs = get_funcs_exe_source # Compil tests log_info("Remove old files") os.system("make clean") log_info("Compile C files") status = os.system("make") # Find test names c_files = [] for cur_dir, sub_dir, files in os.walk("."): c_files += [x for x in files if x.endswith(".c")] log_info("Found:\n\t- " + "\n\t- ".join(c_files)) for c_file in c_files: filename = c_file[:-2] log_info(" %s:" % filename) # to_check: (addr, expected found) # extra: possible extra match to_check, extra = get_funcs(c_file, filename) print "\n".join("0x%08x: %s" % (addr, funcname) for (addr, funcname) in to_check) # Launch Sibyl log_info("Launch Sibyl") options = ["-j", "gcc", "-i", "5", "-b", "ABIStdCall_x86_32"] if not args.arch_heuristic: options += ["-a", "x86_32"] cmd = ["sibyl", "find"] + options + [filename] cmd += [hex(addr) for addr, _ in to_check] print " ".join(cmd) sibyl = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # Parse result found = [] stdout, stderr = sibyl.communicate() for line in stdout.split("\n"): if not line or not " : " in line: continue addr, func = line.split(" : ") found.append((int(addr, 0), func)) if sibyl.returncode: log_error("Process exits with a %d code" % sibyl.returncode) print stderr exit(sibyl.returncode) log_info("Evaluate results") i = 0 for element in found: if element not in to_check: offset, name = element if offset in extra.get(name, []): # Present in symtab but not in C source file print "[+] Additionnal found: %s (@0x%08x)" % (name, offset) else: alt_names = [ aname for aname, offsets in extra.iteritems() if offset in offsets ] log_error("Bad found: %s (@0x%08x -> '%s')" % (name, offset, ",".join(alt_names))) else: i += 1 for element in to_check: if element not in found: log_error("Unable to find: %s (@0x%08x)" % (element[1], element[0])) log_success("Found %d/%d correct elements" % (i, len(to_check))) log_info("Remove old files") os.system("make clean") return False
def test_learn(args): machine = Machine("x86_64") # Compil tests log_info("Remove old files") os.system("make clean") log_info("Compile C files") status = os.system("make") assert status == 0 # Find test names c_files = [] for cur_dir, sub_dir, files in os.walk("."): c_files += [x[:-2] for x in files if x.endswith(".c")] # Ways to invoke to_invoke = { "Miasm": invoke_miasm, } if args.pin_tracer: to_invoke["PIN"] = invoke_pin # Learn + test fail = False for filename in c_files: if filename in unsupported: log_error("Skip %s (unsupported)" % filename) continue with open(filename) as fdesc: cont = Container.from_stream(fdesc) func_name = filename func_addr = cont.loc_db.get_name_offset(func_name) header_filename = "%s.h" % filename for name, cb in to_invoke.iteritems(): log_info("Learning %s over %s with %s" % (func_name, filename, name)) cmdline = cb(filename, func_name, header_filename, cont) print " ".join(cmdline) sibyl = subprocess.Popen(cmdline, env=os.environ, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = sibyl.communicate() if sibyl.returncode != 0: log_error("Failed to learn with error:") print stderr fail = True continue log_info("Testing generated class") mod = imp.new_module("testclass") exec stdout in mod.__dict__ classTest = getattr(mod, "TESTS")[0] tl = TestLauncher(filename, machine, ABI_AMD64_SYSTEMV, [classTest], config.jit_engine) possible_funcs = tl.run(func_addr) if tl.possible_funcs and possible_funcs == [filename]: log_success("Generated class recognize the function " \ "'%s'" % func_name) else: log_error("Generated class failed to recognize the function " \ "'%s'" % func_name) fail = True # Clean log_info("Remove old files") os.system("make clean") return fail
def test_find(args): if args.func_heuristic: get_funcs = get_funcs_heuristics else: get_funcs = get_funcs_exe_source # Compil tests log_info( "Remove old files" ) os.system("make clean") log_info( "Compile C files" ) status = os.system("make") # Find test names c_files = [] for cur_dir, sub_dir, files in os.walk("."): c_files += [x for x in files if x.endswith(".c")] log_info( "Found:\n\t- " + "\n\t- ".join(c_files) ) for c_file in c_files: filename = c_file[:-2] log_info( " %s:" % filename ) # to_check: (addr, expected found) # extra: possible extra match to_check, extra = get_funcs(c_file, filename) print "\n".join("0x%08x: %s" % (addr, funcname) for (addr, funcname) in to_check) # Launch Sibyl log_info( "Launch Sibyl" ) options = ["-j", "gcc", "-i", "5", "-b", "ABIStdCall_x86_32"] if not args.arch_heuristic: options += ["-a", "x86_32"] cmd = ["sibyl", "find"] + options + [filename] cmd += [hex(addr) for addr, _ in to_check] print " ".join(cmd) sibyl = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # Parse result found = [] stdout, stderr = sibyl.communicate() for line in stdout.split("\n"): if not line or not " : " in line: continue addr, func = line.split(" : ") found.append((int(addr, 0), func)) if sibyl.returncode: log_error("Process exits with a %d code" % sibyl.returncode) print stderr exit(sibyl.returncode) log_info( "Evaluate results" ) i = 0 for element in found: if element not in to_check: offset, name = element if offset in extra.get(name, []): # Present in symtab but not in C source file print "[+] Additionnal found: %s (@0x%08x)" % (name, offset) else: alt_names = [aname for aname, offsets in extra.iteritems() if offset in offsets] log_error("Bad found: %s (@0x%08x -> '%s')" % (name, offset, ",".join(alt_names))) else: i += 1 for element in to_check: if element not in found: log_error("Unable to find: %s (@0x%08x)" % (element[1], element[0])) log_success("Found %d/%d correct elements" % (i, len(to_check))) log_info( "Remove old files" ) os.system("make clean") return False
def test_find(args): custom_tag = "my_" whitelist_funcs = ["main"] # Compil tests log_info("Remove old files") os.system("make clean") log_info("Compile C files") status = os.system("make") # Find test names c_files = [] for cur_dir, sub_dir, files in os.walk("."): c_files += [x for x in files if x.endswith(".c")] log_info("Found:\n\t- " + "\n\t- ".join(c_files)) m = re.compile("\w+[ \*]+(\w+)\(.*\)") for c_file in c_files: # Get function defined in the source with open(c_file) as fdesc: data = fdesc.read() filename = c_file[:-2] log_info(" %s:" % filename) funcs = [] for p in m.finditer(data): funcs.append(p.groups()[0]) funcs = list(x for x in set(funcs) if x not in whitelist_funcs) # Find corresponding binary offset to_check = [] with open(filename) as fdesc: elf = ELF(fdesc.read()) symbols = {} for name, symb in elf.getsectionbyname(".symtab").symbols.iteritems(): offset = symb.value if name.startswith("__"): name = name[2:] symbols.setdefault(name, set()).add(offset) if name in funcs: if name.startswith(custom_tag): ## Custom tags can be used to write equivalent functions like ## 'my_strlen' for a custom strlen name = name[len(custom_tag):] to_check.append((offset, name)) print "\n".join("0x%08x: %s" % (addr, funcname) for (addr, funcname) in to_check) # Launch Sibyl log_info("Launch Sibyl") options = ["-j", "gcc", "-i", "5", "-b", "ABIStdCall_x86_32"] if not args.arch_heuristic: options += ["-a", "x86_32"] cmd = ["sibyl", "find"] + options + [filename] if not args.func_heuristic: cmd += [hex(addr) for addr, f in to_check] print " ".join(cmd) sibyl = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # Parse result found = [] stdout, stderr = sibyl.communicate() for line in stdout.split("\n"): if not line: continue addr, func = line.split(" : ") found.append((int(addr, 16), func)) if sibyl.returncode: log_error("Process exits with a %d code" % sibyl.returncode) print stderr exit(sibyl.returncode) log_info("Evaluate results") i = 0 for element in found: if element not in to_check: offset, name = element if offset in symbols.get(name, []): # Present in symtab but not in C source file print "[+] Additionnal found: %s (@0x%08x)" % (name, offset) else: alt_names = [ aname for aname, offsets in symbols.iteritems() if offset in offsets ] log_error("Bad found: %s (@0x%08x -> '%s')" % (name, offset, ",".join(alt_names))) else: i += 1 for element in to_check: if element not in found: log_error("Unable to find: %s (@0x%08x)" % (element[1], element[0])) log_success("Found %d/%d correct elements" % (i, len(to_check))) log_info("Remove old files") os.system("make clean")
def init_sensors(self) -> int: try: self.gom = Gomspace() except Exception as e: # self.gom = None log_error(e) logger.error("GOM initialization failed") else: logger.info("Gom initialized") try: self.gyro = GyroSensor() except Exception as e: # self.gyro = None log_error(e) logger.error("GYRO initialization failed") else: logger.info("Gyro initialized") try: self.adc = ADC(self.gyro) self.adc.read_temperature() except Exception as e: # self.adc = None log_error(e) logger.error("ADC initialization failed") else: logger.info("ADC initialized") try: self.rtc = RTC() self.rtc.get_time() except Exception as e: # self.rtc = None log_error(e) logger.error("RTC initialization failed") else: logger.info("RTC initialized") try: self.nemo_manager = NemoManager(port_id=3, data_dir=NEMO_DIR, reset_gpio_ch=16) except Exception as e: # self.nemo_manager = None log_error(e) logger.error("NEMO initialization failed") else: logger.info("NEMO initialized") try: self.radio = Radio() except Exception as e: # self.radio = None log_error(e) logger.error("RADIO initialization failed") else: logger.info("Radio initialized") # initialize the Mux, select a camera try: self.mux = camera.CameraMux() self.mux.selectCamera(1) except Exception as e: # self.mux = None log_error(e) logger.error("MUX initialization failed") else: logger.info("Mux initialized") cameras_list = [0, 0, 0] # initialize cameras only if not a hard boot (or first boot) if not hard_boot() and os.path.isdir(self.log_dir): try: self.camera = camera.Camera() for i in [1, 2, 3]: try: self.mux.selectCamera(i) f, t = self.camera.rawObservation(f"initialization-{i}-{int(time())}") except Exception as e: log_error(e) logger.error(f"CAM{i} initialization failed") cameras_list[i - 1] = 0 else: logger.info(f"Cam{i} initialized with {f}:{t}") cameras_list[i - 1] = 1 if 0 in cameras_list: raise Exception except Exception: # self.camera = None logger.error(f"Cameras initialization failed") else: logger.info("Cameras initialized") else: self.need_to_reboot = True # make a bitmask of the initialized sensors for downlinking sensors = [self.gom, self.radio, self.gyro, self.adc, self.rtc, self.mux, self.camera] sensor_functioning_list = [int(bool(sensor)) for sensor in sensors] sensor_functioning_list.extend(cameras_list) sensor_bitmask = ''.join(map(str, sensor_functioning_list)) logger.debug(f"Sensors: {sensor_bitmask}") return int(sensor_bitmask, 2)