Snap for 11967491 from 2db9f0ea9952d7704e5a21009c1d9ff47570fbc4 to 24Q3-release Change-Id: Icf1f3513625eae92eb2957fc86fabec29748a4c0
diff --git a/src/android/aidl/com/android/server/thread/openthread/DnsTxtAttribute.aidl b/src/android/aidl/com/android/server/thread/openthread/DnsTxtAttribute.aidl index 8fa9ed8..d2db1f4 100644 --- a/src/android/aidl/com/android/server/thread/openthread/DnsTxtAttribute.aidl +++ b/src/android/aidl/com/android/server/thread/openthread/DnsTxtAttribute.aidl
@@ -31,6 +31,8 @@ /** * An attribute in DNS TXT Resource Record. */ +@JavaOnlyImmutable +@JavaDerive(equals=true, toString=true) parcelable DnsTxtAttribute { String name; // The name of the attribute. byte[] value; // The value of the attribute.
diff --git a/src/android/aidl/com/android/server/thread/openthread/MeshcopTxtAttributes.aidl b/src/android/aidl/com/android/server/thread/openthread/MeshcopTxtAttributes.aidl index 3ac1db8..f97965d 100644 --- a/src/android/aidl/com/android/server/thread/openthread/MeshcopTxtAttributes.aidl +++ b/src/android/aidl/com/android/server/thread/openthread/MeshcopTxtAttributes.aidl
@@ -28,6 +28,8 @@ package com.android.server.thread.openthread; +import com.android.server.thread.openthread.DnsTxtAttribute; + /** * A collection of MeshCoP TXT entries that are supplied by Android platform. */ @@ -53,5 +55,11 @@ */ byte[] vendorOui; - // More vendor-specific (v*) TXT entries can be added here + /** + * Non-standard (vendor-specific) _meshcop._udp TXT entries. + * + * All TXT keys MUST start with "v". + * + */ + List<DnsTxtAttribute> nonStandardTxtEntries; }
diff --git a/src/android/java/com/android/server/thread/openthread/testing/FakeOtDaemon.java b/src/android/java/com/android/server/thread/openthread/testing/FakeOtDaemon.java index 931e373..993b9fc 100644 --- a/src/android/java/com/android/server/thread/openthread/testing/FakeOtDaemon.java +++ b/src/android/java/com/android/server/thread/openthread/testing/FakeOtDaemon.java
@@ -52,6 +52,7 @@ import java.time.Duration; import java.util.ArrayList; +import java.util.List; import java.util.NoSuchElementException; /** A fake implementation of the {@link IOtDaemon} AIDL API for testing. */ @@ -158,6 +159,8 @@ mOverriddenMeshcopTxts.vendorOui = overriddenMeshcopTxts.vendorOui.clone(); mOverriddenMeshcopTxts.vendorName = overriddenMeshcopTxts.vendorName; mOverriddenMeshcopTxts.modelName = overriddenMeshcopTxts.modelName; + mOverriddenMeshcopTxts.nonStandardTxtEntries = + List.copyOf(overriddenMeshcopTxts.nonStandardTxtEntries); registerStateCallback(callback, PROACTIVE_LISTENER_ID); }
diff --git a/src/android/otdaemon_server.cpp b/src/android/otdaemon_server.cpp index 030556e..5f5ea3c 100644 --- a/src/android/otdaemon_server.cpp +++ b/src/android/otdaemon_server.cpp
@@ -477,14 +477,26 @@ const std::shared_ptr<IOtDaemonCallback> &aCallback, const std::string &aCountryCode) { - std::string instanceName = aMeshcopTxts.vendorName + " " + aMeshcopTxts.modelName; + std::string instanceName = aMeshcopTxts.vendorName + " " + aMeshcopTxts.modelName; + Mdns::Publisher::TxtList nonStandardTxts; + otbrError error; setCountryCodeInternal(aCountryCode, nullptr /* aReceiver */); registerStateCallbackInternal(aCallback, -1 /* listenerId */); mMdnsPublisher.SetINsdPublisher(aINsdPublisher); - mBorderAgent.SetMeshCopServiceValues(instanceName, aMeshcopTxts.modelName, aMeshcopTxts.vendorName, - aMeshcopTxts.vendorOui); + + for (const auto &txtAttr : aMeshcopTxts.nonStandardTxtEntries) + { + nonStandardTxts.emplace_back(txtAttr.name.c_str(), txtAttr.value.data(), txtAttr.value.size()); + } + error = mBorderAgent.SetMeshCopServiceValues(instanceName, aMeshcopTxts.modelName, aMeshcopTxts.vendorName, + aMeshcopTxts.vendorOui, nonStandardTxts); + if (error != OTBR_ERROR_NONE) + { + otbrLogCrit("Failed to set MeshCoP values: %d", static_cast<int>(error)); + } + mBorderAgent.SetEnabled(enabled); if (enabled)
diff --git a/src/border_agent/border_agent.cpp b/src/border_agent/border_agent.cpp index b6acf18..96700d5 100644 --- a/src/border_agent/border_agent.cpp +++ b/src/border_agent/border_agent.cpp
@@ -146,20 +146,30 @@ mNcp.AddThreadStateChangedCallback([this](otChangedFlags aFlags) { HandleThreadStateChanged(aFlags); }); } -otbrError BorderAgent::SetMeshCopServiceValues(const std::string &aServiceInstanceName, - const std::string &aProductName, - const std::string &aVendorName, - const std::vector<uint8_t> &aVendorOui) +otbrError BorderAgent::SetMeshCopServiceValues(const std::string &aServiceInstanceName, + const std::string &aProductName, + const std::string &aVendorName, + const std::vector<uint8_t> &aVendorOui, + const Mdns::Publisher::TxtList &aNonStandardTxtEntries) { otbrError error = OTBR_ERROR_NONE; VerifyOrExit(aProductName.size() <= kMaxProductNameLength, error = OTBR_ERROR_INVALID_ARGS); VerifyOrExit(aVendorName.size() <= kMaxVendorNameLength, error = OTBR_ERROR_INVALID_ARGS); VerifyOrExit(aVendorOui.empty() || aVendorOui.size() == kVendorOuiLength, error = OTBR_ERROR_INVALID_ARGS); + for (const auto &txtEntry : aNonStandardTxtEntries) + { + VerifyOrExit(!txtEntry.mKey.empty() && txtEntry.mKey.front() == 'v', error = OTBR_ERROR_INVALID_ARGS); + } mProductName = aProductName; mVendorName = aVendorName; mVendorOui = aVendorOui; + mMeshCopTxtUpdate.clear(); + for (const auto &txtEntry : aNonStandardTxtEntries) + { + mMeshCopTxtUpdate[txtEntry.mKey] = txtEntry.mValue; + } mBaseServiceInstanceName = aServiceInstanceName; @@ -317,7 +327,6 @@ } } -#if OTBR_ENABLE_DBUS_SERVER void AppendVendorTxtEntries(const std::map<std::string, std::vector<uint8_t>> &aVendorEntries, Mdns::Publisher::TxtList &aTxtList) { @@ -343,7 +352,6 @@ } } } -#endif void BorderAgent::PublishMeshCopService(void) { @@ -417,9 +425,8 @@ #if OTBR_ENABLE_BORDER_ROUTING AppendOmrTxtEntry(*instance, txtList); #endif -#if OTBR_ENABLE_DBUS_SERVER + AppendVendorTxtEntries(mMeshCopTxtUpdate, txtList); -#endif if (otBorderAgentGetState(instance) != OT_BORDER_AGENT_STATE_STOPPED) {
diff --git a/src/border_agent/border_agent.hpp b/src/border_agent/border_agent.hpp index 39a0d2c..b5b71f5 100644 --- a/src/border_agent/border_agent.hpp +++ b/src/border_agent/border_agent.hpp
@@ -99,22 +99,24 @@ * * This method must be called before this BorderAgent is enabled by SetEnabled. * - * @param[in] aServiceInstanceName The service instance name; suffix may be appended to this value to avoid - * name conflicts. - * @param[in] aProductName The product name; must not exceed length of kMaxProductNameLength - * and an empty string will be ignored. - * @param[in] aVendorName The vendor name; must not exceed length of kMaxVendorNameLength - * and an empty string will be ignored. - * @param[in] aVendorOui The vendor OUI; must have length of 3 bytes or be empty and ignored. + * @param[in] aServiceInstanceName The service instance name; suffix may be appended to this value to avoid + * name conflicts. + * @param[in] aProductName The product name; must not exceed length of kMaxProductNameLength + * and an empty string will be ignored. + * @param[in] aVendorName The vendor name; must not exceed length of kMaxVendorNameLength + * and an empty string will be ignored. + * @param[in] aVendorOui The vendor OUI; must have length of 3 bytes or be empty and ignored. + * @param[in] aNonStandardTxtEntries Non-standard (vendor-specific) TXT entries whose key MUST start with "v" * * @returns OTBR_ERROR_INVALID_ARGS If aVendorName, aProductName or aVendorOui exceeds the - * allowed ranges. + * allowed ranges or invalid keys are found in aNonStandardTxtEntries * @returns OTBR_ERROR_NONE If successfully set the meshcop service values. */ - otbrError SetMeshCopServiceValues(const std::string &aServiceInstanceName, - const std::string &aProductName, - const std::string &aVendorName, - const std::vector<uint8_t> &aVendorOui = {}); + otbrError SetMeshCopServiceValues(const std::string &aServiceInstanceName, + const std::string &aProductName, + const std::string &aVendorName, + const std::vector<uint8_t> &aVendorOui = {}, + const Mdns::Publisher::TxtList &aNonStandardTxtEntries = {}); /** * This method enables/disables the Border Agent. @@ -153,9 +155,7 @@ Mdns::Publisher &mPublisher; bool mIsEnabled; -#if OTBR_ENABLE_DBUS_SERVER std::map<std::string, std::vector<uint8_t>> mMeshCopTxtUpdate; -#endif std::vector<uint8_t> mVendorOui;
diff --git a/tests/android/java/com/android/server/thread/openthread/testing/FakeOtDaemonTest.java b/tests/android/java/com/android/server/thread/openthread/testing/FakeOtDaemonTest.java index 2ee0553..8e214f4 100644 --- a/tests/android/java/com/android/server/thread/openthread/testing/FakeOtDaemonTest.java +++ b/tests/android/java/com/android/server/thread/openthread/testing/FakeOtDaemonTest.java
@@ -53,6 +53,7 @@ import androidx.test.filters.SmallTest; import com.android.server.thread.openthread.BackboneRouterState; +import com.android.server.thread.openthread.DnsTxtAttribute; import com.android.server.thread.openthread.IChannelMasksReceiver; import com.android.server.thread.openthread.INsdPublisher; import com.android.server.thread.openthread.IOtDaemonCallback; @@ -67,6 +68,7 @@ import org.mockito.MockitoAnnotations; import java.util.ArrayList; +import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; @@ -119,6 +121,7 @@ mOverriddenMeshcopTxts.vendorName = TEST_VENDOR_NAME; mOverriddenMeshcopTxts.vendorOui = TEST_VENDOR_OUI; mOverriddenMeshcopTxts.modelName = TEST_MODEL_NAME; + mOverriddenMeshcopTxts.nonStandardTxtEntries = List.of(); } @Test @@ -126,6 +129,8 @@ mOverriddenMeshcopTxts.vendorName = TEST_VENDOR_NAME; mOverriddenMeshcopTxts.vendorOui = TEST_VENDOR_OUI; mOverriddenMeshcopTxts.modelName = TEST_MODEL_NAME; + mOverriddenMeshcopTxts.nonStandardTxtEntries = + List.of(new DnsTxtAttribute("v2", new byte[] {0x02})); mFakeOtDaemon.initialize( mMockTunFd, @@ -141,6 +146,8 @@ assertThat(meshcopTxts.vendorName).isEqualTo(TEST_VENDOR_NAME); assertThat(meshcopTxts.vendorOui).isEqualTo(TEST_VENDOR_OUI); assertThat(meshcopTxts.modelName).isEqualTo(TEST_MODEL_NAME); + assertThat(meshcopTxts.nonStandardTxtEntries) + .containsExactly(new DnsTxtAttribute("v2", new byte[] {0x02})); assertThat(mFakeOtDaemon.getTunFd()).isEqualTo(mMockTunFd); assertThat(mFakeOtDaemon.getEnabledState()).isEqualTo(OT_STATE_ENABLED); assertThat(mFakeOtDaemon.getNsdPublisher()).isEqualTo(mMockNsdPublisher);