aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/android/aidl/com/android/server/thread/openthread/INsdPublisher.aidl26
-rw-r--r--src/android/aidl/com/android/server/thread/openthread/INsdResolveHostCallback.aidl35
-rw-r--r--src/android/aidl/com/android/server/thread/openthread/IOtDaemon.aidl4
-rw-r--r--src/android/aidl/com/android/server/thread/openthread/IOtDaemonCallback.aidl8
-rw-r--r--src/android/aidl/com/android/server/thread/openthread/OnMeshPrefixConfig.aidl41
-rw-r--r--src/android/aidl/com/android/server/thread/openthread/OtDaemonState.aidl3
-rw-r--r--src/android/java/com/android/server/thread/openthread/testing/FakeOtDaemon.java9
-rw-r--r--src/android/mdns_publisher.cpp64
-rw-r--r--src/android/mdns_publisher.hpp46
-rw-r--r--src/android/otdaemon_server.cpp86
-rw-r--r--src/android/otdaemon_server.hpp12
-rw-r--r--tests/android/java/com/android/server/thread/openthread/testing/FakeOtDaemonTest.java2
12 files changed, 294 insertions, 42 deletions
diff --git a/src/android/aidl/com/android/server/thread/openthread/INsdPublisher.aidl b/src/android/aidl/com/android/server/thread/openthread/INsdPublisher.aidl
index 84549f9b..74bec2fb 100644
--- a/src/android/aidl/com/android/server/thread/openthread/INsdPublisher.aidl
+++ b/src/android/aidl/com/android/server/thread/openthread/INsdPublisher.aidl
@@ -32,6 +32,7 @@ import com.android.server.thread.openthread.DnsTxtAttribute;
import com.android.server.thread.openthread.INsdStatusReceiver;
import com.android.server.thread.openthread.INsdDiscoverServiceCallback;
import com.android.server.thread.openthread.INsdResolveServiceCallback;
+import com.android.server.thread.openthread.INsdResolveHostCallback;
/**
* The service which supports mDNS advertising and discovery by {@link NsdManager}.
@@ -150,4 +151,29 @@ oneway interface INsdPublisher {
* service resolution operation
*/
void stopServiceResolution(int listenerId);
+
+ /**
+ * Resolves an mDNS host.
+ *
+ * <p>To stop resolving a host, use stopHostResolution.
+ *
+ * @param name the hostname
+ * @param callback the callback when a host is resolved.
+ * @param listenerId the ID of DnsResolver.Callback which is used to identify the
+ * host resolution operation
+ */
+ void resolveHost(in String name,
+ in INsdResolveHostCallback callback,
+ int listenerId);
+
+ /**
+ * Stops resolving an mDNS host.
+ *
+ * <p>To stop resolving a host, the caller must pass in the same listener ID which was used
+ * when starting resolving the host.
+ *
+ * @param listenerId the ID of the DnsResolver.Callback which is used to identify the
+ * host resolution operation
+ */
+ void stopHostResolution(int listenerId);
}
diff --git a/src/android/aidl/com/android/server/thread/openthread/INsdResolveHostCallback.aidl b/src/android/aidl/com/android/server/thread/openthread/INsdResolveHostCallback.aidl
new file mode 100644
index 00000000..920a181e
--- /dev/null
+++ b/src/android/aidl/com/android/server/thread/openthread/INsdResolveHostCallback.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+package com.android.server.thread.openthread;
+
+/** Receives the information of a resolved host. */
+oneway interface INsdResolveHostCallback {
+ void onHostResolved(in String name,
+ in List<String> addresses);
+}
diff --git a/src/android/aidl/com/android/server/thread/openthread/IOtDaemon.aidl b/src/android/aidl/com/android/server/thread/openthread/IOtDaemon.aidl
index d07f72a5..60ee87b6 100644
--- a/src/android/aidl/com/android/server/thread/openthread/IOtDaemon.aidl
+++ b/src/android/aidl/com/android/server/thread/openthread/IOtDaemon.aidl
@@ -140,9 +140,9 @@ oneway interface IOtDaemon {
* Leaves from the current network.
*
* 1. It returns success immediately if this device has already left or disabled
- * 2. Else if there is already an onging {@code join} request, no action will be taken but
+ * 2. Else if there is already an onging {@code leave} request, no action will be taken but
* the {@code receiver} will be invoked after the previous request is completed
- * 3. Otherwise, OTBR sends Address Release Notification (i.e. ADDR_REL.ntf) to grcefully
+ * 3. Otherwise, OTBR sends Address Release Notification (i.e. ADDR_REL.ntf) to gracefully
* detach from the current network and it takes 1 second to finish
* 4. The Operational Dataset will be removed from persistent storage
*
diff --git a/src/android/aidl/com/android/server/thread/openthread/IOtDaemonCallback.aidl b/src/android/aidl/com/android/server/thread/openthread/IOtDaemonCallback.aidl
index 34bdfaef..7bd6fde6 100644
--- a/src/android/aidl/com/android/server/thread/openthread/IOtDaemonCallback.aidl
+++ b/src/android/aidl/com/android/server/thread/openthread/IOtDaemonCallback.aidl
@@ -31,6 +31,7 @@ package com.android.server.thread.openthread;
import com.android.server.thread.openthread.BackboneRouterState;
import com.android.server.thread.openthread.Ipv6AddressInfo;
import com.android.server.thread.openthread.OtDaemonState;
+import com.android.server.thread.openthread.OnMeshPrefixConfig;
/** OpenThread daemon callbacks. */
oneway interface IOtDaemonCallback {
@@ -60,10 +61,9 @@ oneway interface IOtDaemonCallback {
void onBackboneRouterStateChanged(in BackboneRouterState bbrState);
/**
- * Called when Thread enabled state has changed. Valid values are STATE_* defined in
- * {@link ThreadNetworkController}.
+ * Called when Thread on-mesh prefixes have changed.
*
- * @param enabled {@code true} if Thread is enabled, {@code false} if Thread is disabled.
+ * @param onMeshPrefixConfigList the list of IPv6 prefixes.
*/
- void onThreadEnabledChanged(in int enabled);
+ void onPrefixChanged(in List<OnMeshPrefixConfig> onMeshPrefixConfigList);
}
diff --git a/src/android/aidl/com/android/server/thread/openthread/OnMeshPrefixConfig.aidl b/src/android/aidl/com/android/server/thread/openthread/OnMeshPrefixConfig.aidl
new file mode 100644
index 00000000..b7ee7194
--- /dev/null
+++ b/src/android/aidl/com/android/server/thread/openthread/OnMeshPrefixConfig.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+package com.android.server.thread.openthread;
+
+/**
+ * On-mesh prefix configuration.
+ *
+ * This is a mapping of <a href="https://openthread.io/reference/struct/ot-border-router-config">otBorderRouterConfig</a>
+ */
+parcelable OnMeshPrefixConfig {
+ byte[] prefix; // The raw IPv6 prefix bytes, should be 16 bytes
+ int prefixLength; // The IPv6 prefix length (in bits)
+
+ // More fields of otBorderRouterConfig can be added here when needed.
+}
diff --git a/src/android/aidl/com/android/server/thread/openthread/OtDaemonState.aidl b/src/android/aidl/com/android/server/thread/openthread/OtDaemonState.aidl
index c13a9492..b96baaa5 100644
--- a/src/android/aidl/com/android/server/thread/openthread/OtDaemonState.aidl
+++ b/src/android/aidl/com/android/server/thread/openthread/OtDaemonState.aidl
@@ -48,4 +48,7 @@ parcelable OtDaemonState {
// Active Oprational Dataset encoded as Thread TLVs. Empty array means the dataset doesn't
// exist
byte[] pendingDatasetTlvs;
+
+ // The Thread enabled state OT_STATE_DISABLED, OT_STATE_ENABLED and OT_STATE_DISABLING.
+ int threadEnabled;
}
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 ce50eba9..931e3735 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
@@ -72,7 +72,6 @@ public final class FakeOtDaemon extends IOtDaemon.Stub {
private OtDaemonState mState;
private BackboneRouterState mBbrState;
private boolean mIsInitialized = false;
- private int mThreadEnabled = OT_STATE_DISABLED;
private int mChannelMasksReceiverOtError = OT_ERROR_NONE;
private int mSupportedChannelMask = 0x07FFF800; // from channel 11 to 26
private int mPreferredChannelMask = 0;
@@ -98,12 +97,12 @@ public final class FakeOtDaemon extends IOtDaemon.Stub {
mState.deviceRole = OT_DEVICE_ROLE_DISABLED;
mState.activeDatasetTlvs = new byte[0];
mState.pendingDatasetTlvs = new byte[0];
+ mState.threadEnabled = OT_STATE_DISABLED;
mBbrState = new BackboneRouterState();
mBbrState.multicastForwardingEnabled = false;
mBbrState.listeningAddresses = new ArrayList<>();
mTunFd = null;
- mThreadEnabled = OT_STATE_DISABLED;
mNsdPublisher = null;
mIsInitialized = false;
@@ -151,7 +150,7 @@ public final class FakeOtDaemon extends IOtDaemon.Stub {
throws RemoteException {
mIsInitialized = true;
mTunFd = tunFd;
- mThreadEnabled = enabled ? OT_STATE_ENABLED : OT_STATE_DISABLED;
+ mState.threadEnabled = enabled ? OT_STATE_ENABLED : OT_STATE_DISABLED;
mNsdPublisher = nsdPublisher;
mCountryCode = countryCode;
@@ -181,7 +180,7 @@ public final class FakeOtDaemon extends IOtDaemon.Stub {
}
public int getEnabledState() {
- return mThreadEnabled;
+ return mState.threadEnabled;
}
public OtDaemonState getState() {
@@ -228,7 +227,7 @@ public final class FakeOtDaemon extends IOtDaemon.Stub {
public void setThreadEnabled(boolean enabled, IOtStatusReceiver receiver) {
mHandler.post(
() -> {
- mThreadEnabled = enabled ? OT_STATE_ENABLED : OT_STATE_DISABLED;
+ mState.threadEnabled = enabled ? OT_STATE_ENABLED : OT_STATE_DISABLED;
try {
receiver.onSuccess();
} catch (RemoteException e) {
diff --git a/src/android/mdns_publisher.cpp b/src/android/mdns_publisher.cpp
index 6febeccb..0bade461 100644
--- a/src/android/mdns_publisher.cpp
+++ b/src/android/mdns_publisher.cpp
@@ -108,6 +108,30 @@ Status MdnsPublisher::NsdResolveServiceCallback::onServiceResolved(const std::st
return Status::ok();
}
+Status MdnsPublisher::NsdResolveHostCallback::onHostResolved(const std::string &aName,
+ const std::vector<std::string> &aAddresses)
+{
+ DiscoveredHostInfo info;
+
+ info.mTtl = kDefaultResolvedTtl;
+ for (const auto &addressStr : aAddresses)
+ {
+ Ip6Address address;
+ int error = Ip6Address::FromString(addressStr.c_str(), address);
+
+ if (error != OTBR_ERROR_NONE)
+ {
+ otbrLogInfo("Failed to parse resolved IPv6 address: %s", addressStr.c_str());
+ continue;
+ }
+ info.mAddresses.push_back(address);
+ }
+
+ mSubscription.mPublisher.OnHostResolved(aName, info);
+
+ return Status::ok();
+}
+
void MdnsPublisher::SetINsdPublisher(std::shared_ptr<INsdPublisher> aINsdPublisher)
{
otbrLogInfo("Set INsdPublisher %p", aINsdPublisher.get());
@@ -151,6 +175,12 @@ std::shared_ptr<MdnsPublisher::NsdResolveServiceCallback> CreateNsdResolveServic
return ndk::SharedRefBase::make<MdnsPublisher::NsdResolveServiceCallback>(aServiceSubscription);
}
+std::shared_ptr<MdnsPublisher::NsdResolveHostCallback> CreateNsdResolveHostCallback(
+ MdnsPublisher::HostSubscription &aHostSubscription)
+{
+ return ndk::SharedRefBase::make<MdnsPublisher::NsdResolveHostCallback>(aHostSubscription);
+}
+
void DieForNotImplemented(const char *aFuncName)
{
VerifyOrDie(false, (std::string(aFuncName) + " is not implemented").c_str());
@@ -359,12 +389,42 @@ exit:
void MdnsPublisher::SubscribeHost(const std::string &aHostName)
{
- OTBR_UNUSED_VARIABLE(aHostName);
+ auto host = MakeUnique<HostSubscription>(aHostName, *this, mNsdPublisher, AllocateListenerId());
+
+ VerifyOrExit(IsStarted(), otbrLogWarning("No platform mDNS implementation registered!"));
+
+ mNsdPublisher->resolveHost(aHostName, CreateNsdResolveHostCallback(*host), host->mListenerId);
+ mHostSubscriptions.push_back(std::move(host));
+
+ otbrLogInfo("Subscribe host %s (total %zu)", aHostName.c_str(), mHostSubscriptions.size());
+
+exit:
+ return;
}
void MdnsPublisher::UnsubscribeHost(const std::string &aHostName)
{
- OTBR_UNUSED_VARIABLE(aHostName);
+ HostSubscriptionList::iterator it;
+
+ VerifyOrExit(IsStarted());
+
+ it = std::find_if(
+ mHostSubscriptions.begin(), mHostSubscriptions.end(),
+ [&aHostName](const std::unique_ptr<HostSubscription> &aHost) { return aHost->mName == aHostName; });
+
+ VerifyOrExit(it != mHostSubscriptions.end(),
+ otbrLogWarning("The host %s is already unsubscribed.", aHostName.c_str()));
+
+ {
+ std::unique_ptr<HostSubscription> host = std::move(*it);
+
+ mHostSubscriptions.erase(it);
+ }
+
+ otbrLogInfo("Unsubscribe host %s (left %zu)", aHostName.c_str(), mHostSubscriptions.size());
+
+exit:
+ return;
}
void MdnsPublisher::OnServiceResolveFailedImpl(const std::string &aType,
diff --git a/src/android/mdns_publisher.hpp b/src/android/mdns_publisher.hpp
index 64793dc5..723532ea 100644
--- a/src/android/mdns_publisher.hpp
+++ b/src/android/mdns_publisher.hpp
@@ -32,6 +32,7 @@
#include "mdns/mdns.hpp"
#include <aidl/com/android/server/thread/openthread/BnNsdDiscoverServiceCallback.h>
+#include <aidl/com/android/server/thread/openthread/BnNsdResolveHostCallback.h>
#include <aidl/com/android/server/thread/openthread/BnNsdResolveServiceCallback.h>
#include <aidl/com/android/server/thread/openthread/BnNsdStatusReceiver.h>
#include <aidl/com/android/server/thread/openthread/DnsTxtAttribute.h>
@@ -42,6 +43,7 @@ namespace otbr {
namespace Android {
using Status = ::ndk::ScopedAStatus;
using aidl::com::android::server::thread::openthread::BnNsdDiscoverServiceCallback;
+using aidl::com::android::server::thread::openthread::BnNsdResolveHostCallback;
using aidl::com::android::server::thread::openthread::BnNsdResolveServiceCallback;
using aidl::com::android::server::thread::openthread::BnNsdStatusReceiver;
using aidl::com::android::server::thread::openthread::DnsTxtAttribute;
@@ -157,6 +159,29 @@ public:
std::map<std::string, std::set<ServiceResolver *>> mResolvers;
};
+ struct HostSubscription : private ::NonCopyable
+ {
+ explicit HostSubscription(std::string aName,
+ MdnsPublisher &aPublisher,
+ std::shared_ptr<INsdPublisher> aNsdPublisher,
+ int listenerId)
+ : mName(std::move(aName))
+ , mPublisher(aPublisher)
+ , mNsdPublisher(std::move(aNsdPublisher))
+ , mListenerId(listenerId)
+ {
+ }
+
+ ~HostSubscription(void) { Release(); }
+
+ void Release(void) { mNsdPublisher->stopHostResolution(mListenerId); }
+
+ std::string mName;
+ MdnsPublisher &mPublisher;
+ std::shared_ptr<INsdPublisher> mNsdPublisher;
+ const int32_t mListenerId;
+ };
+
class NsdDiscoverServiceCallback : public BnNsdDiscoverServiceCallback
{
public:
@@ -191,6 +216,20 @@ public:
ServiceSubscription &mSubscription;
};
+ class NsdResolveHostCallback : public BnNsdResolveHostCallback
+ {
+ public:
+ explicit NsdResolveHostCallback(HostSubscription &aSubscription)
+ : mSubscription(aSubscription)
+ {
+ }
+
+ Status onHostResolved(const std::string &aName, const std::vector<std::string> &aAddresses);
+
+ private:
+ HostSubscription &mSubscription;
+ };
+
protected:
otbrError PublishServiceImpl(const std::string &aHostName,
const std::string &aName,
@@ -272,9 +311,11 @@ private:
};
typedef std::vector<std::unique_ptr<ServiceSubscription>> ServiceSubscriptionList;
+ typedef std::vector<std::unique_ptr<HostSubscription>> HostSubscriptionList;
- static constexpr int kMinResolvedTtl = 1;
- static constexpr int kMaxResolvedTtl = 10;
+ static constexpr int kDefaultResolvedTtl = 10;
+ static constexpr int kMinResolvedTtl = 1;
+ static constexpr int kMaxResolvedTtl = 10;
int32_t AllocateListenerId(void);
@@ -282,6 +323,7 @@ private:
int32_t mNextListenerId;
std::shared_ptr<INsdPublisher> mNsdPublisher = nullptr;
ServiceSubscriptionList mServiceSubscriptions;
+ HostSubscriptionList mHostSubscriptions;
};
} // namespace Android
diff --git a/src/android/otdaemon_server.cpp b/src/android/otdaemon_server.cpp
index 1401d513..030556eb 100644
--- a/src/android/otdaemon_server.cpp
+++ b/src/android/otdaemon_server.cpp
@@ -155,6 +155,8 @@ void OtDaemonServer::BinderDeathCallback(void *aBinderServer)
void OtDaemonServer::StateCallback(otChangedFlags aFlags)
{
+ std::vector<OnMeshPrefixConfig> onMeshPrefixes;
+
assert(GetOtInstance() != nullptr);
if (RefreshOtDaemonState(aFlags))
@@ -168,6 +170,7 @@ void OtDaemonServer::StateCallback(otChangedFlags aFlags)
mCallback->onStateChanged(mState, -1);
}
}
+
if (aFlags & OT_CHANGED_THREAD_BACKBONE_ROUTER_STATE)
{
if (mCallback == nullptr)
@@ -179,6 +182,47 @@ void OtDaemonServer::StateCallback(otChangedFlags aFlags)
mCallback->onBackboneRouterStateChanged(GetBackboneRouterState());
}
}
+
+ if ((aFlags & OT_CHANGED_THREAD_NETDATA) && RefreshOnMeshPrefixes())
+ {
+ if (mCallback == nullptr)
+ {
+ otbrLogWarning("Ignoring OT netdata changes: callback is not set");
+ }
+ else
+ {
+ onMeshPrefixes.assign(mOnMeshPrefixes.begin(), mOnMeshPrefixes.end());
+ mCallback->onPrefixChanged(onMeshPrefixes);
+ }
+ }
+}
+
+bool OtDaemonServer::RefreshOnMeshPrefixes()
+{
+ std::set<OnMeshPrefixConfig> onMeshPrefixConfigs;
+ otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
+ otBorderRouterConfig config;
+ bool rv = false;
+
+ VerifyOrExit(GetOtInstance() != nullptr, otbrLogWarning("Can't get on mesh prefixes: OT is not initialized"));
+
+ while (otNetDataGetNextOnMeshPrefix(GetOtInstance(), &iterator, &config) == OT_ERROR_NONE)
+ {
+ OnMeshPrefixConfig onMeshPrefixConfig;
+
+ onMeshPrefixConfig.prefix.assign(std::begin(config.mPrefix.mPrefix.mFields.m8),
+ std::end(config.mPrefix.mPrefix.mFields.m8));
+ onMeshPrefixConfig.prefixLength = config.mPrefix.mLength;
+ onMeshPrefixConfigs.insert(onMeshPrefixConfig);
+ }
+
+ if (mOnMeshPrefixes != onMeshPrefixConfigs)
+ {
+ mOnMeshPrefixes = std::move(onMeshPrefixConfigs);
+ rv = true;
+ }
+exit:
+ return rv;
}
Ipv6AddressInfo OtDaemonServer::ConvertToAddressInfo(const otNetifAddress &aAddress)
@@ -341,7 +385,6 @@ BackboneRouterState OtDaemonServer::GetBackboneRouterState()
state.multicastForwardingEnabled = true;
break;
}
- otbrLogInfo("Updating backbone router state (bbr state = %d)", bbrState);
while (otBackboneRouterMulticastListenerGetNext(GetOtInstance(), &iter, &info) == OT_ERROR_NONE)
{
@@ -446,11 +489,11 @@ void OtDaemonServer::initializeInternal(const bool
if (enabled)
{
- enableThread(nullptr /* aReceiver */);
+ EnableThread(nullptr /* aReceiver */);
}
else
{
- updateThreadEnabledState(OT_STATE_DISABLED, nullptr /* aReceiver */);
+ UpdateThreadEnabledState(OT_STATE_DISABLED, nullptr /* aReceiver */);
}
}
@@ -463,13 +506,13 @@ Status OtDaemonServer::terminate(void)
return Status::ok();
}
-void OtDaemonServer::updateThreadEnabledState(const int enabled, const std::shared_ptr<IOtStatusReceiver> &aReceiver)
+void OtDaemonServer::UpdateThreadEnabledState(const int enabled, const std::shared_ptr<IOtStatusReceiver> &aReceiver)
{
- VerifyOrExit(enabled != mThreadEnabled);
+ VerifyOrExit(enabled != mState.threadEnabled);
- otbrLogInfo("Thread enabled state changed: %s -> %s", ThreadEnabledStateToString(mThreadEnabled),
+ otbrLogInfo("Thread enabled state changed: %s -> %s", ThreadEnabledStateToString(mState.threadEnabled),
ThreadEnabledStateToString(enabled));
- mThreadEnabled = enabled;
+ mState.threadEnabled = enabled;
if (aReceiver != nullptr)
{
@@ -490,14 +533,14 @@ void OtDaemonServer::updateThreadEnabledState(const int enabled, const std::shar
if (mCallback != nullptr)
{
- mCallback->onThreadEnabledChanged(mThreadEnabled);
+ mCallback->onStateChanged(mState, -1);
}
exit:
return;
}
-void OtDaemonServer::enableThread(const std::shared_ptr<IOtStatusReceiver> &aReceiver)
+void OtDaemonServer::EnableThread(const std::shared_ptr<IOtStatusReceiver> &aReceiver)
{
otOperationalDatasetTlvs datasetTlvs;
@@ -507,7 +550,7 @@ void OtDaemonServer::enableThread(const std::shared_ptr<IOtStatusReceiver> &aRec
(void)otIp6SetEnabled(GetOtInstance(), true);
(void)otThreadSetEnabled(GetOtInstance(), true);
}
- updateThreadEnabledState(OT_STATE_ENABLED, aReceiver);
+ UpdateThreadEnabledState(OT_STATE_ENABLED, aReceiver);
}
Status OtDaemonServer::setThreadEnabled(const bool enabled, const std::shared_ptr<IOtStatusReceiver> &aReceiver)
@@ -524,9 +567,9 @@ void OtDaemonServer::setThreadEnabledInternal(const bool enabled, const std::sha
VerifyOrExit(GetOtInstance() != nullptr, error = OT_ERROR_INVALID_STATE, message = "OT is not initialized");
- VerifyOrExit(mThreadEnabled != OT_STATE_DISABLING, error = OT_ERROR_BUSY, message = "Thread is disabling");
+ VerifyOrExit(mState.threadEnabled != OT_STATE_DISABLING, error = OT_ERROR_BUSY, message = "Thread is disabling");
- if ((mThreadEnabled == OT_STATE_ENABLED) == enabled)
+ if ((mState.threadEnabled == OT_STATE_ENABLED) == enabled)
{
aReceiver->onSuccess();
ExitNow();
@@ -534,18 +577,18 @@ void OtDaemonServer::setThreadEnabledInternal(const bool enabled, const std::sha
if (enabled)
{
- enableThread(aReceiver);
+ EnableThread(aReceiver);
}
else
{
// `aReceiver` should not be set here because the operation isn't finished yet
- updateThreadEnabledState(OT_STATE_DISABLING, nullptr /* aReceiver */);
+ UpdateThreadEnabledState(OT_STATE_DISABLING, nullptr /* aReceiver */);
LeaveGracefully([aReceiver, this]() {
// Ignore errors as those operations should always succeed
(void)otThreadSetEnabled(GetOtInstance(), false);
(void)otIp6SetEnabled(GetOtInstance(), false);
- updateThreadEnabledState(OT_STATE_DISABLED, aReceiver);
+ UpdateThreadEnabledState(OT_STATE_DISABLED, aReceiver);
});
}
@@ -578,7 +621,6 @@ void OtDaemonServer::registerStateCallbackInternal(const std::shared_ptr<IOtDaem
// state callback, here needs to invoke the callback
RefreshOtDaemonState(/* aFlags */ 0xffffffff);
mCallback->onStateChanged(mState, listenerId);
- mCallback->onThreadEnabledChanged(mThreadEnabled);
mCallback->onBackboneRouterStateChanged(GetBackboneRouterState());
exit:
@@ -660,9 +702,9 @@ void OtDaemonServer::joinInternal(const std::vector<uint8_t> &aAct
std::string message;
otOperationalDatasetTlvs datasetTlvs;
- VerifyOrExit(mThreadEnabled != OT_STATE_DISABLING, error = OT_ERROR_BUSY, message = "Thread is disabling");
+ VerifyOrExit(mState.threadEnabled != OT_STATE_DISABLING, error = OT_ERROR_BUSY, message = "Thread is disabling");
- VerifyOrExit(mThreadEnabled == OT_STATE_ENABLED,
+ VerifyOrExit(mState.threadEnabled == OT_STATE_ENABLED,
error = static_cast<int>(IOtDaemon::ErrorCode::OT_ERROR_THREAD_DISABLED),
message = "Thread is disabled");
@@ -718,9 +760,9 @@ void OtDaemonServer::leaveInternal(const std::shared_ptr<IOtStatusReceiver> &aRe
VerifyOrExit(GetOtInstance() != nullptr, error = OT_ERROR_INVALID_STATE, message = "OT is not initialized");
- VerifyOrExit(mThreadEnabled != OT_STATE_DISABLING, error = OT_ERROR_BUSY, message = "Thread is disabling");
+ VerifyOrExit(mState.threadEnabled != OT_STATE_DISABLING, error = OT_ERROR_BUSY, message = "Thread is disabling");
- if (mThreadEnabled == OT_STATE_DISABLED)
+ if (mState.threadEnabled == OT_STATE_DISABLED)
{
FinishLeave(aReceiver);
ExitNow();
@@ -806,9 +848,9 @@ void OtDaemonServer::scheduleMigrationInternal(const std::vector<uint8_t>
std::string message;
otOperationalDataset emptyDataset;
- VerifyOrExit(mThreadEnabled != OT_STATE_DISABLING, error = OT_ERROR_BUSY, message = "Thread is disabling");
+ VerifyOrExit(mState.threadEnabled != OT_STATE_DISABLING, error = OT_ERROR_BUSY, message = "Thread is disabling");
- VerifyOrExit(mThreadEnabled == OT_STATE_ENABLED,
+ VerifyOrExit(mState.threadEnabled == OT_STATE_ENABLED,
error = static_cast<int>(IOtDaemon::ErrorCode::OT_ERROR_THREAD_DISABLED),
message = "Thread is disabled");
diff --git a/src/android/otdaemon_server.hpp b/src/android/otdaemon_server.hpp
index 8566ca9b..11d42f36 100644
--- a/src/android/otdaemon_server.hpp
+++ b/src/android/otdaemon_server.hpp
@@ -62,6 +62,7 @@ using aidl::com::android::server::thread::openthread::IOtDaemonCallback;
using aidl::com::android::server::thread::openthread::IOtStatusReceiver;
using aidl::com::android::server::thread::openthread::Ipv6AddressInfo;
using aidl::com::android::server::thread::openthread::MeshcopTxtAttributes;
+using aidl::com::android::server::thread::openthread::OnMeshPrefixConfig;
using aidl::com::android::server::thread::openthread::OtDaemonState;
class OtDaemonServer : public BnOtDaemon, public MainloopProcessor, public vendor::VendorServer
@@ -154,12 +155,12 @@ private:
otBackboneRouterMulticastListenerEvent aEvent,
const otIp6Address *aAddress);
void PushTelemetryIfConditionMatch();
- void updateThreadEnabledState(const int aEnabled, const std::shared_ptr<IOtStatusReceiver> &aReceiver);
- void enableThread(const std::shared_ptr<IOtStatusReceiver> &aReceiver);
- Ipv6AddressInfo ConvertToAddressInfo(const otNetifAddress &aAddress);
- Ipv6AddressInfo ConvertToAddressInfo(const otNetifMulticastAddress &aAddress);
+ bool RefreshOnMeshPrefixes();
+ Ipv6AddressInfo ConvertToAddressInfo(const otNetifAddress &aAddress);
+ Ipv6AddressInfo ConvertToAddressInfo(const otNetifMulticastAddress &aAddress);
+ void UpdateThreadEnabledState(const int aEnabled, const std::shared_ptr<IOtStatusReceiver> &aReceiver);
+ void EnableThread(const std::shared_ptr<IOtStatusReceiver> &aReceiver);
- int mThreadEnabled = OT_STATE_DISABLED;
otbr::Application &mApplication;
otbr::Ncp::ControllerOpenThread &mNcp;
otbr::BorderAgent &mBorderAgent;
@@ -175,6 +176,7 @@ private:
std::shared_ptr<IOtStatusReceiver> mMigrationReceiver;
std::vector<LeaveCallback> mLeaveCallbacks;
BorderRouterConfigurationParcel mBorderRouterConfiguration;
+ std::set<OnMeshPrefixConfig> mOnMeshPrefixes;
static constexpr Seconds kTelemetryCheckInterval = Seconds(600); // 600 seconds
static constexpr Seconds kTelemetryUploadIntervalThreshold = Seconds(60 * 60 * 12); // 12 hours
};
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 b3758ac1..2ee05537 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
@@ -186,6 +186,7 @@ public final class FakeOtDaemonTest {
assertThat(state.deviceRole).isEqualTo(FakeOtDaemon.OT_DEVICE_ROLE_DISABLED);
assertThat(state.activeDatasetTlvs).isEmpty();
assertThat(state.pendingDatasetTlvs).isEmpty();
+ assertThat(state.threadEnabled).isEqualTo(OT_STATE_DISABLED);
assertThat(listenerIdRef.get()).isEqualTo(7);
BackboneRouterState bbrState = bbrStateRef.get();
assertThat(bbrState.multicastForwardingEnabled).isFalse();
@@ -345,6 +346,7 @@ public final class FakeOtDaemonTest {
assertThat(state.deviceRole).isEqualTo(OT_DEVICE_ROLE_DISABLED);
assertThat(state.activeDatasetTlvs).isEqualTo(new byte[0]);
assertThat(state.pendingDatasetTlvs).isEqualTo(new byte[0]);
+ assertThat(state.threadEnabled).isEqualTo(OT_STATE_DISABLED);
BackboneRouterState bbrState = mFakeOtDaemon.getBackboneRouterState();
assertThat(bbrState.multicastForwardingEnabled).isFalse();
assertThat(bbrState.listeningAddresses).isEqualTo(new ArrayList<>());