134 lines · 4.5 KB · Python
RawDownload
#!/usr/bin/python3# SPDX-License-Identifier: GPL-2.0import argparseimport binasciiimport osimport errnofrom dbc import * ERRORS = {    errno.EACCES: "Access is denied",    errno.E2BIG: "Excess data provided",    errno.EINVAL: "Bad parameters",    errno.EAGAIN: "Bad state",    errno.ENOENT: "Not implemented or message failure",    errno.EBUSY: "Busy",    errno.ENFILE: "Overflow",    errno.EPERM: "Signature invalid",} messages = {    "get-fmax-cap": PARAM_GET_FMAX_CAP,    "set-fmax-cap": PARAM_SET_FMAX_CAP,    "get-power-cap": PARAM_GET_PWR_CAP,    "set-power-cap": PARAM_SET_PWR_CAP,    "get-graphics-mode": PARAM_GET_GFX_MODE,    "set-graphics-mode": PARAM_SET_GFX_MODE,    "get-current-temp": PARAM_GET_CURR_TEMP,    "get-fmax-max": PARAM_GET_FMAX_MAX,    "get-fmax-min": PARAM_GET_FMAX_MIN,    "get-soc-power-max": PARAM_GET_SOC_PWR_MAX,    "get-soc-power-min": PARAM_GET_SOC_PWR_MIN,    "get-soc-power-cur": PARAM_GET_SOC_PWR_CUR,}  def _pretty_buffer(ba):    return str(binascii.hexlify(ba, " "))  def parse_args():    parser = argparse.ArgumentParser(        description="Dynamic Boost control command line interface"    )    parser.add_argument(        "command",        choices=["get-nonce", "get-param", "set-param", "set-uid"],        help="Command to send",    )    parser.add_argument("--device", default="/dev/dbc", help="Device to operate")    parser.add_argument("--signature", help="File containing signature for command")    parser.add_argument("--message", choices=messages.keys(), help="Message index")    parser.add_argument("--data", help="Argument to pass to message")    parser.add_argument("--uid", help="File containing UID to pass")    return parser.parse_args()  def pretty_error(code):    if code in ERRORS:        print(ERRORS[code])    else:        print("failed with return code %d" % code)  if __name__ == "__main__":    args = parse_args()    data = 0    sig = None    uid = None    if not os.path.exists(args.device):        raise IOError("Missing device {device}".format(device=args.device))    if args.signature:        if not os.path.exists(args.signature):            raise ValueError("Invalid signature file %s" % args.signature)        with open(args.signature, "rb") as f:            sig = f.read()        if len(sig) != DBC_SIG_SIZE:            raise ValueError(                "Invalid signature length %d (expected %d)" % (len(sig), DBC_SIG_SIZE)            )    if args.uid:        if not os.path.exists(args.uid):            raise ValueError("Invalid uid file %s" % args.uid)        with open(args.uid, "rb") as f:            uid = f.read()        if len(uid) != DBC_UID_SIZE:            raise ValueError(                "Invalid UID length %d (expected %d)" % (len(uid), DBC_UID_SIZE)            )    if args.data:        try:            data = int(args.data, 10)        except ValueError:            data = int(args.data, 16)     with open(args.device) as d:        if args.command == "get-nonce":            try:                nonce = get_nonce(d, sig)                print("Nonce: %s" % _pretty_buffer(bytes(nonce)))            except OSError as e:                pretty_error(e.errno)        elif args.command == "set-uid":            try:                result = set_uid(d, uid, sig)                if result:                    print("Set UID")            except OSError as e:                pretty_error(e.errno)        elif args.command == "get-param":            if not args.message or args.message.startswith("set"):                raise ValueError("Invalid message %s" % args.message)            try:                param, signature = process_param(d, messages[args.message], sig)                print(                    "Parameter: {par}, response signature {sig}".format(                        par=param,                        sig=_pretty_buffer(bytes(signature)),                    )                )            except OSError as e:                pretty_error(e.errno)        elif args.command == "set-param":            if not args.message or args.message.startswith("get"):                raise ValueError("Invalid message %s" % args.message)            try:                param, signature = process_param(d, messages[args.message], sig, data)                print(                    "Parameter: {par}, response signature {sig}".format(                        par=param,                        sig=_pretty_buffer(bytes(signature)),                    )                )            except OSError as e:                pretty_error(e.errno)