{ version: 0.1.0 uses: { keycodes: 0.0.1 } documentation: { order: [ broadcast_messages !broadcast_messages.md.j2 ] reserved_tokens: ''' Two token values are reserved: `0x0000` and `0xFFFF`: * `0x0000`: A message sent by a host application may use this token if no response is to be sent -- a "fire and forget" message. * `0xFFFF`: Signifies a "broadcast" message sent by the firmware without prompting from the host application. Broadcast messages are defined later in this document. Any request will generate at least one corresponding response, with the exception of messages using reserved tokens. Maximum total message length is 128 bytes due to RAM constraints. ''' broadcast_messages: ''' ## Broadcast messages Broadcast messages may be sent by the firmware to the host, without a corresponding inbound request. Each broadcast message uses the token `0xFFFF`, and does not expect a response from the host. Tokens are followed by an _ID_ signifying the type of broadcast, with corresponding _payload_. ''' } response_flags: { bits: { 1: { name: Secure Failure define: SECURE_FAILURE description: ''' When this bit is set, the requested _route_ was marked _secure_ but an _unlock sequence_ has not completed. ''' } 6: { name: Unlocking define: UNLOCK_IN_PROGRESS description: ''' When this bit is set, an _unlock sequence_ is in progress. ''' } 7: { name: Unlocked define: UNLOCKED description: ''' When this bit is set, an _unlock sequence_ has completed, and _secure routes_ may be invoked. ''' } } } type_docs: { u64: ''' An unsigned 64-bit integral, commonly seen as `uint64_t` from _stdint.h_. ''' "struct{}": ''' A structure of data, packing different objects together. Data is "compacted" -- there are no padding bytes between fields. Equivalent to a packed C-style `struct`. The order in which they're defined matches the order of the data in the response packet. ''' } term_definitions: { Capability: ''' A way to determine if certain functionality is enabled in the firmware. Any _subsystem_ that provides build-time restriction of functionality must provide a _route_ for a _capabilities query_. ''' "Secure Route": ''' A _route_ which has potentially destructive consequences, necessitating prior approval by the user before executing. ''' "Unlock sequence": ''' A physical sequence initiated by the user to enable execution of _secure routes_. ''' } type_definitions: { broadcast_header: { name: Broadcast Header description: Packet format for broadcast messages. type: struct struct_length: 4 struct_members: [ { type: token name: token }, { type: u8 name: type }, { type: u8 name: length } ] } } broadcast_messages: { define_prefix: XAP_BROADCAST messages: { 0x00: { name: Log message define: LOG_MESSAGE description: ''' Replicates and replaces the same functionality as if using the standard QMK `CONSOLE_ENABLE = yes` in `rules.mk`. Normal prints within the firmware will manifest as log messages broadcast to the host. `hid_listen` will not be functional with XAP enabled. Log message payloads include a `u8` signifying the length of the text, followed by the `u8[Length]` containing the text itself. **Example Log Broadcast** -- log message "Hello QMK!" | Byte | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | **Purpose** | Token | Token | Broadcast Type | Length | Payload | Payload | Payload | Payload | Payload | Payload | Payload | Payload | Payload | Payload | | **Value** | `0xFF` | `0xFF` | `0x00` | `0x0A`(10) | `0x48`(H) | `0x65`(e) | `0x6C`(l) | `0x6C`(l) | `0x6F`(o) | `0x20`( ) | `0x51`(Q) | `0x4D`(M) | `0x4B`(K) | `0x21`(!) | ''' } 0x01: { name: Secure Status define: SECURE_STATUS description: ''' Secure status has changed. Payloads include a `u8` matching a 'Secure Status' request. **Example Secure Status Broadcast** -- secure "Unlocking" | Byte | 0 | 1 | 2 | 3 | | --- | --- | --- | --- | --- | | **Purpose** | Token | Token | Broadcast Type | Secure Status | | **Value** | `0xFF` | `0xFF` | `0x01` | `0x01` | ''' return_type: u8 } } } routes: { 0x00: { routes: { 0x01: { type: command name: Capabilities Query define: CAPABILITIES_QUERY description: ''' XAP subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem. ''' return_type: u32 return_purpose: capabilities return_constant: XAP_ROUTE_XAP_CAPABILITIES } 0x02: { type: command name: Enabled subsystem query define: SUBSYSTEM_QUERY description: ''' XAP protocol subsystem query. Each bit should be considered as a "usable" subsystem. For example, checking `(value & (1 << XAP_ROUTE_QMK) != 0)` means the QMK subsystem is enabled and available for querying. ''' return_type: u32 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 ''' permissions: ignore return_type: u8 return_execute: secure_status } 0x04: { type: command name: Secure Unlock define: SECURE_UNLOCK description: Initiate secure route unlock sequence return_execute: secure_unlock } 0x05: { type: command name: Secure Lock define: SECURE_LOCK permissions: ignore description: Disable secure routes return_execute: secure_lock } } }, 0x01: { type: router name: QMK define: QMK description: ''' This subsystem is always present, and provides the ability to address QMK-specific functionality. ''' routes: { 0x00: { type: command name: Version Query define: VERSION_QUERY description: ''' QMK protocol version query. * Returns the BCD-encoded version in the format of XX.YY.ZZZZ => `0xXXYYZZZZ` * e.g. 3.2.115 will match `0x03020115`, or bytes {0x15,0x01,0x02,0x03}. * Response: * `u32` value. ''' return_type: u32 return_purpose: bcd-version return_constant: QMK_BCD_VERSION } 0x01: { type: command name: Capabilities Query define: CAPABILITIES_QUERY description: ''' QMK subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem. ''' return_type: u32 return_purpose: capabilities return_constant: XAP_ROUTE_QMK_CAPABILITIES } 0x02: { type: command name: Board identifiers define: BOARD_IDENTIFIERS description: ''' Retrieves the set of identifying information for the board. ''' return_type: struct return_struct_length: 10 return_struct_members: [ { type: u16 name: Vendor ID }, { type: u16 name: Product ID }, { type: u16 name: Product Version }, { type: u32 name: QMK Unique Identifier } ] return_constant: [ VENDOR_ID PRODUCT_ID DEVICE_VER XAP_KEYBOARD_IDENTIFIER ] } 0x03: { type: command name: Board Manufacturer define: BOARD_MANUFACTURER description: Retrieves the name of the manufacturer return_type: string return_constant: QSTR(MANUFACTURER) } 0x04: { type: command name: Product Name define: PRODUCT_NAME description: Retrieves the product name return_type: string return_constant: QSTR(PRODUCT) } 0x05: { type: command name: info.json length define: INFO_LEN_QUERY description: Retrieves the length of info.json return_type: u32 return_constant: INFO_JSON_GZ_LEN } 0x06: { type: command name: info.json define: INFO_QUERY description: Retrieves a chunk of info.json request_type: u16 request_purpose: offset return_type: u8[32] return_execute: get_info_json_chunk } 0x07: { type: command name: Jump to bootloader define: BOOTLOADER_JUMP permissions: secure 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 } 0x08: { type: command name: info.json define: HARDWARE_ID description: Retrieves a unique identifier for the board. return_type: u32[4] return_execute: get_hardware_id } } }, 0x02: { type: router name: Keyboard define: KB description: ''' This subsystem is always present, and reserved for user-specific functionality. No routes are defined by XAP. ''' routes: { } }, 0x03: { type: router name: User define: USER description: ''' This subsystem is always present, and reserved for user-specific functionality. No routes are defined by XAP. ''' routes: { } } } }