135 lines · python
1#!/usr/bin/python32# SPDX-License-Identifier: GPL-2.03import argparse4import binascii5import os6import errno7from dbc import *8 9ERRORS = {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 20messages = {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 36def _pretty_buffer(ba):37 return str(binascii.hexlify(ba, " "))38 39 40def 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 57def pretty_error(code):58 if code in ERRORS:59 print(ERRORS[code])60 else:61 print("failed with return code %d" % code)62 63 64if __name__ == "__main__":65 args = parse_args()66 data = 067 sig = None68 uid = None69 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)135