| 1 | |
| 2 | |
| 3 | import argparse
|
| 4 | import binascii
|
| 5 | import os
|
| 6 | import errno
|
| 7 | from dbc import *
|
| 8 |
|
| 9 | ERRORS = {
|
| 10 | errno.EACCES: "Access is denied",
|
| 11 | errno.E2BIG: "Excess data provided",
|
| 12 | errno.EINVAL: "Bad parameters",
|
| 13 | errno.EAGAIN: "Bad state",
|
| 14 | errno.ENOENT: "Not implemented or message failure",
|
| 15 | errno.EBUSY: "Busy",
|
| 16 | errno.ENFILE: "Overflow",
|
| 17 | errno.EPERM: "Signature invalid",
|
| 18 | }
|
| 19 |
|
| 20 | messages = {
|
| 21 | "get-fmax-cap": PARAM_GET_FMAX_CAP,
|
| 22 | "set-fmax-cap": PARAM_SET_FMAX_CAP,
|
| 23 | "get-power-cap": PARAM_GET_PWR_CAP,
|
| 24 | "set-power-cap": PARAM_SET_PWR_CAP,
|
| 25 | "get-graphics-mode": PARAM_GET_GFX_MODE,
|
| 26 | "set-graphics-mode": PARAM_SET_GFX_MODE,
|
| 27 | "get-current-temp": PARAM_GET_CURR_TEMP,
|
| 28 | "get-fmax-max": PARAM_GET_FMAX_MAX,
|
| 29 | "get-fmax-min": PARAM_GET_FMAX_MIN,
|
| 30 | "get-soc-power-max": PARAM_GET_SOC_PWR_MAX,
|
| 31 | "get-soc-power-min": PARAM_GET_SOC_PWR_MIN,
|
| 32 | "get-soc-power-cur": PARAM_GET_SOC_PWR_CUR,
|
| 33 | }
|
| 34 |
|
| 35 |
|
| 36 | def _pretty_buffer(ba):
|
| 37 | return str(binascii.hexlify(ba, " "))
|
| 38 |
|
| 39 |
|
| 40 | def parse_args():
|
| 41 | parser = argparse.ArgumentParser(
|
| 42 | description="Dynamic Boost control command line interface"
|
| 43 | )
|
| 44 | parser.add_argument(
|
| 45 | "command",
|
| 46 | choices=["get-nonce", "get-param", "set-param", "set-uid"],
|
| 47 | help="Command to send",
|
| 48 | )
|
| 49 | parser.add_argument("--device", default="/dev/dbc", help="Device to operate")
|
| 50 | parser.add_argument("--signature", help="File containing signature for command")
|
| 51 | parser.add_argument("--message", choices=messages.keys(), help="Message index")
|
| 52 | parser.add_argument("--data", help="Argument to pass to message")
|
| 53 | parser.add_argument("--uid", help="File containing UID to pass")
|
| 54 | return parser.parse_args()
|
| 55 |
|
| 56 |
|
| 57 | def pretty_error(code):
|
| 58 | if code in ERRORS:
|
| 59 | print(ERRORS[code])
|
| 60 | else:
|
| 61 | print("failed with return code %d" % code)
|
| 62 |
|
| 63 |
|
| 64 | if __name__ == "__main__":
|
| 65 | args = parse_args()
|
| 66 | data = 0
|
| 67 | sig = None
|
| 68 | uid = None
|
| 69 | if not os.path.exists(args.device):
|
| 70 | raise IOError("Missing device {device}".format(device=args.device))
|
| 71 | if args.signature:
|
| 72 | if not os.path.exists(args.signature):
|
| 73 | raise ValueError("Invalid signature file %s" % args.signature)
|
| 74 | with open(args.signature, "rb") as f:
|
| 75 | sig = f.read()
|
| 76 | if len(sig) != DBC_SIG_SIZE:
|
| 77 | raise ValueError(
|
| 78 | "Invalid signature length %d (expected %d)" % (len(sig), DBC_SIG_SIZE)
|
| 79 | )
|
| 80 | if args.uid:
|
| 81 | if not os.path.exists(args.uid):
|
| 82 | raise ValueError("Invalid uid file %s" % args.uid)
|
| 83 | with open(args.uid, "rb") as f:
|
| 84 | uid = f.read()
|
| 85 | if len(uid) != DBC_UID_SIZE:
|
| 86 | raise ValueError(
|
| 87 | "Invalid UID length %d (expected %d)" % (len(uid), DBC_UID_SIZE)
|
| 88 | )
|
| 89 | if args.data:
|
| 90 | try:
|
| 91 | data = int(args.data, 10)
|
| 92 | except ValueError:
|
| 93 | data = int(args.data, 16)
|
| 94 |
|
| 95 | with open(args.device) as d:
|
| 96 | if args.command == "get-nonce":
|
| 97 | try:
|
| 98 | nonce = get_nonce(d, sig)
|
| 99 | print("Nonce: %s" % _pretty_buffer(bytes(nonce)))
|
| 100 | except OSError as e:
|
| 101 | pretty_error(e.errno)
|
| 102 | elif args.command == "set-uid":
|
| 103 | try:
|
| 104 | result = set_uid(d, uid, sig)
|
| 105 | if result:
|
| 106 | print("Set UID")
|
| 107 | except OSError as e:
|
| 108 | pretty_error(e.errno)
|
| 109 | elif args.command == "get-param":
|
| 110 | if not args.message or args.message.startswith("set"):
|
| 111 | raise ValueError("Invalid message %s" % args.message)
|
| 112 | try:
|
| 113 | param, signature = process_param(d, messages[args.message], sig)
|
| 114 | print(
|
| 115 | "Parameter: {par}, response signature {sig}".format(
|
| 116 | par=param,
|
| 117 | sig=_pretty_buffer(bytes(signature)),
|
| 118 | )
|
| 119 | )
|
| 120 | except OSError as e:
|
| 121 | pretty_error(e.errno)
|
| 122 | elif args.command == "set-param":
|
| 123 | if not args.message or args.message.startswith("get"):
|
| 124 | raise ValueError("Invalid message %s" % args.message)
|
| 125 | try:
|
| 126 | param, signature = process_param(d, messages[args.message], sig, data)
|
| 127 | print(
|
| 128 | "Parameter: {par}, response signature {sig}".format(
|
| 129 | par=param,
|
| 130 | sig=_pretty_buffer(bytes(signature)),
|
| 131 | )
|
| 132 | )
|
| 133 | except OSError as e:
|
| 134 | pretty_error(e.errno)
|