switch-based handlers.

This commit is contained in:
Nick Brassel 2025-04-22 16:34:10 +10:00
parent 0d6dbe4a5f
commit e1202569ce
No known key found for this signature in database
2 changed files with 38 additions and 137 deletions

View File

@ -106,61 +106,49 @@ static const {{ data.return_type | type_to_c_before }} {{ this_prefix_lc }}_data
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Routes // Routes
{% macro append_routing_table(prefix, container, route_stack) %} {% macro append_routing_function(prefix, container, route_stack) %}
{% set this_route_stack = route_stack.copy() %} {% set this_route_stack = route_stack.copy() %}
{{ this_route_stack.append(container) or '' }} {{ this_route_stack.append(container) or '' }}
{% if 'routes' in container %} {% if 'routes' in container %}
{% for route, data in container.routes | dictsort %} {% for route, data in container.routes | dictsort %}
{% set this_prefix_uc = (prefix + '_' + data.define) | upper %} {% set this_prefix_uc = (prefix + '_' + data.define) | upper %}
{% set this_prefix_lc = this_prefix_uc | lower %} {% set this_prefix_lc = this_prefix_uc | lower %}
{{ append_routing_table(this_prefix_lc, data, this_route_stack) }} {{ append_routing_function(this_prefix_lc, data, this_route_stack) }}
{% endfor %} {% endfor %}
{% call route_conditions(this_route_stack) %} {% call route_conditions(this_route_stack) %}
static const xap_route_t {{ prefix | lower}}_table[] PROGMEM = { bool {{ prefix | lower }}_route_handler(xap_token_t token, const uint8_t *data, size_t data_len) {
switch (data[0]) {
{% for route, data in container.routes | dictsort %} {% for route, data in container.routes | dictsort %}
{% set inner_route_stack = this_route_stack.copy() %} {% set inner_route_stack = this_route_stack.copy() %}
{{ inner_route_stack.append(data) or '' }} {{ inner_route_stack.append(data) or '' }}
{% if 'permissions' in data %}
{% set secure_status = 'ROUTE_PERMISSIONS_SECURE' %}
{% else %}
{% set secure_status = 'ROUTE_PERMISSIONS_INSECURE' %}
{% endif %}
{% call route_conditions(inner_route_stack) %} {% call route_conditions(inner_route_stack) %}
[{{ prefix | upper }}_{{ data.define }}] = { case {{ prefix | upper }}_{{ data.define }}:
{% if 'routes' in data %} {
.flags = { {% if 'permissions' in data %}
.type = XAP_ROUTE, if(xap_ensure_unlocked(token)) { return true; } // Route requires secure unlock
.secure = {{ secure_status }}, {% else %}
}, secure_activity_event();
.child_routes = {{ prefix | lower }}_{{ data.define | lower }}_table,
.child_routes_len = sizeof({{ prefix | lower }}_{{ data.define | lower }}_table)/sizeof(xap_route_t),
{% elif 'return_execute' in data %}
.flags = {
.type = XAP_EXECUTE,
.secure = {{ secure_status }},
},
.handler = xap_respond_{{ data.return_execute | lower }},
{% elif 'return_constant' in data and data.return_type == 'string' %}
.flags = {
.type = XAP_CONST_MEM,
.secure = {{ secure_status }},
},
.const_data = {{ prefix | lower }}_{{ data.define | lower }}_str,
.const_data_len = sizeof({{ prefix | lower }}_{{ data.define | lower }}_str) - 1,
{% elif 'return_constant' in data %}
.flags = {
.type = XAP_CONST_MEM,
.secure = {{ secure_status }},
},
.const_data = &{{ prefix | lower }}_{{ data.define | lower }}_data,
.const_data_len = sizeof({{ prefix | lower }}_{{ data.define | lower }}_data),
{% endif %} {% endif %}
}, {% if 'routes' in data %}
extern bool {{ prefix | lower }}_{{ data.define | lower }}_route_handler(xap_token_t token, const uint8_t *data, size_t data_len);
return {{ prefix | lower }}_{{ data.define | lower }}_route_handler(token, &data[1], data_len - 1);
{% elif 'return_execute' in data %}
return xap_respond_{{ data.return_execute | lower }}(token, &data[1], data_len - 1);
{% elif 'return_constant' in data and data.return_type == 'string' %}
return xap_respond_data_P(token, {{ prefix | lower }}_{{ data.define | lower }}_str, sizeof({{ prefix | lower }}_{{ data.define | lower }}_str) - 1);
{% elif 'return_constant' in data %}
return xap_respond_data(token, &{{ prefix | lower }}_{{ data.define | lower }}_data, sizeof({{ prefix | lower }}_{{ data.define | lower }}_data));
{% endif %}
}
{% endcall %} {% endcall %}
{% endfor %} {% endfor %}
}; default:
break;
}
return false;
}
{% endcall %} {% endcall %}
{% endif %} {% endif %}
{% endmacro %} {% endmacro %}
{{ append_routing_table("xap_route", xap, []) }} {{ append_routing_function("xap_route", xap, []) }}

View File

@ -49,61 +49,9 @@ bool get_config_blob_chunk(uint16_t offset, uint8_t *data, uint8_t data_len) {
# define ENABLED_BACKLIGHT_EFFECTS 0b00000000 # define ENABLED_BACKLIGHT_EFFECTS 0b00000000
#endif #endif
#define QSTR2(z) #z bool xap_ensure_unlocked(xap_token_t token) {
#define QSTR(z) QSTR2(z)
typedef enum xap_route_type_t {
XAP_UNUSED = 0, // "Unused" needs to be zero -- undefined routes (through preprocessor) will be skipped
XAP_ROUTE,
XAP_EXECUTE,
XAP_VALUE,
XAP_CONST_MEM,
TOTAL_XAP_ROUTE_TYPES
} xap_route_type_t;
#define XAP_ROUTE_TYPE_BIT_COUNT 3
typedef enum xap_route_secure_t {
ROUTE_PERMISSIONS_INSECURE,
ROUTE_PERMISSIONS_SECURE,
} xap_route_secure_t;
#define XAP_ROUTE_SECURE_BIT_COUNT 2
typedef struct __attribute__((packed)) xap_route_flags_t {
xap_route_type_t type : XAP_ROUTE_TYPE_BIT_COUNT;
xap_route_secure_t secure : XAP_ROUTE_SECURE_BIT_COUNT;
} xap_route_flags_t;
_Static_assert(TOTAL_XAP_ROUTE_TYPES <= (1 << (XAP_ROUTE_TYPE_BIT_COUNT)), "Number of XAP route types is too large for XAP_ROUTE_TYPE_BITS.");
_Static_assert(sizeof(xap_route_flags_t) == 1, "xap_route_flags_t is not length of 1");
typedef struct xap_route_t xap_route_t;
struct __attribute__((packed)) xap_route_t {
const xap_route_flags_t flags;
union {
// XAP_ROUTE
struct {
const xap_route_t *child_routes;
const uint8_t child_routes_len;
};
// XAP_EXECUTE
bool (*handler)(xap_token_t token, const uint8_t *data, size_t data_len);
// XAP_VALUE / XAP_CONST_MEM
struct {
const void * const_data;
const uint8_t const_data_len;
};
};
};
#include <xap_generated.inl>
bool xap_pre_execute_route(xap_token_t token, const xap_route_t *route) {
#ifdef SECURE_ENABLE #ifdef SECURE_ENABLE
if (!secure_is_unlocked() && (route->flags.secure == ROUTE_PERMISSIONS_SECURE)) { if (!secure_is_unlocked()) {
xap_respond_failure(token, XAP_RESPONSE_FLAG_SECURE_FAILURE); xap_respond_failure(token, XAP_RESPONSE_FLAG_SECURE_FAILURE);
return true; return true;
} }
@ -114,50 +62,15 @@ bool xap_pre_execute_route(xap_token_t token, const xap_route_t *route) {
return false; return false;
} }
void xap_execute_route(xap_token_t token, const xap_route_t *routes, size_t max_routes, const uint8_t *data, size_t data_len) { #define QSTR2(z) #z
if (data_len == 0) return; #define QSTR(z) QSTR2(z)
xap_identifier_t id = data[0];
if (id < max_routes) { #include <xap_generated.inl>
xap_route_t route;
memcpy_P(&route, &routes[id], sizeof(xap_route_t));
if (xap_pre_execute_route(token, &route)) {
return;
}
switch (route.flags.type) {
case XAP_ROUTE:
if (route.child_routes != NULL && route.child_routes_len > 0 && data_len > 0) {
xap_execute_route(token, route.child_routes, route.child_routes_len, &data[1], data_len - 1);
return;
}
break;
case XAP_EXECUTE:
if (route.handler != NULL) {
bool ok = (route.handler)(token, data_len == 1 ? NULL : &data[1], data_len - 1);
if (ok) return;
}
break;
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;
default:
break;
}
}
void xap_receive(xap_token_t token, const uint8_t *data, size_t length) {
extern bool xap_route_route_handler(xap_token_t token, const uint8_t *data, size_t data_len);
if (!xap_route_route_handler(token, data, length)) {
// Nothing got handled, so we respond with failure. // Nothing got handled, so we respond with failure.
xap_respond_failure(token, XAP_RESPONSE_FLAG_FAILED); xap_respond_failure(token, XAP_RESPONSE_FLAG_FAILED);
} }
void xap_receive(xap_token_t token, const uint8_t *data, size_t length) {
xap_execute_route(token, xap_route_table, sizeof(xap_route_table) / sizeof(xap_route_t), data, length);
} }