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