Skip to content

Commit

Permalink
refactor: Split endpoint to transport and instance
Browse files Browse the repository at this point in the history
Changed the endpoints code to rename the existing endpoint types to
"transport" and add the concept of "endpoint instances". A transport is
the method by which data is sent, while instances allow describing
multiple endpoints that use the same transport (e.g. bluetooth profiles)

Also added new APIs to get the total number of possible endpoint
instances and assign each instance a unique index, which can be used
for tracking separate state for each endpoint in other code files.
  • Loading branch information
joelspadin committed Jun 18, 2023
1 parent dcf5e75 commit fcec2ad
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 128 deletions.
33 changes: 13 additions & 20 deletions app/boards/arm/corneish_zen/widgets/output_status.c
Expand Up @@ -16,7 +16,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/event_manager.h>
#include <zmk/events/usb_conn_state_changed.h>
#include <zmk/events/ble_active_profile_changed.h>
#include <zmk/events/endpoint_selection_changed.h>
#include <zmk/events/endpoint_changed.h>
#include <zmk/usb.h>
#include <zmk/ble.h>
#include <zmk/endpoints.h>
Expand All @@ -39,31 +39,31 @@ LV_IMG_DECLARE(USB_connected);
static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets);

struct output_status_state {
enum zmk_endpoint selected_endpoint;
struct zmk_endpoint_instance selected_endpoint;
bool active_profile_connected;
bool active_profile_bonded;
uint8_t active_profile_index;
};

static struct output_status_state get_state(const zmk_event_t *_eh) {
return (struct output_status_state){.selected_endpoint = zmk_endpoints_selected(),
.active_profile_connected =
zmk_ble_active_profile_is_connected(),
.active_profile_bonded = !zmk_ble_active_profile_is_open(),
.active_profile_index = zmk_ble_active_profile_index()};
return (struct output_status_state){
.selected_endpoint = zmk_endpoints_selected(),
.active_profile_connected = zmk_ble_active_profile_is_connected(),
.active_profile_bonded = !zmk_ble_active_profile_is_open(),
};
;
}

static void set_status_symbol(lv_obj_t *icon, struct output_status_state state) {
switch (state.selected_endpoint) {
case ZMK_ENDPOINT_USB:
switch (state.selected_endpoint.transport) {
case ZMK_TRANSPORT_USB:
lv_img_set_src(icon, &USB_connected);
break;
case ZMK_ENDPOINT_BLE:
case ZMK_TRANSPORT_BLE:
if (state.active_profile_bonded) {
if (state.active_profile_connected) {
// sprintf(text, LV_SYMBOL_BLUETOOTH "%i " LV_SYMBOL_OK, active_profile_index);
switch (state.active_profile_index) {
switch (state.selected_endpoint.ble.profile_index) {
case 0:
lv_img_set_src(icon, &bluetooth_connected_1);
break;
Expand All @@ -84,7 +84,7 @@ static void set_status_symbol(lv_obj_t *icon, struct output_status_state state)
lv_img_set_src(icon, &bluetooth_disconnected_right);
}
} else {
switch (state.active_profile_index) {
switch (state.selected_endpoint.ble.profile_index) {
case 0:
lv_img_set_src(icon, &bluetooth_advertising_1);
break;
Expand Down Expand Up @@ -113,14 +113,7 @@ static void output_status_update_cb(struct output_status_state state) {

ZMK_DISPLAY_WIDGET_LISTENER(widget_output_status, struct output_status_state,
output_status_update_cb, get_state)
ZMK_SUBSCRIPTION(widget_output_status, zmk_endpoint_selection_changed);

#if IS_ENABLED(CONFIG_USB_DEVICE_STACK)
ZMK_SUBSCRIPTION(widget_output_status, zmk_usb_conn_state_changed);
#endif
#if defined(CONFIG_ZMK_BLE)
ZMK_SUBSCRIPTION(widget_output_status, zmk_ble_active_profile_changed);
#endif
ZMK_SUBSCRIPTION(widget_output_status, zmk_endpoint_changed);

int zmk_widget_output_status_init(struct zmk_widget_output_status *widget, lv_obj_t *parent) {
widget->obj = lv_img_create(parent);
Expand Down
62 changes: 59 additions & 3 deletions app/include/zmk/endpoints.h
Expand Up @@ -6,10 +6,66 @@

#pragma once

#include <zmk/ble.h>
#include <zmk/endpoints_types.h>

int zmk_endpoints_select(enum zmk_endpoint endpoint);
int zmk_endpoints_toggle();
enum zmk_endpoint zmk_endpoints_selected();
/**
* Recommended length of string buffer for printing endpoint identifiers.
*/
#define ZMK_ENDPOINT_STR_LEN 10

#ifdef CONFIG_ZMK_USB
#define ZMK_ENDPOINT_USB_COUNT 1
#else
#define ZMK_ENDPOINT_USB_COUNT 0
#endif

#ifdef CONFIG_ZMK_BLE
#define ZMK_ENDPOINT_BLE_COUNT ZMK_BLE_PROFILE_COUNT
#else
#define ZMK_ENDPOINT_BLE_COUNT 0
#endif

/**
* The total number of different (struct zmk_endpoint_instance) values that can
* be selected.
*
* Note that this value may change between firmware versions, so it should not
* be used in any persistent storage.
*/
#define ZMK_ENDPOINT_COUNT (ZMK_ENDPOINT_USB_COUNT + ZMK_ENDPOINT_BLE_COUNT)

bool zmk_endpoint_instance_equals(struct zmk_endpoint_instance a, struct zmk_endpoint_instance b);

/**
* Writes a string identifying an endpoint instance.
*
* @param str Address of output string buffer
* @param len Length of string buffer. See ZMK_ENDPOINT_STR_LEN for recommended length.
*
* @returns Number of characters written.
*/
int zmk_endpoint_instance_print(char *str, size_t len, struct zmk_endpoint_instance endpoint);

/**
* Gets a unique index for an endpoint instance. This can be used together with
* ZMK_ENDPOINT_COUNT to manage separate state for each endpoint instance.
*
* Note that the index for a specific instance may change between firmware versions,
* so it should not be used in any persistent storage.
*/
int zmk_endpoint_instance_to_index(struct zmk_endpoint_instance endpoint);

/**
* Sets the preferred endpoint transport to use. (If the preferred endpoint is
* not available, a different one may automatically be selected.)
*/
int zmk_endpoints_select_transport(enum zmk_transport transport);
int zmk_endpoints_toggle_transport(void);

/**
* Gets the currently-selected endpoint.
*/
struct zmk_endpoint_instance zmk_endpoints_selected(void);

int zmk_endpoints_send_report(uint16_t usage_page);
32 changes: 29 additions & 3 deletions app/include/zmk/endpoints_types.h
Expand Up @@ -6,7 +6,33 @@

#pragma once

enum zmk_endpoint {
ZMK_ENDPOINT_USB,
ZMK_ENDPOINT_BLE,
/**
* The method by which data is sent.
*/
enum zmk_transport {
ZMK_TRANSPORT_USB,
ZMK_TRANSPORT_BLE,
};

/**
* Configuration to select an endpoint on ZMK_TRANSPORT_USB.
*/
struct zmk_transport_usb_data {};

/**
* Configuration to select an endpoint on ZMK_TRANSPORT_BLE.
*/
struct zmk_transport_ble_data {
int profile_index;
};

/**
* A specific endpoint to which data may be sent.
*/
struct zmk_endpoint_instance {
enum zmk_transport transport;
union {
struct zmk_transport_usb_data usb; // ZMK_TRANSPORT_USB
struct zmk_transport_ble_data ble; // ZMK_TRANSPORT_BLE
};
};
Expand Up @@ -11,8 +11,8 @@
#include <zmk/endpoints_types.h>
#include <zmk/event_manager.h>

struct zmk_endpoint_selection_changed {
enum zmk_endpoint endpoint;
struct zmk_endpoint_changed {
struct zmk_endpoint_instance endpoint;
};

ZMK_EVENT_DECLARE(zmk_endpoint_selection_changed);
ZMK_EVENT_DECLARE(zmk_endpoint_changed);
6 changes: 3 additions & 3 deletions app/src/behaviors/behavior_outputs.c
Expand Up @@ -24,11 +24,11 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) {
switch (binding->param1) {
case OUT_TOG:
return zmk_endpoints_toggle();
return zmk_endpoints_toggle_transport();
case OUT_USB:
return zmk_endpoints_select(ZMK_ENDPOINT_USB);
return zmk_endpoints_select_transport(ZMK_TRANSPORT_USB);
case OUT_BLE:
return zmk_endpoints_select(ZMK_ENDPOINT_BLE);
return zmk_endpoints_select_transport(ZMK_TRANSPORT_BLE);
default:
LOG_ERR("Unknown output command: %d", binding->param1);
}
Expand Down
29 changes: 10 additions & 19 deletions app/src/display/widgets/output_status.c
Expand Up @@ -14,48 +14,46 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/event_manager.h>
#include <zmk/events/usb_conn_state_changed.h>
#include <zmk/events/ble_active_profile_changed.h>
#include <zmk/events/endpoint_selection_changed.h>
#include <zmk/events/endpoint_changed.h>
#include <zmk/usb.h>
#include <zmk/ble.h>
#include <zmk/endpoints.h>

static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets);

struct output_status_state {
enum zmk_endpoint selected_endpoint;
struct zmk_endpoint_instance selected_endpoint;
bool active_profile_connected;
bool active_profile_bonded;
uint8_t active_profile_index;
};

static struct output_status_state get_state(const zmk_event_t *_eh) {
return (struct output_status_state){.selected_endpoint = zmk_endpoints_selected(),
.active_profile_connected =
zmk_ble_active_profile_is_connected(),
.active_profile_bonded = !zmk_ble_active_profile_is_open(),
.active_profile_index = zmk_ble_active_profile_index()};
.active_profile_bonded = !zmk_ble_active_profile_is_open()};
;
}

static void set_status_symbol(lv_obj_t *label, struct output_status_state state) {
char text[10] = {};

switch (state.selected_endpoint) {
case ZMK_ENDPOINT_USB:
switch (state.selected_endpoint.transport) {
case ZMK_TRANSPORT_USB:
strcat(text, LV_SYMBOL_USB);
break;
case ZMK_ENDPOINT_BLE:
case ZMK_TRANSPORT_BLE:
if (state.active_profile_bonded) {
if (state.active_profile_connected) {
snprintf(text, sizeof(text), LV_SYMBOL_WIFI " %i " LV_SYMBOL_OK,
state.active_profile_index + 1);
state.selected_endpoint.ble.profile_index + 1);
} else {
snprintf(text, sizeof(text), LV_SYMBOL_WIFI " %i " LV_SYMBOL_CLOSE,
state.active_profile_index + 1);
state.selected_endpoint.ble.profile_index + 1);
}
} else {
snprintf(text, sizeof(text), LV_SYMBOL_WIFI " %i " LV_SYMBOL_SETTINGS,
state.active_profile_index + 1);
state.selected_endpoint.ble.profile_index + 1);
}
break;
}
Expand All @@ -70,14 +68,7 @@ static void output_status_update_cb(struct output_status_state state) {

ZMK_DISPLAY_WIDGET_LISTENER(widget_output_status, struct output_status_state,
output_status_update_cb, get_state)
ZMK_SUBSCRIPTION(widget_output_status, zmk_endpoint_selection_changed);

#if IS_ENABLED(CONFIG_USB_DEVICE_STACK)
ZMK_SUBSCRIPTION(widget_output_status, zmk_usb_conn_state_changed);
#endif
#if defined(CONFIG_ZMK_BLE)
ZMK_SUBSCRIPTION(widget_output_status, zmk_ble_active_profile_changed);
#endif
ZMK_SUBSCRIPTION(widget_output_status, zmk_endpoint_changed);

int zmk_widget_output_status_init(struct zmk_widget_output_status *widget, lv_obj_t *parent) {
widget->obj = lv_label_create(parent);
Expand Down

0 comments on commit fcec2ad

Please sign in to comment.