class TestATRE(unittest.TestCase): """ Test ATRuntime Environment commands preparation and evaluation NOTE: this tests doesn't test communicator! """ def __init__(self, methodName): super().__init__(methodName) self.atre = ATRuntimeEnvironment() self.script_dir = "%s/scripts/" % dirname(__file__) def test_session_reset(self): #Try to reset session cmd = ATCommand("AT", "OK") cmds = [cmd] self.atre.init_session(cmds) def set_esks(self): #Try to set ESK esks = [] esk = ESK.to_ESKValue(ESK.get_esk_from_string("AOF"), "True") self.assertIsNotNone(esk, "Could not parse ESK") esks.append((esk, 0)) self.atre.set_ESKs(esks) def parse_script(self): #Try to parse script try: self.atre.parse_ATScript("%s%s" % (self.script_dir, SCRIPT)) except ATScriptNotFound as err: raise err except ATScriptSyntaxError as err: raise err def test_session_key(self): #Try to get unexisting key with self.assertRaises(KeyError): self.atre.get_session_value("foobar") def test_run(self): self.atre = ATRuntimeEnvironment(True) #Configure virtual communicator #Parse script try: self.atre.parse_ATScript("%s%s" % (self.script_dir, SCRIPT_RUN)) except (ATScriptNotFound, ATScriptSyntaxError) as err: self.assertTrue(False, "Could not parse AT script: %s" % err) #Assert uninitialized atre with self.assertRaises(ATREUninitializedError): self.atre.run() #Initialize communicator and then run self.atre.configure_virtual_communicator("virtualAdapter", 115200, 10, "\r", read_callback, write_callback, in_waiting) try: self.atre.run() except (ATRuntimeError, ATSerialPortError, ATREUninitializedError) as err: self.assertTrue(False, "Runtime error: %s" % err) def test_exec(self): self.atre = ATRuntimeEnvironment(True) #Exec single command string with self.assertRaises(ATREUninitializedError): self.atre.exec("AT;;OK") self.atre.configure_virtual_communicator("virtualAdapter", 115200, 10, "\r", read_callback, write_callback, in_waiting) self.atre.open_serial() self.atre.exec("AT;;OK;;100") #Tests delay too #Test bad response with self.assertRaises(ATRuntimeError): self.atre.exec("AT;;NOK") #Test ESK self.atre.exec("PRINT Foobar") with self.assertRaises(ATRuntimeError): self.atre.exec("GETENV aaaaaaaaaaa") self.assertIsNone(self.atre.exec("")) self.atre.close_serial() def test_exec_step(self): self.atre = ATRuntimeEnvironment(True) #Configure virtual communicator self.atre.configure_virtual_communicator("virtualAdapter", 115200, 10, "\r", read_callback, write_callback, in_waiting) #Parse script try: self.atre.parse_ATScript("%s%s" % (self.script_dir, SCRIPT_RUN)) except (ATScriptNotFound, ATScriptSyntaxError) as err: self.assertTrue(False, "Could not parse AT script: %s" % err) #Open serial self.atre.open_serial() res = True while res: try: res = self.atre.exec_next() except (ATRuntimeError, ATSerialPortError, ATREUninitializedError) as err: self.assertTrue(False, "Runtime error: %s" % err) self.atre.close_serial() #With errors self.atre.init_session([]) #Parse script try: self.atre.parse_ATScript("%s%s" % (self.script_dir, SCRIPT_ATRE_ERR)) except (ATScriptNotFound, ATScriptSyntaxError) as err: self.assertTrue(False, "Could not parse AT script: %s" % err) #Open serial self.atre.open_serial() with self.assertRaises(ATRuntimeError): self.atre.exec_next() self.atre.close_serial() def test_fail_parse(self): self.atre = ATRuntimeEnvironment(True) #Configure virtual communicator self.atre.configure_virtual_communicator("virtualAdapter", 115200, 10, "\r", read_callback, write_callback, in_waiting) #Parse script with self.assertRaises(ATScriptNotFound): self.atre.parse_ATScript("/tmp/unexisting_script.ats") with self.assertRaises(ATScriptSyntaxError): self.atre.parse_ATScript("%s%s" % (self.script_dir, SCRIPT_ERR)) def test_add_command(self): self.atre = ATRuntimeEnvironment(True) #Configure virtual communicator self.atre.configure_virtual_communicator("virtualAdapter", 115200, 10, "\r", read_callback, write_callback, in_waiting) cmd = ATCommand("AT", "OK") self.assertTrue(self.atre.add_command(cmd), "ATRE add_command failed") def test_serial(self): self.atre = ATRuntimeEnvironment(True) #Open before init with self.assertRaises(ATREUninitializedError): self.atre.open_serial() #Close before init with self.assertRaises(ATREUninitializedError): self.atre.close_serial() #Configure virtual communicator self.atre.configure_virtual_communicator("virtualAdapter", 115200, 10, "\r", read_callback, write_callback, in_waiting) self.atre.open_serial() self.atre.open_serial() #Re-open, nothing strange should happen self.atre.close_serial() self.atre.close_serial() #Re-close, nothing strange should happen def test_exceptions(self): #AtSerialPortError msg = "Could not open Serial Device" exc = ATSerialPortError(msg) self.assertIsNotNone(str(exc)) self.assertEqual(repr(exc), msg) #ATScriptNotFound msg = "Could not open file /tmp/foobar.ats" exc = ATScriptNotFound(msg) self.assertIsNotNone(str(exc)) self.assertEqual(repr(exc), msg) #ATScriptSyntaxError msg = "Error while parsing AT script" exc = ATScriptSyntaxError(msg) self.assertIsNotNone(str(exc)) self.assertEqual(repr(exc), msg) #ATREUninitializedError msg = "Uninitialized AT Runtime Environment" exc = ATREUninitializedError(msg) self.assertIsNotNone(str(exc)) self.assertEqual(repr(exc), msg) #ATRuntimeError msg = "Runtime Error" exc = ATRuntimeError(msg) self.assertIsNotNone(str(exc)) self.assertEqual(repr(exc), msg)
def main(argc, argv): #Get option global verbose serial_port = None command = None baudrate = 115200 try: optlist, args = getopt(argv, "b::vh") #Iterate over options for opt, arg in optlist: if opt == "-b": baudrate = int(arg) elif opt == "-v": verbose = True elif opt == "-h": usage() return 255 if args: if len(args) < 2: usage("Missing Arguments") return 255 serial_port = args[0] command = args[1] else: usage("Missing arguments") return 255 except GetoptError as err: usage(err) return 255 #Instantiate attila atrunenv = ATRuntimeEnvironment(abort_on_failure=False) #Configure communicator atrunenv.configure_communicator(serial_port, baudrate, 5000, line_break="\r\n") atcommand = None if command == "SILENCE": atcommand = "AT^CURC=0;;OK" elif command == "IMEI": atcommand = "AT+CGSN;;^[0-9]{15}$" elif command == "CSQ": atcommand = "AT+CSQ;;[0-9]{1,2}" elif command == "RSSI": atcommand = "AT+CSQ;;[0-9]{1,2}" elif command == "MODEL": atcommand = "AT+GMM;;(.*)(.?[0-9])" elif command == "OPERATOR": atcommand = "AT+COPS?;;\\\"(.*)\\\"" elif command == "CREG": atcommand = "AT+CREG?;;[0-9]{1},[0-9]{1}" else: print_err("Unknown command %s" % command) return 1 #Open serial try: atrunenv.open_serial() except ATSerialPortError as err: print_err("Could not open serial: %s" % err) return 1 try: response = atrunenv.exec(atcommand) except Exception as err: print_err("Could not execute AT command: %s" % err) atrunenv.close_serial() return 1 #Close serial atrunenv.close_serial() #Print response if response.response: #Fix response for rssi if command == "RSSI": out = -113 + (int(response.response) * 2) else: out = response.response print(out) if verbose: print_info(response.full_response) else: print_err(response.full_response) return 1 return 0
class TestATRE(unittest.TestCase): """ Test ATRuntime Environment commands preparation and evaluation NOTE: this tests doesn't test communicator! """ def __init__(self, methodName): super().__init__(methodName) self.atre = ATRuntimeEnvironment() self.script_dir = "%s/scripts/" % dirname(__file__) #Verify constructor self.assertEqual(self.atre.aof, True) def test_session_reset(self): # Try to reset session cmd = ATCommand("AT", "OK") cmds = [cmd] self.atre.init_session(cmds) def test_set_esks(self): # Try to set ESK esks = [] esk = ESK.to_ESKValue(ESK.get_esk_from_string("AOF"), "True") self.assertIsNotNone(esk, "Could not parse ESK AOF") esks.append((esk, 0)) self.atre.set_ESKs(esks) #Test ESKs self.assertTrue( self.atre._ATRuntimeEnvironment__process_ESK( ESK.to_ESKValue(ESK.AOF, "True"))) self.assertTrue( self.atre._ATRuntimeEnvironment__process_ESK( ESK.to_ESKValue(ESK.BAUDRATE, "9600"))) self.assertTrue( self.atre._ATRuntimeEnvironment__process_ESK( ESK.to_ESKValue(ESK.BREAK, "CRLF"))) #Use a different ATRE for device new_atre = ATRuntimeEnvironment() self.assertTrue( new_atre._ATRuntimeEnvironment__process_ESK( ESK.to_ESKValue(ESK.DEVICE, "/dev/ttyS1"))) self.assertTrue( self.atre._ATRuntimeEnvironment__process_ESK( ESK.to_ESKValue(ESK.DSRDTR, "True"))) self.assertTrue( self.atre._ATRuntimeEnvironment__process_ESK( ESK.to_ESKValue(ESK.EXEC, "echo foo"))) self.assertTrue( self.atre._ATRuntimeEnvironment__process_ESK( ESK.to_ESKValue(ESK.GETENV, "PATH"))) self.assertTrue( self.atre._ATRuntimeEnvironment__process_ESK( ESK.to_ESKValue(ESK.PRINT, "foobar"))) self.assertTrue( self.atre._ATRuntimeEnvironment__process_ESK( ESK.to_ESKValue(ESK.RTSCTS, "True"))) self.assertTrue( self.atre._ATRuntimeEnvironment__process_ESK( ESK.to_ESKValue(ESK.SET, "PIN=1522"))) self.assertTrue( self.atre._ATRuntimeEnvironment__process_ESK( ESK.to_ESKValue(ESK.TIMEOUT, "5"))) tempfile = NamedTemporaryFile() self.assertTrue( self.atre._ATRuntimeEnvironment__process_ESK( ESK.to_ESKValue(ESK.WRITE, "%s HELLO WORLD!" % tempfile.name))) #Bad cases self.assertFalse( self.atre._ATRuntimeEnvironment__process_ESK( ESK.to_ESKValue(ESK.DEVICE, "/dev/ttyS1"))) def test_write(self): #Test write tempfile = NamedTemporaryFile() self.assertTrue( self.atre._ATRuntimeEnvironment__write_file( tempfile.name, "HELLO WORLD!")) #Try bad write self.assertFalse( self.atre._ATRuntimeEnvironment__write_file("/", "HELLO WORLD!")) def test_reconfigure_communicator(self): self.assertTrue( self.atre._ATRuntimeEnvironment__reconfigure_communicator()) def test_parse_script(self): # Try to parse script try: self.atre.parse_ATScript("%s%s" % (self.script_dir, SCRIPT)) except ATScriptNotFound as err: raise err except ATScriptSyntaxError as err: raise err def test_configure_communicator(self): self.atre.configure_communicator("/dev/ttyS0", 115200, 5, "\r\n", False, False) self.assertEqual( self.atre._ATRuntimeEnvironment__communicator.serial_port, "/dev/ttyS0") self.assertEqual( self.atre._ATRuntimeEnvironment__communicator.baud_rate, 115200) self.assertEqual( self.atre._ATRuntimeEnvironment__communicator.default_timeout, 5) self.assertEqual( self.atre._ATRuntimeEnvironment__communicator.line_break, "\r\n") self.assertEqual(self.atre._ATRuntimeEnvironment__communicator.rtscts, False) self.assertEqual(self.atre._ATRuntimeEnvironment__communicator.dsrdtr, False) def test_session_key(self): # Try to get unexisting key with self.assertRaises(KeyError): self.atre.get_session_value("foobar") def test_run(self): self.atre = ATRuntimeEnvironment(True) # Configure virtual communicator # Parse script try: self.atre.parse_ATScript("%s%s" % (self.script_dir, SCRIPT_RUN)) except (ATScriptNotFound, ATScriptSyntaxError) as err: self.assertTrue(False, "Could not parse AT script: %s" % err) # Assert uninitialized atre with self.assertRaises(ATREUninitializedError): self.atre.run() # Initialize communicator and then run self.atre.configure_virtual_communicator("virtualAdapter", 115200, 10, "\r", read_callback, write_callback, in_waiting) try: self.atre.run() except (ATRuntimeError, ATSerialPortError, ATREUninitializedError) as err: self.assertTrue(False, "Runtime error: %s" % err) def test_exec(self): self.atre = ATRuntimeEnvironment(True) # Exec single command string with self.assertRaises(ATREUninitializedError): self.atre.exec("AT;;OK") self.atre.configure_virtual_communicator("virtualAdapter", 115200, 10, "\r\n", read_callback, write_callback, in_waiting) self.atre.open_serial() self.atre.exec("AT;;OK;;100") # Tests delay too # Test bad response with self.assertRaises(ATRuntimeError): self.atre.exec("AT;;NOK") # Test ESK self.atre.exec("PRINT Foobar") with self.assertRaises(ATRuntimeError): self.atre.exec("GETENV aaaaaaaaaaa") self.assertIsNone(self.atre.exec("")) self.atre.close_serial() def test_exec_step(self): self.atre = ATRuntimeEnvironment(True) # Configure virtual communicator self.atre.configure_virtual_communicator("virtualAdapter", 115200, 10, "\r", read_callback, write_callback, in_waiting) # Parse script try: self.atre.parse_ATScript("%s%s" % (self.script_dir, SCRIPT_RUN)) except (ATScriptNotFound, ATScriptSyntaxError) as err: self.assertTrue(False, "Could not parse AT script: %s" % err) # Open serial self.atre.open_serial() res = True while res: try: res = self.atre.exec_next() except (ATRuntimeError, ATSerialPortError, ATREUninitializedError) as err: self.assertTrue(False, "Runtime error: %s" % err) self.atre.close_serial() # With errors self.atre.init_session([]) # Parse script try: self.atre.parse_ATScript("%s%s" % (self.script_dir, SCRIPT_ATRE_ERR)) except (ATScriptNotFound, ATScriptSyntaxError) as err: self.assertTrue(False, "Could not parse AT script: %s" % err) # Open serial self.atre.open_serial() with self.assertRaises(ATRuntimeError): self.atre.exec_next() self.atre.close_serial() def test_fail_parse(self): self.atre = ATRuntimeEnvironment(True) # Configure virtual communicator self.atre.configure_virtual_communicator("virtualAdapter", 115200, 10, "\r", read_callback, write_callback, in_waiting) # Parse script with self.assertRaises(ATScriptNotFound): self.atre.parse_ATScript("/tmp/unexisting_script.ats") with self.assertRaises(ATScriptSyntaxError): self.atre.parse_ATScript("%s%s" % (self.script_dir, SCRIPT_ERR)) def test_add_command(self): self.atre = ATRuntimeEnvironment(True) # Configure virtual communicator self.atre.configure_virtual_communicator("virtualAdapter", 115200, 10, "\r", read_callback, write_callback, in_waiting) cmd = ATCommand("AT", "OK") self.assertTrue(self.atre.add_command(cmd), "ATRE add_command failed") def test_serial(self): self.atre = ATRuntimeEnvironment(True) # Open before init with self.assertRaises(ATREUninitializedError): self.atre.open_serial() # Close before init with self.assertRaises(ATREUninitializedError): self.atre.close_serial() # Configure virtual communicator self.atre.configure_virtual_communicator("virtualAdapter", 115200, 10, "\r", read_callback, write_callback, in_waiting) self.atre.open_serial() self.atre.open_serial() # Re-open, nothing strange should happen self.atre.close_serial() self.atre.close_serial() # Re-close, nothing strange should happen def test_exceptions(self): # AtSerialPortError msg = "Could not open Serial Device" exc = ATSerialPortError(msg) self.assertIsNotNone(str(exc)) self.assertEqual(repr(exc), msg) # ATScriptNotFound msg = "Could not open file /tmp/foobar.ats" exc = ATScriptNotFound(msg) self.assertIsNotNone(str(exc)) self.assertEqual(repr(exc), msg) # ATScriptSyntaxError msg = "Error while parsing AT script" exc = ATScriptSyntaxError(msg) self.assertIsNotNone(str(exc)) self.assertEqual(repr(exc), msg) # ATREUninitializedError msg = "Uninitialized AT Runtime Environment" exc = ATREUninitializedError(msg) self.assertIsNotNone(str(exc)) self.assertEqual(repr(exc), msg) # ATRuntimeError msg = "Runtime Error" exc = ATRuntimeError(msg) self.assertIsNotNone(str(exc)) self.assertEqual(repr(exc), msg)
def main(): global sigterm_called global interactive_mode #Options script_file = None device = None baud_rate = None default_timeout = 0 line_break = None logfile = None log_level = LOG_LEVEL_INFO verbose = False quiet = False abort_on_failure = True to_stdout = False try: optlist, args = getopt(argv[1:], "p::b::T::B::L::l::Avqh") if args: interactive_mode = False script_file = args[0] for opt, arg in optlist: if opt == "-p": device = arg elif opt == "-b": try: baud_rate = int(arg) except ValueError: opt_error("Specified baud rate is not a number!") elif opt == "-T": try: default_timeout = int(arg) except ValueError: opt_error("Specified default timeout is not a number!") elif opt == "-B": line_break = arg #Verify line break if line_break == "CRLF": line_break = "\r\n" elif line_break == "LF": line_break = "\n" elif line_break == "CR": line_break = "\r" elif line_break == "NONE": line_break = None else: opt_error("Invalid line break '%s'" % line_break) elif opt == "-L": logfile = arg elif opt == "-l": try: log_level = int(arg) if log_level < LOG_LEVEL_CRITICAL or log_level > LOG_LEVEL_DEBUG: opt_error("Log level is out of range") else: log_level = get_log_level_from_option(log_level) except ValueError: opt_error("Log level is not a number") elif opt == "-A": try: abort_on_failure = eval(arg) if abort_on_failure != True and abort_on_failure != False: opt_error("Abort on failure has a bad value: '%s', but should be True or False" % abort_on_failure) except NameError: opt_error("Abort on failure has a bad value") elif opt == "-v": verbose = True elif opt == "-q": quiet = True elif opt == "-h": print(USAGE) exit(0) else: opt_error("Unkown option '%s'" % opt) except GetoptError as err: opt_error(err) #Set signal handlers listener signal(SIGTERM, sigterm_handler) signal(SIGINT, sigterm_handler) #Prepare logger if requested if logfile: if logfile == "stdout": to_stdout = True stdout_handler = logging.StreamHandler(stdout) stdout_handler.setFormatter(logging.Formatter("%(asctime)s [%(levelname)s]: %(message)s", datefmt="%Y-%m-%dT%H:%M:%S")) logging.getLogger().addHandler(stdout_handler) else: logging.basicConfig(filename=logfile, level=log_level, format="%(asctime)s [%(levelname)s]: %(message)s", datefmt="%Y-%m-%dT%H:%M:%S") else: logging.getLogger().disabled = True #Instance ATRuntime environment atrunenv = ATRuntimeEnvironment(abort_on_failure) #Configure serial if device and baud_rate: atrunenv.configure_communicator(device, baud_rate, default_timeout, line_break) logging.info("Setup communicator (device: %s, baud_rate: %d)" % (device, baud_rate)) if verbose and not to_stdout: print("Setup communicator (device: %s, baud_rate: %d)" % (device, baud_rate)) #Open serial try: atrunenv.open_serial() logging.info("Serial port opened (%s)" % device) if verbose and not to_stdout: print("Serial port opened") except ATSerialPortError as err: logging.error("Could not open serial port: %s" % err) if not to_stdout and not quiet: print("Could not open serial port: %s" % err) except ATREUninitializedError as err: logging.error("Uninitialized runtime environment: %s " % err) if not to_stdout and not quiet: print("Uninitialized runtime environment: %s" % err) exit(1) #Parse file if set if script_file: logging.debug("Trying to parse file %s..." % script_file) try: atrunenv.parse_ATScript(script_file) except ATScriptNotFound as err: logging.error("Could not find script file %s: %s" % (script_file, err)) if not to_stdout: print("Could not find script file %s: %s" % (script_file, err)) exit(1) except ATScriptSyntaxError as err: logging.error("Script Syntax error: %s" % err) if not to_stdout: print("Script syntax error: %s" % err) exit(1) #Execute script response = 1 while response and not sigterm_called: try: response = atrunenv.exec_next() if not response: continue #Handle response if response.response and response.command: logging.info("%s (%d ms) >> %s" % (response.command.command, response.execution_time, response.response)) if not to_stdout and not quiet: print("%s (%d ms) >> %s" % (response.command.command, response.execution_time, response.response)) else: #Command failed (this snippet gets executed only if aof is false) logging.error("%s (%d ms) >> %s" % (response.command.command, response.execution_time, "\n".join(response.full_response))) if not to_stdout and not quiet: print("%s (%d ms) >> %s" % (response.command.command, response.execution_time, "\n".join(response.full_response))) except ATSerialPortError as err: logging.error("Serial Port error: %s" % err) if not to_stdout: print("Serial Port error: %s" % err) if atrunenv.aof: break except ATRuntimeError as err: logging.error("Runtime error: %s" % err) if not to_stdout: print("Runtime error: %s" % err) if atrunenv.aof: break except ATREUninitializedError as err: logging.error("Uninitialized runtime environment: %s " % err) else: #Interactive mode while not sigterm_called: command_line = input(">> ") if not command_line: continue #Parse and execute command try: response = atrunenv.exec(command_line) if response: #Was a command (otherwise was probably ESK) if response.response: #Command was successful logging.info("%s (%d ms) >> %s" % (response.command.command, response.execution_time, response.response)) if not to_stdout and not quiet: print("<< %s (%d ms) >> %s" % (response.command.command, response.execution_time, response.response)) else: #Command error logging.error("%s (%d ms) >> %s" % (response.command.command, response.execution_time, "\n".join(response.full_response))) if not to_stdout and not quiet: print("<< %s (%d ms) >> %s" % (response.command.command, response.execution_time, "\n".join(response.full_response))) else: logging.info("%s >> OK" % command_line) if not to_stdout and not quiet: print("%s >> OK" % command_line) except ATScriptSyntaxError as err: logging.error("Syntax error: %s" % err) if not to_stdout: print("Syntax error: %s" % err) continue except ATSerialPortError as err: logging.error("Serial Port error: %s" % err) if not to_stdout: print("Serial Port error: %s" % err) except ATRuntimeError as err: logging.error("Runtime error: %s" % err) if not to_stdout: print("Runtime error: %s" % err) #Close serial try: atrunenv.close_serial() except ATSerialPortError as err: logging.error("Could not close serial port: %s" % err) if not to_stdout and not quiet: print("Could not close serial port: %s" % err) exit(1) except ATREUninitializedError as err: logging.error("Couldn't close serial port, since device was not initialized") if verbose and not to_stdout: print("Couldn't close serial port, since device was not initialized") #Execution terminated logging.info("attila terminated with exit code 0") if not to_stdout and verbose: print("attila terminated with exit code 0")
def main(): global sigterm_called global interactive_mode # Options script_file = None device = None baud_rate = None default_timeout = 0 line_break = None rtscts = True dsrdtr = True logfile = None log_level = LOG_LEVEL_INFO verbose = False quiet = False abort_on_failure = True to_stdout = False try: optlist, args = getopt(argv[1:], "p::b::T::B::L::l::A::R::D::vqh") if args: interactive_mode = False script_file = args[0] for opt, arg in optlist: if opt == "-p": device = arg elif opt == "-b": try: baud_rate = int(arg) except ValueError: opt_error("Specified baud rate is not a number!") elif opt == "-T": try: default_timeout = int(arg) except ValueError: opt_error("Specified default timeout is not a number!") elif opt == "-B": line_break = arg # Verify line break if line_break == "CRLF": line_break = "\r\n" elif line_break == "LF": line_break = "\n" elif line_break == "CR": line_break = "\r" elif line_break == "NONE": line_break = None else: opt_error("Invalid line break '%s'" % line_break) elif opt == "-L": logfile = arg elif opt == "-l": try: log_level = int(arg) if log_level < LOG_LEVEL_CRITICAL or log_level > LOG_LEVEL_DEBUG: opt_error("Log level is out of range") else: log_level = get_log_level_from_option(log_level) except ValueError: opt_error("Log level is not a number") elif opt == "-A": try: abort_on_failure = eval(arg) if abort_on_failure != True and abort_on_failure != False: opt_error( "Abort on failure has a bad value: '%s', but should be True or False" % abort_on_failure) except NameError: opt_error("Abort on failure has a bad value") elif opt == "-R": try: rtscts = eval(arg) if rtscts != True and rtscts != False: opt_error( "rtscts has a bad value: '%s', but should be True or False" % rtscts) except NameError: opt_error("rtscts has a bad value") elif opt == "-D": try: dsrdtr = eval(arg) if dsrdtr != True and dsrdtr != False: opt_error( "dsrdtr has a bad value: '%s', but should be True or False" % dsrdtr) except NameError: opt_error("dsrdtr has a bad value") elif opt == "-v": verbose = True elif opt == "-q": quiet = True elif opt == "-h": print(USAGE) exit(0) else: opt_error("Unkown option '%s'" % opt) except GetoptError as err: opt_error(err) # Prepare logger if requested if logfile: if logfile == "stdout": to_stdout = True stdout_handler = logging.StreamHandler(stdout) stdout_handler.setFormatter( logging.Formatter("%(asctime)s [%(levelname)s]: %(message)s", datefmt="%Y-%m-%dT%H:%M:%S")) logging.getLogger().addHandler(stdout_handler) else: logging.basicConfig( filename=logfile, level=log_level, format="%(asctime)s [%(levelname)s]: %(message)s", datefmt="%Y-%m-%dT%H:%M:%S") else: logging.getLogger().disabled = True # Instance ATRuntime environment atrunenv = ATRuntimeEnvironment(abort_on_failure) # Configure serial if device and baud_rate: atrunenv.configure_communicator(device, baud_rate, default_timeout, line_break, rtscts, dsrdtr) logging.info("Setup communicator (device: %s, baud_rate: %d)" % (device, baud_rate)) if verbose and not to_stdout: print("Setup communicator (device: %s, baud_rate: %d)" % (device, baud_rate)) # Open serial try: atrunenv.open_serial() logging.info("Serial port opened (%s)" % device) if verbose and not to_stdout: print("Serial port opened") except ATSerialPortError as err: logging.error("Could not open serial port: %s" % err) if not to_stdout and not quiet: print("Could not open serial port: %s" % err) except ATREUninitializedError as err: logging.error("Uninitialized runtime environment: %s " % err) if not to_stdout and not quiet: print("Uninitialized runtime environment: %s" % err) exit(1) # Parse file if set if script_file: # Set signal handlers listener signal(SIGTERM, sigterm_handler) signal(SIGINT, sigterm_handler) logging.debug("Trying to parse file %s..." % script_file) try: atrunenv.parse_ATScript(script_file) except ATScriptNotFound as err: logging.error("Could not find script file %s: %s" % (script_file, err)) if not to_stdout: print("Could not find script file %s: %s" % (script_file, err)) exit(1) except ATScriptSyntaxError as err: logging.error("Script Syntax error: %s" % err) if not to_stdout: print("Script syntax error: %s" % err) exit(1) # Execute script response = 1 while response and not sigterm_called: try: response = atrunenv.exec_next() if not response: continue # Handle response if response.response and response.command: logging.info("%s (%d ms) >> %s" % (response.command.command, response.execution_time, response.response)) if not to_stdout and not quiet: print("%s (%d ms) >> %s" % (response.command.command, response.execution_time, response.response)) else: # Command failed (this snippet gets executed only if aof is false) logging.error( "%s (%d ms) >> %s" % (response.command.command, response.execution_time, "\n".join(response.full_response))) if not to_stdout and not quiet: print( "%s (%d ms) >> %s" % (response.command.command, response.execution_time, "\n".join(response.full_response))) except ATSerialPortError as err: logging.error("Serial Port error: %s" % err) if not to_stdout: print("Serial Port error: %s" % err) if atrunenv.aof: break except ATRuntimeError as err: logging.error("Runtime error: %s" % err) if not to_stdout: print("Runtime error: %s" % err) if atrunenv.aof: break except ATREUninitializedError as err: logging.error("Uninitialized runtime environment: %s " % err) else: # Interactive mode getch = _Getch() command_line = "" history = [] history_index = 0 sigterm_called = False print(">> ", end='', flush=True) while not sigterm_called: stdin = getch() #Handle input asciich = ord(stdin) if asciich == 3 or asciich == 4: #CTRL + C, CTRL + D sigterm_called = True continue elif asciich == 27: #Arrow arrow_key = getch() + getch() if arrow_key == "[A": #Up #history len 1 => if history_index - 1 >= 0: history_index -= 1 command_line = history[history_index] print("\r\033[K>> %s" % command_line, end='', flush=True) continue elif arrow_key == "[B": #Down if history_index + 1 < len(history): history_index += 1 command_line = history[history_index] print("\r\033[K>> %s" % command_line, end='', flush=True) elif history_index + 1 >= len(history): command_line = "" history_index = len(history) print("\r\033[K>> %s" % command_line, end='', flush=True) continue else: continue #Ignore elif asciich == 8 or asciich == 127: #Backspace command_line = command_line[:-1] print("\r\033[K>> %s" % command_line, end='', flush=True) continue elif asciich != 13 and asciich != 10: #Not a newline #Append char to buffer command_line += stdin print(stdin, end='', flush=True) continue #Newline if not command_line: print() print(">> ", end='', flush=True) command_line = "" continue print() #Push command to history history.append(command_line) # Parse and execute command try: response = atrunenv.exec(command_line) if response: # Was a command (otherwise was probably ESK) if response.response: # Command was successful logging.info( "%s (%d ms) >> %s" % (response.command.command, response.execution_time, response.response)) if not to_stdout and not quiet: print("<< %s (%d ms) >> %s" % (response.command.command, response.execution_time, response.response)) else: # Command error logging.error( "%s (%d ms) >> %s" % (response.command.command, response.execution_time, "\n".join(response.full_response))) if not to_stdout and not quiet: print("<< %s (%d ms) >> %s" % (response.command.command, response.execution_time, "\n".join( response.full_response))) else: logging.info("%s >> OK" % command_line) if not to_stdout and not quiet: print("%s >> OK" % command_line) except ATScriptSyntaxError as err: logging.error("Syntax error: %s" % err) if not to_stdout: print("Syntax error: %s" % err) except ATSerialPortError as err: logging.error("Serial Port error: %s" % err) if not to_stdout: print("Serial Port error: %s" % err) except ATRuntimeError as err: logging.error("Runtime error: %s" % err) if not to_stdout: print("Runtime error: %s" % err) except ATREUninitializedError as err: logging.error("Uninitialized error: %s" % err) if not to_stdout: print("Uninitialized error: %s" % err) #Reset command line and history index command_line = "" history_index = len(history) print(">> ", end='', flush=True) # Close serial try: atrunenv.close_serial() except ATSerialPortError as err: logging.error("Could not close serial port: %s" % err) if not to_stdout and not quiet: print("Could not close serial port: %s" % err) exit(1) except ATREUninitializedError as err: logging.error( "Couldn't close serial port, since device was not initialized") if verbose and not to_stdout: print( "Couldn't close serial port, since device was not initialized") # Execution terminated logging.info("attila terminated with exit code 0") if not to_stdout and verbose: print("attila terminated with exit code 0")