aboutsummaryrefslogtreecommitdiff
path: root/src/dbus
diff options
context:
space:
mode:
authorwhd <7058128+superwhd@users.noreply.github.com>2021-11-10 13:53:16 +0800
committerGitHub <noreply@github.com>2021-11-09 21:53:16 -0800
commit12c6a87bc3b83eea78b711b14464d5fb53d2369c (patch)
treebed248d8afbd6d9e8df1c9192d48b1695fc0dd89 /src/dbus
parent4f8d85b124a0b6ad3a1b832e0db8579e0bf74530 (diff)
downloadot-br-posix-12c6a87bc3b83eea78b711b14464d5fb53d2369c.tar.gz
[d-bus] implement D-Bus API UpdateVendorMeshCopTxtEntries (#1081)
This commit implements a D-Bus API for updating the entries in TXT record of MeshCoP service. The API caller provides a list of (key, value) pairs, which contains all the entries it wants to update. Then otbr-agent will re-publish the MeshCoP service with the updated TXT record. If the list is empty, it will reset the TXT record, discarding changes made by previous API calls.
Diffstat (limited to 'src/dbus')
-rw-r--r--src/dbus/client/thread_api_dbus.cpp6
-rw-r--r--src/dbus/client/thread_api_dbus.hpp19
-rw-r--r--src/dbus/common/constants.hpp1
-rw-r--r--src/dbus/common/dbus_message_helper.hpp14
-rw-r--r--src/dbus/common/dbus_message_helper_openthread.cpp27
-rw-r--r--src/dbus/common/types.hpp6
-rw-r--r--src/dbus/server/dbus_thread_object.cpp25
-rw-r--r--src/dbus/server/dbus_thread_object.hpp1
-rw-r--r--src/dbus/server/introspect.xml16
9 files changed, 115 insertions, 0 deletions
diff --git a/src/dbus/client/thread_api_dbus.cpp b/src/dbus/client/thread_api_dbus.cpp
index 57ffed34..05ae018c 100644
--- a/src/dbus/client/thread_api_dbus.cpp
+++ b/src/dbus/client/thread_api_dbus.cpp
@@ -719,5 +719,11 @@ ClientError ThreadApiDBus::AttachAllNodesTo(const std::vector<uint8_t> &aDataset
return CallDBusMethodSync(OTBR_DBUS_ATTACH_ALL_NODES_TO_METHOD, args);
}
+ClientError ThreadApiDBus::UpdateVendorMeshCopTxtEntries(std::vector<TxtEntry> &aUpdate)
+{
+ auto args = std::tie(aUpdate);
+ return CallDBusMethodSync(OTBR_DBUS_UPDATE_VENDOR_MESHCOP_TXT_METHOD, args);
+}
+
} // namespace DBus
} // namespace otbr
diff --git a/src/dbus/client/thread_api_dbus.hpp b/src/dbus/client/thread_api_dbus.hpp
index 200686ff..c130c7c8 100644
--- a/src/dbus/client/thread_api_dbus.hpp
+++ b/src/dbus/client/thread_api_dbus.hpp
@@ -675,6 +675,25 @@ public:
*/
std::string GetInterfaceName(void);
+ /**
+ * This method sets multiple vendor-specific entries for the TXT record of the MeshCoP service.
+ *
+ * @note
+ * - The @p aUpdate must contain all vendor-specific TXT entries you want to update. The latest call will supersede
+ * previous calls.
+ * - If @p aUpdate contains thread-specific entries like 'nn', 'at', the whole update will be rejected.
+ * - If @p aUpdate contains a key which is already published in TXT record, it will be updated according to @p
+ * aUpdate.
+ *
+ * @param[in] aUpdate The updated key-value entries.
+ *
+ * @retval ERROR_NONE Successfully performed the dbus function call
+ * @retval ERROR_DBUS dbus encode/decode error
+ * @retval ... OpenThread defined error value otherwise
+ *
+ */
+ ClientError UpdateVendorMeshCopTxtEntries(std::vector<TxtEntry> &aUpdate);
+
private:
ClientError CallDBusMethodSync(const std::string &aMethodName);
ClientError CallDBusMethodAsync(const std::string &aMethodName, DBusPendingCallNotifyFunction aFunction);
diff --git a/src/dbus/common/constants.hpp b/src/dbus/common/constants.hpp
index 2004f0a9..3b58a1c9 100644
--- a/src/dbus/common/constants.hpp
+++ b/src/dbus/common/constants.hpp
@@ -57,6 +57,7 @@
#define OTBR_DBUS_ADD_EXTERNAL_ROUTE_METHOD "AddExternalRoute"
#define OTBR_DBUS_REMOVE_EXTERNAL_ROUTE_METHOD "RemoveExternalRoute"
#define OTBR_DBUS_ATTACH_ALL_NODES_TO_METHOD "AttachAllNodesTo"
+#define OTBR_DBUS_UPDATE_VENDOR_MESHCOP_TXT_METHOD "UpdateVendorMeshCopTxtEntries"
#define OTBR_DBUS_PROPERTY_MESH_LOCAL_PREFIX "MeshLocalPrefix"
#define OTBR_DBUS_PROPERTY_LEGACY_ULA_PREFIX "LegacyULAPrefix"
diff --git a/src/dbus/common/dbus_message_helper.hpp b/src/dbus/common/dbus_message_helper.hpp
index 194c3a6f..4bfad00a 100644
--- a/src/dbus/common/dbus_message_helper.hpp
+++ b/src/dbus/common/dbus_message_helper.hpp
@@ -73,6 +73,8 @@ otbrError DBusMessageEncode(DBusMessageIter *aIter, const LeaderData &aLeaderDat
otbrError DBusMessageExtract(DBusMessageIter *aIter, LeaderData &aLeaderData);
otbrError DBusMessageEncode(DBusMessageIter *aIter, const ChannelQuality &aQuality);
otbrError DBusMessageExtract(DBusMessageIter *aIter, ChannelQuality &aQuality);
+otbrError DBusMessageEncode(DBusMessageIter *aIter, const TxtEntry &aTxtEntry);
+otbrError DBusMessageExtract(DBusMessageIter *aIter, TxtEntry &aTxtEntry);
template <typename T> struct DBusTypeTrait;
@@ -177,6 +179,18 @@ template <> struct DBusTypeTrait<std::vector<ChildInfo>>
static constexpr const char *TYPE_AS_STRING = "a(tuuqqyyyyqqbbbb)";
};
+template <> struct DBusTypeTrait<TxtEntry>
+{
+ // struct of { string, array<uint8> }
+ static constexpr const char *TYPE_AS_STRING = "(say)";
+};
+
+template <> struct DBusTypeTrait<std::vector<TxtEntry>>
+{
+ // array of struct of { string, array<uint8> }
+ static constexpr const char *TYPE_AS_STRING = "a(say)";
+};
+
template <> struct DBusTypeTrait<int8_t>
{
static constexpr int TYPE = DBUS_TYPE_BYTE;
diff --git a/src/dbus/common/dbus_message_helper_openthread.cpp b/src/dbus/common/dbus_message_helper_openthread.cpp
index 7193f4d4..5072de63 100644
--- a/src/dbus/common/dbus_message_helper_openthread.cpp
+++ b/src/dbus/common/dbus_message_helper_openthread.cpp
@@ -438,5 +438,32 @@ exit:
return error;
}
+otbrError DBusMessageEncode(DBusMessageIter *aIter, const TxtEntry &aTxtEntry)
+{
+ DBusMessageIter sub;
+ otbrError error = OTBR_ERROR_NONE;
+ auto args = std::tie(aTxtEntry.mKey, aTxtEntry.mValue);
+
+ VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_STRUCT, nullptr, &sub));
+ SuccessOrExit(error = ConvertToDBusMessage(&sub, args));
+ VerifyOrExit(dbus_message_iter_close_container(aIter, &sub) == true, error = OTBR_ERROR_DBUS);
+exit:
+ return error;
+}
+
+otbrError DBusMessageExtract(DBusMessageIter *aIter, TxtEntry &aTxtEntry)
+{
+ DBusMessageIter sub;
+ otbrError error = OTBR_ERROR_NONE;
+ auto args = std::tie(aTxtEntry.mKey, aTxtEntry.mValue);
+
+ VerifyOrExit(dbus_message_iter_get_arg_type(aIter) == DBUS_TYPE_STRUCT, error = OTBR_ERROR_DBUS);
+ dbus_message_iter_recurse(aIter, &sub);
+ SuccessOrExit(error = ConvertToTuple(&sub, args));
+ dbus_message_iter_next(aIter);
+exit:
+ return error;
+}
+
} // namespace DBus
} // namespace otbr
diff --git a/src/dbus/common/types.hpp b/src/dbus/common/types.hpp
index 08811c81..30251568 100644
--- a/src/dbus/common/types.hpp
+++ b/src/dbus/common/types.hpp
@@ -490,6 +490,12 @@ struct LeaderData
uint8_t mLeaderRouterId; ///< Leader Router ID
};
+struct TxtEntry
+{
+ std::string mKey;
+ std::vector<uint8_t> mValue;
+};
+
} // namespace DBus
} // namespace otbr
diff --git a/src/dbus/server/dbus_thread_object.cpp b/src/dbus/server/dbus_thread_object.cpp
index ea1cce44..daa88311 100644
--- a/src/dbus/server/dbus_thread_object.cpp
+++ b/src/dbus/server/dbus_thread_object.cpp
@@ -133,6 +133,8 @@ otbrError DBusThreadObject::Init(void)
std::bind(&DBusThreadObject::RemoveExternalRouteHandler, this, _1));
RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_ATTACH_ALL_NODES_TO_METHOD,
std::bind(&DBusThreadObject::AttachAllNodesToHandler, this, _1));
+ RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_UPDATE_VENDOR_MESHCOP_TXT_METHOD,
+ std::bind(&DBusThreadObject::UpdateMeshCopTxtHandler, this, _1));
RegisterMethod(DBUS_INTERFACE_INTROSPECTABLE, DBUS_INTROSPECT_METHOD,
std::bind(&DBusThreadObject::IntrospectHandler, this, _1));
@@ -1059,6 +1061,29 @@ exit:
return error;
}
+void DBusThreadObject::UpdateMeshCopTxtHandler(DBusRequest &aRequest)
+{
+ auto threadHelper = mNcp->GetThreadHelper();
+ otError error = OT_ERROR_NONE;
+ std::map<std::string, std::vector<uint8_t>> update;
+ std::vector<TxtEntry> updatedTxtEntries;
+ auto args = std::tie(updatedTxtEntries);
+
+ VerifyOrExit(DBusMessageToTuple(*aRequest.GetMessage(), args) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
+ for (const auto &entry : updatedTxtEntries)
+ {
+ update[entry.mKey] = entry.mValue;
+ }
+ for (const auto reservedKey : {"rv", "tv", "sb", "nn", "xp", "at", "pt", "dn", "sq", "bb", "omr"})
+ {
+ VerifyOrExit(!update.count(reservedKey), error = OT_ERROR_INVALID_ARGS);
+ }
+ threadHelper->OnUpdateMeshCopTxt(std::move(update));
+
+exit:
+ aRequest.ReplyOtResult(error);
+}
+
otError DBusThreadObject::GetRadioRegionHandler(DBusMessageIter &aIter)
{
auto threadHelper = mNcp->GetThreadHelper();
diff --git a/src/dbus/server/dbus_thread_object.hpp b/src/dbus/server/dbus_thread_object.hpp
index a1b8d34a..6dc22b65 100644
--- a/src/dbus/server/dbus_thread_object.hpp
+++ b/src/dbus/server/dbus_thread_object.hpp
@@ -92,6 +92,7 @@ private:
void RemoveOnMeshPrefixHandler(DBusRequest &aRequest);
void AddExternalRouteHandler(DBusRequest &aRequest);
void RemoveExternalRouteHandler(DBusRequest &aRequest);
+ void UpdateMeshCopTxtHandler(DBusRequest &aRequest);
void IntrospectHandler(DBusRequest &aRequest);
diff --git a/src/dbus/server/introspect.xml b/src/dbus/server/introspect.xml
index a3f86efb..199853c0 100644
--- a/src/dbus/server/introspect.xml
+++ b/src/dbus/server/introspect.xml
@@ -175,6 +175,22 @@
<arg name="prefix" type="(ayy)"/>
</method>
+ <!-- UpdateMeshCopTxt: Update multiple entries in the TXT record.
+ @key: The key of the entry.
+ @value: The value of the entry.
+
+ The prefix structure is:
+ <literallayout>
+ struct {
+ string key
+ uint8[] value
+ }
+ </literallayout>
+ -->
+ <method name="UpdateVendorMeshCopTxtEntries">
+ <arg name="update" type="a(say)" direction="in"/>
+ </method>
+
<!-- MeshLocalPrefix: The /64 mesh-local prefix. -->
<property name="MeshLocalPrefix" type="ay" access="readwrite">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>