pw_rpc: Expand server-side packet processing

- Handle various error cases with incoming packets.
- Dynamically assign a channel when a packet's ID doesn't exist.
- Reserve space in the response buffer for packet "header" fields.

Change-Id: Ibdce99c8ff1d37aa46bb4e400a4d8f8e646a8ac7
diff --git a/pw_rpc/server_test.cc b/pw_rpc/server_test.cc
index aae410e..85eecc0 100644
--- a/pw_rpc/server_test.cc
+++ b/pw_rpc/server_test.cc
@@ -15,10 +15,13 @@
 #include "pw_rpc/server.h"
 
 #include "gtest/gtest.h"
+#include "pw_rpc/internal/packet.h"
 
 namespace pw::rpc {
 namespace {
 
+using internal::Packet;
+using internal::PacketType;
 using std::byte;
 
 template <size_t buffer_size>
@@ -39,35 +42,110 @@
   span<const byte> sent_packet_;
 };
 
-TestOutput<512> output(1);
+Packet MakePacket(uint32_t channel_id,
+                  uint32_t service_id,
+                  uint32_t method_id,
+                  span<const byte> payload) {
+  Packet packet = Packet::Empty(PacketType::RPC);
+  packet.set_channel_id(channel_id);
+  packet.set_service_id(service_id);
+  packet.set_method_id(method_id);
+  packet.set_payload(payload);
+  return packet;
+}
 
-// clang-format off
-constexpr uint8_t encoded_packet[] = {
-  // type = PacketType::kRpc
-  0x08, 0x00,
-  // channel_id = 1
-  0x10, 0x01,
-  // service_id = 42
-  0x18, 0x2a,
-  // method_id = 27
-  0x20, 0x1b,
-  // payload
-  0x82, 0x02, 0xff, 0xff,
-};
-// clang-format on
-
-TEST(Server, DoesStuff) {
+TEST(Server, ProcessPacket_SendsResponse) {
+  TestOutput<128> output(1);
   Channel channels[] = {
-      Channel(1, &output),
-      Channel(2, &output),
+      Channel::Create<1>(&output),
+      Channel::Create<2>(&output),
   };
   Server server(channels);
   internal::Service service(42, {});
   server.RegisterService(service);
 
-  server.ProcessPacket(as_bytes(span(encoded_packet)), output);
-  auto packet = output.sent_packet();
-  EXPECT_GT(packet.size(), 0u);
+  byte encoded_packet[64];
+  constexpr byte payload[] = {byte(0x82), byte(0x02), byte(0xff), byte(0xff)};
+  Packet request = MakePacket(1, 42, 27, payload);
+  auto sws = request.Encode(encoded_packet);
+
+  server.ProcessPacket(span(encoded_packet, sws.size()), output);
+  Packet packet = Packet::FromBuffer(output.sent_packet());
+  EXPECT_EQ(packet.status(), Status::OK);
+  EXPECT_EQ(packet.channel_id(), 1u);
+  EXPECT_EQ(packet.service_id(), 42u);
+}
+
+TEST(Server, ProcessPacket_SendsNotFoundOnInvalidService) {
+  TestOutput<128> output(1);
+  Channel channels[] = {
+      Channel::Create<1>(&output),
+      Channel::Create<2>(&output),
+  };
+  Server server(channels);
+  internal::Service service(42, {});
+  server.RegisterService(service);
+
+  byte encoded_packet[64];
+  constexpr byte payload[] = {byte(0x82), byte(0x02), byte(0xff), byte(0xff)};
+  Packet request = MakePacket(1, 43, 27, payload);
+  auto sws = request.Encode(encoded_packet);
+
+  server.ProcessPacket(span(encoded_packet, sws.size()), output);
+  Packet packet = Packet::FromBuffer(output.sent_packet());
+  EXPECT_EQ(packet.status(), Status::NOT_FOUND);
+  EXPECT_EQ(packet.channel_id(), 1u);
+  EXPECT_EQ(packet.service_id(), 0u);
+}
+
+TEST(Server, ProcessPacket_AssignsAnUnassignedChannel) {
+  TestOutput<128> output(1);
+  Channel channels[] = {
+      Channel::Create<1>(&output),
+      Channel::Create<2>(&output),
+      Channel(),
+  };
+  Server server(channels);
+  internal::Service service(42, {});
+  server.RegisterService(service);
+
+  byte encoded_packet[64];
+  constexpr byte payload[] = {byte(0x82), byte(0x02), byte(0xff), byte(0xff)};
+  Packet request = MakePacket(/*channel_id=*/99, 42, 27, payload);
+  auto sws = request.Encode(encoded_packet);
+
+  TestOutput<128> unassigned_output(2);
+  server.ProcessPacket(span(encoded_packet, sws.size()), unassigned_output);
+  ASSERT_EQ(channels[2].id(), 99u);
+
+  Packet packet = Packet::FromBuffer(unassigned_output.sent_packet());
+  EXPECT_EQ(packet.status(), Status::OK);
+  EXPECT_EQ(packet.channel_id(), 99u);
+  EXPECT_EQ(packet.service_id(), 42u);
+}
+
+TEST(Server, ProcessPacket_SendsResourceExhaustedWhenChannelCantBeAssigned) {
+  TestOutput<128> output(1);
+  Channel channels[] = {
+      Channel::Create<1>(&output),
+      Channel::Create<2>(&output),
+  };
+  Server server(channels);
+  internal::Service service(42, {});
+  server.RegisterService(service);
+
+  byte encoded_packet[64];
+  constexpr byte payload[] = {byte(0x82), byte(0x02), byte(0xff), byte(0xff)};
+  Packet request = MakePacket(/*channel_id=*/99, 42, 27, payload);
+  auto sws = request.Encode(encoded_packet);
+
+  server.ProcessPacket(span(encoded_packet, sws.size()), output);
+
+  Packet packet = Packet::FromBuffer(output.sent_packet());
+  EXPECT_EQ(packet.status(), Status::RESOURCE_EXHAUSTED);
+  EXPECT_EQ(packet.channel_id(), 0u);
+  EXPECT_EQ(packet.service_id(), 0u);
+  EXPECT_EQ(packet.method_id(), 0u);
 }
 
 }  // namespace