diff --git a/Software/Chameleon/Device.py b/Software/Chameleon/Device.py index 6aae7d57..68dcafb7 100644 --- a/Software/Chameleon/Device.py +++ b/Software/Chameleon/Device.py @@ -7,6 +7,7 @@ import time import Chameleon + class Device: COMMAND_VERSION = "VERSION" COMMAND_UPLOAD = "UPLOAD" @@ -57,7 +58,7 @@ class Device: SET_CHAR = "=" GET_CHAR = "?" - def __init__(self, verboseFunc = None): + def __init__(self, verboseFunc=None): self.verboseFunc = verboseFunc self.serial = serial.Serial(None, 9600, timeout=5.0) self.versionString = "" @@ -130,6 +131,7 @@ def writeCmd(self, cmd): # Get status response status = self.serial.readline().decode('ascii').rstrip() + self.verboseLog(status) if (len(status) == 0): self.verboseLog("Executing <{}>: Timeout".format(cmd)) @@ -140,10 +142,11 @@ def writeCmd(self, cmd): statusCode, statusText = status.split(":") statusCode = int(statusCode) - result = {'statusCode': statusCode, 'statusText': statusText, 'response': None} + result = {'statusCode': statusCode, + 'statusText': statusText, 'response': None} if (statusCode == self.STATUS_CODE_OK_WITH_TEXT): - result['response'] = self.readResponse() + result['response'] = self.readResponse() elif (statusCode == self.STATUS_CODE_TRUE): result['response'] = True elif (statusCode == self.STATUS_CODE_FALSE): @@ -153,7 +156,11 @@ def writeCmd(self, cmd): def readResponse(self): # Read response to command, if any - response = self.serial.readline().decode('ascii').rstrip() + response = "" + while self.serial.in_waiting: + line = self.serial.read().decode('ascii') + response += line + response = response.rstrip().replace('\t', ' ').replace('\r\n', ' | ') self.verboseLog("Response: {}".format(response)) return response @@ -214,10 +221,10 @@ def cmdLogMode(self, newLogMode): def cmdVersion(self): return self.getSetCmd(self.COMMAND_VERSION) - def cmdSetting(self, newSetting = None): + def cmdSetting(self, newSetting=None): return self.getSetCmd(self.COMMAND_SETTING, newSetting) - def cmdUID(self, newUID = None): + def cmdUID(self, newUID=None): return self.getSetCmd(self.COMMAND_UID, newUID) def cmdGetUID(self): @@ -229,43 +236,43 @@ def cmdIdentify(self): def cmdDumpMFU(self): return self.returnCmd(self.COMMAND_DUMPMFU) - def cmdConfig(self, newConfig = None): + def cmdConfig(self, newConfig=None): if (newConfig == self.SUGGEST_CHAR): return self.getCmdSuggestions(self.COMMAND_CONFIG) else: return self.getSetCmd(self.COMMAND_CONFIG, newConfig) - def cmdLButton(self, newAction = None): + def cmdLButton(self, newAction=None): if (newAction == self.SUGGEST_CHAR): return self.getCmdSuggestions(self.COMMAND_LBUTTON) else: return self.getSetCmd(self.COMMAND_LBUTTON, newAction) - def cmdLButtonLong(self, newAction = None): + def cmdLButtonLong(self, newAction=None): if (newAction == self.SUGGEST_CHAR): return self.getCmdSuggestions(self.COMMAND_LBUTTONLONG) else: return self.getSetCmd(self.COMMAND_LBUTTONLONG, newAction) - def cmdRButton(self, newAction = None): + def cmdRButton(self, newAction=None): if (newAction == self.SUGGEST_CHAR): return self.getCmdSuggestions(self.COMMAND_RBUTTON) else: return self.getSetCmd(self.COMMAND_RBUTTON, newAction) - def cmdRButtonLong(self, newAction = None): + def cmdRButtonLong(self, newAction=None): if (newAction == self.SUGGEST_CHAR): return self.getCmdSuggestions(self.COMMAND_RBUTTONLONG) else: return self.getSetCmd(self.COMMAND_RBUTTONLONG, newAction) - def cmdGreenLED(self, newFunction = None): + def cmdGreenLED(self, newFunction=None): if (newFunction == self.SUGGEST_CHAR): return self.getCmdSuggestions(self.COMMAND_GREEN_LED) else: return self.getSetCmd(self.COMMAND_GREEN_LED, newFunction) - def cmdRedLED(self, newFunction = None): + def cmdRedLED(self, newFunction=None): if (newFunction == self.SUGGEST_CHAR): return self.getCmdSuggestions(self.COMMAND_RED_LED) else: diff --git a/Software/chamtool.py b/Software/chamtool.py index 8a1203f5..973f79d0 100755 --- a/Software/chamtool.py +++ b/Software/chamtool.py @@ -8,15 +8,19 @@ import sys import datetime + def verboseLog(text): formatString = "[{}] {}" timeString = datetime.datetime.utcnow() print(formatString.format(timeString, text), sys.stderr) # Command funcs + + def cmdInfo(chameleon, arg): return "{}".format(chameleon.cmdVersion()['response']) + def cmdSetting(chameleon, arg): result = chameleon.cmdSetting(arg) @@ -29,6 +33,7 @@ def cmdSetting(chameleon, arg): return "Change setting to {} failed: {}".format(arg, result['statusText']) return + def cmdUID(chameleon, arg): result = chameleon.cmdUID(arg) @@ -40,15 +45,19 @@ def cmdUID(chameleon, arg): else: return "Setting UID to {} failed: {}".format(arg, result['statusText']) + def cmdGetUID(chameleon, arg): return "{}".format(chameleon.cmdGetUID()['response']) + def cmdIdentify(chameleon, arg): return "{}".format(chameleon.cmdIdentify()['response']) + def cmdDumpMFU(chameleon, arg): return "{}".format(chameleon.cmdDumpMFU()['response']) + def cmdConfig(chameleon, arg): result = chameleon.cmdConfig(arg) @@ -62,21 +71,25 @@ def cmdConfig(chameleon, arg): else: return "Changing configuration to {} failed: {}".format(arg, result['statusText']) + def cmdUpload(chameleon, arg): with open(arg, 'rb') as fileHandle: bytesSent = chameleon.cmdUploadDump(fileHandle) return "{} Bytes successfully read from {}".format(bytesSent, arg) + def cmdDownload(chameleon, arg): with open(arg, 'wb') as fileHandle: bytesReceived = chameleon.cmdDownloadDump(fileHandle) return "{} Bytes successfully written to {}".format(bytesReceived, arg) + def cmdLog(chameleon, arg): with open(arg, 'wb') as fileHandle: bytesReceived = chameleon.cmdDownloadLog(fileHandle) return "{} Bytes successfully written to {}".format(bytesReceived, arg) + def cmdLogMode(chameleon, arg): result = chameleon.cmdLogMode(arg) @@ -88,6 +101,7 @@ def cmdLogMode(chameleon, arg): else: return "Setting logmode failed: {}".format(arg, result['statusText']) + def cmdLButton(chameleon, arg): result = chameleon.cmdLButton(arg) @@ -101,6 +115,7 @@ def cmdLButton(chameleon, arg): else: return "Setting left button action to {} failed: {}".format(arg, result['statusText']) + def cmdLButtonLong(chameleon, arg): result = chameleon.cmdLButtonLong(arg) @@ -114,6 +129,7 @@ def cmdLButtonLong(chameleon, arg): else: return "Setting long press left button action to {} failed: {}".format(arg, result['statusText']) + def cmdRButton(chameleon, arg): result = chameleon.cmdRButton(arg) @@ -127,6 +143,7 @@ def cmdRButton(chameleon, arg): else: return "Setting right button action to {} failed: {}".format(arg, result['statusText']) + def cmdRButtonLong(chameleon, arg): result = chameleon.cmdRButtonLong(arg) @@ -140,6 +157,7 @@ def cmdRButtonLong(chameleon, arg): else: return "Setting long press right button action to {} failed: {}".format(arg, result['statusText']) + def cmdGreenLED(chameleon, arg): result = chameleon.cmdGreenLED(arg) @@ -153,6 +171,7 @@ def cmdGreenLED(chameleon, arg): else: return "Setting green LED function to {} failed: {}".format(arg, result['statusText']) + def cmdRedLED(chameleon, arg): result = chameleon.cmdRedLED(arg) @@ -166,6 +185,7 @@ def cmdRedLED(chameleon, arg): else: return "Setting red LED function to {} failed: {}".format(arg, result['statusText']) + def cmdThreshold(chameleon, arg): result = chameleon.cmdThreshold(arg) @@ -177,12 +197,15 @@ def cmdThreshold(chameleon, arg): else: return "Setting threshold failed: {}".format(arg, result['statusText']) + def cmdUpgrade(chameleon, arg): if(chameleon.cmdUpgrade() == 0): - print ("Device changed into Upgrade Mode") + print("Device changed into Upgrade Mode") exit(0) # Custom class for argparse + + class CmdListAction(argparse.Action): def __init__(self, option_strings, dest, default=False, required=False, help=None, metavar=None, nargs=None, type=None, choices=None, const=None): @@ -197,33 +220,56 @@ def __call__(self, parser, namespace, values, option_string=None): namespace.cmdList.append([self.dest, values]) + def main(): - argParser = argparse.ArgumentParser(description="Controls the Chameleon through the command line") - argParser.add_argument("-v", "--verbose", dest="verbose", action="store_true", default=0, help="output verbose") - argParser.add_argument("-p", "--port", dest="port", metavar="COMPORT", help="specify device's comport") + argParser = argparse.ArgumentParser( + description="Controls the Chameleon through the command line") + argParser.add_argument("-v", "--verbose", dest="verbose", + action="store_true", default=0, help="output verbose") + argParser.add_argument("-p", "--port", dest="port", + metavar="COMPORT", help="specify device's comport") # Add the commands using custom action that populates a list in the order the arguments are given cmdArgGroup = argParser.add_argument_group(title="Chameleon commands", description="These arguments can appear multiple times and are executed in the order they are given on the command line. " "Some of these arguments can be used with '" + Chameleon.Device.SUGGEST_CHAR + "' as parameter to get a list of suggestions.") - cmdArgGroup.add_argument("-u", "--upload", dest="upload", action=CmdListAction, metavar="DUMPFILE", help="upload a card dump") - cmdArgGroup.add_argument("-d", "--download", dest="download", action=CmdListAction, metavar="DUMPFILE", help="download a card dump") - cmdArgGroup.add_argument("-l", "--log", dest="log", action=CmdListAction, metavar="LOGFILE", help="download the device log") - cmdArgGroup.add_argument("-i", "--info", dest="info", action=CmdListAction, nargs=0, help="retrieve the version information") - cmdArgGroup.add_argument("-s", "--setting", dest="setting", action=CmdListAction, nargs='?', type=int, choices=Chameleon.VALID_SETTINGS, help="retrieve or set the current setting") - cmdArgGroup.add_argument("-U", "--uid", dest="uid", action=CmdListAction, nargs='?', help="retrieve or set the current UID") - cmdArgGroup.add_argument("-gu", "--getuid", dest="getuid", action=CmdListAction, nargs='?', help="retrieve UID of device in range") - cmdArgGroup.add_argument("-I", "--identify", dest="identify", action=CmdListAction, nargs='?', help="identify device in range") - cmdArgGroup.add_argument("-D", "--dumpmfu", dest="dumpmfu", action=CmdListAction, nargs='?', help="dump information about card in range") - cmdArgGroup.add_argument("-c", "--config", dest="config", action=CmdListAction, metavar="CFGNAME", nargs='?', help="retrieve or set the current configuration") - cmdArgGroup.add_argument("-lm", "--logmode", dest="logmode", action=CmdListAction, metavar="LOGMODE", nargs='?', help="retrieve or set the current log mode") - cmdArgGroup.add_argument("-lb", "--lbutton", dest="lbutton", action=CmdListAction, metavar="ACTION", nargs='?', help="retrieve or set the current left button action") - cmdArgGroup.add_argument("-lbl", "--lbuttonlong", dest="lbutton_long", action=CmdListAction, metavar="ACTION", nargs='?', help="retrieve or set the current left button long press action") - cmdArgGroup.add_argument("-rb", "--rbutton", dest="rbutton", action=CmdListAction, metavar="ACTION", nargs='?', help="retrieve or set the current right button action") - cmdArgGroup.add_argument("-rbl", "--rbuttonlong", dest="rbutton_long", action=CmdListAction, metavar="ACTION", nargs='?', help="retrieve or set the current right button long press action") - cmdArgGroup.add_argument("-gl", "--gled", dest="gled", action=CmdListAction, metavar="FUNCTION", nargs='?', help="retrieve or set the current green led function") - cmdArgGroup.add_argument("-rl", "--rled", dest="rled", action=CmdListAction, metavar="FUNCTION", nargs='?', help="retrieve or set the current red led function") - cmdArgGroup.add_argument("-th", "--threshold", dest="threshold", action=CmdListAction, nargs='?', help="retrieve or set the threshold") - cmdArgGroup.add_argument("-ug", "--upgrade", dest="upgrade", action=CmdListAction, nargs=0, help="set the micro Controller to upgrade mode") + cmdArgGroup.add_argument("-u", "--upload", dest="upload", + action=CmdListAction, metavar="DUMPFILE", help="upload a card dump") + cmdArgGroup.add_argument("-d", "--download", dest="download", + action=CmdListAction, metavar="DUMPFILE", help="download a card dump") + cmdArgGroup.add_argument("-l", "--log", dest="log", + action=CmdListAction, metavar="LOGFILE", help="download the device log") + cmdArgGroup.add_argument("-i", "--info", dest="info", action=CmdListAction, + nargs=0, help="retrieve the version information") + cmdArgGroup.add_argument("-s", "--setting", dest="setting", action=CmdListAction, nargs='?', + type=int, choices=Chameleon.VALID_SETTINGS, help="retrieve or set the current setting") + cmdArgGroup.add_argument("-U", "--uid", dest="uid", action=CmdListAction, + nargs='?', help="retrieve or set the current UID") + cmdArgGroup.add_argument("-gu", "--getuid", dest="getuid", + action=CmdListAction, nargs='?', help="retrieve UID of device in range") + cmdArgGroup.add_argument("-I", "--identify", dest="identify", + action=CmdListAction, nargs='?', help="identify device in range") + cmdArgGroup.add_argument("-D", "--dumpmfu", dest="dumpmfu", + action=CmdListAction, nargs='?', help="dump information about card in range") + cmdArgGroup.add_argument("-c", "--config", dest="config", action=CmdListAction, + metavar="CFGNAME", nargs='?', help="retrieve or set the current configuration") + cmdArgGroup.add_argument("-lm", "--logmode", dest="logmode", action=CmdListAction, + metavar="LOGMODE", nargs='?', help="retrieve or set the current log mode") + cmdArgGroup.add_argument("-lb", "--lbutton", dest="lbutton", action=CmdListAction, + metavar="ACTION", nargs='?', help="retrieve or set the current left button action") + cmdArgGroup.add_argument("-lbl", "--lbuttonlong", dest="lbutton_long", action=CmdListAction, + metavar="ACTION", nargs='?', help="retrieve or set the current left button long press action") + cmdArgGroup.add_argument("-rb", "--rbutton", dest="rbutton", action=CmdListAction, + metavar="ACTION", nargs='?', help="retrieve or set the current right button action") + cmdArgGroup.add_argument("-rbl", "--rbuttonlong", dest="rbutton_long", action=CmdListAction, + metavar="ACTION", nargs='?', help="retrieve or set the current right button long press action") + cmdArgGroup.add_argument("-gl", "--gled", dest="gled", action=CmdListAction, + metavar="FUNCTION", nargs='?', help="retrieve or set the current green led function") + cmdArgGroup.add_argument("-rl", "--rled", dest="rled", action=CmdListAction, + metavar="FUNCTION", nargs='?', help="retrieve or set the current red led function") + cmdArgGroup.add_argument("-th", "--threshold", dest="threshold", + action=CmdListAction, nargs='?', help="retrieve or set the threshold") + cmdArgGroup.add_argument("-ug", "--upgrade", dest="upgrade", + action=CmdListAction, nargs=0, help="set the micro Controller to upgrade mode") args = argParser.parse_args() @@ -239,25 +285,25 @@ def main(): if (chameleon.connect(args.port)): # Generate a jumptable and execute all commands in the order they are given on the command line cmdFuncs = { - "setting" : cmdSetting, - "info" : cmdInfo, - "uid" : cmdUID, - "getuid" : cmdGetUID, - "identify" : cmdIdentify, - "dumpmfu" : cmdDumpMFU, - "config" : cmdConfig, - "upload" : cmdUpload, - "download" : cmdDownload, - "log" : cmdLog, - "logmode" : cmdLogMode, - "lbutton" : cmdLButton, - "lbutton_long" : cmdLButtonLong, - "rbutton_long" : cmdRButtonLong, - "rbutton" : cmdRButton, - "gled" : cmdGreenLED, - "rled" : cmdRedLED, - "threshold" : cmdThreshold, - "upgrade" : cmdUpgrade, + "setting": cmdSetting, + "info": cmdInfo, + "uid": cmdUID, + "getuid": cmdGetUID, + "identify": cmdIdentify, + "dumpmfu": cmdDumpMFU, + "config": cmdConfig, + "upload": cmdUpload, + "download": cmdDownload, + "log": cmdLog, + "logmode": cmdLogMode, + "lbutton": cmdLButton, + "lbutton_long": cmdLButtonLong, + "rbutton_long": cmdRButtonLong, + "rbutton": cmdRButton, + "gled": cmdGreenLED, + "rled": cmdRedLED, + "threshold": cmdThreshold, + "upgrade": cmdUpgrade, } if hasattr(args, "cmdList"): @@ -271,14 +317,14 @@ def main(): print("Unable to establish communication on {}".format(args.port)) sys.exit(2) else: - #List possible Chameleon ports + # List possible Chameleon ports print("Use -p COMPORT to specify the communication port (see help).") print("List of potential Chameleons connected to the system:") for port in Chameleon.Device.listDevices(): print(port) - sys.exit(0) + if __name__ == "__main__": main()