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:
Peter Johanson
2024-02-19 08:48:20 +00:00
committed by Pete Johanson
parent ea64fcaf71
commit feda96eb40
28 changed files with 2840 additions and 9 deletions

50
app/src/studio/core.c Normal file
View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2024 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/
#include <zmk/studio/core.h>
ZMK_EVENT_IMPL(zmk_studio_core_lock_state_changed);
static enum zmk_studio_core_lock_state state = IS_ENABLED(CONFIG_ZMK_STUDIO_LOCKING)
? ZMK_STUDIO_CORE_LOCK_STATE_LOCKED
: ZMK_STUDIO_CORE_LOCK_STATE_UNLOCKED;
enum zmk_studio_core_lock_state zmk_studio_core_get_lock_state(void) { return state; }
static void set_state(enum zmk_studio_core_lock_state new_state) {
if (state == new_state) {
return;
}
state = new_state;
raise_zmk_studio_core_lock_state_changed(
(struct zmk_studio_core_lock_state_changed){.state = state});
}
#if CONFIG_ZMK_STUDIO_LOCK_IDLE_TIMEOUT_SEC > 0
static void core_idle_lock_timeout_cb(struct k_work *work) { zmk_studio_core_lock(); }
K_WORK_DELAYABLE_DEFINE(core_idle_lock_timeout, core_idle_lock_timeout_cb);
void zmk_studio_core_reschedule_lock_timeout() {
k_work_reschedule(&core_idle_lock_timeout, K_SECONDS(CONFIG_ZMK_STUDIO_LOCK_IDLE_TIMEOUT_SEC));
}
#else
void zmk_studio_core_reschedule_lock_timeout() {}
#endif
void zmk_studio_core_unlock() {
set_state(ZMK_STUDIO_CORE_LOCK_STATE_UNLOCKED);
zmk_studio_core_reschedule_lock_timeout();
}
void zmk_studio_core_lock() { set_state(ZMK_STUDIO_CORE_LOCK_STATE_LOCKED); }