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 no further client stream messages will be sent. 52 using internal::ClientCall::CloseClientStream; 53 54 // Cancels this RPC. Closes the call locally and sends a CANCELLED error to 55 // the server. 56 using internal::Call::Cancel; 57 58 // Closes this RPC locally. Sends a CLIENT_STREAM_END, but no cancellation 59 // packet. Future packets for this RPC are dropped, and the client sends a 60 // FAILED_PRECONDITION error in response because the call is not active. 61 using internal::ClientCall::Abandon; 62 63 // Allow use as a generic RPC Writer. 64 using internal::Call::operator Writer&; 65 using internal::Call::operator const Writer&; 66 67 private: 68 friend class internal::StreamResponseClientCall; 69 RawClientReaderWriter(internal::LockedEndpoint & client,uint32_t channel_id,uint32_t service_id,uint32_t method_id)70 RawClientReaderWriter(internal::LockedEndpoint& client, 71 uint32_t channel_id, 72 uint32_t service_id, 73 uint32_t method_id) 74 PW_EXCLUSIVE_LOCKS_REQUIRED(internal::rpc_lock()) 75 : StreamResponseClientCall( 76 client, 77 channel_id, 78 service_id, 79 method_id, 80 RawCallProps(MethodType::kBidirectionalStreaming)) {} 81 }; 82 83 // Handles responses for a server streaming RPC. 84 class RawClientReader : private internal::StreamResponseClientCall { 85 public: 86 constexpr RawClientReader() = default; 87 88 RawClientReader(RawClientReader&&) = default; 89 RawClientReader& operator=(RawClientReader&&) = default; 90 91 using internal::StreamResponseClientCall::active; 92 using internal::StreamResponseClientCall::channel_id; 93 94 using internal::StreamResponseClientCall::set_on_completed; 95 using internal::StreamResponseClientCall::set_on_error; 96 using internal::StreamResponseClientCall::set_on_next; 97 98 using internal::Call::Cancel; 99 using internal::ClientCall::Abandon; 100 101 private: 102 friend class internal::StreamResponseClientCall; 103 RawClientReader(internal::LockedEndpoint & client,uint32_t channel_id,uint32_t service_id,uint32_t method_id)104 RawClientReader(internal::LockedEndpoint& client, 105 uint32_t channel_id, 106 uint32_t service_id, 107 uint32_t method_id) 108 PW_EXCLUSIVE_LOCKS_REQUIRED(internal::rpc_lock()) 109 : StreamResponseClientCall(client, 110 channel_id, 111 service_id, 112 method_id, 113 RawCallProps(MethodType::kServerStreaming)) {} 114 }; 115 116 // Sends requests and handles the response for a client streaming RPC. 117 class RawClientWriter : private internal::UnaryResponseClientCall { 118 public: 119 constexpr RawClientWriter() = default; 120 121 RawClientWriter(RawClientWriter&&) = default; 122 RawClientWriter& operator=(RawClientWriter&&) = default; 123 124 using internal::UnaryResponseClientCall::active; 125 using internal::UnaryResponseClientCall::channel_id; 126 127 using internal::UnaryResponseClientCall::set_on_completed; 128 using internal::UnaryResponseClientCall::set_on_error; 129 130 using internal::Call::Cancel; 131 using internal::Call::CloseClientStream; 132 using internal::Call::Write; 133 using internal::ClientCall::Abandon; 134 135 // Allow use as a generic RPC Writer. 136 using internal::Call::operator Writer&; 137 using internal::Call::operator const Writer&; 138 139 private: 140 friend class internal::UnaryResponseClientCall; 141 RawClientWriter(internal::LockedEndpoint & client,uint32_t channel_id,uint32_t service_id,uint32_t method_id)142 RawClientWriter(internal::LockedEndpoint& client, 143 uint32_t channel_id, 144 uint32_t service_id, 145 uint32_t method_id) 146 PW_EXCLUSIVE_LOCKS_REQUIRED(internal::rpc_lock()) 147 : UnaryResponseClientCall(client, 148 channel_id, 149 service_id, 150 method_id, 151 RawCallProps(MethodType::kClientStreaming)) {} 152 }; 153 154 // Handles the response for to unary RPC. 155 class RawUnaryReceiver : private internal::UnaryResponseClientCall { 156 public: 157 constexpr RawUnaryReceiver() = default; 158 159 RawUnaryReceiver(RawUnaryReceiver&&) = default; 160 RawUnaryReceiver& operator=(RawUnaryReceiver&&) = default; 161 162 using internal::UnaryResponseClientCall::active; 163 using internal::UnaryResponseClientCall::channel_id; 164 165 using internal::UnaryResponseClientCall::set_on_completed; 166 using internal::UnaryResponseClientCall::set_on_error; 167 168 using internal::ClientCall::Abandon; 169 using internal::UnaryResponseClientCall::Cancel; 170 171 private: 172 friend class internal::UnaryResponseClientCall; 173 RawUnaryReceiver(internal::LockedEndpoint & client,uint32_t channel_id,uint32_t service_id,uint32_t method_id)174 RawUnaryReceiver(internal::LockedEndpoint& client, 175 uint32_t channel_id, 176 uint32_t service_id, 177 uint32_t method_id) 178 PW_EXCLUSIVE_LOCKS_REQUIRED(internal::rpc_lock()) 179 : UnaryResponseClientCall(client, 180 channel_id, 181 service_id, 182 method_id, 183 RawCallProps(MethodType::kUnary)) {} 184 }; 185 186 } // namespace pw::rpc 187