• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()49 rpc::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()77 thread::ThreadCore& GetRpcDispatchThread() {
78   static RpcDispatchThread rpc_dispatch_thread;
79   return rpc_dispatch_thread;
80 }
81 
82 }  // namespace pw::system
83