Skip to content

Commit

Permalink
pw_hdlc: Helpers for buffer sizing
Browse files Browse the repository at this point in the history
Introduces helpers for sizing buffers that account for HDLC encoding
overhead.

Change-Id: Idfd153a836fedf3835e8961eb168067eee6db2f4
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/101500
Commit-Queue: Auto-Submit <[email protected]>
Reviewed-by: Wyatt Hepler <[email protected]>
Pigweed-Auto-Submit: Armando Montanez <[email protected]>
  • Loading branch information
armandomontanez authored and CQ Bot Account committed Jul 15, 2022
1 parent 1c7a18d commit 1cab1b4
Show file tree
Hide file tree
Showing 14 changed files with 549 additions and 66 deletions.
14 changes: 14 additions & 0 deletions pw_hdlc/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pw_cc_library(
],
hdrs = [
"public/pw_hdlc/decoder.h",
"public/pw_hdlc/encoded_size.h",
"public/pw_hdlc/encoder.h",
],
includes = ["public"],
Expand Down Expand Up @@ -102,6 +103,19 @@ cc_test(
],
)

cc_test(
name = "encoded_size_test",
srcs = ["encoded_size_test.cc"],
deps = [
":pw_hdlc",
"//pw_bytes",
"//pw_result",
"//pw_stream",
"//pw_unit_test",
"//pw_varint",
],
)

cc_test(
name = "wire_packet_parser_test",
srcs = ["wire_packet_parser_test.cc"],
Expand Down
25 changes: 25 additions & 0 deletions pw_hdlc/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ config("default_config") {
group("pw_hdlc") {
public_deps = [
":decoder",
":encoded_size",
":encoder",
]
}
Expand All @@ -37,6 +38,17 @@ pw_source_set("common") {
visibility = [ ":*" ]
}

pw_source_set("encoded_size") {
public_configs = [ ":default_config" ]
public = [ "public/pw_hdlc/encoded_size.h" ]
public_deps = [
":common",
"$dir_pw_bytes",
"$dir_pw_span",
"$dir_pw_varint",
]
}

pw_source_set("decoder") {
public_configs = [ ":default_config" ]
public = [ "public/pw_hdlc/decoder.h" ]
Expand Down Expand Up @@ -68,6 +80,7 @@ pw_source_set("encoder") {
dir_pw_status,
dir_pw_stream,
]
deps = [ ":encoded_size" ]
friend = [ ":*" ]
}

Expand Down Expand Up @@ -111,6 +124,7 @@ pw_test_group("tests") {
":encoder_test",
":decoder_test",
":rpc_channel_test",
":encoded_size_test",
":wire_packet_parser_test",
]
group_deps = [
Expand All @@ -120,6 +134,17 @@ pw_test_group("tests") {
]
}

pw_test("encoded_size_test") {
deps = [
":pw_hdlc",
"$dir_pw_bytes",
"$dir_pw_result",
"$dir_pw_stream",
"$dir_pw_varint",
]
sources = [ "encoded_size_test.cc" ]
}

pw_test("encoder_test") {
deps = [ ":pw_hdlc" ]
sources = [ "encoder_test.cc" ]
Expand Down
2 changes: 1 addition & 1 deletion pw_hdlc/decoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ Status Decoder::CheckFrame() const {
return Status::Unavailable();
}

if (current_frame_size_ < Frame::kMinSizeBytes) {
if (current_frame_size_ < Frame::kMinContentSizeBytes) {
PW_LOG_ERROR("Received %lu-byte frame; frame must be at least 6 bytes",
static_cast<unsigned long>(current_frame_size_));
return Status::DataLoss();
Expand Down
42 changes: 42 additions & 0 deletions pw_hdlc/docs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,48 @@ Decodes one or more HDLC frames from a stream of data.
:param Uint8Array data: bytes to be decoded.
:yields: Valid HDLC frames, logging any errors.

Allocating buffers
------------------
Since HDLC's encoding overhead changes with payload size and what data is being
encoded, this module provides helper functions that are useful for determining
the size of buffers by providing worst-case sizes of frames given a certain
payload size and vice-versa.

.. code-block:: cpp
#include "pw_assert/check.h"
#include "pw_bytes/span.h"
#include "pw_hdlc/encoder"
#include "pw_hdlc/encoded_size.h"
#include "pw_status/status.h"
// The max on-the-wire size in bytes of a single HDLC frame after encoding.
constexpr size_t kMtu = 512;
constexpr size_t kRpcEncodeBufferSize = pw::hdlc::MaxSafePayloadSize(kMtu);
std::array<std::byte, kRpcEncodeBufferSize> rpc_encode_buffer;
// Any data encoded to this buffer is guaranteed to fit in the MTU after
// HDLC encoding.
pw::ConstByteSpan GetRpcEncodeBuffer() {
return rpc_encode_buffer;
}
The HDLC ``Decoder`` has its own helper for allocating a buffer since it doesn't
need the entire escaped frame in-memory to decode, and therefore has slightly
lower overhead.

.. code-block:: cpp
#include "pw_hdlc/decoder.h"
// The max on-the-wire size in bytes of a single HDLC frame after encoding.
constexpr size_t kMtu = 512;
// Create a decoder given the MTU constraint.
constexpr size_t kDecoderBufferSize =
pw::hdlc::Decoder::RequiredBufferSizeForFrameSize(kMtu);
pw::hdlc::DecoderBuffer<kDecoderBufferSize> decoder;
Additional features
===================

Expand Down
Loading

0 comments on commit 1cab1b4

Please sign in to comment.