xref: /aosp_15_r20/external/pigweed/pw_rpc/raw/public/pw_rpc/raw/client_reader_writer.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2022 The Pigweed Authors
2 //
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
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
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
13 // the License.
14 
15 // This file defines the ServerReaderWriter, ServerReader, and ServerWriter
16 // classes for the raw RPC interface. These classes are used for bidirectional,
17 // client, and server streaming RPCs.
18 #pragma once
19 
20 #include "pw_bytes/span.h"
21 #include "pw_rpc/channel.h"
22 #include "pw_rpc/internal/client_call.h"
23 #include "pw_rpc/writer.h"
24 
25 namespace pw::rpc {
26 
27 // Sends requests and handles responses for a bidirectional streaming RPC.
28 //
29 // These classes use private inheritance to hide the internal::Call API while
30 // allow direct use of its public and protected functions.
31 class RawClientReaderWriter : private internal::StreamResponseClientCall {
32  public:
33   constexpr RawClientReaderWriter() = default;
34 
35   RawClientReaderWriter(RawClientReaderWriter&&) = default;
36   RawClientReaderWriter& operator=(RawClientReaderWriter&&) = default;
37 
38   using internal::Call::active;
39   using internal::Call::channel_id;
40 
41   using internal::ClientCall::id;
42 
43   // Functions for setting the callbacks.
44   using internal::StreamResponseClientCall::set_on_completed;
45   using internal::StreamResponseClientCall::set_on_error;
46   using internal::StreamResponseClientCall::set_on_next;
47 
48   // Sends a stream request packet with the given raw payload.
49   using internal::Call::Write;
50 
51   // Notifies the server that the client has requested to stop communication by
52   // sending CLIENT_REQUEST_COMPLETION.
53   using internal::ClientCall::RequestCompletion;
54 
55   // Cancels this RPC. Closes the call locally and sends a CANCELLED error to
56   // the server.
57   using internal::Call::Cancel;
58 
59   // Closes this RPC locally. Sends a CLIENT_REQUEST_COMPLETION, but no
60   // cancellation packet. Future packets for this RPC are dropped, and the
61   // client sends a FAILED_PRECONDITION error in response because the call is
62   // not active.
63   using internal::ClientCall::Abandon;
64 
65   // Closes this RPC locally and waits for any running callbacks to complete.
66   // Sends a CLIENT_REQUEST_COMPLETION, but no cancellation packet. Future
67   // packets for this RPC are dropped, and the client sends a
68   // FAILED_PRECONDITION error in response because the call is not active.
69   using internal::ClientCall::CloseAndWaitForCallbacks;
70 
71   // Allow use as a generic RPC Writer.
72   using internal::Call::as_writer;
73 
74  private:
75   friend class internal::StreamResponseClientCall;
76 
RawClientReaderWriter(internal::LockedEndpoint & client,uint32_t channel_id,uint32_t service_id,uint32_t method_id)77   RawClientReaderWriter(internal::LockedEndpoint& client,
78                         uint32_t channel_id,
79                         uint32_t service_id,
80                         uint32_t method_id)
81       PW_EXCLUSIVE_LOCKS_REQUIRED(internal::rpc_lock())
82       : StreamResponseClientCall(
83             client,
84             channel_id,
85             service_id,
86             method_id,
87             RawCallProps(MethodType::kBidirectionalStreaming)) {}
88 };
89 
90 // Handles responses for a server streaming RPC.
91 class RawClientReader : private internal::StreamResponseClientCall {
92  public:
93   constexpr RawClientReader() = default;
94 
95   RawClientReader(RawClientReader&&) = default;
96   RawClientReader& operator=(RawClientReader&&) = default;
97 
98   using internal::StreamResponseClientCall::active;
99   using internal::StreamResponseClientCall::channel_id;
100 
101   using internal::StreamResponseClientCall::set_on_completed;
102   using internal::StreamResponseClientCall::set_on_error;
103   using internal::StreamResponseClientCall::set_on_next;
104 
105   using internal::Call::Cancel;
106   using internal::Call::RequestCompletion;
107   using internal::ClientCall::Abandon;
108   using internal::ClientCall::CloseAndWaitForCallbacks;
109 
110  private:
111   friend class internal::StreamResponseClientCall;
112 
RawClientReader(internal::LockedEndpoint & client,uint32_t channel_id,uint32_t service_id,uint32_t method_id)113   RawClientReader(internal::LockedEndpoint& client,
114                   uint32_t channel_id,
115                   uint32_t service_id,
116                   uint32_t method_id)
117       PW_EXCLUSIVE_LOCKS_REQUIRED(internal::rpc_lock())
118       : StreamResponseClientCall(client,
119                                  channel_id,
120                                  service_id,
121                                  method_id,
122                                  RawCallProps(MethodType::kServerStreaming)) {}
123 };
124 
125 // Sends requests and handles the response for a client streaming RPC.
126 class RawClientWriter : private internal::UnaryResponseClientCall {
127  public:
128   constexpr RawClientWriter() = default;
129 
130   RawClientWriter(RawClientWriter&&) = default;
131   RawClientWriter& operator=(RawClientWriter&&) = default;
132 
PW_LOCKS_EXCLUDED(internal::rpc_lock ())133   ~RawClientWriter() PW_LOCKS_EXCLUDED(internal::rpc_lock()) {
134     DestroyClientCall();
135   }
136 
137   using internal::UnaryResponseClientCall::active;
138   using internal::UnaryResponseClientCall::channel_id;
139 
140   using internal::UnaryResponseClientCall::set_on_completed;
141   using internal::UnaryResponseClientCall::set_on_error;
142 
143   using internal::Call::Cancel;
144   using internal::Call::RequestCompletion;
145   using internal::Call::Write;
146   using internal::ClientCall::Abandon;
147   using internal::ClientCall::CloseAndWaitForCallbacks;
148 
149   // Allow use as a generic RPC Writer.
150   using internal::Call::as_writer;
151 
152  private:
153   friend class internal::UnaryResponseClientCall;
154 
RawClientWriter(internal::LockedEndpoint & client,uint32_t channel_id,uint32_t service_id,uint32_t method_id)155   RawClientWriter(internal::LockedEndpoint& client,
156                   uint32_t channel_id,
157                   uint32_t service_id,
158                   uint32_t method_id)
159       PW_EXCLUSIVE_LOCKS_REQUIRED(internal::rpc_lock())
160       : UnaryResponseClientCall(client,
161                                 channel_id,
162                                 service_id,
163                                 method_id,
164                                 RawCallProps(MethodType::kClientStreaming)) {}
165 };
166 
167 // Handles the response for to unary RPC.
168 class RawUnaryReceiver : private internal::UnaryResponseClientCall {
169  public:
170   constexpr RawUnaryReceiver() = default;
171 
172   RawUnaryReceiver(RawUnaryReceiver&&) = default;
173   RawUnaryReceiver& operator=(RawUnaryReceiver&&) = default;
174 
PW_LOCKS_EXCLUDED(internal::rpc_lock ())175   ~RawUnaryReceiver() PW_LOCKS_EXCLUDED(internal::rpc_lock()) {
176     DestroyClientCall();
177   }
178 
179   using internal::UnaryResponseClientCall::active;
180   using internal::UnaryResponseClientCall::channel_id;
181 
182   using internal::UnaryResponseClientCall::set_on_completed;
183   using internal::UnaryResponseClientCall::set_on_error;
184 
185   using internal::ClientCall::Abandon;
186   using internal::ClientCall::CloseAndWaitForCallbacks;
187   using internal::UnaryResponseClientCall::Cancel;
188 
189  private:
190   friend class internal::UnaryResponseClientCall;
191 
RawUnaryReceiver(internal::LockedEndpoint & client,uint32_t channel_id,uint32_t service_id,uint32_t method_id)192   RawUnaryReceiver(internal::LockedEndpoint& client,
193                    uint32_t channel_id,
194                    uint32_t service_id,
195                    uint32_t method_id)
196       PW_EXCLUSIVE_LOCKS_REQUIRED(internal::rpc_lock())
197       : UnaryResponseClientCall(client,
198                                 channel_id,
199                                 service_id,
200                                 method_id,
201                                 RawCallProps(MethodType::kUnary)) {}
202 };
203 
204 }  // namespace pw::rpc
205