This document aims to describe the requirements of the new QMK XAP ("extensible application protocol") API. The intention is to provide access to everything currently exposed through the VIA interface, as well as additional subsystems that VIA does not support.
Ultimately the intent is that XAP replaces the current VIA protocol, and the VIA host app (as well as others such as Vial, remap.keys) can leverage XAP going forward. Once sufficient critical mass is reached, support for the VIA protocol can be removed from QMK Firmware.
Comments by @tzarc look like this:
โฆand should not be considered as part of the final document.
see Types
see Definitions
master
branch, it can never be changed, only marked as deprecated
#define
in their user/keymap config.h.90000ms
.#define
in user/keymap config.hThis list is not "locked in" and is non-exhaustive โ it is present mainly to cater for initial feature parity.
0x00
: XAP (always present, introduced XAP version 0.0.1)0x01
: QMK (always present, introduced XAP version 0.1.0)0x02
: Keyboard-specific passthrough (introduced XAP version 0.1.0) โ xap_handler_kb()
0x03
: User-specific passthrough (introduced XAP version 0.1.0) โ xap_handler_user()
0x04
: Dynamic Keymaps0x05
: Dynamic Encoders0x06
: rgblight0x07
: rgb_matrixSubsystem validity should be queried through the "Enabled-in-firmware subsystem query" under the QMK subsystem (route=0x00,0x01
). This is the primary method for determining if a subsystem has been enabled in the running firmware. Example pseudo-C-code running on the host application side:
// elsewhere...
#define XAP_SUBSYSTEM_ID 0x00
#define XAP_SUBSYSTEM_ENABLED_SUBSYSTEMS_QUERY_ID 0x01
// check if subsystem is enabled
bool is_subsystem_enabled(uint8_t subsystem) {
uint8_t query[] = { XAP_SUBSYSTEM_ID, XAP_SUBSYSTEM_ENABLED_SUBSYSTEMS_QUERY_ID };
uint8_t response[32] = {0};
xap_execute(query, sizeof(query), response, sizeof(response));
return (response[subsystem / 8] & (1 << (subsystem % 8))) ? true : false;
}
// elsewhere...
#define RGB_MATRIX_SUBSYSTEM_ID 0x07
bool is_rgb_matrix_enabled = is_subsystem_enabled(RGB_MATRIX_SUBSYSTEM_ID);
Currently unsure if we want to make a distinction between rgblight and rgb_matrix, or whether or not we just provide a flag. There's considerable overlap between the two subsystems, but also enough difference that it could go either way. Should we just call it "lighting", and add support for backlight too?
The addition of dynamic encoders is subject to decisions regarding how to persist their functionality in other in-flight PRs. If they end up being part of the matrix, then we may not need another subsystem.
0x00
(always present, introduced XAP version 0.0.1)This subsystem is always present if XAP is enabled, and provides the ability to query information about the XAP protocol of the connected device.
0x00
: XAP protocol version (always present, introduced XAP version 0.0.1)
0xXXYYZZZZ
0x01010015
.u32
value.0x01
: Enabled-in-firmware subsystem query (always present, introduced XAP version 0.1.0)
u8[16]
= 128 bits = 128 total subsystems.(1ul << SUBSYSTEM_ID)
.0x04
), and rgb_matrix(0x07
) will have the first entry in the array of 0b10011111
. (Note: XAP, QMK, keyboard, and user, will always be present.)0x02
: Query secure route status (always present, introduced XAP version 0.1.0)
u8
:
0
means secure routes are disabled1
means unlock sequence initiated but incomplete2
means secure routes are allowed0x03
: Initiate secure route unlock sequence (always present, introduced XAP version 0.1.0)
0x04
: Disable secure routes (always present, introduced XAP version 0.1.0)
u8
: 1
means secure routes are disabled, any other value signifies failure. If secure routes were already disabled, a 1
will be returned.0x01
(always present, introduced XAP version 0.1.0)This subsystem is always present, and provides routes that are specific to QMK, but not tied to any specific subsystem within QMK, such as jumping to bootloader.
0x00
: QMK subsystem capabilties query (always present, introduced XAP version 0.1.0)
QMK_CAPABILITY_ID
):
0x01
: QMK version (always present)0x02
: Keyboard VID/PID/UniqueID (always present)0x03
: Jump to bootloader (secure)u8[8]
= 64 bits(1ul << QMK_CAPABILITY_ID)
.0b00011111
.0x01
: QMK version (always present, introduced XAP version 0.1.0)
0xXXYYZZZZ
0x00100135
.u32
0x02
: Keyboard VID/PID/UniqueID/UserID (always present, introduced XAP version 0.1.0)
โโโโโโโโโโstruct {
โโโโโโโโโโ u16 VendorID;
โโโโโโโโโโ u16 ProductID;
โโโโโโโโโโ u64 UniqueID; // Format TBD, see below.
โโโโโโโโโโ u16 UserID;
โโโโโโโโโโ}
โโโโโโโโโโโโ% f=$(echo -n planck/rev6 | sha256sum)
โโโโโโโโโโโโ% echo ${f:0:8} # 32-bit
โโโโโโโโโโโโc654a00b
โโโโโโโโโโโโ% echo ${f:0:16} # 64-bit
โโโโโโโโโโโโc654a00b59e9b67e
โโโโโโโโโโโโ% echo ${f:0:32} # 128-bit
โโโโโโโโโโโโc654a00b59e9b67e0c433aaca7437f37
#define XAP_USER_ID 0x1337
to his keymap's config.h0x03
below can accept data associated with @tzarc's handlers.0x03
: Jump to bootloader (secure, introduced XAP version 0.1.0)
u8
:
0
means secure routes are disabled, and should be considered as a failure1
means successful, board will jump to bootloader0x02
xap_receive_kb()
.0x03
xap_receive_user()
.