1 // Copyright 2021 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 #include <array> 16 #include <cstddef> 17 #include <cstdint> 18 #include <cstdio> 19 20 #include "pw_assert/check.h" 21 #include "pw_hdlc/rpc_channel.h" 22 #include "pw_hdlc/rpc_packets.h" 23 #include "pw_log/log.h" 24 #include "pw_sync/mutex.h" 25 #include "pw_system/config.h" 26 #include "pw_system/io.h" 27 #include "pw_system/rpc_server.h" 28 29 namespace pw::system { 30 namespace { 31 32 constexpr size_t kMaxTransmissionUnit = PW_SYSTEM_MAX_TRANSMISSION_UNIT; 33 34 hdlc::RpcChannelOutput hdlc_channel_output(GetWriter(), 35 PW_SYSTEM_DEFAULT_RPC_HDLC_ADDRESS, 36 "HDLC channel"); 37 rpc::Channel channels[] = { 38 rpc::Channel::Create<kDefaultRpcChannelId>(&hdlc_channel_output)}; 39 rpc::Server server(channels); 40 41 // Declare a buffer for decoding incoming HDLC frames. 42 std::array<std::byte, kMaxTransmissionUnit> input_buffer; 43 hdlc::Decoder decoder(input_buffer); 44 45 std::array<std::byte, 1> data; 46 47 } // namespace 48 GetRpcServer()49rpc::Server& GetRpcServer() { return server; } 50 51 class RpcDispatchThread final : public thread::ThreadCore { 52 public: 53 RpcDispatchThread() = default; 54 RpcDispatchThread(const RpcDispatchThread&) = delete; 55 RpcDispatchThread(RpcDispatchThread&&) = delete; 56 RpcDispatchThread& operator=(const RpcDispatchThread&) = delete; 57 RpcDispatchThread& operator=(RpcDispatchThread&&) = delete; 58 Run()59 void Run() override { 60 PW_LOG_INFO("Running RPC server"); 61 while (true) { 62 auto ret_val = GetReader().Read(data); 63 if (ret_val.ok()) { 64 for (std::byte byte : ret_val.value()) { 65 if (auto result = decoder.Process(byte); result.ok()) { 66 hdlc::Frame& frame = result.value(); 67 if (frame.address() == PW_SYSTEM_DEFAULT_RPC_HDLC_ADDRESS) { 68 server.ProcessPacket(frame.data(), hdlc_channel_output); 69 } 70 } 71 } 72 } 73 } 74 } 75 }; 76 GetRpcDispatchThread()77thread::ThreadCore& GetRpcDispatchThread() { 78 static RpcDispatchThread rpc_dispatch_thread; 79 return rpc_dispatch_thread; 80 } 81 82 } // namespace pw::system 83