aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexei Frolov <frolv@google.com>2021-04-09 10:18:17 -0700
committerCQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>2021-04-09 19:05:34 +0000
commit1c670a2693ab23c6d890f1f8d2310ba2b9db72ec (patch)
treec2e3fdb9a0c0bc59223dc503ad0b08752f583080
parent6f5b8fb1ff9a8b2e025863187c7ec7c46fa74929 (diff)
downloadpigweed-1c670a2693ab23c6d890f1f8d2310ba2b9db72ec.tar.gz
pw_rpc: Allow using enums for channel IDs
This adds a Channel::Create overload which accepts an enum ID value, to allow cleaner organization of channel IDs. Change-Id: Id29fba5c36133c1720a0f74e42e86770e8ad5366 Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/40320 Reviewed-by: Wyatt Hepler <hepler@google.com> Commit-Queue: Alexei Frolov <frolv@google.com>
-rw-r--r--pw_rpc/channel_test.cc12
-rw-r--r--pw_rpc/docs.rst27
-rw-r--r--pw_rpc/public/pw_rpc/channel.h14
3 files changed, 53 insertions, 0 deletions
diff --git a/pw_rpc/channel_test.cc b/pw_rpc/channel_test.cc
index 5e16ee6ae..7687a2d8e 100644
--- a/pw_rpc/channel_test.cc
+++ b/pw_rpc/channel_test.cc
@@ -42,6 +42,18 @@ const size_t kReservedSize = 2 /* type */ + 2 /* channel */ + 5 /* service */ +
5 /* method */ + 2 /* payload key */ +
2 /* status */;
+enum class ChannelId {
+ kOne = 1,
+ kTwo = 2,
+};
+
+TEST(Channel, Create_FromEnum) {
+ constexpr rpc::Channel one = Channel::Create<ChannelId::kOne>(nullptr);
+ constexpr rpc::Channel two = Channel::Create<ChannelId::kTwo>(nullptr);
+ static_assert(one.id() == 1);
+ static_assert(two.id() == 2);
+}
+
TEST(Channel, TestPacket_ReservedSizeMatchesMinEncodedSizeBytes) {
EXPECT_EQ(kReservedSize, kTestPacket.MinEncodedSizeBytes());
}
diff --git a/pw_rpc/docs.rst b/pw_rpc/docs.rst
index eca6870cf..fc041656a 100644
--- a/pw_rpc/docs.rst
+++ b/pw_rpc/docs.rst
@@ -238,6 +238,33 @@ channel output and the example service.
server, hdlc_channel_output, input_buffer);
}
+Channels
+========
+``pw_rpc`` sends all of its packets over channels. These are logical,
+application-layer routes used to tell the RPC system where a packet should go.
+
+Channels over a client-server connection must all have a unique ID, which can be
+assigned statically at compile time or dynamically.
+
+.. code-block:: cpp
+
+ // Creating a channel with the static ID 3.
+ pw::rpc::Channel static_channel = pw::rpc::Channel::Create<3>(&output);
+
+ // Grouping channel IDs within an enum can lead to clearer code.
+ enum ChannelId {
+ kUartChannel = 1,
+ kSpiChannel = 2,
+ };
+
+ // Creating a channel with a static ID defined within an enum.
+ pw::rpc::Channel another_static_channel =
+ pw::rpc::Channel::Create<ChannelId::kUartChannel>(&output);
+
+ // Creating a channel with a dynamic ID (note that no output is provided; it
+ // will be set when the channel is used.
+ pw::rpc::Channel dynamic_channel;
+
Services
========
A service is a logical grouping of RPCs defined within a .proto file. ``pw_rpc``
diff --git a/pw_rpc/public/pw_rpc/channel.h b/pw_rpc/public/pw_rpc/channel.h
index d17cd5234..6d87020a8 100644
--- a/pw_rpc/public/pw_rpc/channel.h
+++ b/pw_rpc/public/pw_rpc/channel.h
@@ -15,6 +15,7 @@
#include <cstdint>
#include <span>
+#include <type_traits>
#include "pw_assert/assert.h"
#include "pw_status/status.h"
@@ -76,6 +77,19 @@ class Channel {
return Channel(kId, output);
}
+ // Creates a channel with a static ID from an enum value.
+ template <auto kId,
+ typename T = decltype(kId),
+ typename = std::enable_if_t<std::is_enum_v<T>>,
+ typename U = std::underlying_type_t<T>>
+ constexpr static Channel Create(ChannelOutput* output) {
+ constexpr U kIntId = static_cast<U>(kId);
+ static_assert(kIntId >= 0, "Channel ID cannot be negative");
+ static_assert(kIntId <= std::numeric_limits<uint32_t>::max(),
+ "Channel ID must fit in a uint32");
+ return Create<static_cast<uint32_t>(kIntId)>(output);
+ }
+
constexpr uint32_t id() const { return id_; }
constexpr bool assigned() const { return id_ != kUnassignedChannelId; }