1*61c4878aSAndroid Build Coastguard Worker // Copyright 2020 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker //
3*61c4878aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker // the License at
6*61c4878aSAndroid Build Coastguard Worker //
7*61c4878aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker //
9*61c4878aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker // the License.
14*61c4878aSAndroid Build Coastguard Worker
15*61c4878aSAndroid Build Coastguard Worker // clang-format off
16*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc/internal/log_config.h" // PW_LOG_* macros must be first.
17*61c4878aSAndroid Build Coastguard Worker
18*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc/nanopb/internal/method.h"
19*61c4878aSAndroid Build Coastguard Worker // clang-format on
20*61c4878aSAndroid Build Coastguard Worker
21*61c4878aSAndroid Build Coastguard Worker #include "pb_decode.h"
22*61c4878aSAndroid Build Coastguard Worker #include "pb_encode.h"
23*61c4878aSAndroid Build Coastguard Worker #include "pw_log/log.h"
24*61c4878aSAndroid Build Coastguard Worker #include "pw_rpc/internal/packet.h"
25*61c4878aSAndroid Build Coastguard Worker
26*61c4878aSAndroid Build Coastguard Worker namespace pw::rpc {
27*61c4878aSAndroid Build Coastguard Worker
28*61c4878aSAndroid Build Coastguard Worker namespace internal {
29*61c4878aSAndroid Build Coastguard Worker
CallSynchronousUnary(const CallContext & context,const Packet & request,void * request_struct,void * response_struct) const30*61c4878aSAndroid Build Coastguard Worker void NanopbMethod::CallSynchronousUnary(const CallContext& context,
31*61c4878aSAndroid Build Coastguard Worker const Packet& request,
32*61c4878aSAndroid Build Coastguard Worker void* request_struct,
33*61c4878aSAndroid Build Coastguard Worker void* response_struct) const {
34*61c4878aSAndroid Build Coastguard Worker if (!DecodeRequest(context, request, request_struct)) {
35*61c4878aSAndroid Build Coastguard Worker rpc_lock().unlock();
36*61c4878aSAndroid Build Coastguard Worker return;
37*61c4878aSAndroid Build Coastguard Worker }
38*61c4878aSAndroid Build Coastguard Worker
39*61c4878aSAndroid Build Coastguard Worker NanopbServerCall responder(context.ClaimLocked(), MethodType::kUnary);
40*61c4878aSAndroid Build Coastguard Worker rpc_lock().unlock();
41*61c4878aSAndroid Build Coastguard Worker const Status status = function_.synchronous_unary(
42*61c4878aSAndroid Build Coastguard Worker context.service(), request_struct, response_struct);
43*61c4878aSAndroid Build Coastguard Worker responder.SendUnaryResponse(response_struct, status).IgnoreError();
44*61c4878aSAndroid Build Coastguard Worker }
45*61c4878aSAndroid Build Coastguard Worker
CallUnaryRequest(const CallContext & context,MethodType type,const Packet & request,void * request_struct) const46*61c4878aSAndroid Build Coastguard Worker void NanopbMethod::CallUnaryRequest(const CallContext& context,
47*61c4878aSAndroid Build Coastguard Worker MethodType type,
48*61c4878aSAndroid Build Coastguard Worker const Packet& request,
49*61c4878aSAndroid Build Coastguard Worker void* request_struct) const {
50*61c4878aSAndroid Build Coastguard Worker if (!DecodeRequest(context, request, request_struct)) {
51*61c4878aSAndroid Build Coastguard Worker rpc_lock().unlock();
52*61c4878aSAndroid Build Coastguard Worker return;
53*61c4878aSAndroid Build Coastguard Worker }
54*61c4878aSAndroid Build Coastguard Worker
55*61c4878aSAndroid Build Coastguard Worker NanopbServerCall server_writer(context.ClaimLocked(), type);
56*61c4878aSAndroid Build Coastguard Worker rpc_lock().unlock();
57*61c4878aSAndroid Build Coastguard Worker function_.unary_request(context.service(), request_struct, server_writer);
58*61c4878aSAndroid Build Coastguard Worker }
59*61c4878aSAndroid Build Coastguard Worker
DecodeRequest(const CallContext & context,const Packet & request,void * proto_struct) const60*61c4878aSAndroid Build Coastguard Worker bool NanopbMethod::DecodeRequest(const CallContext& context,
61*61c4878aSAndroid Build Coastguard Worker const Packet& request,
62*61c4878aSAndroid Build Coastguard Worker void* proto_struct) const {
63*61c4878aSAndroid Build Coastguard Worker if (serde_.request().Decode(request.payload(), proto_struct).ok()) {
64*61c4878aSAndroid Build Coastguard Worker return true;
65*61c4878aSAndroid Build Coastguard Worker }
66*61c4878aSAndroid Build Coastguard Worker
67*61c4878aSAndroid Build Coastguard Worker // The channel is known to exist. It was found when the request was processed
68*61c4878aSAndroid Build Coastguard Worker // and the lock has been held since, so GetInternalChannel cannot fail.
69*61c4878aSAndroid Build Coastguard Worker context.server()
70*61c4878aSAndroid Build Coastguard Worker .GetInternalChannel(context.channel_id())
71*61c4878aSAndroid Build Coastguard Worker ->Send(Packet::ServerError(request, Status::DataLoss()))
72*61c4878aSAndroid Build Coastguard Worker .IgnoreError();
73*61c4878aSAndroid Build Coastguard Worker PW_LOG_WARN("Nanopb failed to decode request payload from channel %u",
74*61c4878aSAndroid Build Coastguard Worker unsigned(context.channel_id()));
75*61c4878aSAndroid Build Coastguard Worker return false;
76*61c4878aSAndroid Build Coastguard Worker }
77*61c4878aSAndroid Build Coastguard Worker
78*61c4878aSAndroid Build Coastguard Worker } // namespace internal
79*61c4878aSAndroid Build Coastguard Worker } // namespace pw::rpc
80