blob: 2b2fd661bc277150039a585dab5e6c14db8812d9 [file] [log] [blame]
/*
*
* 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 <string>
#include <thread>
#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<std::byte, kMaxTransmissionUnit> inputBuf;
pw::hdlc::Decoder decoder(inputBuf);
while (true)
{
std::array<std::byte, kMaxTransmissionUnit> 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