[border-agent] signal TXT data change when Id is updated (#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.
This commit is contained in:
Abtin Keshavarzian
2025-04-29 08:56:18 -07:00
committed by GitHub
parent 05c623454b
commit 7a2e337493
3 changed files with 65 additions and 8 deletions
+7 -1
View File
@@ -73,7 +73,7 @@ Error BorderAgent::GetId(Id &aId)
if (Get<Settings>().Read<Settings::BorderAgentId>(mId) != kErrorNone)
{
Random::NonCrypto::Fill(mId);
mId.GenerateRandom();
SuccessOrExit(error = Get<Settings>().Save<Settings::BorderAgentId>(mId));
}
@@ -88,9 +88,15 @@ Error BorderAgent::SetId(const Id &aId)
{
Error error = kErrorNone;
if (mIdInitialized)
{
VerifyOrExit(aId != mId);
}
SuccessOrExit(error = Get<Settings>().Save<Settings::BorderAgentId>(aId));
mId = aId;
mIdInitialized = true;
PostServiceTask();
exit:
return error;
+17 -2
View File
@@ -49,6 +49,7 @@
#include "common/non_copyable.hpp"
#include "common/notifier.hpp"
#include "common/owned_ptr.hpp"
#include "common/random.hpp"
#include "common/tasklet.hpp"
#include "meshcop/dataset.hpp"
#include "meshcop/secure_transport.hpp"
@@ -77,7 +78,6 @@ class BorderAgent : public InstanceLocator, private NonCopyable
class CoapDtlsSession;
public:
typedef otBorderAgentId Id; ///< Border Agent ID.
typedef otBorderAgentCounters Counters; ///< Border Agent Counters.
typedef otBorderAgentSessionInfo SessionInfo; ///< A session info.
typedef otBorderAgentMeshCoPServiceChangedCallback ServiceChangedCallback; ///< Service changed callback.
@@ -121,6 +121,21 @@ public:
explicit BorderAgent(Instance &aInstance);
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
/**
* Represents a Border Agent Identifier.
*/
struct Id : public otBorderAgentId, public Clearable<Id>, public Equatable<Id>
{
static constexpr uint16_t kLength = OT_BORDER_AGENT_ID_LENGTH; ///< The ID length (number of bytes).
/**
* Generates a random ID.
*/
void GenerateRandom(void) { Random::NonCrypto::Fill(mId); }
};
static_assert(sizeof(Id) == Id::kLength, "sizeof(Id) is not valid");
/**
* Gets the randomly generated Border Agent ID.
*
@@ -142,7 +157,7 @@ public:
* to set the ID only once after factory reset. If the ID has never been set by calling this
* method, a random ID will be generated and returned when `GetId()` is called.
*
* @param[out] aId specifies the Border Agent ID.
* @param[in] aId The Border Agent ID.
*
* @retval kErrorNone If successfully set the Border Agent ID.
* @retval ... If failed to set the Border Agent ID.
+41 -5
View File
@@ -751,6 +751,7 @@ public:
: mBorderAgent(aBorderAgent)
, mIsRunning(false)
, mUdpPort(0)
, mCallbackInvoked(false)
{
}
@@ -761,6 +762,7 @@ public:
mIsRunning = mBorderAgent.IsRunning();
mUdpPort = mBorderAgent.GetUdpPort();
SuccessOrQuit(mBorderAgent.PrepareServiceTxtData(mTxtData));
mCallbackInvoked = true;
}
bool FindTxtEntry(const char *aKey, TxtEntry &aTxtEntry)
@@ -785,6 +787,7 @@ public:
BorderAgent::ServiceTxtData mTxtData;
bool mIsRunning;
uint16_t mUdpPort;
bool mCallbackInvoked;
};
template <typename ObjectType> bool CheckObjectSameAsTxtEntryData(const TxtEntry &aTxtEntry, const ObjectType &aObject)
@@ -802,15 +805,19 @@ template <> bool CheckObjectSameAsTxtEntryData<NameData>(const TxtEntry &aTxtEnt
void TestBorderAgentTxtDataCallback(void)
{
Core nexus;
Node &node0 = nexus.CreateNode();
Core nexus;
Node &node0 = nexus.CreateNode();
TxtDataTester txtDataTester(node0.Get<BorderAgent>());
TxtEntry txtEntry;
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
BorderAgent::Id id;
BorderAgent::Id newId;
#endif
Log("------------------------------------------------------------------------------------------------------");
Log("TestBorderAgentTxtDataCallback");
nexus.AdvanceTime(0);
TxtDataTester txtDataTester(node0.Get<BorderAgent>());
TxtEntry txtEntry;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// 1. Set MeshCoP service change callback. Will get initial values.
@@ -819,9 +826,9 @@ void TestBorderAgentTxtDataCallback(void)
nexus.AdvanceTime(1);
// 1.1 Check the initial TXT entries
VerifyOrQuit(txtDataTester.mCallbackInvoked);
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
VerifyOrQuit(txtDataTester.FindTxtEntry("id", txtEntry));
BorderAgent::Id id;
VerifyOrQuit(node0.Get<BorderAgent>().GetId(id) == kErrorNone);
VerifyOrQuit(CheckObjectSameAsTxtEntryData(txtEntry, id));
#endif
@@ -844,11 +851,13 @@ void TestBorderAgentTxtDataCallback(void)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// 2. Join Thread network and check updated values and states.
txtDataTester.mCallbackInvoked = false;
Log("Join Thread network and check updated Txt data and states");
node0.Form();
nexus.AdvanceTime(50 * Time::kOneSecondInMsec);
// 2.1 Check the initial TXT entries
VerifyOrQuit(txtDataTester.mCallbackInvoked);
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
VerifyOrQuit(txtDataTester.FindTxtEntry("id", txtEntry));
VerifyOrQuit(node0.Get<BorderAgent>().GetId(id) == kErrorNone);
@@ -872,6 +881,33 @@ void TestBorderAgentTxtDataCallback(void)
// 2.2 Check the Border Agent state
VerifyOrQuit(txtDataTester.mIsRunning == true);
VerifyOrQuit(txtDataTester.mUdpPort != 0);
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
Log("Change the Border Agent ID and validate that TXT data changed and callback is invoked");
newId.GenerateRandom();
VerifyOrQuit(newId != id);
txtDataTester.mCallbackInvoked = false;
SuccessOrQuit(node0.Get<BorderAgent>().SetId(newId));
nexus.AdvanceTime(1);
VerifyOrQuit(txtDataTester.mCallbackInvoked);
VerifyOrQuit(txtDataTester.FindTxtEntry("id", txtEntry));
VerifyOrQuit(CheckObjectSameAsTxtEntryData(txtEntry, newId));
// Validate that setting the ID to the same value as before is
// correctly detected and does not trigger the callback.
txtDataTester.mCallbackInvoked = false;
SuccessOrQuit(node0.Get<BorderAgent>().SetId(newId));
nexus.AdvanceTime(1);
VerifyOrQuit(!txtDataTester.mCallbackInvoked);
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
}
} // namespace Nexus