blob: fc5f9d1a4d69faf7c4d79619ca5d5269712cc452 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/connectivity/weave/weavestack/app.h"
#include <lib/syslog/cpp/logger.h>
#include <Weave/DeviceLayer/PlatformManager.h>
namespace weavestack {
namespace {
using nl::Weave::DeviceLayer::PlatformMgr;
using nl::Weave::DeviceLayer::PlatformMgrImpl;
} // namespace
App::App() = default;
App::~App() {
Quit();
}
void App::Quit()
{
running_.clear();
PlatformMgrImpl().GetSystemLayer().WakeSelect();
Join();
}
// TODO(fxb/47096): tracks the integration test.
WEAVE_ERROR App::HandlePackets(void) {
int numFDs = 0;
fd_set readFDs, writeFDs, exceptFDs;
FD_ZERO(&readFDs);
FD_ZERO(&writeFDs);
FD_ZERO(&exceptFDs);
struct timeval sleepTime;
sleepTime.tv_sec = 0;
sleepTime.tv_usec = 0;
PlatformMgrImpl().GetSystemLayer().PrepareSelect(numFDs, &readFDs, &writeFDs, &exceptFDs, sleepTime);
PlatformMgrImpl().GetInetLayer().PrepareSelect(numFDs, &readFDs, &writeFDs, &exceptFDs, sleepTime);
int res = select(numFDs, &readFDs, &writeFDs, &exceptFDs, &sleepTime);
if (res < 0) {
FX_LOGS(ERROR) << "select failed: " << strerror(errno);
return WEAVE_ERROR_CONNECTION_ABORTED;
}
PlatformMgrImpl().GetSystemLayer().HandleSelectResult(res, &readFDs, &writeFDs, &exceptFDs);
PlatformMgrImpl().GetInetLayer().HandleSelectResult(res, &readFDs, &writeFDs, &exceptFDs);
return WEAVE_NO_ERROR;
}
WEAVE_ERROR App::Init() {
WEAVE_ERROR err;
syslog::InitLogger({"weavestack"});
err = PlatformMgr().InitWeaveStack();
if (err != WEAVE_NO_ERROR) {
FX_LOGS(ERROR) << "InitWeaveStack() failed " << nl::ErrorStr(err);
return err;
}
return WEAVE_NO_ERROR;
}
void App::RunLoop() {
while (running_.test_and_set()) {
WEAVE_ERROR ret = HandlePackets();
if (ret != WEAVE_NO_ERROR) {
FX_LOGS(ERROR) << "HandlePackets() failed " << ret;
break;
}
}
running_.clear();
}
void App::Join() {
if (thread_.joinable()) {
thread_.join();
}
}
WEAVE_ERROR App::Start() {
running_.test_and_set();
thread_ = std::thread{&App::RunLoop, this};
return WEAVE_NO_ERROR;
}
} // namespace weavestack