pw_rpc: Update protocol for server streams

Update the server-to-client RPC packet types so that the packet type
unambiguously indicates whether it is the first or last packet. This is
already the case for client-to-server RPC packet types.

- Have RESPONSE always be the last packet in the stream. For RPCs
  without a server stream, it includes a payload. Remove
  SERVER_STREAM_END.
- Introduce the SERVER_STREAM packet, to parallel the CLIENT_STREAM
  packet.
- Update the server and client code and tests. Test that old-style
  streaming RPCs still work correctly.
- Refactor the duplicate MessageOutput class into a FakeChannelOutput
  used by both Nanopb and raw RPCs.
- In C++, don't encode default-valued payload and status fields.

Change-Id: I218772dad6c2981dda5f032f298ea43ee5e08b4d
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/49822
Commit-Queue: Wyatt Hepler <hepler@google.com>
Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com>
Reviewed-by: Alexei Frolov <frolv@google.com>
diff --git a/pw_rpc/fake_channel_output.cc b/pw_rpc/fake_channel_output.cc
new file mode 100644
index 0000000..e68a879
--- /dev/null
+++ b/pw_rpc/fake_channel_output.cc
@@ -0,0 +1,62 @@
+// Copyright 2021 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#include "pw_rpc_private/fake_channel_output.h"
+
+#include "pw_assert/check.h"
+#include "pw_result/result.h"
+#include "pw_rpc/internal/packet.h"
+
+namespace pw::rpc::internal::test {
+
+void FakeChannelOutput::clear() {
+  ClearResponses();
+  total_responses_ = 0;
+  last_status_ = Status::Unknown();
+  done_ = false;
+}
+
+Status FakeChannelOutput::SendAndReleaseBuffer(
+    std::span<const std::byte> buffer) {
+  PW_CHECK(!done_);
+  PW_CHECK_PTR_EQ(buffer.data(), packet_buffer_.data());
+
+  if (buffer.empty()) {
+    return OkStatus();
+  }
+
+  Result<Packet> result = Packet::FromBuffer(buffer);
+  PW_CHECK_OK(result.status());
+
+  last_status_ = result.value().status();
+
+  switch (result.value().type()) {
+    case PacketType::RESPONSE:
+      // Server streaming RPCs don't have a payload in their response packet.
+      if (!server_streaming_) {
+        ProcessResponse(result.value().payload());
+      }
+      done_ = true;
+      break;
+    case PacketType::SERVER_STREAM:
+      ProcessResponse(result.value().payload());
+      break;
+    default:
+      PW_CRASH("Unhandled PacketType %d",
+               static_cast<int>(result.value().type()));
+  }
+  return OkStatus();
+}
+
+}  // namespace pw::rpc::internal::test