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:
Submodule pico-keys-sdk updated: fe396bc5b8...a816b6f747
@@ -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) {
|
else if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO || vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) {
|
||||||
if (vendorParam != 0) {
|
if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO) {
|
||||||
if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO) {
|
tmp[PHY_LED_GPIO] = (uint8_t)vendorParam;
|
||||||
tmp[PHY_LED_GPIO] = (uint8_t)vendorParam;
|
opts |= PHY_OPT_GPIO;
|
||||||
opts |= PHY_OPT_GPIO;
|
|
||||||
}
|
|
||||||
else if (vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) {
|
|
||||||
tmp[PHY_LED_BTNESS] = (uint8_t)vendorParam;
|
|
||||||
opts |= PHY_OPT_BTNESS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else if (vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) {
|
||||||
CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER);
|
tmp[PHY_LED_BTNESS] = (uint8_t)vendorParam;
|
||||||
|
opts |= PHY_OPT_BTNESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (vendorCommandId == CTAP_CONFIG_PHY_OPTS) {
|
else if (vendorCommandId == CTAP_CONFIG_PHY_OPTS) {
|
||||||
|
|||||||
@@ -249,6 +249,21 @@ int cbor_vendor_generic(uint8_t cmd, const uint8_t *data, size_t len) {
|
|||||||
goto err;
|
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 {
|
else {
|
||||||
CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION);
|
CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ typedef struct {
|
|||||||
#define CTAP_VENDOR_MSE 0x02
|
#define CTAP_VENDOR_MSE 0x02
|
||||||
#define CTAP_VENDOR_UNLOCK 0x03
|
#define CTAP_VENDOR_UNLOCK 0x03
|
||||||
#define CTAP_VENDOR_EA 0x04
|
#define CTAP_VENDOR_EA 0x04
|
||||||
|
#define CTAP_VENDOR_PHY_OPTS 0x05
|
||||||
|
|
||||||
#define CTAP_PERMISSION_MC 0x01 // MakeCredential
|
#define CTAP_PERMISSION_MC 0x01 // MakeCredential
|
||||||
#define CTAP_PERMISSION_GA 0x02 // GetAssertion
|
#define CTAP_PERMISSION_GA 0x02 // GetAssertion
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ class VendorConfig(Config):
|
|||||||
CONFIG_VENDOR_PHY = 0x1b
|
CONFIG_VENDOR_PHY = 0x1b
|
||||||
CONFIG_PHY_VIDPID = 0x6fcb19b0cbe3acfa
|
CONFIG_PHY_VIDPID = 0x6fcb19b0cbe3acfa
|
||||||
CONFIG_PHY_OPTS = 0x969f3b09eceb805f
|
CONFIG_PHY_OPTS = 0x969f3b09eceb805f
|
||||||
|
CONFIG_PHY_LED_GPIO = 0x7b392a394de9f948
|
||||||
|
CONFIG_PHY_LED_BTNESS = 0x76a85945985d02fd
|
||||||
|
|
||||||
class RESP(IntEnum):
|
class RESP(IntEnum):
|
||||||
KEY_AGREEMENT = 0x01
|
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):
|
class Ctap2Vendor(Ctap2):
|
||||||
def __init__(self, device: CtapDevice, strict_cbor: bool = True):
|
def __init__(self, device: CtapDevice, strict_cbor: bool = True):
|
||||||
super().__init__(device=device, strict_cbor=strict_cbor)
|
super().__init__(device=device, strict_cbor=strict_cbor)
|
||||||
@@ -203,6 +232,7 @@ class Vendor:
|
|||||||
VENDOR_MSE = 0x02
|
VENDOR_MSE = 0x02
|
||||||
VENDOR_UNLOCK = 0x03
|
VENDOR_UNLOCK = 0x03
|
||||||
VENDOR_EA = 0x04
|
VENDOR_EA = 0x04
|
||||||
|
VENDOR_PHY = 0x05
|
||||||
|
|
||||||
@unique
|
@unique
|
||||||
class PARAM(IntEnum):
|
class PARAM(IntEnum):
|
||||||
@@ -220,6 +250,10 @@ class Vendor:
|
|||||||
PARAM = 0x01
|
PARAM = 0x01
|
||||||
COSE_KEY = 0x02
|
COSE_KEY = 0x02
|
||||||
|
|
||||||
|
class PHY_OPTS(IntEnum):
|
||||||
|
PHY_OPT_WCID = 0x1
|
||||||
|
PHY_OPT_DIMM = 0x10
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
ctap: Ctap2Vendor,
|
ctap: Ctap2Vendor,
|
||||||
@@ -409,6 +443,38 @@ class Vendor:
|
|||||||
def vidpid(self, vid, pid):
|
def vidpid(self, vid, pid):
|
||||||
return self.vcfg.vidpid(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():
|
def parse_args():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
subparser = parser.add_subparsers(title="commands", dest="command")
|
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)
|
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 = 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_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()
|
args = parser.parse_args()
|
||||||
return args
|
return args
|
||||||
@@ -469,7 +543,18 @@ def phy(vdr, args):
|
|||||||
sp = val.split(':')
|
sp = val.split(':')
|
||||||
if (len(sp) != 2):
|
if (len(sp) != 2):
|
||||||
print('ERROR: VID/PID have wrong format. Use VID:PID format (e.g. 1234:5678)')
|
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):
|
if (ret):
|
||||||
print(f'Current value: {hexlify(ret)}')
|
print(f'Current value: {hexlify(ret)}')
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user