diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d13eb2..4b1a38e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,14 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(new_kbd) +if(NOT c_std_11 IN_LIST CMAKE_C_COMPILE_FEATURES) + list(APPEND CMAKE_C_COMPILE_FEATURES c_std_11) +endif() + +set(PROTOBUF_PROTOC_EXECUTABLE + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/protoc_nanopb.bat" + CACHE FILEPATH "Project-local protoc wrapper for nanopb" FORCE) + list(APPEND CMAKE_MODULE_PATH ${ZEPHYR_BASE}/modules/nanopb) include(nanopb) @@ -40,6 +48,8 @@ zephyr_nanopb_sources(app KeyBorad/proto/keyboard.proto ) +target_link_libraries(app PRIVATE nanopb) + target_sources(app PRIVATE src/main.c src/events/battery_status_event.c diff --git a/KeyBorad/KeyBorad/DRI/GATT/Dri_Gatt.cpp b/KeyBorad/KeyBorad/DRI/GATT/Dri_Gatt.cpp index 2b0c1ec..b1b6c48 100644 --- a/KeyBorad/KeyBorad/DRI/GATT/Dri_Gatt.cpp +++ b/KeyBorad/KeyBorad/DRI/GATT/Dri_Gatt.cpp @@ -1,10 +1,210 @@ #include "DRI/GATT/Dri_Gatt.h" +#include #include #include +#include +#include +#include +#include +#include #include +#include #include +struct Dri_Gatt_Struct_Context +{ + QLowEnergyController* Controller = nullptr; + QLowEnergyService* Service = nullptr; + QLowEnergyCharacteristic RxCharacteristic; + QLowEnergyCharacteristic TxCharacteristic; + QList ReadQueue; +}; + +namespace +{ + +const QBluetoothUuid kServiceUuid( + QStringLiteral("0b7f6000-38d2-4f62-8f6f-36c4fd73a110")); +const QBluetoothUuid kRxUuid( + QStringLiteral("0b7f6001-38d2-4f62-8f6f-36c4fd73a110")); +const QBluetoothUuid kTxUuid( + QStringLiteral("0b7f6002-38d2-4f62-8f6f-36c4fd73a110")); + +bool Dri_Gatt_Func_WaitForControllerConnected(QLowEnergyController* p_Controller) +{ + QEventLoop EventLoop; + QTimer TimeoutTimer; + bool IsConnected = false; + + TimeoutTimer.setSingleShot(true); + + QObject::connect( + p_Controller, + &QLowEnergyController::connected, + &EventLoop, + [&EventLoop, &IsConnected]() + { + IsConnected = true; + EventLoop.quit(); + }); + QObject::connect( + p_Controller, + static_cast( + &QLowEnergyController::error), + &EventLoop, + [&EventLoop]() + { + EventLoop.quit(); + }); + QObject::connect( + &TimeoutTimer, + &QTimer::timeout, + &EventLoop, + &QEventLoop::quit); + + p_Controller->connectToDevice(); + TimeoutTimer.start(5000); + EventLoop.exec(); + return IsConnected; +} + +bool Dri_Gatt_Func_WaitForServiceDiscovery(QLowEnergyController* p_Controller) +{ + QEventLoop EventLoop; + QTimer TimeoutTimer; + bool IsFinished = false; + + TimeoutTimer.setSingleShot(true); + + QObject::connect( + p_Controller, + &QLowEnergyController::discoveryFinished, + &EventLoop, + [&EventLoop, &IsFinished]() + { + IsFinished = true; + EventLoop.quit(); + }); + QObject::connect( + p_Controller, + static_cast( + &QLowEnergyController::error), + &EventLoop, + [&EventLoop]() + { + EventLoop.quit(); + }); + QObject::connect( + &TimeoutTimer, + &QTimer::timeout, + &EventLoop, + &QEventLoop::quit); + + p_Controller->discoverServices(); + TimeoutTimer.start(5000); + EventLoop.exec(); + return IsFinished; +} + +bool Dri_Gatt_Func_WaitForServiceDetails(QLowEnergyService* p_Service) +{ + QEventLoop EventLoop; + QTimer TimeoutTimer; + bool IsDiscovered = false; + + TimeoutTimer.setSingleShot(true); + + QObject::connect( + p_Service, + &QLowEnergyService::stateChanged, + &EventLoop, + [&EventLoop, &IsDiscovered](QLowEnergyService::ServiceState State) + { + if (State == QLowEnergyService::ServiceDiscovered) + { + IsDiscovered = true; + EventLoop.quit(); + } + }); + QObject::connect( + p_Service, + static_cast( + &QLowEnergyService::error), + &EventLoop, + [&EventLoop]() + { + EventLoop.quit(); + }); + QObject::connect( + &TimeoutTimer, + &QTimer::timeout, + &EventLoop, + &QEventLoop::quit); + + p_Service->discoverDetails(); + TimeoutTimer.start(5000); + EventLoop.exec(); + return IsDiscovered; +} + +bool Dri_Gatt_Func_EnableNotify( + Dri_Gatt_Struct_Context* p_Context, + const QLowEnergyCharacteristic& Characteristic) +{ + if (!Characteristic.isValid() || (p_Context == nullptr) || (p_Context->Service == nullptr)) + { + return false; + } + + const QLowEnergyDescriptor Cccd = + Characteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (!Cccd.isValid()) + { + return false; + } + + QEventLoop EventLoop; + QTimer TimeoutTimer; + bool IsWritten = false; + + TimeoutTimer.setSingleShot(true); + + QObject::connect( + p_Context->Service, + &QLowEnergyService::descriptorWritten, + &EventLoop, + [&EventLoop, &IsWritten, Cccd](const QLowEnergyDescriptor& Descriptor, const QByteArray&) + { + if (Descriptor == Cccd) + { + IsWritten = true; + EventLoop.quit(); + } + }); + QObject::connect( + p_Context->Service, + static_cast( + &QLowEnergyService::error), + &EventLoop, + [&EventLoop]() + { + EventLoop.quit(); + }); + QObject::connect( + &TimeoutTimer, + &QTimer::timeout, + &EventLoop, + &QEventLoop::quit); + + p_Context->Service->writeDescriptor(Cccd, QByteArray::fromHex("0100")); + TimeoutTimer.start(3000); + EventLoop.exec(); + return IsWritten; +} + +} // namespace + QVector Dri_Gatt_Enum() { QVector PortList; @@ -79,6 +279,17 @@ void Dri_Gatt_Close(Dri_Gatt_Struct_Port* p_Port) return; } + if (p_Port->p_Context != nullptr) + { + if (p_Port->p_Context->Controller != nullptr) + { + p_Port->p_Context->Controller->disconnectFromDevice(); + delete p_Port->p_Context->Controller; + } + + delete p_Port->p_Context; + } + *p_Port = Dri_Gatt_Struct_Port(); } @@ -93,38 +304,183 @@ bool Dri_Gatt_Open( } Dri_Gatt_Close(p_Port); + + Dri_Gatt_Struct_Context* const p_Context = new Dri_Gatt_Struct_Context(); + p_Context->Controller = new QLowEnergyController(QBluetoothAddress(DeviceAddress.trimmed())); + + if (!Dri_Gatt_Func_WaitForControllerConnected(p_Context->Controller)) + { + Dri_Gatt_Close(p_Port); + delete p_Context->Controller; + delete p_Context; + return false; + } + + if (!Dri_Gatt_Func_WaitForServiceDiscovery(p_Context->Controller) || + !p_Context->Controller->services().contains(kServiceUuid)) + { + Dri_Gatt_Close(p_Port); + delete p_Context->Controller; + delete p_Context; + return false; + } + + p_Context->Service = p_Context->Controller->createServiceObject(kServiceUuid, p_Context->Controller); + if (p_Context->Service == nullptr) + { + Dri_Gatt_Close(p_Port); + delete p_Context->Controller; + delete p_Context; + return false; + } + + if (!Dri_Gatt_Func_WaitForServiceDetails(p_Context->Service)) + { + Dri_Gatt_Close(p_Port); + delete p_Context->Controller; + delete p_Context; + return false; + } + + p_Context->RxCharacteristic = p_Context->Service->characteristic(kRxUuid); + p_Context->TxCharacteristic = p_Context->Service->characteristic(kTxUuid); + + if (!p_Context->RxCharacteristic.isValid() || !p_Context->TxCharacteristic.isValid()) + { + Dri_Gatt_Close(p_Port); + delete p_Context->Controller; + delete p_Context; + return false; + } + + QObject::connect( + p_Context->Service, + &QLowEnergyService::characteristicChanged, + [p_Context](const QLowEnergyCharacteristic& Characteristic, const QByteArray& Value) + { + if (Characteristic == p_Context->TxCharacteristic) + { + p_Context->ReadQueue.append(Value); + } + }); + + if (!Dri_Gatt_Func_EnableNotify(p_Context, p_Context->TxCharacteristic)) + { + Dri_Gatt_Close(p_Port); + delete p_Context->Controller; + delete p_Context; + return false; + } + + p_Port->p_Context = p_Context; p_Port->IsOpened = true; p_Port->DeviceAddress = DeviceAddress.trimmed(); - return false; + return true; } bool Dri_Gatt_ReadBytes( Dri_Gatt_Struct_Port* p_Port, QByteArray* p_ByteArray, - int) + int TimeoutMs) { if (p_ByteArray != nullptr) { p_ByteArray->clear(); } - if ((p_Port == nullptr) || (p_ByteArray == nullptr) || !p_Port->IsOpened) + if ((p_Port == nullptr) || (p_ByteArray == nullptr) || + !p_Port->IsOpened || (p_Port->p_Context == nullptr)) { return false; } - return false; + if (p_Port->p_Context->ReadQueue.isEmpty() && (TimeoutMs > 0)) + { + QEventLoop EventLoop; + QTimer TimeoutTimer; + + TimeoutTimer.setSingleShot(true); + QObject::connect( + p_Port->p_Context->Service, + &QLowEnergyService::characteristicChanged, + &EventLoop, + [&EventLoop](const QLowEnergyCharacteristic&, const QByteArray&) + { + EventLoop.quit(); + }); + QObject::connect( + &TimeoutTimer, + &QTimer::timeout, + &EventLoop, + &QEventLoop::quit); + + TimeoutTimer.start(TimeoutMs); + EventLoop.exec(); + } + + if (p_Port->p_Context->ReadQueue.isEmpty()) + { + return false; + } + + *p_ByteArray = p_Port->p_Context->ReadQueue.takeFirst(); + return !p_ByteArray->isEmpty(); } bool Dri_Gatt_WriteBytes( Dri_Gatt_Struct_Port* p_Port, const QByteArray& ByteArray, - int) + int TimeoutMs) { - if ((p_Port == nullptr) || !p_Port->IsOpened) + if ((p_Port == nullptr) || !p_Port->IsOpened || (p_Port->p_Context == nullptr)) { return false; } - return !ByteArray.isEmpty(); + if (ByteArray.isEmpty()) + { + return false; + } + + QEventLoop EventLoop; + QTimer TimeoutTimer; + bool IsWritten = false; + + TimeoutTimer.setSingleShot(true); + + QObject::connect( + p_Port->p_Context->Service, + &QLowEnergyService::characteristicWritten, + &EventLoop, + [&EventLoop, &IsWritten, p_Port](const QLowEnergyCharacteristic& Characteristic, const QByteArray&) + { + if (Characteristic == p_Port->p_Context->RxCharacteristic) + { + IsWritten = true; + EventLoop.quit(); + } + }); + QObject::connect( + p_Port->p_Context->Service, + static_cast( + &QLowEnergyService::error), + &EventLoop, + [&EventLoop]() + { + EventLoop.quit(); + }); + QObject::connect( + &TimeoutTimer, + &QTimer::timeout, + &EventLoop, + &QEventLoop::quit); + + p_Port->p_Context->Service->writeCharacteristic( + p_Port->p_Context->RxCharacteristic, + ByteArray, + QLowEnergyService::WriteWithResponse); + TimeoutTimer.start(TimeoutMs > 0 ? TimeoutMs : 3000); + EventLoop.exec(); + + return IsWritten; } diff --git a/KeyBorad/KeyBorad/DRI/GATT/Dri_Gatt.h b/KeyBorad/KeyBorad/DRI/GATT/Dri_Gatt.h index c33033f..19898cc 100644 --- a/KeyBorad/KeyBorad/DRI/GATT/Dri_Gatt.h +++ b/KeyBorad/KeyBorad/DRI/GATT/Dri_Gatt.h @@ -4,6 +4,8 @@ #include #include +struct Dri_Gatt_Struct_Context; + struct Dri_Gatt_Struct_PortInfo { QString DeviceName; @@ -17,7 +19,9 @@ struct Dri_Gatt_Struct_OpenConfig struct Dri_Gatt_Struct_Port { bool IsOpened = false; + QString DeviceName; QString DeviceAddress; + Dri_Gatt_Struct_Context* p_Context = nullptr; }; QVector Dri_Gatt_Enum(); diff --git a/KeyBorad/proto/keyboard.options b/KeyBorad/proto/keyboard.options index 4d42cc9..aa4c5f2 100644 --- a/KeyBorad/proto/keyboard.options +++ b/KeyBorad/proto/keyboard.options @@ -1,2 +1,2 @@ -CdcFrame.payload max_size:64 -Bitmap.usage_bitmap max_size:29 +keyboard.cdc.CdcFrame.payload max_size:64 +keyboard.cdc.Bitmap.usage_bitmap max_size:29 diff --git a/app.overlay b/app.overlay index 5063ee8..3e0b9a2 100644 --- a/app.overlay +++ b/app.overlay @@ -36,7 +36,7 @@ }; }; -&zephyr_udc0 { +&usbd { cdc_acm_uart0: cdc_acm_uart0 { compatible = "zephyr,cdc-acm-uart"; label = "new_kbd CDC ACM"; diff --git a/docs/firmware_proto_transport.md b/docs/firmware_proto_transport.md index e38af58..65cfc84 100644 --- a/docs/firmware_proto_transport.md +++ b/docs/firmware_proto_transport.md @@ -80,6 +80,8 @@ Implemented behavior: - enable CDC ACM class in Zephyr USB device-next stack - add a CDC ACM UART node in devicetree - wire `zephyr_nanopb_sources()` into the build +- force nanopb generation to use the NCS toolchain Python instead of the + broken Windows app alias - add protocol helper functions for: - body encode/decode - CDC frame encode diff --git a/docs/host_dri_rebuild.md b/docs/host_dri_rebuild.md index b6dfc06..e4f25c5 100644 --- a/docs/host_dri_rebuild.md +++ b/docs/host_dri_rebuild.md @@ -62,7 +62,30 @@ Implemented behavior: - collect device name and address - filter to `LowEnergyCoreConfiguration` - stop after a short timeout -### Node 3: CDC transport cleanup + +### Node 3: GATT open and raw byte transport + +Files updated in this step: + +- `KeyBorad/KeyBorad/DRI/GATT/Dri_Gatt.h` +- `KeyBorad/KeyBorad/DRI/GATT/Dri_Gatt.cpp` + +Design notes: + +- keep transport-only responsibility +- use Qt Bluetooth instead of custom Win32 BLE code +- connect, discover service, subscribe, then pass raw bytes upward + +Implemented behavior: + +- connect to a BLE device by address +- discover the target custom service +- resolve RX/TX characteristics +- enable notify on TX +- queue raw bytes from TX notify +- write raw bytes to RX characteristic + +### Node 4: CDC transport cleanup Files updated in this step: diff --git a/inc/keyboard_proto.h b/inc/keyboard_proto.h index b93aaf5..3c6a62a 100644 --- a/inc/keyboard_proto.h +++ b/inc/keyboard_proto.h @@ -20,11 +20,11 @@ enum keyboard_proto_transport { }; typedef bool (*keyboard_proto_send_body_fn)( - const struct keyboard_cdc_CdcPacketBody *body, + const keyboard_cdc_CdcPacketBody *body, void *user_data); bool keyboard_proto_encode_body( - const struct keyboard_cdc_CdcPacketBody *body, + const keyboard_cdc_CdcPacketBody *body, uint8_t *buffer, size_t buffer_size, size_t *encoded_size); @@ -32,11 +32,11 @@ bool keyboard_proto_encode_body( bool keyboard_proto_decode_body( const uint8_t *buffer, size_t buffer_size, - struct keyboard_cdc_CdcPacketBody *body); + keyboard_cdc_CdcPacketBody *body); bool keyboard_proto_encode_cdc_frame( uint32_t packet_type, - const struct keyboard_cdc_CdcPacketBody *body, + const keyboard_cdc_CdcPacketBody *body, uint8_t *buffer, size_t buffer_size, size_t *encoded_size); @@ -44,19 +44,19 @@ bool keyboard_proto_encode_cdc_frame( bool keyboard_proto_try_take_cdc_frame( uint8_t *buffer, size_t *buffer_size, - struct keyboard_cdc_CdcFrame *frame); + keyboard_cdc_CdcFrame *frame); bool keyboard_proto_build_function_key_event_body( uint16_t usage, bool pressed, - struct keyboard_cdc_CdcPacketBody *body); + keyboard_cdc_CdcPacketBody *body); bool keyboard_proto_build_led_state_body( uint8_t led_mask, - struct keyboard_cdc_CdcPacketBody *body); + keyboard_cdc_CdcPacketBody *body); bool keyboard_proto_handle_host_body( - const struct keyboard_cdc_CdcPacketBody *body, + const keyboard_cdc_CdcPacketBody *body, enum keyboard_proto_transport transport, keyboard_proto_send_body_fn send_fn, void *user_data); diff --git a/scripts/protoc_nanopb.bat b/scripts/protoc_nanopb.bat new file mode 100644 index 0000000..740d15c --- /dev/null +++ b/scripts/protoc_nanopb.bat @@ -0,0 +1,5 @@ +@echo off +setlocal +set PATH=C:\ncs\toolchains\fd21892d0f\opt\bin;%PATH% +"C:\ncs\toolchains\fd21892d0f\opt\bin\python.exe" "C:\ncs\v3.2.4\modules\lib\nanopb\generator\protoc" %* +exit /b %ERRORLEVEL% diff --git a/src/modules/ble_gatt_proto_module.c b/src/modules/ble_gatt_proto_module.c index 1a6d557..23670d8 100644 --- a/src/modules/ble_gatt_proto_module.c +++ b/src/modules/ble_gatt_proto_module.c @@ -32,6 +32,9 @@ struct ble_gatt_proto_ctx { }; static struct ble_gatt_proto_ctx g_ble_proto; +static bool ble_gatt_proto_send_body( + const keyboard_cdc_CdcPacketBody *body, + void *user_data); static void ble_gatt_proto_ccc_changed( const struct bt_gatt_attr *attr, @@ -50,7 +53,7 @@ static ssize_t ble_gatt_proto_rx_write( uint16_t offset, uint8_t flags) { - struct keyboard_cdc_CdcPacketBody body; + keyboard_cdc_CdcPacketBody body; ARG_UNUSED(conn); ARG_UNUSED(attr); @@ -96,7 +99,7 @@ BT_GATT_SERVICE_DEFINE( BT_GATT_PERM_READ | BT_GATT_PERM_WRITE)); static bool ble_gatt_proto_send_body( - const struct keyboard_cdc_CdcPacketBody *body, + const keyboard_cdc_CdcPacketBody *body, void *user_data) { uint8_t buffer[KEYBOARD_PROTO_MAX_BODY_SIZE]; @@ -128,7 +131,7 @@ static bool handle_module_state_event(const struct module_state_event *event) static bool handle_function_key_event(const struct function_key_event *event) { - struct keyboard_cdc_CdcPacketBody body; + keyboard_cdc_CdcPacketBody body; if (!keyboard_proto_build_function_key_event_body(event->usage, event->pressed, @@ -142,7 +145,7 @@ static bool handle_function_key_event(const struct function_key_event *event) static bool handle_keyboard_led_event(const struct keyboard_led_event *event) { - struct keyboard_cdc_CdcPacketBody body; + keyboard_cdc_CdcPacketBody body; if (!keyboard_proto_build_led_state_body( keyboard_led_event_get_mask(event), diff --git a/src/modules/keyboard_proto.c b/src/modules/keyboard_proto.c index 8f98b10..6c489c5 100644 --- a/src/modules/keyboard_proto.c +++ b/src/modules/keyboard_proto.c @@ -3,6 +3,7 @@ #include #include +#include #include "display_theme_event.h" #include "function_bitmap_event.h" @@ -48,23 +49,8 @@ static uint8_t keyboard_proto_calc_checksum(const uint8_t *data, size_t len) return checksum; } -static bool keyboard_proto_fill_payload( - pb_bytes_array_t *dest, - size_t max_size, - const uint8_t *src, - size_t src_len) -{ - if ((dest == NULL) || (src == NULL) || (src_len > max_size)) { - return false; - } - - dest->size = src_len; - memcpy(dest->bytes, src, src_len); - return true; -} - bool keyboard_proto_encode_body( - const struct keyboard_cdc_CdcPacketBody *body, + const keyboard_cdc_CdcPacketBody *body, uint8_t *buffer, size_t buffer_size, size_t *encoded_size) @@ -88,7 +74,7 @@ bool keyboard_proto_encode_body( bool keyboard_proto_decode_body( const uint8_t *buffer, size_t buffer_size, - struct keyboard_cdc_CdcPacketBody *body) + keyboard_cdc_CdcPacketBody *body) { pb_istream_t stream; @@ -96,7 +82,10 @@ bool keyboard_proto_decode_body( return false; } - *body = keyboard_cdc_CdcPacketBody_init_zero; + { + keyboard_cdc_CdcPacketBody empty = keyboard_cdc_CdcPacketBody_init_zero; + *body = empty; + } stream = pb_istream_from_buffer(buffer, buffer_size); if (!pb_decode(&stream, keyboard_cdc_CdcPacketBody_fields, body)) { @@ -108,12 +97,12 @@ bool keyboard_proto_decode_body( bool keyboard_proto_encode_cdc_frame( uint32_t packet_type, - const struct keyboard_cdc_CdcPacketBody *body, + const keyboard_cdc_CdcPacketBody *body, uint8_t *buffer, size_t buffer_size, size_t *encoded_size) { - struct keyboard_cdc_CdcFrame frame = keyboard_cdc_CdcFrame_init_zero; + keyboard_cdc_CdcFrame frame = keyboard_cdc_CdcFrame_init_zero; uint8_t payload[KEYBOARD_PROTO_MAX_BODY_SIZE]; size_t payload_size = 0U; pb_ostream_t stream; @@ -131,10 +120,11 @@ bool keyboard_proto_encode_cdc_frame( frame.head2 = 0x55U; frame.payload_length = payload_size; frame.type = (keyboard_cdc_CdcPacketType)packet_type; - if (!keyboard_proto_fill_payload(&frame.payload, KEYBOARD_PROTO_MAX_BODY_SIZE, - payload, payload_size)) { + if (payload_size > KEYBOARD_PROTO_MAX_BODY_SIZE) { return false; } + frame.payload.size = payload_size; + memcpy(frame.payload.bytes, payload, payload_size); checksum_bytes[0] = (uint8_t)frame.head1; checksum_bytes[1] = (uint8_t)frame.head2; @@ -154,7 +144,7 @@ bool keyboard_proto_encode_cdc_frame( return true; } -static bool keyboard_proto_validate_frame(const struct keyboard_cdc_CdcFrame *frame) +static bool keyboard_proto_validate_frame(const keyboard_cdc_CdcFrame *frame) { uint8_t checksum_bytes[4U + KEYBOARD_PROTO_MAX_BODY_SIZE]; uint8_t checksum; @@ -181,10 +171,10 @@ static bool keyboard_proto_validate_frame(const struct keyboard_cdc_CdcFrame *fr bool keyboard_proto_try_take_cdc_frame( uint8_t *buffer, size_t *buffer_size, - struct keyboard_cdc_CdcFrame *frame) + keyboard_cdc_CdcFrame *frame) { for (size_t candidate_len = 1U; candidate_len <= *buffer_size; ++candidate_len) { - struct keyboard_cdc_CdcFrame candidate = keyboard_cdc_CdcFrame_init_zero; + keyboard_cdc_CdcFrame candidate = keyboard_cdc_CdcFrame_init_zero; pb_istream_t stream = pb_istream_from_buffer(buffer, candidate_len); if (!pb_decode(&stream, keyboard_cdc_CdcFrame_fields, &candidate)) { @@ -206,9 +196,12 @@ bool keyboard_proto_try_take_cdc_frame( } static bool keyboard_proto_build_hello_rsp_body( - struct keyboard_cdc_CdcPacketBody *body) + keyboard_cdc_CdcPacketBody *body) { - *body = keyboard_cdc_CdcPacketBody_init_zero; + { + keyboard_cdc_CdcPacketBody empty = keyboard_cdc_CdcPacketBody_init_zero; + *body = empty; + } body->which_body = KB_PROTO_BODY_TAG_HELLO_RSP; body->body.hello_rsp.protocol_version = 1U; body->body.hello_rsp.vendor_id = 0x1209U; @@ -221,9 +214,12 @@ static bool keyboard_proto_build_hello_rsp_body( static bool keyboard_proto_build_ack_body( uint32_t acked_type, - struct keyboard_cdc_CdcPacketBody *body) + keyboard_cdc_CdcPacketBody *body) { - *body = keyboard_cdc_CdcPacketBody_init_zero; + { + keyboard_cdc_CdcPacketBody empty = keyboard_cdc_CdcPacketBody_init_zero; + *body = empty; + } body->which_body = KB_PROTO_BODY_TAG_ACK; body->body.ack.acked_type = acked_type; return true; @@ -232,9 +228,12 @@ static bool keyboard_proto_build_ack_body( static bool keyboard_proto_build_error_body( uint32_t error_type, uint32_t error_code, - struct keyboard_cdc_CdcPacketBody *body) + keyboard_cdc_CdcPacketBody *body) { - *body = keyboard_cdc_CdcPacketBody_init_zero; + { + keyboard_cdc_CdcPacketBody empty = keyboard_cdc_CdcPacketBody_init_zero; + *body = empty; + } body->which_body = KB_PROTO_BODY_TAG_ERROR; body->body.error.error_type = error_type; body->body.error.error_code = (keyboard_cdc_ErrorCode)error_code; @@ -244,13 +243,16 @@ static bool keyboard_proto_build_error_body( bool keyboard_proto_build_function_key_event_body( uint16_t usage, bool pressed, - struct keyboard_cdc_CdcPacketBody *body) + keyboard_cdc_CdcPacketBody *body) { if (body == NULL) { return false; } - *body = keyboard_cdc_CdcPacketBody_init_zero; + { + keyboard_cdc_CdcPacketBody empty = keyboard_cdc_CdcPacketBody_init_zero; + *body = empty; + } body->which_body = KB_PROTO_BODY_TAG_FUNCTION_KEY_EVENT; body->body.function_key_event.usage = usage; body->body.function_key_event.action = pressed ? 1U : 0U; @@ -259,24 +261,27 @@ bool keyboard_proto_build_function_key_event_body( bool keyboard_proto_build_led_state_body( uint8_t led_mask, - struct keyboard_cdc_CdcPacketBody *body) + keyboard_cdc_CdcPacketBody *body) { if (body == NULL) { return false; } - *body = keyboard_cdc_CdcPacketBody_init_zero; + { + keyboard_cdc_CdcPacketBody empty = keyboard_cdc_CdcPacketBody_init_zero; + *body = empty; + } body->which_body = KB_PROTO_BODY_TAG_LED_STATE; body->body.led_state.led_mask = led_mask; return true; } static bool keyboard_proto_handle_bitmap( - const struct keyboard_cdc_CdcPacketBody *body, + const keyboard_cdc_CdcPacketBody *body, keyboard_proto_send_body_fn send_fn, void *user_data) { - struct keyboard_cdc_CdcPacketBody response; + keyboard_cdc_CdcPacketBody response; if (body->body.bitmap.usage_bitmap.size != KEYBOARD_PROTO_FUNCTION_BITMAP_SIZE) { keyboard_proto_build_error_body(KB_PROTO_PACKET_BITMAP, @@ -292,13 +297,13 @@ static bool keyboard_proto_handle_bitmap( } static bool keyboard_proto_handle_time_sync( - const struct keyboard_cdc_CdcPacketBody *body, + const keyboard_cdc_CdcPacketBody *body, enum keyboard_proto_transport transport, keyboard_proto_send_body_fn send_fn, void *user_data) { struct time_sync_update update; - struct keyboard_cdc_CdcPacketBody response; + keyboard_cdc_CdcPacketBody response; if (!time_manager_is_ready()) { keyboard_proto_build_error_body(KB_PROTO_PACKET_TIME_SYNC, @@ -326,11 +331,11 @@ static bool keyboard_proto_handle_time_sync( } static bool keyboard_proto_handle_theme_rgb( - const struct keyboard_cdc_CdcPacketBody *body, + const keyboard_cdc_CdcPacketBody *body, keyboard_proto_send_body_fn send_fn, void *user_data) { - struct keyboard_cdc_CdcPacketBody response; + keyboard_cdc_CdcPacketBody response; display_theme_event_submit((uint8_t)body->body.theme_rgb.red, (uint8_t)body->body.theme_rgb.green, @@ -341,12 +346,12 @@ static bool keyboard_proto_handle_theme_rgb( } bool keyboard_proto_handle_host_body( - const struct keyboard_cdc_CdcPacketBody *body, + const keyboard_cdc_CdcPacketBody *body, enum keyboard_proto_transport transport, keyboard_proto_send_body_fn send_fn, void *user_data) { - struct keyboard_cdc_CdcPacketBody response; + keyboard_cdc_CdcPacketBody response; if ((body == NULL) || (send_fn == NULL)) { return false; diff --git a/src/modules/usb_cdc_proto_module.c b/src/modules/usb_cdc_proto_module.c index 4042511..0c99dbc 100644 --- a/src/modules/usb_cdc_proto_module.c +++ b/src/modules/usb_cdc_proto_module.c @@ -32,7 +32,7 @@ static struct usb_cdc_proto_ctx g_usb_cdc = { }; static uint32_t keyboard_proto_packet_type_from_body( - const struct keyboard_cdc_CdcPacketBody *body) + const keyboard_cdc_CdcPacketBody *body) { switch (body->which_body) { case 1U: @@ -59,7 +59,7 @@ static uint32_t keyboard_proto_packet_type_from_body( } static bool usb_cdc_proto_send_body( - const struct keyboard_cdc_CdcPacketBody *body, + const keyboard_cdc_CdcPacketBody *body, void *user_data) { struct usb_cdc_proto_ctx *ctx = user_data; @@ -88,8 +88,8 @@ static bool usb_cdc_proto_send_body( static void usb_cdc_proto_process_rx_work(struct k_work *work) { - struct keyboard_cdc_CdcFrame frame; - struct keyboard_cdc_CdcPacketBody body; + keyboard_cdc_CdcFrame frame; + keyboard_cdc_CdcPacketBody body; ARG_UNUSED(work); @@ -162,7 +162,7 @@ static bool handle_module_state_event(const struct module_state_event *event) static bool handle_function_key_event(const struct function_key_event *event) { - struct keyboard_cdc_CdcPacketBody body; + keyboard_cdc_CdcPacketBody body; if (!g_usb_cdc.ready) { return false; @@ -180,7 +180,7 @@ static bool handle_function_key_event(const struct function_key_event *event) static bool handle_keyboard_led_event(const struct keyboard_led_event *event) { - struct keyboard_cdc_CdcPacketBody body; + keyboard_cdc_CdcPacketBody body; if (!g_usb_cdc.ready) { return false;