diff --git a/data/xap/xap_0.1.0.hjson b/data/xap/xap_0.1.0.hjson index 42b0476f7a..132fc421bc 100755 --- a/data/xap/xap_0.1.0.hjson +++ b/data/xap/xap_0.1.0.hjson @@ -252,6 +252,24 @@ return_type: u8[32] return_execute: get_info_json_chunk } + 0x07: { + type: command + name: Jump to bootloader + define: BOOTLOADER_JUMP + secure: true + enable_if_preprocessor: defined(BOOTLOADER_JUMP_SUPPORTED) + description: + ''' + Jump to bootloader + + May not be present – if QMK capabilities query returns “true”, then jump to bootloader is supported + + * 0 means secure routes are disabled, and should be considered as a failure + * 1 means successful, board will jump to bootloader + ''' + return_type: u8 + return_execute: request_bootloader_jump + } } }, diff --git a/lib/python/qmk/cli/xap/xap.py b/lib/python/qmk/cli/xap/xap.py index 3626512829..1ba144a644 100644 --- a/lib/python/qmk/cli/xap/xap.py +++ b/lib/python/qmk/cli/xap/xap.py @@ -139,6 +139,7 @@ def _list_devices(): # TODO: better formatting like "lsusb -v"? data = _query_device_info(device) print_dotted_output(data) + # _xap_transaction(device, 0x01, 0x07, 1) @cli.argument('-d', '--device', help='device to select - uses format :.') diff --git a/lib/python/qmk/xap/gen_firmware/inline_generator.py b/lib/python/qmk/xap/gen_firmware/inline_generator.py index 93bb6c7afd..2ae2221c7b 100755 --- a/lib/python/qmk/xap/gen_firmware/inline_generator.py +++ b/lib/python/qmk/xap/gen_firmware/inline_generator.py @@ -26,16 +26,16 @@ def _get_c_type(xap_type): def _get_c_size(xap_type): if xap_type == 'u8': - return 1 + return 'sizeof(uint8_t)' elif xap_type == 'u16': - return 2 + return 'sizeof(uint16_t)' elif xap_type == 'u32': - return 4 + return 'sizeof(uint32_t)' elif xap_type == 'u64': return 8 elif xap_type == 'u8[32]': return 32 - return -1 + return 0 def _get_route_type(container): @@ -69,17 +69,30 @@ def _append_routing_table_declaration(lines, container, container_id, route_stac elif 'return_execute' in container: execute = container['return_execute'] - request_type = container['request_type'] + request_type = container.get('request_type', None) return_type = container['return_type'] lines.append( f''' bool xap_respond_{execute}(xap_token_t token, const uint8_t *data, size_t data_len) {{ - if (data_len != sizeof({_get_c_type(request_type)})) {{ + if (data_len != {_get_c_size(request_type)}) {{ xap_respond_failure(token, 0); return false; }} uint8_t ret[{_get_c_size(return_type)}] = {{0}}; +''' + ) + if not request_type: + lines.append(f''' + bool {execute}(uint8_t *ret, uint8_t ret_len); + if(!{execute}(ret, sizeof(ret))) {{ + xap_respond_failure(token, 0); + return false; + }} +''') + else: + lines.append( + f''' {_get_c_type(request_type)} *argp = ({_get_c_type(request_type)} *)&data[0]; bool {execute}({_get_c_type(request_type)} arg, uint8_t *ret, uint8_t ret_len); @@ -87,10 +100,11 @@ bool xap_respond_{execute}(xap_token_t token, const uint8_t *data, size_t data_l xap_respond_failure(token, 0); return false; }} - +''' + ) + lines.append(''' return xap_respond_data(token, ret, sizeof(ret)); -}}''' - ) +}''') # elif 'return_value' in container: # value = container['return_value'] diff --git a/quantum/xap/xap.c b/quantum/xap/xap.c index 00901b0423..1eb3786cc1 100644 --- a/quantum/xap/xap.c +++ b/quantum/xap/xap.c @@ -29,6 +29,21 @@ bool get_info_json_chunk(uint16_t offset, uint8_t *data, uint8_t data_len) { uint8_t secure_status = 2; +// TODO: how to set this if "custom" is just an empty stub +#ifndef BOOTLOADER_JUMP_SUPPORTED +# define BOOTLOADER_JUMP_SUPPORTED +#endif + +#ifdef BOOTLOADER_JUMP_SUPPORTED +bool request_bootloader_jump(uint8_t *data, uint8_t data_len) { + data[0] = secure_status == 2; + + // TODO: post to deferred queue so this request can return? + reset_keyboard(); + return true; +} +#endif + #define QSTR2(z) #z #define QSTR(z) QSTR2(z)