// Copyright 2023 The Pigweed Authors // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy of // the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations under // the License. #define PW_LOG_MODULE_NAME "IO" #include "pw_digital_io/digital_io_service.h" #include "pw_digital_io/digital_io.pwpb.h" #include "pw_log/log.h" #include "pw_result/result.h" #include "pw_rpc/pwpb/server_reader_writer.h" #include "pw_status/status.h" namespace pw::digital_io { void DigitalIoService::Enable( const pwpb::DigitalIoEnableRequest::Message& request, rpc::PwpbUnaryResponder& responder) { Status result = OkStatus(); if (request.line_index >= lines_.size()) { result = Status::InvalidArgument(); } else { auto& line = lines_[request.line_index].get(); if (request.enable) { result = line.Enable(); } else { result = line.Disable(); } } if (const auto finished = responder.Finish({}, result); !finished.ok()) { PW_LOG_ERROR("Enable failed to send response %d", finished.code()); } } void DigitalIoService::SetState( const pwpb::DigitalIoSetStateRequest::Message& request, rpc::PwpbUnaryResponder& responder) { Status result = OkStatus(); if (request.line_index >= lines_.size()) { result = Status::InvalidArgument(); } else { auto& line = lines_[request.line_index].get(); if (!line.provides_output()) { result = Status::InvalidArgument(); } else { if (request.state == pwpb::DigitalIoState::kActive) { result = line.SetStateActive(); } else { result = line.SetStateInactive(); } } } if (const auto finished = responder.Finish({}, result); !finished.ok()) { PW_LOG_ERROR("SetState failed to send response %d", finished.code()); } } void DigitalIoService::GetState( const pwpb::DigitalIoGetStateRequest::Message& request, rpc::PwpbUnaryResponder& responder) { pw::Result result; if (request.line_index >= lines_.size()) { result = pw::Status::InvalidArgument(); } else { auto& line = lines_[request.line_index].get(); if (!line.provides_input()) { result = pw::Status::InvalidArgument(); } else { result = line.GetState(); } } auto finished = pw::OkStatus(); if (result.ok()) { pwpb::DigitalIoState state = *result == State::kActive ? pwpb::DigitalIoState::kActive : pwpb::DigitalIoState::kInactive; finished = responder.Finish({.state = state}, OkStatus()); } else { finished = responder.Finish({}, result.status()); } if (!finished.ok()) { PW_LOG_ERROR("GetState failed to send response %d", finished.code()); } } } // namespace pw::digital_io