mirror of
https://github.com/zmkfirmware/zmk.git
synced 2026-03-24 06:55:17 -05:00
feat(studio): Initial RPC infrastructure and subsystems.
* UART and BLE/GATT transports for a protobuf encoded RPC request/response protocol. * Custom framing protocol is used to frame a give message. * Requests/responses are divided into major "subsystems" which handle requests and create response messages. * Notification support, including mapping local events to RPC notifications by a given subsystem. * Meta responses for "no response" and "unlock needed". * Initial basic lock state support in a new core section, and allow specifying if a given RPC callback requires unlocked state or not. * Add behavior subsystem with full metadata support and examples of using callback to serialize a repeated field without extra stack space needed. Co-authored-by: Cem Aksoylar <caksoylar@users.noreply.github.com>
This commit is contained in:
committed by
Pete Johanson
parent
ea64fcaf71
commit
feda96eb40
80
app/src/studio/core_subsystem.c
Normal file
80
app/src/studio/core_subsystem.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2024 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <zephyr/drivers/hwinfo.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
#include <pb_encode.h>
|
||||
#include <zmk/studio/core.h>
|
||||
#include <zmk/studio/rpc.h>
|
||||
|
||||
ZMK_RPC_SUBSYSTEM(core)
|
||||
|
||||
#define CORE_RESPONSE(type, ...) ZMK_RPC_RESPONSE(core, type, __VA_ARGS__)
|
||||
|
||||
static bool encode_device_info_name(pb_ostream_t *stream, const pb_field_t *field,
|
||||
void *const *arg) {
|
||||
if (!pb_encode_tag_for_field(stream, field)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return pb_encode_string(stream, CONFIG_ZMK_KEYBOARD_NAME, strlen(CONFIG_ZMK_KEYBOARD_NAME));
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_HWINFO)
|
||||
static bool encode_device_info_serial_number(pb_ostream_t *stream, const pb_field_t *field,
|
||||
void *const *arg) {
|
||||
uint8_t id_buffer[32];
|
||||
const ssize_t id_size = hwinfo_get_device_id(id_buffer, ARRAY_SIZE(id_buffer));
|
||||
|
||||
if (id_size <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!pb_encode_tag_for_field(stream, field)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return pb_encode_string(stream, id_buffer, id_size);
|
||||
}
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_HWINFO)
|
||||
|
||||
zmk_studio_Response get_device_info(const zmk_studio_Request *req) {
|
||||
zmk_core_GetDeviceInfoResponse resp = zmk_core_GetDeviceInfoResponse_init_zero;
|
||||
|
||||
resp.name.funcs.encode = encode_device_info_name;
|
||||
#if IS_ENABLED(CONFIG_HWINFO)
|
||||
resp.serial_number.funcs.encode = encode_device_info_serial_number;
|
||||
#endif // IS_ENABLED(CONFIG_HWINFO)
|
||||
|
||||
return CORE_RESPONSE(get_device_info, resp);
|
||||
}
|
||||
|
||||
zmk_studio_Response get_lock_state(const zmk_studio_Request *req) {
|
||||
zmk_core_LockState resp = zmk_studio_core_get_lock_state();
|
||||
|
||||
return CORE_RESPONSE(get_lock_state, resp);
|
||||
}
|
||||
|
||||
ZMK_RPC_SUBSYSTEM_HANDLER(core, get_device_info, ZMK_STUDIO_RPC_HANDLER_UNSECURED);
|
||||
ZMK_RPC_SUBSYSTEM_HANDLER(core, get_lock_state, ZMK_STUDIO_RPC_HANDLER_UNSECURED);
|
||||
|
||||
static int core_event_mapper(const zmk_event_t *eh, zmk_studio_Notification *n) {
|
||||
struct zmk_studio_core_lock_state_changed *lock_ev = as_zmk_studio_core_lock_state_changed(eh);
|
||||
|
||||
if (!lock_ev) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
LOG_DBG("Mapped a lock state event properly");
|
||||
|
||||
*n = ZMK_RPC_NOTIFICATION(core, lock_state_changed, lock_ev->state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZMK_RPC_EVENT_MAPPER(core, core_event_mapper, zmk_studio_core_lock_state_changed);
|
||||
Reference in New Issue
Block a user