Skip to content

Commit ce3fc80

Browse files
committed
dfu: share upload framing across transports
* move firmware-upload command parsing and ACK framing into common DFU code so WebUSB and WebSockets use the same upload protocol * update WebSockets handlers to return fixed-size owned responses * refactor bootloader WebUSB so HWA only owns USB buffers and endpoint plumbing, while the instance layer owns RX queuing, upload parsing, and DFU writer state
1 parent 47c4254 commit ce3fc80

40 files changed

Lines changed: 1808 additions & 533 deletions

File tree

app/bootloader/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../common/src/metadata ${CMAKE_CURREN
99
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../common/src/signaling ${CMAKE_CURRENT_BINARY_DIR}/signaling_common)
1010
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../common/src/dfu/writer ${CMAKE_CURRENT_BINARY_DIR}/dfu_writer)
1111
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../common/src/dfu/dfu_stream_parser ${CMAKE_CURRENT_BINARY_DIR}/dfu_stream_parser)
12+
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../common/src/dfu/upload ${CMAKE_CURRENT_BINARY_DIR}/dfu_upload)
1213
add_subdirectory(src/io/indicators)
1314
add_subdirectory(src/dfu/direct_update_writer)
1415
add_subdirectory(src/signaling)
@@ -19,6 +20,7 @@ target_link_libraries(app
1920
opendeck_common_metadata
2021
opendeck_common_signaling
2122
opendeck_common_dfu_dfu_stream_parser
23+
opendeck_common_dfu_upload
2224
opendeck_bootloader_io_indicators
2325
opendeck_bootloader_dfu_direct_update_writer
2426
opendeck_bootloader_signaling

app/bootloader/src/dfu/direct_update_writer/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ target_sources(opendeck_bootloader_dfu_direct_update_writer PRIVATE
66
)
77

88
target_link_libraries(opendeck_bootloader_dfu_direct_update_writer
9-
PRIVATE
9+
PUBLIC
1010
opendeck_common_dfu_dfu_stream_parser
1111
opendeck_common_dfu_writer
1212
opendeck_common_metadata

app/bootloader/src/protocols/websockets/handler/firmware_upload/firmware_upload_handler.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,17 @@ using namespace opendeck::bootloader::protocols::websockets::firmware_upload;
1212
namespace
1313
{
1414
LOG_MODULE_REGISTER(opendeck_bootloader_websockets_firmware_upload, CONFIG_OPENDECK_LOG_LEVEL); // NOLINT
15+
16+
static_assert(sizeof(opendeck::common::dfu::upload::Ack) <=
17+
opendeck::common::protocols::websockets::Handler::RESPONSE_SIZE);
1518
} // namespace
1619

1720
FirmwareUploadHandler::FirmwareUploadHandler(bootloader::dfu::direct_update_writer::DirectUpdateWriter& direct_update_writer)
1821
: _firmware_upload(direct_update_writer)
1922
{}
2023

21-
std::optional<std::span<const uint8_t>> FirmwareUploadHandler::handle_frame(std::span<const uint8_t> data, [[maybe_unused]] uint32_t session_id)
24+
std::optional<FirmwareUploadHandler::Response> FirmwareUploadHandler::handle_frame(std::span<const uint8_t> data,
25+
[[maybe_unused]] uint32_t session_id)
2226
{
2327
const auto response = _firmware_upload.handle(data);
2428

@@ -27,14 +31,19 @@ std::optional<std::span<const uint8_t>> FirmwareUploadHandler::handle_frame(std:
2731
return std::nullopt;
2832
}
2933

30-
_response = response->response;
31-
3234
if (response->finished)
3335
{
3436
LOG_INF("Bootloader network DFU upload complete");
3537
}
3638

37-
return std::span<const uint8_t>(_response.data(), _response.size());
39+
const auto ack_bytes = opendeck::common::dfu::upload::ack_to_bytes(response->response);
40+
41+
Response handler_response = {};
42+
handler_response.size = ack_bytes.size();
43+
44+
std::copy(ack_bytes.begin(), ack_bytes.end(), handler_response.data.begin());
45+
46+
return handler_response;
3847
}
3948

4049
void FirmwareUploadHandler::on_close_session([[maybe_unused]] uint32_t session_id)

app/bootloader/src/protocols/websockets/handler/firmware_upload/firmware_upload_handler.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88
#include "bootloader/src/dfu/direct_update_writer/instance/impl/direct_update_writer.h"
99
#include "common/src/protocols/websockets/handler/handler.h"
1010
#include "common/src/protocols/websockets/firmware_upload/firmware_upload.h"
11-
#include "common/src/protocols/websockets/shared/firmware_upload.h"
1211

1312
namespace opendeck::bootloader::protocols::websockets::firmware_upload
1413
{
1514
/**
16-
* @brief Handles direct firmware upload WebSockets frames in the bootloader.
15+
* @brief Handles bootloader-side WebSockets DFU directly into the application slot.
16+
*
17+
* Unlike the firmware-side handler, the bootloader is already running in the update environment, so it
18+
* installs the validated firmware image directly and does not need to request a reboot into another mode.
1719
*/
1820
class FirmwareUploadHandler : public opendeck::common::protocols::websockets::Handler
1921
{
@@ -31,9 +33,9 @@ namespace opendeck::bootloader::protocols::websockets::firmware_upload
3133
* @param data Frame payload bytes.
3234
* @param session_id Unused bootloader WebSockets session id.
3335
*
34-
* @return ACK frame when the firmware-upload frame was handled, otherwise `std::nullopt`.
36+
* @return Serialized DFU ACK when the firmware-upload frame was handled, otherwise `std::nullopt`.
3537
*/
36-
std::optional<std::span<const uint8_t>> handle_frame(std::span<const uint8_t> data, uint32_t session_id) override;
38+
std::optional<Response> handle_frame(std::span<const uint8_t> data, uint32_t session_id) override;
3739

3840
/**
3941
* @brief Aborts any active firmware upload.
@@ -43,7 +45,6 @@ namespace opendeck::bootloader::protocols::websockets::firmware_upload
4345
void on_close_session(uint32_t session_id) override;
4446

4547
private:
46-
opendeck::common::protocols::websockets::FirmwareUpload _firmware_upload;
47-
opendeck::common::protocols::websockets::FirmwareUploadAck _response = {};
48+
opendeck::common::protocols::websockets::FirmwareUpload _firmware_upload;
4849
};
4950
} // namespace opendeck::bootloader::protocols::websockets::firmware_upload

app/bootloader/src/protocols/websockets/instance/impl/websockets.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
#pragma once
77

8+
#include "common/src/dfu/upload/shared/common.h"
89
#include "common/src/protocols/websockets/instance/impl/websockets.h"
910
#include "common/src/protocols/websockets/shared/buffers.h"
10-
#include "common/src/protocols/websockets/shared/firmware_upload.h"
1111

1212
namespace opendeck::bootloader::protocols::websockets
1313
{
@@ -33,8 +33,8 @@ namespace opendeck::bootloader::protocols::websockets
3333

3434
private:
3535
using WebSocketsBuffers = opendeck::common::protocols::websockets::Buffers<
36-
opendeck::common::protocols::websockets::FIRMWARE_UPLOAD_FRAME_SIZE,
37-
opendeck::common::protocols::websockets::FIRMWARE_UPLOAD_ACK_SIZE,
36+
opendeck::common::dfu::upload::FRAME_SIZE,
37+
sizeof(opendeck::common::dfu::upload::Ack),
3838
4>;
3939

4040
opendeck::common::protocols::websockets::BuffersBase& buffers() override

app/bootloader/src/protocols/webusb/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ if(CONFIG_PROJECT_BOOTLOADER_SUPPORT_USB_DFU)
66
instance/impl/webusb.cpp
77
)
88

9+
target_link_libraries(opendeck_bootloader_protocols_webusb
10+
PUBLIC
11+
opendeck_common_dfu_upload
12+
)
13+
914
if(CONFIG_HW_BUILD)
1015
add_subdirectory(hwa/hw)
1116

app/bootloader/src/protocols/webusb/builder/hw/builder_hw.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ namespace opendeck::bootloader::protocols::webusb
2323
* @param direct_update_writer Direct-update writer that receives incoming DFU bytes.
2424
*/
2525
explicit Builder(bootloader::dfu::direct_update_writer::DirectUpdateWriter& direct_update_writer)
26-
: _hwa(direct_update_writer)
27-
, _instance(_hwa)
26+
: _instance(_hwa, direct_update_writer)
2827
{}
2928

3029
/**

app/bootloader/src/protocols/webusb/hwa/hw/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ target_sources(opendeck_bootloader_protocols_webusb_hwa_hw PRIVATE
77

88
target_link_libraries(opendeck_bootloader_protocols_webusb_hwa_hw
99
PRIVATE
10-
opendeck_common_dfu_dfu_stream_parser
10+
opendeck_common_dfu_upload
1111
opendeck_common_metadata
1212
zlibs_drivers_usb_hw
1313
zephyr_interface

0 commit comments

Comments
 (0)