feat(protocol): 添加时间同步和主题颜色协议支持
- 添加CDC_PROTO_TYPE_LED_STATE、CDC_PROTO_TYPE_TIME_SYNC和 CDC_PROTO_TYPE_THEME_RGB协议类型定义 - 在protobuf中定义LedState、TimeSync和ThemeRgb消息结构 - 更新CdcPacketBody消息以包含新的协议类型 - 增加协议能力标志位以支持新功能
This commit is contained in:
@@ -18,8 +18,11 @@
|
||||
|
||||
#include <proto/device_comm.pb.h>
|
||||
|
||||
#include "theme_rgb_update_event.h"
|
||||
#include "time_sync_event.h"
|
||||
#include "cdc_proto_tx_event.h"
|
||||
#include "function_bitmap_update_event.h"
|
||||
#include "hid_led_event.h"
|
||||
#include "key_function_event.h"
|
||||
#include "protocol_module.h"
|
||||
#include "usb_device_state_event.h"
|
||||
@@ -31,7 +34,7 @@ LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF);
|
||||
#define PROTOCOL_PRODUCT_ID 0x52F0U
|
||||
#define PROTOCOL_FIRMWARE_MAJOR 0U
|
||||
#define PROTOCOL_FIRMWARE_MINOR 0U
|
||||
#define PROTOCOL_CAPABILITY_FLAGS BIT(0)
|
||||
#define PROTOCOL_CAPABILITY_FLAGS (BIT(0) | BIT(1) | BIT(2) | BIT(3))
|
||||
|
||||
static bool initialized;
|
||||
static bool running;
|
||||
@@ -50,6 +53,12 @@ static bool type_matches_body(uint8_t type, const CdcPacketBody *body)
|
||||
return body->which_body == CdcPacketBody_bitmap_tag;
|
||||
case CDC_PROTO_TYPE_FUNCTION_KEY_EVENT:
|
||||
return body->which_body == CdcPacketBody_function_key_event_tag;
|
||||
case CDC_PROTO_TYPE_LED_STATE:
|
||||
return body->which_body == CdcPacketBody_led_state_tag;
|
||||
case CDC_PROTO_TYPE_TIME_SYNC:
|
||||
return body->which_body == CdcPacketBody_time_sync_tag;
|
||||
case CDC_PROTO_TYPE_THEME_RGB:
|
||||
return body->which_body == CdcPacketBody_theme_rgb_tag;
|
||||
case CDC_PROTO_TYPE_ACK:
|
||||
return body->which_body == CdcPacketBody_ack_tag;
|
||||
case CDC_PROTO_TYPE_ERROR:
|
||||
@@ -152,6 +161,17 @@ static int encode_function_key_event(uint16_t usage, uint8_t action,
|
||||
return encode_body(&body, payload, payload_buf_size, payload_len);
|
||||
}
|
||||
|
||||
static int encode_led_state(uint32_t led_mask, uint8_t *payload,
|
||||
size_t payload_buf_size, size_t *payload_len)
|
||||
{
|
||||
CdcPacketBody body = CdcPacketBody_init_zero;
|
||||
|
||||
body.which_body = CdcPacketBody_led_state_tag;
|
||||
body.body.led_state.led_mask = led_mask;
|
||||
|
||||
return encode_body(&body, payload, payload_buf_size, payload_len);
|
||||
}
|
||||
|
||||
static int submit_cdc_proto_tx_event(uint8_t type, const uint8_t *payload,
|
||||
size_t payload_len)
|
||||
{
|
||||
@@ -188,6 +208,45 @@ static int submit_function_bitmap_update_event(const Bitmap *bitmap)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int submit_theme_rgb_update_event(const ThemeRgb *theme_rgb)
|
||||
{
|
||||
struct theme_rgb_update_event *event;
|
||||
|
||||
if ((theme_rgb == NULL) ||
|
||||
(theme_rgb->red > 255U) ||
|
||||
(theme_rgb->green > 255U) ||
|
||||
(theme_rgb->blue > 255U)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
event = new_theme_rgb_update_event();
|
||||
event->theme.r = (uint8_t)theme_rgb->red;
|
||||
event->theme.g = (uint8_t)theme_rgb->green;
|
||||
event->theme.b = (uint8_t)theme_rgb->blue;
|
||||
APP_EVENT_SUBMIT(event);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int submit_time_sync_event(const TimeSync *time_sync)
|
||||
{
|
||||
struct time_sync_event *event;
|
||||
|
||||
if (time_sync == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
event = new_time_sync_event();
|
||||
event->version = time_sync->version;
|
||||
event->flags = time_sync->flags;
|
||||
event->timezone_min = time_sync->timezone_min;
|
||||
event->utc_ms = time_sync->utc_ms;
|
||||
event->accuracy_ms = time_sync->accuracy_ms;
|
||||
APP_EVENT_SUBMIT(event);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int encode_error_response(uint8_t req_type, ErrorCode error_code,
|
||||
uint8_t *rsp_type, uint8_t *rsp_payload,
|
||||
size_t rsp_payload_buf_size,
|
||||
@@ -339,6 +398,51 @@ int protocol_module_process_cdc_packet(uint8_t req_type,
|
||||
return encode_ack_response(req_type, rsp_type, rsp_payload,
|
||||
rsp_payload_buf_size, rsp_payload_len);
|
||||
|
||||
case CDC_PROTO_TYPE_TIME_SYNC:
|
||||
if (!hello_done) {
|
||||
return encode_error_response(req_type, ErrorCode_ERROR_CODE_NOT_READY,
|
||||
rsp_type, rsp_payload,
|
||||
rsp_payload_buf_size,
|
||||
rsp_payload_len);
|
||||
}
|
||||
|
||||
if (body.body.time_sync.version != 1U) {
|
||||
return encode_error_response(req_type, ErrorCode_ERROR_CODE_INVALID_PARAM,
|
||||
rsp_type, rsp_payload,
|
||||
rsp_payload_buf_size,
|
||||
rsp_payload_len);
|
||||
}
|
||||
|
||||
err = submit_time_sync_event(&body.body.time_sync);
|
||||
if (err) {
|
||||
return encode_error_response(req_type, ErrorCode_ERROR_CODE_INVALID_PARAM,
|
||||
rsp_type, rsp_payload,
|
||||
rsp_payload_buf_size,
|
||||
rsp_payload_len);
|
||||
}
|
||||
|
||||
return encode_ack_response(req_type, rsp_type, rsp_payload,
|
||||
rsp_payload_buf_size, rsp_payload_len);
|
||||
|
||||
case CDC_PROTO_TYPE_THEME_RGB:
|
||||
if (!hello_done) {
|
||||
return encode_error_response(req_type, ErrorCode_ERROR_CODE_NOT_READY,
|
||||
rsp_type, rsp_payload,
|
||||
rsp_payload_buf_size,
|
||||
rsp_payload_len);
|
||||
}
|
||||
|
||||
err = submit_theme_rgb_update_event(&body.body.theme_rgb);
|
||||
if (err) {
|
||||
return encode_error_response(req_type, ErrorCode_ERROR_CODE_INVALID_PARAM,
|
||||
rsp_type, rsp_payload,
|
||||
rsp_payload_buf_size,
|
||||
rsp_payload_len);
|
||||
}
|
||||
|
||||
return encode_ack_response(req_type, rsp_type, rsp_payload,
|
||||
rsp_payload_buf_size, rsp_payload_len);
|
||||
|
||||
default:
|
||||
LOG_WRN("Unsupported CDC protocol type:0x%02x", req_type);
|
||||
return encode_error_response(req_type, ErrorCode_ERROR_CODE_UNKNOWN_TYPE,
|
||||
@@ -373,6 +477,30 @@ static bool handle_key_function_event(const struct key_function_event *event)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool handle_hid_led_event(const struct hid_led_event *event)
|
||||
{
|
||||
uint8_t payload[64];
|
||||
size_t payload_len;
|
||||
int err;
|
||||
|
||||
if (!running || !usb_active || !hello_done) {
|
||||
return false;
|
||||
}
|
||||
|
||||
err = encode_led_state(event->led_bm, payload, sizeof(payload), &payload_len);
|
||||
if (err) {
|
||||
LOG_WRN("LedState encode failed (%d)", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
err = submit_cdc_proto_tx_event(CDC_PROTO_TYPE_LED_STATE, payload, payload_len);
|
||||
if (err) {
|
||||
LOG_WRN("LedState submit failed (%d)", err);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool handle_usb_device_state_event(const struct usb_device_state_event *event)
|
||||
{
|
||||
usb_active = (event->state == USB_DEVICE_STATE_ACTIVE);
|
||||
@@ -389,6 +517,10 @@ static bool app_event_handler(const struct app_event_header *aeh)
|
||||
return handle_key_function_event(cast_key_function_event(aeh));
|
||||
}
|
||||
|
||||
if (is_hid_led_event(aeh)) {
|
||||
return handle_hid_led_event(cast_hid_led_event(aeh));
|
||||
}
|
||||
|
||||
if (is_usb_device_state_event(aeh)) {
|
||||
return handle_usb_device_state_event(cast_usb_device_state_event(aeh));
|
||||
}
|
||||
@@ -453,6 +585,7 @@ static bool app_event_handler(const struct app_event_header *aeh)
|
||||
}
|
||||
|
||||
APP_EVENT_LISTENER(MODULE, app_event_handler);
|
||||
APP_EVENT_SUBSCRIBE(MODULE, hid_led_event);
|
||||
APP_EVENT_SUBSCRIBE(MODULE, key_function_event);
|
||||
APP_EVENT_SUBSCRIBE(MODULE, module_state_event);
|
||||
APP_EVENT_SUBSCRIBE(MODULE, usb_device_state_event);
|
||||
|
||||
Reference in New Issue
Block a user