From 639e6277ce35edaaf2cfdb3c3274fdcb07762247 Mon Sep 17 00:00:00 2001 From: Rongli Sun Date: Tue, 6 Aug 2024 22:46:50 +0800 Subject: [PATCH] [cli] add state command (#293) This commit adds `state` command to show the state ("active", "petitioning", "connected", or "disabled"). --- src/app/cli/README.md | 16 +++++++++++++++ src/app/cli/interpreter.cpp | 30 +++++++++++++++++++++++++++++ src/app/cli/interpreter.hpp | 1 + src/app/cli/interpreter_test.cpp | 31 ++++++++++++++++++++++++++++++ src/app/commissioner_app.cpp | 5 +++++ src/app/commissioner_app.hpp | 2 ++ src/app/commissioner_app_dummy.cpp | 5 +++++ src/app/commissioner_app_mock.hpp | 2 ++ 8 files changed, 92 insertions(+) diff --git a/src/app/cli/README.md b/src/app/cli/README.md index f843ba4e..543ceeba 100644 --- a/src/app/cli/README.md +++ b/src/app/cli/README.md @@ -338,6 +338,22 @@ To start establishing secure session, and petitioning as the active Commissioner > ``` +### State + +Show the state of the commissioner candidate + +- "active": It's now an active commissioner accepted and will periodically sends keep alive messages in background +- "petitioning": It's attempting to petition as active commissioner +- "connected": The commissioner candidate has successfully established secure session with border agent +- "disabled": It's not an active commissioner, nor securely connected with the Border Agent + +```shell +> state +connected +[done] +> +``` + ### Active Upon success, the Commissioner periodically sends keep alive messages in background. The Commissioner now is in the active state: diff --git a/src/app/cli/interpreter.cpp b/src/app/cli/interpreter.cpp index aa002a2e..3641d300 100644 --- a/src/app/cli/interpreter.cpp +++ b/src/app/cli/interpreter.cpp @@ -200,6 +200,7 @@ const std::map &Interpreter::mEvaluatorMap {"announce", &Interpreter::ProcessAnnounce}, {"panid", &Interpreter::ProcessPanId}, {"energy", &Interpreter::ProcessEnergy}, {"exit", &Interpreter::ProcessExit}, {"quit", &Interpreter::ProcessExit}, {"help", &Interpreter::ProcessHelp}, + {"state", &Interpreter::ProcessState}, }; const std::map &Interpreter::mUsageMap = *new std::map{ @@ -207,6 +208,7 @@ const std::map &Interpreter::mUsageMap = *new std::map "config set admincode <9-digits-thread-administrator-passcode>\n" "config get pskc\n" "config set pskc "}, + {"state", "state"}, {"start", "start [--connect-only]\n" "start [ --nwk ]"}, {"stop", "stop\n" @@ -288,6 +290,7 @@ const std::vector &Interpreter::mMultiNetworkSyntax = Interpreter::StringArray{"start"}, Interpreter::StringArray{"stop"}, Interpreter::StringArray{"active"}, + Interpreter::StringArray{"state"}, Interpreter::StringArray{"sessionid"}, Interpreter::StringArray{"bbrdataset", "get"}, Interpreter::StringArray{"commdataset", "get"}, @@ -942,6 +945,33 @@ Interpreter::Value Interpreter::ProcessConfig(const Expression &aExpr) return value; } +Interpreter::Value Interpreter::ProcessState(const Expression &) +{ + Value value; + CommissionerAppPtr commissioner = nullptr; + + SuccessOrExit(value = mJobManager->GetSelectedCommissioner(commissioner)); + + switch (commissioner->GetState()) + { + case State::kDisabled: + value = std::string("disabled"); + break; + case State::kConnected: + value = std::string("connected"); + break; + case State::kPetitioning: + value = std::string("petitioning"); + break; + case State::kActive: + value = std::string("active"); + break; + } + +exit: + return value; +} + Interpreter::Value Interpreter::ProcessStart(const Expression &aExpr) { Value value; diff --git a/src/app/cli/interpreter.hpp b/src/app/cli/interpreter.hpp index c4e0d690..cc1c1010 100644 --- a/src/app/cli/interpreter.hpp +++ b/src/app/cli/interpreter.hpp @@ -202,6 +202,7 @@ class Interpreter Value ProcessConfig(const Expression &aExpr); Value ProcessStart(const Expression &aExpr); + Value ProcessState(const Expression &aExpr); Value ProcessStop(const Expression &aExpr); Value ProcessActive(const Expression &aExpr); Value ProcessToken(const Expression &aExpr); diff --git a/src/app/cli/interpreter_test.cpp b/src/app/cli/interpreter_test.cpp index e0e3db38..12fc5638 100644 --- a/src/app/cli/interpreter_test.cpp +++ b/src/app/cli/interpreter_test.cpp @@ -949,6 +949,37 @@ TEST_F(InterpreterTestSuite, PC_StartLegacySyntaxSuccess) EXPECT_TRUE(value.HasNoError()); } +TEST_F(InterpreterTestSuite, PC_State) +{ + TestContext ctx; + InitContext(ctx); + + EXPECT_CALL(*ctx.mDefaultCommissionerObject, GetState()) + .Times(4) + .WillOnce(Return(State::kActive)) + .WillOnce(Return(State::kPetitioning)) + .WillOnce(Return(State::kConnected)) + .WillOnce(Return(State::kDisabled)); + + Interpreter::Expression expr; + Interpreter::Value value; + expr = ctx.mInterpreter.ParseExpression("state"); + value = ctx.mInterpreter.Eval(expr); + EXPECT_STREQ("active", value.ToString().c_str()); + + expr = ctx.mInterpreter.ParseExpression("state"); + value = ctx.mInterpreter.Eval(expr); + EXPECT_STREQ("petitioning", value.ToString().c_str()); + + expr = ctx.mInterpreter.ParseExpression("state"); + value = ctx.mInterpreter.Eval(expr); + EXPECT_STREQ("connected", value.ToString().c_str()); + + expr = ctx.mInterpreter.ParseExpression("state"); + value = ctx.mInterpreter.Eval(expr); + EXPECT_STREQ("disabled", value.ToString().c_str()); +} + TEST_F(InterpreterTestSuite, PC_StartLegacyConnectSyntaxErrorFails) { TestContext ctx; diff --git a/src/app/commissioner_app.cpp b/src/app/commissioner_app.cpp index 00731757..5809ba22 100644 --- a/src/app/commissioner_app.cpp +++ b/src/app/commissioner_app.cpp @@ -152,6 +152,11 @@ bool CommissionerApp::IsActive() const return mCommissioner->IsActive(); } +State CommissionerApp::GetState() const +{ + return mCommissioner->GetState(); +} + bool CommissionerApp::IsCcmMode() const { return mCommissioner->IsCcmMode(); diff --git a/src/app/commissioner_app.hpp b/src/app/commissioner_app.hpp index 1b39d089..ae0591cf 100644 --- a/src/app/commissioner_app.hpp +++ b/src/app/commissioner_app.hpp @@ -128,6 +128,8 @@ class CommissionerApp : public CommissionerHandler MOCKABLE Error Connect(const std::string &aBorderAgentAddr, uint16_t aBorderAgentPort); + MOCKABLE State GetState() const; + MOCKABLE Error Start(std::string &aExistingCommissionerId, const std::string &aBorderAgentAddr, uint16_t aBorderAgentPort); diff --git a/src/app/commissioner_app_dummy.cpp b/src/app/commissioner_app_dummy.cpp index 07c2d3f8..549fcfd7 100644 --- a/src/app/commissioner_app_dummy.cpp +++ b/src/app/commissioner_app_dummy.cpp @@ -129,6 +129,11 @@ bool CommissionerApp::IsActive() const return false; } +State CommissionerApp::GetState() const +{ + return State::kDisabled; +} + Error CommissionerApp::SaveNetworkData(const std::string &aFilename) { UNUSED(aFilename); diff --git a/src/app/commissioner_app_mock.hpp b/src/app/commissioner_app_mock.hpp index 2a7303b2..ea47d9fd 100644 --- a/src/app/commissioner_app_mock.hpp +++ b/src/app/commissioner_app_mock.hpp @@ -77,6 +77,8 @@ class CommissionerAppMock : public ::ot::commissioner::CommissionerApp MOCK_METHOD(void, Stop, ()); MOCK_METHOD(void, CancelRequests, ()); MOCK_METHOD(bool, IsActive, (), (const)); + MOCK_METHOD(State, GetState, (), (const)); + MOCK_METHOD(Error, SaveNetworkData, (const std::string &)); MOCK_METHOD(Error, SyncNetworkData, ());