From 646fdc7d170d76ccb6885434814191b2012683b8 Mon Sep 17 00:00:00 2001 From: zvecr Date: Thu, 31 Mar 2022 01:18:26 +0100 Subject: [PATCH] Rework code gen for return of dynamic variables --- data/xap/xap_0.1.0.hjson | 16 ++++++++++++ lib/python/qmk/cli/xap/xap.py | 11 +++++--- .../qmk/xap/gen_firmware/inline_generator.py | 26 ++++++++++++++----- quantum/xap/xap.c | 23 +++++++++------- quantum/xap/xap.h | 1 + 5 files changed, 58 insertions(+), 19 deletions(-) diff --git a/data/xap/xap_0.1.0.hjson b/data/xap/xap_0.1.0.hjson index 38d36dddfae..82dffb192b7 100755 --- a/data/xap/xap_0.1.0.hjson +++ b/data/xap/xap_0.1.0.hjson @@ -127,6 +127,22 @@ return_purpose: capabilities return_constant: XAP_ROUTE_CAPABILITIES } + 0x03: { + type: command + name: Secure Status + define: SECURE_STATUS + description: + ''' + Query secure route status + + * 0 means secure routes are disabled + * 1 means unlock sequence initiated but incomplete + * 2 means secure routes are allowed + * any other value should be interpreted as disabled + ''' + return_type: u8 + return_value: secure_status + } } }, diff --git a/lib/python/qmk/cli/xap/xap.py b/lib/python/qmk/cli/xap/xap.py index 3eb107d7843..3626512829c 100644 --- a/lib/python/qmk/cli/xap/xap.py +++ b/lib/python/qmk/cli/xap/xap.py @@ -82,7 +82,7 @@ def _xap_transaction(device, sub, route, ret_len, *args): return array_alpha[4:] -def _query_device_version(device): +def _query_device(device): ver_data = _xap_transaction(device, 0x00, 0x00, 4) if not ver_data: return {'xap': 'UNKNOWN'} @@ -91,7 +91,10 @@ def _query_device_version(device): a = (ver_data[3] << 24) + (ver_data[2] << 16) + (ver_data[1] << 8) + (ver_data[0]) ver = f'{a>>24}.{a>>16 & 0xFF}.{a & 0xFFFF}' - return {'xap': ver} + secure = int.from_bytes(_xap_transaction(device, 0x00, 0x03, 1), 'little') + secure = 'unlocked' if secure == 2 else 'LOCKED' + + return {'xap': ver, 'secure': secure} def _query_device_info_len(device): @@ -129,8 +132,8 @@ def _list_devices(): for dev in devices: device = hid.Device(path=dev['path']) - data = _query_device_version(device) - cli.log.info(" %04x:%04x %s %s [API:%s]", dev['vendor_id'], dev['product_id'], dev['manufacturer_string'], dev['product_string'], data['xap']) + data = _query_device(device) + cli.log.info(" %04x:%04x %s %s [API:%s] %s", dev['vendor_id'], dev['product_id'], dev['manufacturer_string'], dev['product_string'], data['xap'], data['secure']) if cli.config.general.verbose: # TODO: better formatting like "lsusb -v"? diff --git a/lib/python/qmk/xap/gen_firmware/inline_generator.py b/lib/python/qmk/xap/gen_firmware/inline_generator.py index 9cee29b455b..93bb6c7afd7 100755 --- a/lib/python/qmk/xap/gen_firmware/inline_generator.py +++ b/lib/python/qmk/xap/gen_firmware/inline_generator.py @@ -43,9 +43,12 @@ def _get_route_type(container): return 'XAP_ROUTE' elif 'return_execute' in container: return 'XAP_EXECUTE' + elif 'return_value' in container: + if container['return_type'] == 'u8': + return 'XAP_VALUE' elif 'return_constant' in container: if container['return_type'] == 'u32': - return 'XAP_VALUE' + return 'XAP_CONST_MEM' elif container['return_type'] == 'struct': return 'XAP_CONST_MEM' elif container['return_type'] == 'string': @@ -89,10 +92,18 @@ bool xap_respond_{execute}(xap_token_t token, const uint8_t *data, size_t data_l }}''' ) + # elif 'return_value' in container: + # value = container['return_value'] + # return_type = container['return_type'] + # lines.append('') + # lines.append(f'{_get_c_type(return_type)} {value} = 0;') + elif 'return_constant' in container: if container['return_type'] == 'u32': - pass + constant = container['return_constant'] + lines.append('') + lines.append(f'static const uint32_t {route_name}_data PROGMEM = {constant};') elif container['return_type'] == 'struct': lines.append('') @@ -146,9 +157,10 @@ def _append_routing_table_entry_execute(lines, container, container_id, route_st lines.append(f' .handler = xap_respond_{value},') -def _append_routing_table_entry_u32value(lines, container, container_id, route_stack): - value = container['return_constant'] - lines.append(f' .u32value = {value},') +def _append_routing_table_entry_value(lines, container, container_id, route_stack): + value = container['return_value'] + lines.append(f' .const_data = &{value},') + lines.append(f' .const_data_len = sizeof({value}),') def _append_routing_table_entry_u32getter(lines, container, container_id, route_stack): @@ -183,9 +195,11 @@ def _append_routing_table_entry(lines, container, container_id, route_stack): _append_routing_table_entry_route(lines, container, container_id, route_stack) elif 'return_execute' in container: _append_routing_table_entry_execute(lines, container, container_id, route_stack) + elif 'return_value' in container: + _append_routing_table_entry_value(lines, container, container_id, route_stack) elif 'return_constant' in container: if container['return_type'] == 'u32': - _append_routing_table_entry_u32value(lines, container, container_id, route_stack) + _append_routing_table_entry_const_data(lines, container, container_id, route_stack) elif container['return_type'] == 'struct': _append_routing_table_entry_const_data(lines, container, container_id, route_stack) elif container['return_type'] == 'string': diff --git a/quantum/xap/xap.c b/quantum/xap/xap.c index fce5014c623..333e53e8458 100644 --- a/quantum/xap/xap.c +++ b/quantum/xap/xap.c @@ -27,6 +27,8 @@ bool get_info_json_chunk(uint16_t offset, uint8_t *data, uint8_t data_len) { return true; } +uint8_t secure_status = 2; + #define QSTR2(z) #z #define QSTR(z) QSTR2(z) @@ -63,15 +65,12 @@ struct __attribute__((packed)) xap_route_t { // XAP_EXECUTE bool (*handler)(xap_token_t token, const uint8_t *data, size_t data_len); - // XAP_VALUE - uint32_t u32value; - // XAP_GETTER uint32_t (*u32getter)(void); - // XAP_CONST_MEM + // XAP_VALUE / XAP_CONST_MEM struct { - const void * const_data; + const void *const_data; const uint8_t const_data_len; }; }; @@ -86,6 +85,12 @@ void xap_execute_route(xap_token_t token, const xap_route_t *routes, size_t max_ if (id < max_routes) { xap_route_t route; memcpy_P(&route, &routes[id], sizeof(xap_route_t)); + + if (route.flags.is_secure && secure_status != 2) { + xap_respond_failure(token, XAP_RESPONSE_FLAG_SECURE_FAILURE); + return; + } + switch (route.flags.type) { case XAP_ROUTE: if (route.child_routes != NULL && route.child_routes_len > 0 && data_len > 0) { @@ -101,14 +106,14 @@ void xap_execute_route(xap_token_t token, const xap_route_t *routes, size_t max_ } break; - case XAP_VALUE: - xap_respond_u32(token, route.u32value); - return; - case XAP_GETTER: xap_respond_u32(token, (route.u32getter)()); return; + case XAP_VALUE: + xap_respond_data(token, route.const_data, route.const_data_len); + return; + case XAP_CONST_MEM: xap_respond_data_P(token, route.const_data, route.const_data_len); return; diff --git a/quantum/xap/xap.h b/quantum/xap/xap.h index 67e41d31ea1..828531a92bb 100644 --- a/quantum/xap/xap.h +++ b/quantum/xap/xap.h @@ -33,6 +33,7 @@ typedef uint16_t xap_token_t; #define XAP_RESPONSE_FLAG_FAILED 0 #define XAP_RESPONSE_FLAG_SUCCESS (1 << 0) +#define XAP_RESPONSE_FLAG_SECURE_FAILURE (1 << 1) void xap_respond_failure(xap_token_t token, xap_response_flags_t response_flags); bool xap_respond_u32(xap_token_t token, uint32_t value);