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