blob: f4468abf7b80ffd87728e351226d8142f1fde4bb [file] [log] [blame]
Alex Perry5f474f22020-02-01 12:14:24 -08001#include "aos/network/web_proxy_utils.h"
2
Stephan Pleinesf63bde82024-01-13 15:59:33 -08003namespace aos::web_proxy {
Alex Perry5f474f22020-02-01 12:14:24 -08004
James Kuszmaul1ec74432020-07-30 20:26:45 -07005namespace {
Alex Perry5f474f22020-02-01 12:14:24 -08006// Recommended max size is 64KiB for compatibility reasons. 256KiB theoretically
7// works on chrome but seemed to have some consistency issues. Picked a size in
8// the middle which seems to work.
9constexpr size_t kPacketSize = 125000;
10
Austin Schuhd16ef442021-04-25 14:44:42 -070011// Max header size we have seen is 72 bytes, followed by 48 bytes of scratch
12// space.
13constexpr size_t kMaxHeaderSize = 72 + 48;
14
James Kuszmaul1ec74432020-07-30 20:26:45 -070015int GetPacketCountFromSize(const int packet_size) {
16 return packet_size / kPacketSize + 1;
17}
18
19flatbuffers::Offset<flatbuffers::Vector<uint8_t>> FillOutPacketVector(
20 flatbuffers::FlatBufferBuilder *fbb, absl::Span<const uint8_t> span,
21 const int packet_index) {
22 flatbuffers::Offset<flatbuffers::Vector<uint8_t>> data_offset;
23 if (kPacketSize * (packet_index + 1) < span.size()) {
24 data_offset = fbb->CreateVector(
25 static_cast<const uint8_t *>(span.data()) + kPacketSize * packet_index,
26 kPacketSize);
27 } else {
28 const int prefix_size = kPacketSize * packet_index;
29 data_offset = fbb->CreateVector(
30 static_cast<const uint8_t *>(span.data()) + prefix_size,
31 span.size() - prefix_size);
32 }
33 return data_offset;
34}
35} // namespace
36
Alex Perry5f474f22020-02-01 12:14:24 -080037int GetPacketCount(const Context &context) {
James Kuszmaul1ec74432020-07-30 20:26:45 -070038 return GetPacketCountFromSize(context.size);
Alex Perry5f474f22020-02-01 12:14:24 -080039}
40
Austin Schuhd16ef442021-04-25 14:44:42 -070041size_t PackedMessageSize(const Context &context, int packet_index) {
42 // Make sure the final size is aligned because flatbuffers will align it up
43 // otherwise.
44 constexpr size_t kAlignment = 8;
45 if (kPacketSize * (packet_index + 1) < context.size) {
46 return (kPacketSize + kMaxHeaderSize + kAlignment - 1) & ~(kAlignment - 1);
47 } else {
48 const int prefix_size = kPacketSize * packet_index;
49 return (context.size - prefix_size + kMaxHeaderSize + kAlignment - 1) &
50 ~(kAlignment - 1);
51 }
52}
53
Alex Perry5f474f22020-02-01 12:14:24 -080054flatbuffers::Offset<MessageHeader> PackMessage(
55 flatbuffers::FlatBufferBuilder *fbb, const Context &context,
56 int channel_index, int packet_index) {
James Kuszmaul1ec74432020-07-30 20:26:45 -070057 const int packet_count = GetPacketCount(context);
58 const flatbuffers::Offset<flatbuffers::Vector<uint8_t>> data_offset =
59 FillOutPacketVector(
60 fbb,
61 absl::Span<const uint8_t>{static_cast<const uint8_t *>(context.data),
62 context.size},
63 packet_index);
Alex Perry5f474f22020-02-01 12:14:24 -080064
65 MessageHeader::Builder message_header_builder(*fbb);
66 message_header_builder.add_channel_index(channel_index);
67 message_header_builder.add_queue_index(context.queue_index);
68 message_header_builder.add_packet_count(packet_count);
69 message_header_builder.add_packet_index(packet_index);
70 message_header_builder.add_data(data_offset);
71 message_header_builder.add_length(context.size);
James Kuszmaul48413bf2020-09-01 19:19:05 -070072 message_header_builder.add_monotonic_sent_time(
73 context.monotonic_event_time.time_since_epoch().count());
Alex Perry5f474f22020-02-01 12:14:24 -080074
75 return message_header_builder.Finish();
76}
77
James Kuszmaul1ec74432020-07-30 20:26:45 -070078std::vector<FlatbufferDetachedBuffer<MessageHeader>> PackBuffer(
79 absl::Span<const uint8_t> span) {
80 flatbuffers::FlatBufferBuilder fbb;
81 std::vector<FlatbufferDetachedBuffer<MessageHeader>> buffers;
82 const int packet_count = GetPacketCountFromSize(span.size());
83 for (int ii = 0; ii < packet_count; ++ii) {
84 const flatbuffers::Offset<flatbuffers::Vector<uint8_t>> data_offset =
85 FillOutPacketVector(&fbb, span, ii);
86
87 MessageHeader::Builder message_header_builder(fbb);
88 message_header_builder.add_packet_count(packet_count);
89 message_header_builder.add_packet_index(ii);
90 message_header_builder.add_data(data_offset);
91 message_header_builder.add_length(span.size());
92
93 fbb.Finish(message_header_builder.Finish());
94
95 buffers.emplace_back(fbb.Release());
96 }
97 return buffers;
98}
99
Stephan Pleinesf63bde82024-01-13 15:59:33 -0800100} // namespace aos::web_proxy