• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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 #pragma once
15 
16 #include "pw_assert/light.h"
17 #include "pw_containers/intrusive_list.h"
18 #include "pw_rpc/internal/channel.h"
19 #include "pw_rpc/internal/packet.h"
20 #include "pw_status/status.h"
21 
22 namespace pw::rpc::internal {
23 
24 // Base class representing an active client-side RPC call. Implementations
25 // derive from this class and provide a packet handler function which is
26 // called with a reference to the ClientCall object and the received packet.
27 class BaseClientCall : public IntrusiveList<BaseClientCall>::Item {
28  public:
29   using ResponseHandler = void (*)(BaseClientCall&, const Packet&);
30 
BaseClientCall(rpc::Channel * channel,uint32_t service_id,uint32_t method_id,ResponseHandler handler)31   constexpr BaseClientCall(rpc::Channel* channel,
32                            uint32_t service_id,
33                            uint32_t method_id,
34                            ResponseHandler handler)
35       : channel_(static_cast<Channel*>(channel)),
36         service_id_(service_id),
37         method_id_(method_id),
38         handler_(handler),
39         active_(true) {
40     PW_ASSERT(channel_ != nullptr);
41     Register();
42   }
43 
~BaseClientCall()44   ~BaseClientCall() { Unregister(); }
45 
46   BaseClientCall(const BaseClientCall&) = delete;
47   BaseClientCall& operator=(const BaseClientCall&) = delete;
48 
BaseClientCall(BaseClientCall && other)49   BaseClientCall(BaseClientCall&& other) { *this = std::move(other); }
50   BaseClientCall& operator=(BaseClientCall&& other);
51 
active()52   constexpr bool active() const { return active_; }
53 
54   void Cancel();
55 
56  protected:
channel()57   constexpr Channel& channel() const { return *channel_; }
service_id()58   constexpr uint32_t service_id() const { return service_id_; }
method_id()59   constexpr uint32_t method_id() const { return method_id_; }
60 
61   std::span<std::byte> AcquirePayloadBuffer();
62   Status ReleasePayloadBuffer(std::span<const std::byte> payload);
63 
64   void Unregister();
65 
66  private:
67   friend class rpc::Client;
68 
69   void Register();
70 
HandleResponse(const Packet & packet)71   void HandleResponse(const Packet& packet) { handler_(*this, packet); }
72 
73   Packet NewPacket(PacketType type,
74                    std::span<const std::byte> payload = {}) const;
75 
76   Channel* channel_;
77   uint32_t service_id_;
78   uint32_t method_id_;
79   Channel::OutputBuffer request_;
80   ResponseHandler handler_;
81   bool active_;
82 };
83 
84 }  // namespace pw::rpc::internal
85