Skip to content

Commit

Permalink
Add multipart message constants
Browse files Browse the repository at this point in the history
  • Loading branch information
tuokri committed Nov 16, 2023
1 parent 8b29715 commit 052f621
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 16 deletions.
5 changes: 5 additions & 0 deletions include/umb/constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ constexpr uint16_t g_max_message_count = std::numeric_limits<uint16_t>::max() -
// Max size of dynamic field payload part.
constexpr auto g_max_dynamic_size = 255;

// Message part field for single part messages is always constant.
constexpr auto g_part_single_part = 255;
// Value indicating final part of multipart message.
constexpr auto g_part_multi_part_end = 254;

constexpr size_t g_sizeof_byte = 1;
constexpr size_t g_sizeof_int32 = 4;
constexpr size_t g_sizeof_uint16 = 2;
Expand Down
2 changes: 2 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,8 @@ render(
data["packet_size"] = ::umb::g_packet_size;
data["sizeof_uscript_char"] = ::umb::g_sizeof_uscript_char;
data["max_dynamic_size"] = ::umb::g_max_dynamic_size;
data["part_single_part"] = ::umb::g_part_single_part;
data["part_multi_part_end"] = ::umb::g_part_multi_part_end;
data["generate_meta_cpp"] = g_generate_meta_cpp;

const auto prog_dir = boost::dll::program_location().parent_path();
Expand Down
5 changes: 3 additions & 2 deletions templates/uscript.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class {{ class_name }} extends Object
const HEADER_SIZE = {{ header_size }};
const PAYLOAD_SIZE = {{ payload_size }};
const PACKET_SIZE = {{ packet_size }};
const PART_SINGLE_PART = {{ part_single_part }};

const {{ uscript_message_type_prefix }}_None = 0;
{% for message in messages %}
Expand All @@ -36,9 +37,9 @@ struct Packet
// should be sent: Size=0, Part=0, Type=0 ({{ uscript_message_type_prefix }}_None).
var byte Size;

// 255 for single-part messages. 0-254 for multipart messages. Incremented
// {{ part_single_part }} for single-part messages. 0-254 for multipart messages. Incremented
// for each part. Parts must be sent in an order that matches this field.
// The final multipart sequence indicator message has Part set to 0.
// The final multipart sequence indicator message has Part set to {{ part_multi_part_end }}.
var byte Part;

// 16 bit field. 2 bytes. Maximum number of supported messages
Expand Down
2 changes: 1 addition & 1 deletion templates/uscript_encode_static_packet_header.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// Encode packet header.
Bytes[{{ pad(x, sz) }}{{ x }}] = {{ sz }};
{% set x = x + 1 %}
Bytes[{{ pad(x, sz) }}{{ x }}] = {{ 0 }}; // Part.
Bytes[{{ pad(x, sz) }}{{ x }}] = PART_SINGLE_PART; // Part.
{% set x = x + 1 %}
Bytes[{{ pad(x, sz) }}{{ x }}] = {{ uscript_message_type_prefix }}_{{ message.name }} & 0xff;
{% set x = x + 1 %}
Expand Down
2 changes: 1 addition & 1 deletion templates/uscript_test_mutator.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ final simulated function int Test_{{ message.name }}()
{{ cls }}{{ message.name }}_ToMultiBytes({{ msg1 }}, DynamicBytes);
`ulog("{{ message.name }}: DynamicBytes.Length =" @ DynamicBytes.Length);
`ulog("{{ message.name }}: DynamicBytes[0] =" @ string(DynamicBytes[0]));
if ((DynamicBytes.Length < 255) && (DynamicBytes.Length != DynamicBytes[0]))
if ((DynamicBytes.Length < PACKET_SIZE) && (DynamicBytes.Length != DynamicBytes[0]))
{
`ulog("##CHECK FAILED##: DYNAMIC CODING: dynamic length mismatch");
for (X = 0; X < Max(DynamicBytes.Length, DynamicBytes[0]); ++X)
Expand Down
44 changes: 32 additions & 12 deletions tests/umb_echo_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include <boost/asio/detached.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/read.hpp>
#include <boost/asio/signal_set.hpp>
#include <boost/asio/write.hpp>

Expand All @@ -66,32 +67,50 @@ awaitable<void> echo(tcp::socket socket)
try
{
std::shared_ptr<umb::Message> msg;
std::array<umb::byte, 2048> data{};
std::array<umb::byte, 2048> msg_buf{};
// TODO: should we read into a larger buffer?
std::array<umb::byte, 255> data{};
std::vector<umb::byte> msg_buf{};

for (;;)
{
std::size_t n = co_await socket.async_read_some(boost::asio::buffer(data),
use_awaitable);
// 1. read 1 byte, it should be the packet size.
// - if 255, we can expect to receive more than 255 bytes!
// - next byte indicates part, value (0-254), 254 end marker always
// - elif < 255, expect only that amount
// - part should always be 255

// TODO: read entire header here.
co_await boost::asio::async_read(
socket, boost::asio::buffer(data),
boost::asio::transfer_exactly(umb::g_header_size), use_awaitable);

// std::size_t n = co_await socket.async_read_some(boost::asio::buffer(data),
// use_awaitable);

// Parse UMB message.
// Serialize it to bytes, send it back.

const auto size = static_cast<size_t>(data[0]);
std::cout << std::format("size: {}\n", size);

if (n < size)
{
std::cout << std::format("got {} bytes, size indicates {}, waiting for more...\n",
n, size);
throw std::runtime_error("TODO: handle this");
}

const auto part = data[1];
std::cout << std::format("part: {}\n", part);

const auto type = static_cast<testmessages::umb::MessageType>(
data[2] | (data[3] << 8));

if (size == 0)
{
std::cout << std::format("got invalid size: {}\n", size);
throw std::runtime_error("TODO: handle this");
}

const auto read_num = size - umb::g_header_size;
auto d = std::span{data.begin() + umb::g_header_size, data.size() - umb::g_header_size};
co_await boost::asio::async_read(
socket, boost::asio::buffer(d),
boost::asio::transfer_exactly(read_num), use_awaitable);

#if WINDOWS
const auto mt_str = std::to_string(static_cast<uint16_t>(type));
#else
Expand Down Expand Up @@ -142,7 +161,8 @@ awaitable<void> echo(tcp::socket socket)
const auto bytes_out = msg->to_bytes();
const auto size_out = msg->serialized_size();

co_await async_write(socket, boost::asio::buffer(bytes_out, size_out), use_awaitable);
co_await async_write(socket,
boost::asio::buffer(bytes_out, size_out), use_awaitable);
}
}
catch (const std::exception& e)
Expand Down

0 comments on commit 052f621

Please sign in to comment.