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 ClientReaderWriter, ClientReader, ClientWriter, 16 // and UnaryReceiver classes for the pw_protobuf RPC interface. These classes 17 // are used for bidirectional, client, and server streaming, and unary RPCs. 18 #pragma once 19 20 #include "pw_bytes/span.h" 21 #include "pw_function/function.h" 22 #include "pw_rpc/channel.h" 23 #include "pw_rpc/internal/client_call.h" 24 #include "pw_rpc/internal/config.h" 25 #include "pw_rpc/pwpb/internal/common.h" 26 27 #if PW_RPC_DYNAMIC_ALLOCATION 28 #include PW_RPC_MAKE_UNIQUE_PTR_INCLUDE 29 #endif // PW_RPC_DYNAMIC_ALLOCATION 30 31 namespace pw::rpc { 32 namespace internal { 33 34 // internal::PwpbUnaryResponseClientCall extends 35 // internal::UnaryResponseClientCall by adding a method serializer/deserializer 36 // passed in to Start(), typed request messages to the Start() call, and an 37 // on_completed callback templated on the response type. 38 template <typename Response> 39 class PwpbUnaryResponseClientCall : public UnaryResponseClientCall { 40 public: 41 // Start() can be called with zero or one request objects. 42 template <typename CallType, typename... Request> Start(Endpoint & client,uint32_t channel_id,uint32_t service_id,uint32_t method_id,const PwpbMethodSerde & serde,Function<void (const Response &,Status)> && on_completed,Function<void (Status)> && on_error,const Request &...request)43 static CallType Start(Endpoint& client, 44 uint32_t channel_id, 45 uint32_t service_id, 46 uint32_t method_id, 47 const PwpbMethodSerde& serde, 48 Function<void(const Response&, Status)>&& on_completed, 49 Function<void(Status)>&& on_error, 50 const Request&... request) 51 PW_LOCKS_EXCLUDED(rpc_lock()) { 52 rpc_lock().lock(); 53 CallType call( 54 client.ClaimLocked(), channel_id, service_id, method_id, serde); 55 SetCallbacksAndSendRequest(call, 56 client, 57 serde, 58 std::move(on_completed), 59 std::move(on_error), 60 request...); 61 return call; 62 } 63 64 template <typename CallType, typename... Request> StartDynamic(Endpoint & client,uint32_t channel_id,uint32_t service_id,uint32_t method_id,const PwpbMethodSerde & serde,Function<void (const Response &,Status)> && on_completed,Function<void (Status)> && on_error,const Request &...request)65 static auto StartDynamic( 66 Endpoint& client, 67 uint32_t channel_id, 68 uint32_t service_id, 69 uint32_t method_id, 70 const PwpbMethodSerde& serde, 71 Function<void(const Response&, Status)>&& on_completed, 72 Function<void(Status)>&& on_error, 73 const Request&... request) PW_LOCKS_EXCLUDED(rpc_lock()) { 74 rpc_lock().lock(); 75 auto call = PW_RPC_MAKE_UNIQUE_PTR(CallType, 76 client.ClaimLocked(), 77 channel_id, 78 service_id, 79 method_id, 80 serde); 81 SetCallbacksAndSendRequest(*call, 82 client, 83 serde, 84 std::move(on_completed), 85 std::move(on_error), 86 request...); 87 return call; 88 } 89 90 protected: 91 // Derived classes allow default construction so that users can declare a 92 // variable into which to move client reader/writers from RPC calls. PwpbUnaryResponseClientCall()93 constexpr PwpbUnaryResponseClientCall() : serde_(nullptr) {} 94 PwpbUnaryResponseClientCall(LockedEndpoint & client,uint32_t channel_id,uint32_t service_id,uint32_t method_id,MethodType type,const PwpbMethodSerde & serde)95 PwpbUnaryResponseClientCall(LockedEndpoint& client, 96 uint32_t channel_id, 97 uint32_t service_id, 98 uint32_t method_id, 99 MethodType type, 100 const PwpbMethodSerde& serde) 101 PW_EXCLUSIVE_LOCKS_REQUIRED(rpc_lock()) 102 : UnaryResponseClientCall( 103 client, channel_id, service_id, method_id, StructCallProps(type)), 104 serde_(&serde) {} 105 106 // Allow derived classes to be constructed moving another instance. 107 PwpbUnaryResponseClientCall(PwpbUnaryResponseClientCall&& other) PW_LOCKS_EXCLUDED(rpc_lock ())108 PW_LOCKS_EXCLUDED(rpc_lock()) { 109 *this = std::move(other); 110 } 111 112 // Allow derived classes to use move assignment from another instance. 113 PwpbUnaryResponseClientCall& operator=(PwpbUnaryResponseClientCall&& other) PW_LOCKS_EXCLUDED(rpc_lock ())114 PW_LOCKS_EXCLUDED(rpc_lock()) { 115 RpcLockGuard lock; 116 MovePwpbUnaryResponseClientCallFrom(other); 117 return *this; 118 } 119 ~PwpbUnaryResponseClientCall()120 ~PwpbUnaryResponseClientCall() { DestroyClientCall(); } 121 122 // Implement moving by copying the serde pointer and on_completed function. MovePwpbUnaryResponseClientCallFrom(PwpbUnaryResponseClientCall & other)123 void MovePwpbUnaryResponseClientCallFrom(PwpbUnaryResponseClientCall& other) 124 PW_EXCLUSIVE_LOCKS_REQUIRED(rpc_lock()) { 125 MoveUnaryResponseClientCallFrom(other); 126 serde_ = other.serde_; 127 set_pwpb_on_completed_locked(std::move(other.pwpb_on_completed_)); 128 } 129 set_on_completed(Function<void (const Response & response,Status)> && on_completed)130 void set_on_completed( 131 Function<void(const Response& response, Status)>&& on_completed) 132 PW_LOCKS_EXCLUDED(rpc_lock()) { 133 RpcLockGuard lock; 134 set_pwpb_on_completed_locked(std::move(on_completed)); 135 } 136 137 // Sends a streamed request. 138 // Returns the following Status codes: 139 // 140 // OK - the request was successfully sent 141 // FAILED_PRECONDITION - the writer is closed 142 // INTERNAL - pw_rpc was unable to encode the pw_protobuf protobuf 143 // other errors - the ChannelOutput failed to send the packet; the error 144 // codes are determined by the ChannelOutput implementation 145 // 146 template <typename Request> SendStreamRequest(const Request & request)147 Status SendStreamRequest(const Request& request) 148 PW_LOCKS_EXCLUDED(rpc_lock()) { 149 RpcLockGuard lock; 150 return PwpbSendStream(*this, request, serde_); 151 } 152 153 private: 154 template <typename CallType, typename... Request> SetCallbacksAndSendRequest(CallType & call,Endpoint & client,const PwpbMethodSerde & serde,Function<void (const Response &,Status)> && on_completed,Function<void (Status)> && on_error,const Request &...request)155 static void SetCallbacksAndSendRequest( 156 CallType& call, 157 Endpoint& client, 158 const PwpbMethodSerde& serde, 159 Function<void(const Response&, Status)>&& on_completed, 160 Function<void(Status)>&& on_error, 161 const Request&... request) PW_UNLOCK_FUNCTION(rpc_lock()) { 162 call.set_pwpb_on_completed_locked(std::move(on_completed)); 163 call.set_on_error_locked(std::move(on_error)); 164 165 if constexpr (sizeof...(Request) == 0u) { 166 call.SendInitialClientRequest({}); 167 } else { 168 PwpbSendInitialRequest(call, serde.request(), request...); 169 } 170 171 client.CleanUpCalls(); 172 } 173 set_pwpb_on_completed_locked(Function<void (const Response & response,Status)> && on_completed)174 void set_pwpb_on_completed_locked( 175 Function<void(const Response& response, Status)>&& on_completed) 176 PW_EXCLUSIVE_LOCKS_REQUIRED(rpc_lock()) { 177 pwpb_on_completed_ = std::move(on_completed); 178 179 UnaryResponseClientCall::set_on_completed_locked( 180 [this](ConstByteSpan payload, Status status) 181 PW_NO_LOCK_SAFETY_ANALYSIS { 182 DecodeToStructAndInvokeOnCompleted( 183 payload, serde_->response(), pwpb_on_completed_, status); 184 }); 185 } 186 187 const PwpbMethodSerde* serde_ PW_GUARDED_BY(rpc_lock()); 188 Function<void(const Response&, Status)> pwpb_on_completed_ 189 PW_GUARDED_BY(rpc_lock()); 190 }; 191 192 // internal::PwpbStreamResponseClientCall extends 193 // internal::StreamResponseClientCall by adding a method serializer/deserializer 194 // passed in to Start(), typed request messages to the Start() call, and an 195 // on_next callback templated on the response type. 196 template <typename Response> 197 class PwpbStreamResponseClientCall : public StreamResponseClientCall { 198 public: 199 // Start() can be called with zero or one request objects. 200 template <typename CallType, typename... Request> Start(Endpoint & client,uint32_t channel_id,uint32_t service_id,uint32_t method_id,const PwpbMethodSerde & serde,Function<void (const Response &)> && on_next,Function<void (Status)> && on_completed,Function<void (Status)> && on_error,const Request &...request)201 static CallType Start(Endpoint& client, 202 uint32_t channel_id, 203 uint32_t service_id, 204 uint32_t method_id, 205 const PwpbMethodSerde& serde, 206 Function<void(const Response&)>&& on_next, 207 Function<void(Status)>&& on_completed, 208 Function<void(Status)>&& on_error, 209 const Request&... request) 210 PW_LOCKS_EXCLUDED(rpc_lock()) { 211 rpc_lock().lock(); 212 CallType call( 213 client.ClaimLocked(), channel_id, service_id, method_id, serde); 214 SetCallbacksAndSendRequest(call, 215 client, 216 serde, 217 std::move(on_next), 218 std::move(on_completed), 219 std::move(on_error), 220 request...); 221 return call; 222 } 223 224 template <typename CallType, typename... Request> StartDynamic(Endpoint & client,uint32_t channel_id,uint32_t service_id,uint32_t method_id,const PwpbMethodSerde & serde,Function<void (const Response &)> && on_next,Function<void (Status)> && on_completed,Function<void (Status)> && on_error,const Request &...request)225 static auto StartDynamic(Endpoint& client, 226 uint32_t channel_id, 227 uint32_t service_id, 228 uint32_t method_id, 229 const PwpbMethodSerde& serde, 230 Function<void(const Response&)>&& on_next, 231 Function<void(Status)>&& on_completed, 232 Function<void(Status)>&& on_error, 233 const Request&... request) 234 PW_LOCKS_EXCLUDED(rpc_lock()) { 235 rpc_lock().lock(); 236 auto call = PW_RPC_MAKE_UNIQUE_PTR(CallType, 237 client.ClaimLocked(), 238 channel_id, 239 service_id, 240 method_id, 241 serde); 242 SetCallbacksAndSendRequest(*call, 243 client, 244 serde, 245 std::move(on_next), 246 std::move(on_completed), 247 std::move(on_error), 248 request...); 249 return call; 250 } 251 252 protected: 253 // Derived classes allow default construction so that users can declare a 254 // variable into which to move client reader/writers from RPC calls. PwpbStreamResponseClientCall()255 constexpr PwpbStreamResponseClientCall() : serde_(nullptr) {} 256 PwpbStreamResponseClientCall(LockedEndpoint & client,uint32_t channel_id,uint32_t service_id,uint32_t method_id,MethodType type,const PwpbMethodSerde & serde)257 PwpbStreamResponseClientCall(LockedEndpoint& client, 258 uint32_t channel_id, 259 uint32_t service_id, 260 uint32_t method_id, 261 MethodType type, 262 const PwpbMethodSerde& serde) 263 PW_EXCLUSIVE_LOCKS_REQUIRED(rpc_lock()) 264 : StreamResponseClientCall( 265 client, channel_id, service_id, method_id, StructCallProps(type)), 266 serde_(&serde) {} 267 268 // Allow derived classes to be constructed moving another instance. 269 PwpbStreamResponseClientCall(PwpbStreamResponseClientCall&& other) PW_LOCKS_EXCLUDED(rpc_lock ())270 PW_LOCKS_EXCLUDED(rpc_lock()) { 271 *this = std::move(other); 272 } 273 274 // Allow derived classes to use move assignment from another instance. 275 PwpbStreamResponseClientCall& operator=(PwpbStreamResponseClientCall&& other) PW_LOCKS_EXCLUDED(rpc_lock ())276 PW_LOCKS_EXCLUDED(rpc_lock()) { 277 RpcLockGuard lock; 278 MovePwpbStreamResponseClientCallFrom(other); 279 return *this; 280 } 281 ~PwpbStreamResponseClientCall()282 ~PwpbStreamResponseClientCall() { DestroyClientCall(); } 283 284 // Implement moving by copying the serde pointer and on_next function. MovePwpbStreamResponseClientCallFrom(PwpbStreamResponseClientCall & other)285 void MovePwpbStreamResponseClientCallFrom(PwpbStreamResponseClientCall& other) 286 PW_EXCLUSIVE_LOCKS_REQUIRED(rpc_lock()) { 287 MoveStreamResponseClientCallFrom(other); 288 serde_ = other.serde_; 289 set_pwpb_on_next_locked(std::move(other.pwpb_on_next_)); 290 } 291 set_on_next(Function<void (const Response & response)> && on_next)292 void set_on_next(Function<void(const Response& response)>&& on_next) 293 PW_LOCKS_EXCLUDED(rpc_lock()) { 294 RpcLockGuard lock; 295 set_pwpb_on_next_locked(std::move(on_next)); 296 } 297 298 // Sends a streamed request. 299 // Returns the following Status codes: 300 // 301 // OK - the request was successfully sent 302 // FAILED_PRECONDITION - the writer is closed 303 // INTERNAL - pw_rpc was unable to encode the pw_protobuf protobuf 304 // other errors - the ChannelOutput failed to send the packet; the error 305 // codes are determined by the ChannelOutput implementation 306 // 307 template <typename Request> SendStreamRequest(const Request & request)308 Status SendStreamRequest(const Request& request) 309 PW_LOCKS_EXCLUDED(rpc_lock()) { 310 RpcLockGuard lock; 311 return PwpbSendStream(*this, request, serde_); 312 } 313 314 private: 315 template <typename CallType, typename... Request> SetCallbacksAndSendRequest(CallType & call,Endpoint & client,const PwpbMethodSerde & serde,Function<void (const Response &)> && on_next,Function<void (Status)> && on_completed,Function<void (Status)> && on_error,const Request &...request)316 static void SetCallbacksAndSendRequest( 317 CallType& call, 318 Endpoint& client, 319 const PwpbMethodSerde& serde, 320 Function<void(const Response&)>&& on_next, 321 Function<void(Status)>&& on_completed, 322 Function<void(Status)>&& on_error, 323 const Request&... request) PW_UNLOCK_FUNCTION(rpc_lock()) { 324 call.set_pwpb_on_next_locked(std::move(on_next)); 325 call.set_on_completed_locked(std::move(on_completed)); 326 call.set_on_error_locked(std::move(on_error)); 327 328 if constexpr (sizeof...(Request) == 0u) { 329 call.SendInitialClientRequest({}); 330 } else { 331 PwpbSendInitialRequest(call, serde.request(), request...); 332 } 333 client.CleanUpCalls(); 334 } 335 set_pwpb_on_next_locked(Function<void (const Response & response)> && on_next)336 void set_pwpb_on_next_locked( 337 Function<void(const Response& response)>&& on_next) 338 PW_EXCLUSIVE_LOCKS_REQUIRED(rpc_lock()) { 339 pwpb_on_next_ = std::move(on_next); 340 341 Call::set_on_next_locked( 342 [this](ConstByteSpan payload) PW_NO_LOCK_SAFETY_ANALYSIS { 343 DecodeToStructAndInvokeOnNext( 344 payload, serde_->response(), pwpb_on_next_); 345 }); 346 } 347 348 const PwpbMethodSerde* serde_ PW_GUARDED_BY(rpc_lock()); 349 Function<void(const Response&)> pwpb_on_next_ PW_GUARDED_BY(rpc_lock()); 350 }; 351 352 } // namespace internal 353 354 // The PwpbClientReaderWriter is used to send and receive typed messages in a 355 // pw_protobuf bidirectional streaming RPC. 356 // 357 // These classes use private inheritance to hide the internal::Call API while 358 // allow direct use of its public and protected functions. 359 template <typename Request, typename Response> 360 class PwpbClientReaderWriter 361 : private internal::PwpbStreamResponseClientCall<Response> { 362 public: 363 // Allow default construction so that users can declare a variable into 364 // which to move client reader/writers from RPC calls. 365 constexpr PwpbClientReaderWriter() = default; 366 367 PwpbClientReaderWriter(PwpbClientReaderWriter&&) = default; 368 PwpbClientReaderWriter& operator=(PwpbClientReaderWriter&&) = default; 369 370 using internal::Call::active; 371 using internal::Call::channel_id; 372 373 // Writes a request. Returns the following Status codes: 374 // 375 // OK - the request was successfully sent 376 // FAILED_PRECONDITION - the writer is closed 377 // INTERNAL - pw_rpc was unable to encode the pw_protobuf message 378 // other errors - the ChannelOutput failed to send the packet; the error 379 // codes are determined by the ChannelOutput implementation 380 // Write(const Request & request)381 Status Write(const Request& request) { 382 return internal::PwpbStreamResponseClientCall<Response>::SendStreamRequest( 383 request); 384 } 385 386 // Notifies the server that the client has requested to stop communication by 387 // sending CLIENT_REQUEST_COMPLETION. 388 using internal::ClientCall::RequestCompletion; 389 390 // Cancels this RPC. Closes the call locally and sends a CANCELLED error to 391 // the server. 392 using internal::Call::Cancel; 393 394 // Closes this RPC locally. Sends a CLIENT_REQUEST_COMPLETION, but no 395 // cancellation packet. Future packets for this RPC are dropped, and the 396 // client sends a FAILED_PRECONDITION error in response because the call is 397 // not active. 398 using internal::ClientCall::Abandon; 399 400 // Closes this RPC locally and waits for any running callbacks to complete. 401 // Sends a CLIENT_REQUEST_COMPLETION, but no cancellation packet. Future 402 // packets for this RPC are dropped, and the client sends a 403 // FAILED_PRECONDITION error in response because the call is not active. 404 using internal::ClientCall::CloseAndWaitForCallbacks; 405 406 // Functions for setting RPC event callbacks. 407 using internal::PwpbStreamResponseClientCall<Response>::set_on_next; 408 using internal::StreamResponseClientCall::set_on_completed; 409 using internal::StreamResponseClientCall::set_on_error; 410 411 protected: 412 friend class internal::PwpbStreamResponseClientCall<Response>; 413 PwpbClientReaderWriter(internal::LockedEndpoint & client,uint32_t channel_id_v,uint32_t service_id,uint32_t method_id,const PwpbMethodSerde & serde)414 PwpbClientReaderWriter(internal::LockedEndpoint& client, 415 uint32_t channel_id_v, 416 uint32_t service_id, 417 uint32_t method_id, 418 const PwpbMethodSerde& serde) 419 PW_EXCLUSIVE_LOCKS_REQUIRED(internal::rpc_lock()) 420 : internal::PwpbStreamResponseClientCall<Response>( 421 client, 422 channel_id_v, 423 service_id, 424 method_id, 425 MethodType::kBidirectionalStreaming, 426 serde) {} 427 }; 428 429 // The PwpbClientReader is used to receive typed messages and send a typed 430 // response in a pw_protobuf client streaming RPC. 431 // 432 // These classes use private inheritance to hide the internal::Call API while 433 // allow direct use of its public and protected functions. 434 template <typename Response> 435 class PwpbClientReader 436 : private internal::PwpbStreamResponseClientCall<Response> { 437 public: 438 // Allow default construction so that users can declare a variable into 439 // which to move client reader/writers from RPC calls. 440 constexpr PwpbClientReader() = default; 441 442 PwpbClientReader(PwpbClientReader&&) = default; 443 PwpbClientReader& operator=(PwpbClientReader&&) = default; 444 445 using internal::StreamResponseClientCall::active; 446 using internal::StreamResponseClientCall::channel_id; 447 448 using internal::Call::Cancel; 449 using internal::Call::RequestCompletion; 450 using internal::ClientCall::Abandon; 451 using internal::ClientCall::CloseAndWaitForCallbacks; 452 453 // Functions for setting RPC event callbacks. 454 using internal::PwpbStreamResponseClientCall<Response>::set_on_next; 455 using internal::StreamResponseClientCall::set_on_completed; 456 using internal::StreamResponseClientCall::set_on_error; 457 458 private: 459 friend class internal::PwpbStreamResponseClientCall<Response>; 460 PwpbClientReader(internal::LockedEndpoint & client,uint32_t channel_id_v,uint32_t service_id,uint32_t method_id,const PwpbMethodSerde & serde)461 PwpbClientReader(internal::LockedEndpoint& client, 462 uint32_t channel_id_v, 463 uint32_t service_id, 464 uint32_t method_id, 465 const PwpbMethodSerde& serde) 466 PW_EXCLUSIVE_LOCKS_REQUIRED(internal::rpc_lock()) 467 : internal::PwpbStreamResponseClientCall<Response>( 468 client, 469 channel_id_v, 470 service_id, 471 method_id, 472 MethodType::kServerStreaming, 473 serde) {} 474 }; 475 476 // The PwpbClientWriter is used to send typed responses in a pw_protobuf server 477 // streaming RPC. 478 // 479 // These classes use private inheritance to hide the internal::Call API while 480 // allow direct use of its public and protected functions. 481 template <typename Request, typename Response> 482 class PwpbClientWriter 483 : private internal::PwpbUnaryResponseClientCall<Response> { 484 public: 485 // Allow default construction so that users can declare a variable into 486 // which to move client reader/writers from RPC calls. 487 constexpr PwpbClientWriter() = default; 488 489 PwpbClientWriter(PwpbClientWriter&&) = default; 490 PwpbClientWriter& operator=(PwpbClientWriter&&) = default; 491 492 using internal::UnaryResponseClientCall::active; 493 using internal::UnaryResponseClientCall::channel_id; 494 495 // Writes a request. Returns the following Status codes: 496 // 497 // OK - the request was successfully sent 498 // FAILED_PRECONDITION - the writer is closed 499 // INTERNAL - pw_rpc was unable to encode the pw_protobuf message 500 // other errors - the ChannelOutput failed to send the packet; the error 501 // codes are determined by the ChannelOutput implementation 502 // Write(const Request & request)503 Status Write(const Request& request) { 504 return internal::PwpbUnaryResponseClientCall<Response>::SendStreamRequest( 505 request); 506 } 507 508 using internal::Call::Cancel; 509 using internal::Call::RequestCompletion; 510 using internal::ClientCall::Abandon; 511 using internal::ClientCall::CloseAndWaitForCallbacks; 512 513 // Functions for setting RPC event callbacks. 514 using internal::PwpbUnaryResponseClientCall<Response>::set_on_completed; 515 using internal::UnaryResponseClientCall::set_on_error; 516 517 private: 518 friend class internal::PwpbUnaryResponseClientCall<Response>; 519 PwpbClientWriter(internal::LockedEndpoint & client,uint32_t channel_id_v,uint32_t service_id,uint32_t method_id,const PwpbMethodSerde & serde)520 PwpbClientWriter(internal::LockedEndpoint& client, 521 uint32_t channel_id_v, 522 uint32_t service_id, 523 uint32_t method_id, 524 const PwpbMethodSerde& serde) 525 PW_EXCLUSIVE_LOCKS_REQUIRED(internal::rpc_lock()) 526 527 : internal::PwpbUnaryResponseClientCall<Response>( 528 client, 529 channel_id_v, 530 service_id, 531 method_id, 532 MethodType::kClientStreaming, 533 serde) {} 534 }; 535 536 // The PwpbUnaryReceiver is used to handle a typed response to a pw_protobuf 537 // unary RPC. 538 // 539 // These classes use private inheritance to hide the internal::Call API while 540 // allow direct use of its public and protected functions. 541 template <typename Response> 542 class PwpbUnaryReceiver 543 : private internal::PwpbUnaryResponseClientCall<Response> { 544 public: 545 // Allow default construction so that users can declare a variable into 546 // which to move client reader/writers from RPC calls. 547 constexpr PwpbUnaryReceiver() = default; 548 549 PwpbUnaryReceiver(PwpbUnaryReceiver&&) = default; 550 PwpbUnaryReceiver& operator=(PwpbUnaryReceiver&&) = default; 551 552 using internal::Call::active; 553 using internal::Call::channel_id; 554 555 // Functions for setting RPC event callbacks. 556 using internal::Call::set_on_error; 557 using internal::PwpbUnaryResponseClientCall<Response>::set_on_completed; 558 559 using internal::Call::Cancel; 560 using internal::ClientCall::Abandon; 561 using internal::ClientCall::CloseAndWaitForCallbacks; 562 563 private: 564 friend class internal::PwpbUnaryResponseClientCall<Response>; 565 PwpbUnaryReceiver(internal::LockedEndpoint & client,uint32_t channel_id_v,uint32_t service_id,uint32_t method_id,const PwpbMethodSerde & serde)566 PwpbUnaryReceiver(internal::LockedEndpoint& client, 567 uint32_t channel_id_v, 568 uint32_t service_id, 569 uint32_t method_id, 570 const PwpbMethodSerde& serde) 571 PW_EXCLUSIVE_LOCKS_REQUIRED(internal::rpc_lock()) 572 : internal::PwpbUnaryResponseClientCall<Response>(client, 573 channel_id_v, 574 service_id, 575 method_id, 576 MethodType::kUnary, 577 serde) {} 578 }; 579 580 } // namespace pw::rpc 581