pw_rpc: ChannelOutput MTU function; docs
- Add a MaximumTransmissionUnit() function to the ChannelOutput API.
Implementations specify the largest buffer they can allocate in an
AcquireBuffer() call. This information will eventually be exposed to
RPC users through the call object.
- Document the new ChannelOutput API.
Change-Id: I46272560a7f267d5b8ae345f24c6f9ef7cafcc4d
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/80720
Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com>
Reviewed-by: Alexei Frolov <frolv@google.com>
Commit-Queue: Wyatt Hepler <hepler@google.com>
diff --git a/pw_hdlc/public/pw_hdlc/rpc_channel.h b/pw_hdlc/public/pw_hdlc/rpc_channel.h
index 03cd7ad..cd6c16c 100644
--- a/pw_hdlc/public/pw_hdlc/rpc_channel.h
+++ b/pw_hdlc/public/pw_hdlc/rpc_channel.h
@@ -42,6 +42,8 @@
buffer_(buffer),
address_(address) {}
+ size_t MaximumTransmissionUnit() override { return buffer_.size(); }
+
std::span<std::byte> AcquireBuffer() override { return buffer_; }
Status SendAndReleaseBuffer(std::span<const std::byte> buffer) override {
@@ -70,6 +72,8 @@
const char* channel_name)
: ChannelOutput(channel_name), writer_(writer), address_(address) {}
+ size_t MaximumTransmissionUnit() override { return buffer_.size(); }
+
std::span<std::byte> AcquireBuffer() override { return buffer_; }
Status SendAndReleaseBuffer(std::span<const std::byte> buffer) override {
diff --git a/pw_rpc/channel_test.cc b/pw_rpc/channel_test.cc
index 3edd5a7..7a54bd1 100644
--- a/pw_rpc/channel_test.cc
+++ b/pw_rpc/channel_test.cc
@@ -27,6 +27,7 @@
class NameTester : public ChannelOutput {
public:
NameTester(const char* name) : ChannelOutput(name) {}
+ size_t MaximumTransmissionUnit() override { return 0; }
std::span<std::byte> AcquireBuffer() override { return {}; }
Status SendAndReleaseBuffer(std::span<const std::byte>) override {
return OkStatus();
diff --git a/pw_rpc/docs.rst b/pw_rpc/docs.rst
index 6869470..67008cf 100644
--- a/pw_rpc/docs.rst
+++ b/pw_rpc/docs.rst
@@ -1051,3 +1051,33 @@
* ``pw_rpc.common` which can be enabled via ``CONFIG_PIGWEED_RPC_COMMON=y``.
* ``pw_rpc.synchronized_channel_output`` which can be enabled via
``CONFIG_PIGWEED_RPC_SYNCHRONIZED_CHANNEL_OUTPUT=y``.
+
+ChannelOutput API
+=================
+``pw_rpc`` endpoints sends packets using the :cpp:class:`ChannelOutput`
+interface.
+
+.. cpp:class:: pw::rpc::ChannelOutput
+
+ pw_rpc endpoints use the ``ChannelOutput`` class to send packets. Systems that
+ integrate pw_rpc must use one or more ``ChannelOutput`` instances.
+
+ .. cpp:function:: virtual size_t MaximumTransmissionUnit()
+
+ Returns the size of the largest buffer that :cpp:func:`AcquireBuffer` can
+ allocate.
+
+ .. cpp:function:: virtual std::byte* AcquireBuffer(size_t size_bytes)
+
+ Acquires a buffer of the specified size into which to write an outgoing RPC
+ packet. If a buffer of the specified size cannot be allocated, returns
+ nullptr. The implementation is expected to handle synchronization if
+ necessary.
+
+ .. cpp:function:: virtual Status SendAndReleaseBuffer(std::span<const std::byte> buffer)
+
+ Sends the contents of a buffer previously obtained from
+ :cpp:func:`AcquireBuffer`. This may be called with an empty span, in which
+ case the buffer should be released without sending any data. Returns OK if
+ further packets may be sent or any other status if the Channel is no longer
+ able to send packets.
diff --git a/pw_rpc/method_test.cc b/pw_rpc/method_test.cc
index 823ad08..792e0a3 100644
--- a/pw_rpc/method_test.cc
+++ b/pw_rpc/method_test.cc
@@ -52,6 +52,7 @@
public:
constexpr NullChannelOutput() : ChannelOutput("NullChannelOutput") {}
+ size_t MaximumTransmissionUnit() override { return 0; }
ByteSpan AcquireBuffer() override { return {}; }
Status SendAndReleaseBuffer(ConstByteSpan) override { return OkStatus(); }
} channel_output;
diff --git a/pw_rpc/public/pw_rpc/channel.h b/pw_rpc/public/pw_rpc/channel.h
index 4d61ad6..fc4b5c3 100644
--- a/pw_rpc/public/pw_rpc/channel.h
+++ b/pw_rpc/public/pw_rpc/channel.h
@@ -22,13 +22,6 @@
#include "pw_status/status.h"
namespace pw::rpc {
-namespace internal {
-
-class BaseClientCall;
-
-} // namespace internal
-
-class Client;
class ChannelOutput {
public:
@@ -40,7 +33,10 @@
constexpr const char* name() const { return name_; }
- // Acquire a buffer into which to write an outgoing RPC packet. The
+ // Returns the maximum buffer size that this ChannelOutput can support.
+ virtual size_t MaximumTransmissionUnit() { return 0; }
+
+ // Acquires a buffer into which to write an outgoing RPC packet. The
// implementation is expected to handle synchronization if necessary.
virtual std::span<std::byte> AcquireBuffer()
PW_LOCKS_EXCLUDED(internal::rpc_lock()) = 0;
diff --git a/pw_rpc/public/pw_rpc/internal/fake_channel_output.h b/pw_rpc/public/pw_rpc/internal/fake_channel_output.h
index e7f6dd2..40febcf 100644
--- a/pw_rpc/public/pw_rpc/internal/fake_channel_output.h
+++ b/pw_rpc/public/pw_rpc/internal/fake_channel_output.h
@@ -146,6 +146,8 @@
private:
friend class rpc::FakeServer;
+ size_t MaximumTransmissionUnit() final { return encoding_buffer_.size(); }
+
ByteSpan AcquireBuffer() final;
// Processes buffer according to packet type and `return_after_packet_count_`
diff --git a/pw_rpc/public/pw_rpc/internal/test_utils.h b/pw_rpc/public/pw_rpc/internal/test_utils.h
index 9c0f48b..24903e8 100644
--- a/pw_rpc/public/pw_rpc/internal/test_utils.h
+++ b/pw_rpc/public/pw_rpc/internal/test_utils.h
@@ -39,6 +39,8 @@
: ChannelOutput(name), sent_data_ {}
{}
+ size_t MaximumTransmissionUnit() override { return buffer_size(); }
+
std::span<std::byte> AcquireBuffer() override { return buffer_; }
Status SendAndReleaseBuffer(std::span<const std::byte> buffer) override {
diff --git a/pw_rpc/public/pw_rpc/synchronized_channel_output.h b/pw_rpc/public/pw_rpc/synchronized_channel_output.h
index c67fe19..863b94c 100644
--- a/pw_rpc/public/pw_rpc/synchronized_channel_output.h
+++ b/pw_rpc/public/pw_rpc/synchronized_channel_output.h
@@ -33,6 +33,10 @@
constexpr SynchronizedChannelOutput(sync::Mutex& mutex, Args&&... args)
: BaseChannelOutput(std::forward<Args>(args)...), mutex_(mutex) {}
+ size_t MaximumTransmissionUnit() final {
+ return BaseChannelOutput::MaximumTransmissionUnit();
+ }
+
std::span<std::byte> AcquireBuffer() final PW_EXCLUSIVE_LOCK_FUNCTION() {
mutex_.lock();
return BaseChannelOutput::AcquireBuffer();
diff --git a/pw_rpc/size_report/server_only.cc b/pw_rpc/size_report/server_only.cc
index 27e0c7d..a516124 100644
--- a/pw_rpc/size_report/server_only.cc
+++ b/pw_rpc/size_report/server_only.cc
@@ -24,6 +24,8 @@
public:
Output() : ChannelOutput("output") {}
+ size_t MaximumTransmissionUnit() override { return sizeof(buffer_); }
+
std::span<std::byte> AcquireBuffer() override { return buffer_; }
pw::Status SendAndReleaseBuffer(std::span<const std::byte> buffer) override {
diff --git a/pw_rpc/size_report/server_with_echo_service.cc b/pw_rpc/size_report/server_with_echo_service.cc
index a1e9b50..caaf34f 100644
--- a/pw_rpc/size_report/server_with_echo_service.cc
+++ b/pw_rpc/size_report/server_with_echo_service.cc
@@ -27,6 +27,8 @@
public:
Output() : ChannelOutput("output") {}
+ size_t MaximumTransmissionUnit() override { return sizeof(buffer_); }
+
std::span<std::byte> AcquireBuffer() override { return buffer_; }
pw::Status SendAndReleaseBuffer(std::span<const std::byte> buffer) override {