diff options
author | Alexei Frolov <frolv@google.com> | 2021-04-09 10:18:17 -0700 |
---|---|---|
committer | CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2021-04-09 19:05:34 +0000 |
commit | 1c670a2693ab23c6d890f1f8d2310ba2b9db72ec (patch) | |
tree | c2e3fdb9a0c0bc59223dc503ad0b08752f583080 | |
parent | 6f5b8fb1ff9a8b2e025863187c7ec7c46fa74929 (diff) | |
download | pigweed-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.cc | 12 | ||||
-rw-r--r-- | pw_rpc/docs.rst | 27 | ||||
-rw-r--r-- | pw_rpc/public/pw_rpc/channel.h | 14 |
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; } |