19#include "pw_containers/intrusive_list.h"
20#include "pw_rpc/channel.h"
21#include "pw_rpc/internal/call.h"
22#include "pw_rpc/internal/endpoint.h"
23#include "pw_rpc/internal/grpc.h"
24#include "pw_rpc/internal/lock.h"
25#include "pw_rpc/internal/method.h"
26#include "pw_rpc/internal/method_info.h"
27#include "pw_rpc/internal/server_call.h"
28#include "pw_rpc/service.h"
29#include "pw_span/span.h"
30#include "pw_status/status.h"
36class Server :
public internal::Endpoint {
40#if PW_RPC_DYNAMIC_ALLOCATION
41 _PW_RPC_CONSTEXPR
Server() =
default;
55 template <
typename... OtherServices>
56 void RegisterService(
Service& service, OtherServices&... services)
58 internal::RpcLockGuard lock;
59 services_.push_front(service);
63 (services_.push_front(services), ...);
70 bool IsServiceRegistered(
const Service& service)
const
72 internal::RpcLockGuard lock;
74 for (
const Service& svc : services_) {
75 if (&svc == &service) {
83 template <
typename... OtherServices>
84 void UnregisterService(
Service& service, OtherServices&... services)
86 internal::rpc_lock().lock();
87 UnregisterServiceLocked(service,
static_cast<Service&
>(services)...);
103 friend class internal::Call;
104 friend class ServerTestHelper;
108 friend class pw::grpc::PwRpcHandler;
111 friend class RawServerReaderWriter;
112 friend class RawServerWriter;
113 friend class RawServerReader;
114 friend class RawUnaryResponder;
116 template <
typename,
typename>
117 friend class NanopbServerReaderWriter;
119 friend class NanopbServerWriter;
120 template <
typename,
typename>
121 friend class NanopbServerReader;
123 friend class NanopbUnaryResponder;
125 template <
typename,
typename>
126 friend class PwpbServerReaderWriter;
128 friend class PwpbServerWriter;
129 template <
typename,
typename>
130 friend class PwpbServerReader;
132 friend class PwpbUnaryResponder;
140 template <
typename CallType,
142 MethodType kExpected,
143 typename ServiceImpl,
145 [[nodiscard]] CallType OpenCall(uint32_t channel_id,
146 ServiceImpl& service,
147 const MethodImpl& method)
149 internal::rpc_lock().lock();
151 using Info = internal::MethodInfo<kMethod>;
152 if constexpr (kExpected == MethodType::kUnary) {
154 Info::kType == kExpected,
155 "UnaryResponder objects may only be opened for unary RPCs.");
156 }
else if constexpr (kExpected == MethodType::kServerStreaming) {
158 Info::kType == kExpected,
159 "ServerWriters may only be opened for server streaming RPCs.");
160 }
else if constexpr (kExpected == MethodType::kClientStreaming) {
162 Info::kType == kExpected,
163 "ServerReaders may only be opened for client streaming RPCs.");
164 }
else if constexpr (kExpected == MethodType::kBidirectionalStreaming) {
165 static_assert(Info::kType == kExpected,
166 "ServerReaderWriters may only be opened for bidirectional "
170 CallType call(internal::CallContext(
171 *
this, channel_id, service, method, internal::kOpenCallId)
177 std::tuple<Service*, const internal::Method*> FindMethod(uint32_t service_id,
181 std::tuple<Service*, const internal::Method*> FindMethodLocked(
182 uint32_t service_id, uint32_t method_id)
185 std::tuple<Service*, const internal::Method*> FindMethodLocked(
186 const internal::Packet& packet)
189 return FindMethodLocked(packet.service_id(), packet.method_id());
192 void HandleCompletionRequest(
const internal::Packet& packet,
194 IntrusiveList<internal::Call>::iterator call)
197 void HandleClientStreamPacket(
const internal::Packet& packet,
199 IntrusiveList<internal::Call>::iterator call)
202 template <
typename... OtherServices>
203 void UnregisterServiceLocked(
Service& service, OtherServices&... services)
205 services_.remove(service);
206 UnregisterServiceLocked(services...);
207 AbortCallsForService(service);
210 void UnregisterServiceLocked() {}
212 Status ProcessPacket(internal::Packet packet)
216 using Endpoint::active_call_count;
217 using Endpoint::ClaimLocked;
218 using Endpoint::CleanUpCalls;
219 using Endpoint::GetInternalChannel;
Definition: intrusive_list.h:88
Definition: channel.h:161
Definition: span_impl.h:235
#define PW_GUARDED_BY(x)
Definition: lock_annotations.h:60
#define PW_EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: lock_annotations.h:146
#define PW_UNLOCK_FUNCTION(...)
Definition: lock_annotations.h:247
#define PW_LOCKS_EXCLUDED(...)
Definition: lock_annotations.h:176