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 {