/* * * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * * 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 * * http://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. */ #include "RpcClientProcessor.h" #include #include #include "pw_hdlc/decoder.h" #include "pw_hdlc/default_addresses.h" #include "pw_hdlc/rpc_channel.h" #include "pw_stream/socket_stream.h" namespace chip { namespace rpc { namespace client { namespace { // Constants constexpr size_t kMaxTransmissionUnit = 256; const char * kDefaultRpcServerAddress = "127.0.0.1"; // RPC Stream and Channel Setup pw::stream::SocketStream rpcSocketStream; pw::hdlc::RpcChannelOutput hdlcChannelOutput(rpcSocketStream, pw::hdlc::kDefaultRpcAddress, "HDLC channel"); pw::rpc::Channel channels[] = { pw::rpc::Channel::Create<1>(&hdlcChannelOutput) }; pw::rpc::Client rpcClient(channels); // RPC Stream and Channel Setup uint16_t rpcServerPort = 0; const char * rpcServerAddress = kDefaultRpcServerAddress; // Function to process incoming packets void ProcessPackets() { std::array inputBuf; pw::hdlc::Decoder decoder(inputBuf); while (true) { std::array data; auto ret = rpcSocketStream.Read(data); if (!ret.ok()) { if (ret.status() == pw::Status::OutOfRange()) { // Handle remote disconnect rpcSocketStream.Close(); return; } continue; } for (std::byte byte : ret.value()) { auto result = decoder.Process(byte); if (!result.ok()) { // Wait for more bytes that form a complete packet continue; } pw::hdlc::Frame & frame = result.value(); if (frame.address() != pw::hdlc::kDefaultRpcAddress) { // Wrong address; ignore the packet continue; } rpcClient.ProcessPacket(frame.data()).IgnoreError(); } } } } // namespace void SetRpcServerAddress(const char * address) { rpcServerAddress = address; } void SetRpcServerPort(uint16_t port) { rpcServerPort = port; } pw::rpc::Client & GetDefaultRpcClient() { return rpcClient; } CHIP_ERROR StartPacketProcessing() { if (rpcSocketStream.Connect(rpcServerAddress, rpcServerPort) != PW_STATUS_OK) { // Handle connection error return CHIP_ERROR_NOT_CONNECTED; } // Start a thread to process incoming packets std::thread packet_processor(ProcessPackets); packet_processor.detach(); return CHIP_NO_ERROR; } } // namespace client } // namespace rpc } // namespace chip