Skip to content

Commit

Permalink
[controller] add ncp host (#2329)
Browse files Browse the repository at this point in the history
This commit adds the `NcpHost` class which is the implementation of
`ThreadController` under NCP case.

This commit updates `ThreadController::Create` to create `NcpHost`
under the NCP case, allowing `otbr-agent` to start when the
co-processor is a NCP, though no functionalities have been implemented
yet.

This commit also adds a CI workflow to use expect script to test
otbr-agent in NCP case. For this PR, a simple test is added to start
otbr-agent with NCP (dry run) and check the co-processor version.
  • Loading branch information
Irving-cl authored Jun 20, 2024
1 parent 8838874 commit 7b7f332
Show file tree
Hide file tree
Showing 8 changed files with 494 additions and 5 deletions.
67 changes: 67 additions & 0 deletions .github/workflows/ncp_mode.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#
# Copyright (c) 2024, The OpenThread Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of the copyright holder nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#

name: NcpMode

on:
push:
branches-ignore:
- 'dependabot/**'
pull_request:
branches:
- 'main'

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || (github.repository == 'openthread/ot-br-posix' && github.run_id) || github.ref }}
cancel-in-progress: true

jobs:

ncp_mode:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
mdns: ["mDNSResponder", "avahi"]
env:
BUILD_TARGET: check
OTBR_MDNS: ${{ matrix.mdns }}
OTBR_COVERAGE: 1
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Bootstrap
run: tests/scripts/bootstrap.sh
- name: Build
run: |
script/test build
- name: Run
run: OTBR_VERBOSE=${RUNNER_DEBUG:-0} script/test ncp_mode
- name: Codecov
uses: codecov/codecov-action@v4
3 changes: 3 additions & 0 deletions script/test
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ main()
meshcop)
top_builddir="${OTBR_TOP_BUILDDIR}" print_result ./tests/scripts/meshcop
;;
ncp_mode)
top_builddir="${OTBR_TOP_BUILDDIR}" print_result ./tests/scripts/ncp_mode
;;
openwrt)
print_result ./tests/scripts/openwrt
;;
Expand Down
2 changes: 2 additions & 0 deletions src/ncp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#

add_library(otbr-ncp
ncp_host.cpp
ncp_host.hpp
rcp_host.cpp
rcp_host.hpp
thread_host.cpp
Expand Down
89 changes: 89 additions & 0 deletions src/ncp/ncp_host.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright (c) 2024, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#define OTBR_LOG_TAG "NCP_HOST"

#include "ncp_host.hpp"

#include <openthread/error.h>
#include <openthread/thread.h>

#include <openthread/openthread-system.h>

#include "lib/spinel/spinel_driver.hpp"

namespace otbr {
namespace Ncp {

NcpHost::NcpHost(bool aDryRun)
: mSpinelDriver(*static_cast<ot::Spinel::SpinelDriver *>(otSysGetSpinelDriver()))
{
memset(&mConfig, 0, sizeof(mConfig));
mConfig.mDryRun = aDryRun;
mConfig.mSpeedUpFactor = 1;
}

const char *NcpHost::GetCoprocessorVersion(void)
{
return mSpinelDriver.GetVersion();
}

void NcpHost::Init(void)
{
otSysInit(&mConfig);
}

void NcpHost::Deinit(void)
{
otSysDeinit();
}

void NcpHost::GetDeviceRole(DeviceRoleHandler aHandler)
{
// TODO: Implement the API with NCP Spinel
aHandler(OT_ERROR_NOT_IMPLEMENTED, OT_DEVICE_ROLE_DISABLED);
}

void NcpHost::Process(const MainloopContext &aMainloop)
{
mSpinelDriver.Process(&aMainloop);
}

void NcpHost::Update(MainloopContext &aMainloop)
{
mSpinelDriver.GetSpinelInterface()->UpdateFdSet(&aMainloop);

if (mSpinelDriver.HasPendingFrame())
{
aMainloop.mTimeout.tv_sec = 0;
aMainloop.mTimeout.tv_usec = 0;
}
}

} // namespace Ncp
} // namespace otbr
82 changes: 82 additions & 0 deletions src/ncp/ncp_host.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright (c) 2024, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

/**
* @file
* This file includes definitions of OpenThead Host for NCP.
*/

#ifndef OTBR_AGENT_NCP_HOST_HPP_
#define OTBR_AGENT_NCP_HOST_HPP_

#include "lib/spinel/coprocessor_type.h"
#include "lib/spinel/spinel_driver.hpp"

#include "common/mainloop.hpp"
#include "ncp/thread_host.hpp"

namespace otbr {
namespace Ncp {

class NcpHost : public MainloopProcessor, public ThreadHost
{
public:
/**
* Constructor.
*
* @param[in] aDryRun TRUE to indicate dry-run mode. FALSE otherwise.
*
*/
NcpHost(bool aDryRun);

/**
* Destructor.
*
*/
~NcpHost(void) override = default;

// ThreadHost methods
void GetDeviceRole(const DeviceRoleHandler aHandler) override;
CoprocessorType GetCoprocessorType(void) override { return OT_COPROCESSOR_NCP; }
const char *GetCoprocessorVersion(void) override;
void Init(void) override;
void Deinit(void) override;

// MainloopProcessor methods
void Update(MainloopContext &aMainloop) override;
void Process(const MainloopContext &aMainloop) override;

private:
ot::Spinel::SpinelDriver &mSpinelDriver;
otPlatformConfig mConfig;
};

} // namespace Ncp
} // namespace otbr

#endif // OTBR_AGENT_NCP_HOST_HPP_
16 changes: 11 additions & 5 deletions src/ncp/thread_host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include "lib/spinel/coprocessor_type.h"

#include "ncp_host.hpp"
#include "rcp_host.hpp"

namespace otbr {
Expand Down Expand Up @@ -63,14 +64,19 @@ std::unique_ptr<ThreadHost> ThreadHost::Create(const char *

coprocessorType = otSysInitCoprocessor(&urls);

if (coprocessorType == OT_COPROCESSOR_RCP)
switch (coprocessorType)
{
case OT_COPROCESSOR_RCP:
host = MakeUnique<RcpHost>(aInterfaceName, aRadioUrls, aBackboneInterfaceName, aDryRun, aEnableAutoAttach);
}
else
{
// TODO: add NCP type
break;

case OT_COPROCESSOR_NCP:
host = MakeUnique<NcpHost>(aDryRun);
break;

default:
DieNow("Unknown coprocessor type!");
break;
}

return host;
Expand Down
16 changes: 16 additions & 0 deletions tests/scripts/expect/ncp_version.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/expect -f

set timeout 1

# Spawn the otbr-agent with NCP in Dry Run mode
spawn $::env(EXP_OTBR_AGENT_PATH) -I $::env(EXP_TUN_NAME) -v -d7 --radio-version "spinel+hdlc+forkpty://$::env(EXP_OT_NCP_PATH)?forkpty-arg=$::env(EXP_LEADER_NODE_ID)"

# Expect the NCP version
expect -re {OPENTHREAD/[0-9a-z]{9}; SIMULATION} {
} timeout {
puts "timeout!"
exit 1
}

# Wait for the spawned process to terminate
expect eof
Loading

0 comments on commit 7b7f332

Please sign in to comment.