1 // Copyright 2020 The Pigweed Authors
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
7 // https://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
20 #include "pw_bytes/span.h"
21 #include "pw_rpc_protos/internal/packet.pwpb.h"
22 #include "pw_status/status_with_size.h"
24 namespace pw::rpc::internal {
28 static constexpr uint32_t kUnassignedId = 0;
30 // Parses a packet from a protobuf message. Missing or malformed fields take
31 // their default values.
32 static Result<Packet> FromBuffer(ConstByteSpan data);
34 // Creates an RPC packet with the channel, service, and method ID of the
36 static constexpr Packet Response(const Packet& request,
37 Status status = OkStatus()) {
38 return Packet(PacketType::RESPONSE,
46 // Creates a SERVER_ERROR packet with the channel, service, and method ID of
47 // the provided packet.
48 static constexpr Packet ServerError(const Packet& packet, Status status) {
49 return Packet(PacketType::SERVER_ERROR,
57 // Creates a CLIENT_ERROR packet with the channel, service, and method ID of
58 // the provided packet.
59 static constexpr Packet ClientError(const Packet& packet, Status status) {
60 return Packet(PacketType::CLIENT_ERROR,
68 // Creates an empty packet.
70 : Packet(PacketType{}, kUnassignedId, kUnassignedId, kUnassignedId) {}
72 constexpr Packet(PacketType type,
76 ConstByteSpan payload = {},
77 Status status = OkStatus())
79 channel_id_(channel_id),
80 service_id_(service_id),
81 method_id_(method_id),
85 // Encodes the packet into its wire format. Returns the encoded size.
86 Result<ConstByteSpan> Encode(ByteSpan buffer) const;
88 // Determines the space required to encode the packet proto fields for a
89 // response, excluding the payload. This may be used to split the buffer into
90 // reserved space and available space for the payload.
91 size_t MinEncodedSizeBytes() const;
93 enum Destination : bool { kServer, kClient };
95 constexpr Destination destination() const {
96 return static_cast<int>(type_) % 2 == 0 ? kServer : kClient;
99 constexpr PacketType type() const { return type_; }
100 constexpr uint32_t channel_id() const { return channel_id_; }
101 constexpr uint32_t service_id() const { return service_id_; }
102 constexpr uint32_t method_id() const { return method_id_; }
103 constexpr const ConstByteSpan& payload() const { return payload_; }
104 constexpr Status status() const { return status_; }
106 constexpr void set_type(PacketType type) { type_ = type; }
107 constexpr void set_channel_id(uint32_t channel_id) {
108 channel_id_ = channel_id;
110 constexpr void set_service_id(uint32_t service_id) {
111 service_id_ = service_id;
113 constexpr void set_method_id(uint32_t method_id) { method_id_ = method_id; }
114 constexpr void set_payload(ConstByteSpan payload) { payload_ = payload; }
115 constexpr void set_status(Status status) { status_ = status; }
119 uint32_t channel_id_;
120 uint32_t service_id_;
122 ConstByteSpan payload_;
126 } // namespace pw::rpc::internal