Skip to content

Commit 7a2e337

Browse files
authored
[border-agent] signal TXT data change when Id is updated (openthread#11457)
This commit updates the `BorderAgent` to ensure that if its `Id` is changed using the `SetId()` method, any consequent changes to the generated TXT data for the MeshCoP service are correctly signaled. This signaling is performed using the "Service TXT Data changed callback". This commit also updates `test_border_agent` to validate this.
1 parent 05c6234 commit 7a2e337

3 files changed

Lines changed: 65 additions & 8 deletions

File tree

src/core/meshcop/border_agent.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ Error BorderAgent::GetId(Id &aId)
7373

7474
if (Get<Settings>().Read<Settings::BorderAgentId>(mId) != kErrorNone)
7575
{
76-
Random::NonCrypto::Fill(mId);
76+
mId.GenerateRandom();
7777
SuccessOrExit(error = Get<Settings>().Save<Settings::BorderAgentId>(mId));
7878
}
7979

@@ -88,9 +88,15 @@ Error BorderAgent::SetId(const Id &aId)
8888
{
8989
Error error = kErrorNone;
9090

91+
if (mIdInitialized)
92+
{
93+
VerifyOrExit(aId != mId);
94+
}
95+
9196
SuccessOrExit(error = Get<Settings>().Save<Settings::BorderAgentId>(aId));
9297
mId = aId;
9398
mIdInitialized = true;
99+
PostServiceTask();
94100

95101
exit:
96102
return error;

src/core/meshcop/border_agent.hpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include "common/non_copyable.hpp"
5050
#include "common/notifier.hpp"
5151
#include "common/owned_ptr.hpp"
52+
#include "common/random.hpp"
5253
#include "common/tasklet.hpp"
5354
#include "meshcop/dataset.hpp"
5455
#include "meshcop/secure_transport.hpp"
@@ -77,7 +78,6 @@ class BorderAgent : public InstanceLocator, private NonCopyable
7778
class CoapDtlsSession;
7879

7980
public:
80-
typedef otBorderAgentId Id; ///< Border Agent ID.
8181
typedef otBorderAgentCounters Counters; ///< Border Agent Counters.
8282
typedef otBorderAgentSessionInfo SessionInfo; ///< A session info.
8383
typedef otBorderAgentMeshCoPServiceChangedCallback ServiceChangedCallback; ///< Service changed callback.
@@ -121,6 +121,21 @@ class BorderAgent : public InstanceLocator, private NonCopyable
121121
explicit BorderAgent(Instance &aInstance);
122122

123123
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
124+
/**
125+
* Represents a Border Agent Identifier.
126+
*/
127+
struct Id : public otBorderAgentId, public Clearable<Id>, public Equatable<Id>
128+
{
129+
static constexpr uint16_t kLength = OT_BORDER_AGENT_ID_LENGTH; ///< The ID length (number of bytes).
130+
131+
/**
132+
* Generates a random ID.
133+
*/
134+
void GenerateRandom(void) { Random::NonCrypto::Fill(mId); }
135+
};
136+
137+
static_assert(sizeof(Id) == Id::kLength, "sizeof(Id) is not valid");
138+
124139
/**
125140
* Gets the randomly generated Border Agent ID.
126141
*
@@ -142,7 +157,7 @@ class BorderAgent : public InstanceLocator, private NonCopyable
142157
* to set the ID only once after factory reset. If the ID has never been set by calling this
143158
* method, a random ID will be generated and returned when `GetId()` is called.
144159
*
145-
* @param[out] aId specifies the Border Agent ID.
160+
* @param[in] aId The Border Agent ID.
146161
*
147162
* @retval kErrorNone If successfully set the Border Agent ID.
148163
* @retval ... If failed to set the Border Agent ID.

tests/nexus/test_border_agent.cpp

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,7 @@ class TxtDataTester
751751
: mBorderAgent(aBorderAgent)
752752
, mIsRunning(false)
753753
, mUdpPort(0)
754+
, mCallbackInvoked(false)
754755
{
755756
}
756757

@@ -761,6 +762,7 @@ class TxtDataTester
761762
mIsRunning = mBorderAgent.IsRunning();
762763
mUdpPort = mBorderAgent.GetUdpPort();
763764
SuccessOrQuit(mBorderAgent.PrepareServiceTxtData(mTxtData));
765+
mCallbackInvoked = true;
764766
}
765767

766768
bool FindTxtEntry(const char *aKey, TxtEntry &aTxtEntry)
@@ -785,6 +787,7 @@ class TxtDataTester
785787
BorderAgent::ServiceTxtData mTxtData;
786788
bool mIsRunning;
787789
uint16_t mUdpPort;
790+
bool mCallbackInvoked;
788791
};
789792

790793
template <typename ObjectType> bool CheckObjectSameAsTxtEntryData(const TxtEntry &aTxtEntry, const ObjectType &aObject)
@@ -802,15 +805,19 @@ template <> bool CheckObjectSameAsTxtEntryData<NameData>(const TxtEntry &aTxtEnt
802805

803806
void TestBorderAgentTxtDataCallback(void)
804807
{
805-
Core nexus;
806-
Node &node0 = nexus.CreateNode();
808+
Core nexus;
809+
Node &node0 = nexus.CreateNode();
810+
TxtDataTester txtDataTester(node0.Get<BorderAgent>());
811+
TxtEntry txtEntry;
812+
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
813+
BorderAgent::Id id;
814+
BorderAgent::Id newId;
815+
#endif
807816

808817
Log("------------------------------------------------------------------------------------------------------");
809818
Log("TestBorderAgentTxtDataCallback");
810819

811820
nexus.AdvanceTime(0);
812-
TxtDataTester txtDataTester(node0.Get<BorderAgent>());
813-
TxtEntry txtEntry;
814821

815822
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
816823
// 1. Set MeshCoP service change callback. Will get initial values.
@@ -819,9 +826,9 @@ void TestBorderAgentTxtDataCallback(void)
819826
nexus.AdvanceTime(1);
820827

821828
// 1.1 Check the initial TXT entries
829+
VerifyOrQuit(txtDataTester.mCallbackInvoked);
822830
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
823831
VerifyOrQuit(txtDataTester.FindTxtEntry("id", txtEntry));
824-
BorderAgent::Id id;
825832
VerifyOrQuit(node0.Get<BorderAgent>().GetId(id) == kErrorNone);
826833
VerifyOrQuit(CheckObjectSameAsTxtEntryData(txtEntry, id));
827834
#endif
@@ -844,11 +851,13 @@ void TestBorderAgentTxtDataCallback(void)
844851

845852
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
846853
// 2. Join Thread network and check updated values and states.
854+
txtDataTester.mCallbackInvoked = false;
847855
Log("Join Thread network and check updated Txt data and states");
848856
node0.Form();
849857
nexus.AdvanceTime(50 * Time::kOneSecondInMsec);
850858

851859
// 2.1 Check the initial TXT entries
860+
VerifyOrQuit(txtDataTester.mCallbackInvoked);
852861
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
853862
VerifyOrQuit(txtDataTester.FindTxtEntry("id", txtEntry));
854863
VerifyOrQuit(node0.Get<BorderAgent>().GetId(id) == kErrorNone);
@@ -872,6 +881,33 @@ void TestBorderAgentTxtDataCallback(void)
872881
// 2.2 Check the Border Agent state
873882
VerifyOrQuit(txtDataTester.mIsRunning == true);
874883
VerifyOrQuit(txtDataTester.mUdpPort != 0);
884+
885+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
886+
887+
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
888+
Log("Change the Border Agent ID and validate that TXT data changed and callback is invoked");
889+
890+
newId.GenerateRandom();
891+
VerifyOrQuit(newId != id);
892+
893+
txtDataTester.mCallbackInvoked = false;
894+
SuccessOrQuit(node0.Get<BorderAgent>().SetId(newId));
895+
896+
nexus.AdvanceTime(1);
897+
898+
VerifyOrQuit(txtDataTester.mCallbackInvoked);
899+
VerifyOrQuit(txtDataTester.FindTxtEntry("id", txtEntry));
900+
VerifyOrQuit(CheckObjectSameAsTxtEntryData(txtEntry, newId));
901+
902+
// Validate that setting the ID to the same value as before is
903+
// correctly detected and does not trigger the callback.
904+
905+
txtDataTester.mCallbackInvoked = false;
906+
SuccessOrQuit(node0.Get<BorderAgent>().SetId(newId));
907+
nexus.AdvanceTime(1);
908+
VerifyOrQuit(!txtDataTester.mCallbackInvoked);
909+
910+
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
875911
}
876912

877913
} // namespace Nexus

0 commit comments

Comments
 (0)