Added support to configure LED GPIO, LED brightness and LED dimming.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2024-09-27 20:56:33 +02:00
parent 720c2e45f3
commit 2d09a5c8e5
5 changed files with 109 additions and 13 deletions

View File

@@ -244,18 +244,13 @@ int cbor_config(const uint8_t *data, size_t len) {
}
}
else if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO || vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) {
if (vendorParam != 0) {
if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO) {
tmp[PHY_LED_GPIO] = (uint8_t)vendorParam;
opts |= PHY_OPT_GPIO;
}
else if (vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) {
tmp[PHY_LED_BTNESS] = (uint8_t)vendorParam;
opts |= PHY_OPT_BTNESS;
}
if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO) {
tmp[PHY_LED_GPIO] = (uint8_t)vendorParam;
opts |= PHY_OPT_GPIO;
}
else {
CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER);
else if (vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) {
tmp[PHY_LED_BTNESS] = (uint8_t)vendorParam;
opts |= PHY_OPT_BTNESS;
}
}
else if (vendorCommandId == CTAP_CONFIG_PHY_OPTS) {

View File

@@ -249,6 +249,21 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) {
goto err;
}
}
else if (cmd == CTAP_VENDOR_PHY_OPTS) {
if (vendorCmd == 0x01) {
uint16_t opts = 0;
if (file_has_data(ef_phy)) {
uint8_t *data = file_get_data(ef_phy);
opts = (data[PHY_OPTS] << 8) | data[PHY_OPTS+1];
}
CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, 1));
CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x01));
CBOR_CHECK(cbor_encode_uint(&mapEncoder, opts));
}
else {
CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION);
}
}
else {
CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION);
}

View File

@@ -125,6 +125,7 @@ typedef struct {
#define CTAP_VENDOR_MSE 0x02
#define CTAP_VENDOR_UNLOCK 0x03
#define CTAP_VENDOR_EA 0x04
#define CTAP_VENDOR_PHY_OPTS 0x05
#define CTAP_PERMISSION_MC 0x01 // MakeCredential
#define CTAP_PERMISSION_GA 0x02 // GetAssertion

View File

@@ -86,6 +86,8 @@ class VendorConfig(Config):
CONFIG_VENDOR_PHY = 0x1b
CONFIG_PHY_VIDPID = 0x6fcb19b0cbe3acfa
CONFIG_PHY_OPTS = 0x969f3b09eceb805f
CONFIG_PHY_LED_GPIO = 0x7b392a394de9f948
CONFIG_PHY_LED_BTNESS = 0x76a85945985d02fd
class RESP(IntEnum):
KEY_AGREEMENT = 0x01
@@ -119,6 +121,33 @@ class VendorConfig(Config):
},
)
def led_gpio(self, gpio):
self._call(
VendorConfig.CMD.CONFIG_VENDOR_PHY,
{
VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_PHY_LED_GPIO,
VendorConfig.PARAM.VENDOR_PARAM: gpio
},
)
def led_brightness(self, brightness):
self._call(
VendorConfig.CMD.CONFIG_VENDOR_PHY,
{
VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_PHY_LED_BTNESS,
VendorConfig.PARAM.VENDOR_PARAM: brightness
},
)
def phy_opts(self, opts):
self._call(
VendorConfig.CMD.CONFIG_VENDOR_PHY,
{
VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_PHY_OPTS,
VendorConfig.PARAM.VENDOR_PARAM: opts
},
)
class Ctap2Vendor(Ctap2):
def __init__(self, device: CtapDevice, strict_cbor: bool = True):
super().__init__(device=device, strict_cbor=strict_cbor)
@@ -203,6 +232,7 @@ class Vendor:
VENDOR_MSE = 0x02
VENDOR_UNLOCK = 0x03
VENDOR_EA = 0x04
VENDOR_PHY = 0x05
@unique
class PARAM(IntEnum):
@@ -220,6 +250,10 @@ class Vendor:
PARAM = 0x01
COSE_KEY = 0x02
class PHY_OPTS(IntEnum):
PHY_OPT_WCID = 0x1
PHY_OPT_DIMM = 0x10
def __init__(
self,
ctap: Ctap2Vendor,
@@ -409,6 +443,38 @@ class Vendor:
def vidpid(self, vid, pid):
return self.vcfg.vidpid(vid, pid)
def led_gpio(self, gpio):
return self.vcfg.led_gpio(gpio)
def led_brightness(self, brightness):
if (brightness > 15):
print('ERROR: Brightness must be between 0 and 15')
return
return self.vcfg.led_brightness(brightness)
def led_dimmable(self, onoff):
opts = self.phy_opts()
if (onoff):
opts |= Vendor.PHY_OPTS.PHY_OPT_DIMM
else:
opts &= ~Vendor.PHY_OPTS.PHY_OPT_DIMM
print(f'opts: {opts}')
return self.vcfg.phy_opts(opts)
def wcid(self, onoff):
opts = self.phy_opts()
if (onoff):
opts |= Vendor.PHY_OPTS.PHY_OPT_WCID
else:
opts &= ~Vendor.PHY_OPTS.PHY_OPT_WCID
return self.vcfg.phy_opts(opts)
def phy_opts(self):
return self._call(
Vendor.CMD.VENDOR_PHY,
Vendor.SUBCMD.ENABLE,
)[Vendor.RESP.PARAM]
def parse_args():
parser = argparse.ArgumentParser()
subparser = parser.add_subparsers(title="commands", dest="command")
@@ -428,6 +494,14 @@ def parse_args():
subparser_phy = parser_phy.add_subparsers(title='commands', dest='subcommand', required=True)
parser_phy_vp = subparser_phy.add_parser('vidpid', help='Sets VID/PID. Use VID:PID format (e.g. 1234:5678)')
parser_phy_vp.add_argument('value', help='Value of the PHY option.', metavar='VAL', nargs='?')
parser_phy_ledn = subparser_phy.add_parser('led_gpio', help='Sets LED GPIO number.')
parser_phy_ledn.add_argument('value', help='Value of the PHY option.', metavar='VAL', nargs='?')
parser_phy_optwcid = subparser_phy.add_parser('wcid', help='Enable/Disable Web CCID interface.')
parser_phy_optwcid.add_argument('value', choices=['enable', 'disable'], help='Enable/Disable Web CCID interface.', nargs='?')
parser_phy_ledbtness = subparser_phy.add_parser('led_brightness', help='Sets LED max. brightness.')
parser_phy_ledbtness.add_argument('value', help='Value of the max. brightness.', metavar='VAL', nargs='?')
parser_phy_optdimm = subparser_phy.add_parser('led_dimmable', help='Enable/Disable LED dimming.')
parser_phy_optdimm.add_argument('value', choices=['enable', 'disable'], help='Enable/Disable LED dimming.', nargs='?')
args = parser.parse_args()
return args
@@ -469,7 +543,18 @@ def phy(vdr, args):
sp = val.split(':')
if (len(sp) != 2):
print('ERROR: VID/PID have wrong format. Use VID:PID format (e.g. 1234:5678)')
ret = vdr.vidpid(int(sp[0],16), int(sp[1],16))
ret = vdr.vidpid(int(sp[0],16), int(sp[1],16))
elif (args.subcommand == 'led_gpio'):
val = int(val)
ret = vdr.led_gpio(val)
elif (args.subcommand == 'led_brightness'):
val = int(val)
ret = vdr.led_brightness(val)
elif (args.subcommand == 'led_dimmable'):
ret = vdr.led_dimmable(val == 'enable')
elif (args.subcommand == 'wcid'):
ret = vdr.wcid(val == 'enable')
if (ret):
print(f'Current value: {hexlify(ret)}')
else: