Zero-copy TX: span_writer packer, static buffers, no vector returns
This commit is contained in:
@@ -22,20 +22,21 @@ void dispatch_schedule_ms(uint32_t ms, std::function<void()> fn) {
|
||||
}
|
||||
|
||||
[[noreturn]] void dispatch_run(std::span<const handler_entry> handlers) {
|
||||
std::unordered_map<int8_t, std::vector<std::vector<uint8_t>> (*)(uint32_t, std::span<const uint8_t>)> handler_map;
|
||||
std::unordered_map<int8_t, handler_fn> handler_map;
|
||||
for (auto& entry : handlers) {
|
||||
handler_map[entry.type_id] = entry.handle;
|
||||
}
|
||||
|
||||
static usb_cdc usb;
|
||||
static static_vector<uint8_t, 256> usb_rx_buf;
|
||||
static uint8_t tx_buf[1514];
|
||||
|
||||
net_set_handler([&](std::span<const uint8_t> payload) -> std::vector<std::vector<uint8_t>> {
|
||||
net_set_handler([&](std::span<const uint8_t> payload, span_writer &out) -> size_t {
|
||||
auto msg = try_decode(payload.data(), payload.size());
|
||||
if (!msg) return {};
|
||||
if (!msg) return 0;
|
||||
auto it = handler_map.find(msg->type_id);
|
||||
if (it == handler_map.end()) return {};
|
||||
return it->second(msg->message_id, msg->payload);
|
||||
if (it == handler_map.end()) return 0;
|
||||
return it->second(msg->message_id, msg->payload, out);
|
||||
});
|
||||
|
||||
while (true) {
|
||||
@@ -62,13 +63,16 @@ void dispatch_schedule_ms(uint32_t ms, std::function<void()> fn) {
|
||||
|
||||
auto it = handler_map.find(msg->type_id);
|
||||
if (it != handler_map.end()) {
|
||||
for (auto& response : it->second(msg->message_id, msg->payload)) {
|
||||
if (response.size() > usb.tx.free()) {
|
||||
auto err = encode_response(msg->message_id,
|
||||
DeviceError{2, "response too large: " + std::to_string(response.size())});
|
||||
usb.send(err);
|
||||
span_writer out(tx_buf, sizeof(tx_buf));
|
||||
size_t resp_len = it->second(msg->message_id, msg->payload, out);
|
||||
if (resp_len > 0) {
|
||||
if (resp_len > usb.tx.free()) {
|
||||
span_writer err_out(tx_buf, sizeof(tx_buf));
|
||||
size_t err_len = encode_response_into(err_out, msg->message_id,
|
||||
DeviceError{2, "response too large: " + std::to_string(resp_len)});
|
||||
usb.send(std::span<const uint8_t>{tx_buf, err_len});
|
||||
} else {
|
||||
usb.send(response);
|
||||
usb.send(std::span<const uint8_t>{tx_buf, resp_len});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user