xref: /aosp_15_r20/external/pigweed/pw_digital_io/digital_io_service.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2023 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 #define PW_LOG_MODULE_NAME "IO"
16 
17 #include "pw_digital_io/digital_io_service.h"
18 
19 #include "pw_digital_io/digital_io.pwpb.h"
20 #include "pw_log/log.h"
21 #include "pw_result/result.h"
22 #include "pw_rpc/pwpb/server_reader_writer.h"
23 #include "pw_status/status.h"
24 
25 namespace pw::digital_io {
26 
Enable(const pwpb::DigitalIoEnableRequest::Message & request,rpc::PwpbUnaryResponder<pwpb::DigitalIoEnableResponse::Message> & responder)27 void DigitalIoService::Enable(
28     const pwpb::DigitalIoEnableRequest::Message& request,
29     rpc::PwpbUnaryResponder<pwpb::DigitalIoEnableResponse::Message>&
30         responder) {
31   Status result = OkStatus();
32   if (request.line_index >= lines_.size()) {
33     result = Status::InvalidArgument();
34   } else {
35     auto& line = lines_[request.line_index].get();
36     if (request.enable) {
37       result = line.Enable();
38     } else {
39       result = line.Disable();
40     }
41   }
42 
43   if (const auto finished = responder.Finish({}, result); !finished.ok()) {
44     PW_LOG_ERROR("Enable failed to send response %d", finished.code());
45   }
46 }
47 
SetState(const pwpb::DigitalIoSetStateRequest::Message & request,rpc::PwpbUnaryResponder<pwpb::DigitalIoSetStateResponse::Message> & responder)48 void DigitalIoService::SetState(
49     const pwpb::DigitalIoSetStateRequest::Message& request,
50     rpc::PwpbUnaryResponder<pwpb::DigitalIoSetStateResponse::Message>&
51         responder) {
52   Status result = OkStatus();
53   if (request.line_index >= lines_.size()) {
54     result = Status::InvalidArgument();
55   } else {
56     auto& line = lines_[request.line_index].get();
57     if (!line.provides_output()) {
58       result = Status::InvalidArgument();
59     } else {
60       if (request.state == pwpb::DigitalIoState::kActive) {
61         result = line.SetStateActive();
62       } else {
63         result = line.SetStateInactive();
64       }
65     }
66   }
67 
68   if (const auto finished = responder.Finish({}, result); !finished.ok()) {
69     PW_LOG_ERROR("SetState failed to send response %d", finished.code());
70   }
71 }
72 
GetState(const pwpb::DigitalIoGetStateRequest::Message & request,rpc::PwpbUnaryResponder<pwpb::DigitalIoGetStateResponse::Message> & responder)73 void DigitalIoService::GetState(
74     const pwpb::DigitalIoGetStateRequest::Message& request,
75     rpc::PwpbUnaryResponder<pwpb::DigitalIoGetStateResponse::Message>&
76         responder) {
77   pw::Result<State> result;
78   if (request.line_index >= lines_.size()) {
79     result = pw::Status::InvalidArgument();
80   } else {
81     auto& line = lines_[request.line_index].get();
82     if (!line.provides_input()) {
83       result = pw::Status::InvalidArgument();
84     } else {
85       result = line.GetState();
86     }
87   }
88 
89   auto finished = pw::OkStatus();
90   if (result.ok()) {
91     pwpb::DigitalIoState state = *result == State::kActive
92                                      ? pwpb::DigitalIoState::kActive
93                                      : pwpb::DigitalIoState::kInactive;
94     finished = responder.Finish({.state = state}, OkStatus());
95   } else {
96     finished = responder.Finish({}, result.status());
97   }
98 
99   if (!finished.ok()) {
100     PW_LOG_ERROR("GetState failed to send response %d", finished.code());
101   }
102 }
103 
104 }  // namespace pw::digital_io
105