2 * Copyright (c) 2020, The OpenThread Authors.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
31 #include "dbus/common/dbus_message_helper.hpp"
36 otbrError DBusMessageExtract(DBusMessageIter *aIter, otbrError &aError)
39 otbrError error = DBusMessageExtract(aIter, val);
41 VerifyOrExit(error == OTBR_ERROR_NONE);
42 aError = static_cast<otbrError>(val);
47 otbrError DBusMessageEncode(DBusMessageIter *aIter, const otbrError &aError)
49 return DBusMessageEncode(aIter, static_cast<uint8_t>(aError));
52 otbrError DBusMessageExtract(DBusMessageIter *aIter, ActiveScanResult &aScanResult)
55 otbrError error = OTBR_ERROR_NONE;
57 VerifyOrExit(dbus_message_iter_get_arg_type(aIter) == DBUS_TYPE_STRUCT, error = OTBR_ERROR_DBUS);
58 dbus_message_iter_recurse(aIter, &sub);
60 SuccessOrExit(error = DBusMessageExtract(&sub, aScanResult.mExtAddress));
61 SuccessOrExit(error = DBusMessageExtract(&sub, aScanResult.mNetworkName));
62 SuccessOrExit(error = DBusMessageExtract(&sub, aScanResult.mExtendedPanId));
63 SuccessOrExit(error = DBusMessageExtract(&sub, aScanResult.mSteeringData));
64 SuccessOrExit(error = DBusMessageExtract(&sub, aScanResult.mPanId));
65 SuccessOrExit(error = DBusMessageExtract(&sub, aScanResult.mJoinerUdpPort));
66 SuccessOrExit(error = DBusMessageExtract(&sub, aScanResult.mChannel));
67 SuccessOrExit(error = DBusMessageExtract(&sub, aScanResult.mRssi));
68 SuccessOrExit(error = DBusMessageExtract(&sub, aScanResult.mLqi));
69 SuccessOrExit(error = DBusMessageExtract(&sub, aScanResult.mVersion));
70 SuccessOrExit(error = DBusMessageExtract(&sub, aScanResult.mIsNative));
71 SuccessOrExit(error = DBusMessageExtract(&sub, aScanResult.mIsJoinable));
73 dbus_message_iter_next(aIter);
74 error = OTBR_ERROR_NONE;
79 otbrError DBusMessageEncode(DBusMessageIter *aIter, const ActiveScanResult &aScanResult)
82 otbrError error = OTBR_ERROR_NONE;
84 VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_STRUCT, nullptr, &sub), error = OTBR_ERROR_DBUS);
85 SuccessOrExit(error = DBusMessageEncode(&sub, aScanResult.mExtAddress));
86 SuccessOrExit(error = DBusMessageEncode(&sub, aScanResult.mNetworkName));
87 SuccessOrExit(error = DBusMessageEncode(&sub, aScanResult.mExtendedPanId));
88 SuccessOrExit(error = DBusMessageEncode(&sub, aScanResult.mSteeringData));
89 SuccessOrExit(error = DBusMessageEncode(&sub, aScanResult.mPanId));
90 SuccessOrExit(error = DBusMessageEncode(&sub, aScanResult.mJoinerUdpPort));
91 SuccessOrExit(error = DBusMessageEncode(&sub, aScanResult.mChannel));
92 SuccessOrExit(error = DBusMessageEncode(&sub, aScanResult.mRssi));
93 SuccessOrExit(error = DBusMessageEncode(&sub, aScanResult.mLqi));
94 SuccessOrExit(error = DBusMessageEncode(&sub, aScanResult.mVersion));
95 SuccessOrExit(error = DBusMessageEncode(&sub, aScanResult.mIsNative));
96 SuccessOrExit(error = DBusMessageEncode(&sub, aScanResult.mIsJoinable));
97 VerifyOrExit(dbus_message_iter_close_container(aIter, &sub), error = OTBR_ERROR_DBUS);
99 error = OTBR_ERROR_NONE;
104 otbrError DBusMessageEncode(DBusMessageIter *aIter, const LinkModeConfig &aConfig)
106 otbrError error = OTBR_ERROR_NONE;
109 VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_STRUCT, nullptr, &sub), error = OTBR_ERROR_DBUS);
111 SuccessOrExit(error = DBusMessageEncode(&sub, aConfig.mRxOnWhenIdle));
112 SuccessOrExit(error = DBusMessageEncode(&sub, aConfig.mDeviceType));
113 SuccessOrExit(error = DBusMessageEncode(&sub, aConfig.mNetworkData));
115 VerifyOrExit(dbus_message_iter_close_container(aIter, &sub) == true, error = OTBR_ERROR_DBUS);
116 error = OTBR_ERROR_NONE;
121 otbrError DBusMessageExtract(DBusMessageIter *aIter, LinkModeConfig &aConfig)
123 otbrError error = OTBR_ERROR_DBUS;
126 VerifyOrExit(dbus_message_iter_get_arg_type(aIter) == DBUS_TYPE_STRUCT);
127 dbus_message_iter_recurse(aIter, &sub);
129 SuccessOrExit(DBusMessageExtract(&sub, aConfig.mRxOnWhenIdle));
130 SuccessOrExit(DBusMessageExtract(&sub, aConfig.mDeviceType));
131 SuccessOrExit(DBusMessageExtract(&sub, aConfig.mNetworkData));
133 dbus_message_iter_next(aIter);
134 error = OTBR_ERROR_NONE;
139 otbrError DBusMessageEncode(DBusMessageIter *aIter, const Ip6Prefix &aPrefix)
142 otbrError error = OTBR_ERROR_NONE;
144 VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_STRUCT, nullptr, &sub), error = OTBR_ERROR_DBUS);
145 VerifyOrExit(aPrefix.mPrefix.size() <= OTBR_IP6_PREFIX_SIZE, error = OTBR_ERROR_DBUS);
147 SuccessOrExit(error = DBusMessageEncode(&sub, aPrefix.mPrefix));
148 SuccessOrExit(error = DBusMessageEncode(&sub, aPrefix.mLength));
150 VerifyOrExit(dbus_message_iter_close_container(aIter, &sub), error = OTBR_ERROR_DBUS);
156 otbrError DBusMessageExtract(DBusMessageIter *aIter, Ip6Prefix &aPrefix)
159 otbrError error = OTBR_ERROR_NONE;
161 dbus_message_iter_recurse(aIter, &sub);
162 SuccessOrExit(error = DBusMessageExtract(&sub, aPrefix.mPrefix));
163 VerifyOrExit(aPrefix.mPrefix.size() <= OTBR_IP6_PREFIX_SIZE, error = OTBR_ERROR_DBUS);
164 SuccessOrExit(error = DBusMessageExtract(&sub, aPrefix.mLength));
166 dbus_message_iter_next(aIter);
172 otbrError DBusMessageEncode(DBusMessageIter *aIter, const ExternalRoute &aRoute)
175 otbrError error = OTBR_ERROR_NONE;
177 VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_STRUCT, nullptr, &sub), error = OTBR_ERROR_DBUS);
179 SuccessOrExit(error = DBusMessageEncode(&sub, aRoute.mPrefix));
180 SuccessOrExit(error = DBusMessageEncode(&sub, aRoute.mRloc16));
181 SuccessOrExit(error = DBusMessageEncode(&sub, aRoute.mPreference));
182 SuccessOrExit(error = DBusMessageEncode(&sub, aRoute.mStable));
183 SuccessOrExit(error = DBusMessageEncode(&sub, aRoute.mNextHopIsThisDevice));
185 VerifyOrExit(dbus_message_iter_close_container(aIter, &sub), error = OTBR_ERROR_DBUS);
191 otbrError DBusMessageExtract(DBusMessageIter *aIter, ExternalRoute &aRoute)
194 otbrError error = OTBR_ERROR_NONE;
196 dbus_message_iter_recurse(aIter, &sub);
197 SuccessOrExit(error = DBusMessageExtract(&sub, aRoute.mPrefix));
198 SuccessOrExit(error = DBusMessageExtract(&sub, aRoute.mRloc16));
199 SuccessOrExit(error = DBusMessageExtract(&sub, aRoute.mPreference));
200 SuccessOrExit(error = DBusMessageExtract(&sub, aRoute.mStable));
201 SuccessOrExit(error = DBusMessageExtract(&sub, aRoute.mNextHopIsThisDevice));
203 dbus_message_iter_next(aIter);
209 otbrError DBusMessageEncode(DBusMessageIter *aIter, const OnMeshPrefix &aPrefix)
211 DBusMessageIter sub, flagsSub;
212 auto args = std::tie(aPrefix.mPreferred, aPrefix.mSlaac, aPrefix.mDhcp, aPrefix.mConfigure, aPrefix.mDefaultRoute,
213 aPrefix.mOnMesh, aPrefix.mStable);
214 otbrError error = OTBR_ERROR_NONE;
216 VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_STRUCT, nullptr, &sub), error = OTBR_ERROR_DBUS);
217 SuccessOrExit(error = ConvertToDBusMessage(&sub, std::tie(aPrefix.mPrefix, aPrefix.mPreference)));
218 VerifyOrExit(dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, nullptr, &flagsSub), error = OTBR_ERROR_DBUS);
219 SuccessOrExit(error = ConvertToDBusMessage(&flagsSub, args));
220 VerifyOrExit(dbus_message_iter_close_container(&sub, &flagsSub) == true, error = OTBR_ERROR_DBUS);
221 VerifyOrExit(dbus_message_iter_close_container(aIter, &sub) == true, error = OTBR_ERROR_DBUS);
226 otbrError DBusMessageExtract(DBusMessageIter *aIter, OnMeshPrefix &aPrefix)
228 DBusMessageIter sub, flagsSub;
229 auto args = std::tie(aPrefix.mPrefix, aPrefix.mPreference);
230 auto flagArgs = std::tie(aPrefix.mPreferred, aPrefix.mSlaac, aPrefix.mDhcp, aPrefix.mConfigure,
231 aPrefix.mDefaultRoute, aPrefix.mOnMesh, aPrefix.mStable);
232 otbrError error = OTBR_ERROR_NONE;
234 VerifyOrExit(dbus_message_iter_get_arg_type(aIter) == DBUS_TYPE_STRUCT, error = OTBR_ERROR_DBUS);
235 dbus_message_iter_recurse(aIter, &sub);
236 SuccessOrExit(error = ConvertToTuple(&sub, args));
237 VerifyOrExit(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT, error = OTBR_ERROR_DBUS);
238 dbus_message_iter_recurse(&sub, &flagsSub);
239 SuccessOrExit(error = ConvertToTuple(&flagsSub, flagArgs));
240 dbus_message_iter_next(aIter);
245 otbrError DBusMessageEncode(DBusMessageIter *aIter, const MacCounters &aCounters)
247 auto args = std::tie(aCounters.mTxTotal, aCounters.mTxUnicast, aCounters.mTxBroadcast, aCounters.mTxAckRequested,
248 aCounters.mTxAcked, aCounters.mTxNoAckRequested, aCounters.mTxData, aCounters.mTxDataPoll,
249 aCounters.mTxBeacon, aCounters.mTxBeaconRequest, aCounters.mTxOther, aCounters.mTxRetry,
250 aCounters.mTxErrCca, aCounters.mTxErrAbort, aCounters.mTxErrBusyChannel, aCounters.mRxTotal,
251 aCounters.mRxUnicast, aCounters.mRxBroadcast, aCounters.mRxData, aCounters.mRxDataPoll,
252 aCounters.mRxBeacon, aCounters.mRxBeaconRequest, aCounters.mRxOther,
253 aCounters.mRxAddressFiltered, aCounters.mRxDestAddrFiltered, aCounters.mRxDuplicated,
254 aCounters.mRxErrNoFrame, aCounters.mRxErrUnknownNeighbor, aCounters.mRxErrInvalidSrcAddr,
255 aCounters.mRxErrSec, aCounters.mRxErrFcs, aCounters.mRxErrOther);
257 otbrError error = OTBR_ERROR_NONE;
259 VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_STRUCT, nullptr, &sub), error = OTBR_ERROR_DBUS);
260 SuccessOrExit(error = ConvertToDBusMessage(&sub, args));
261 VerifyOrExit(dbus_message_iter_close_container(aIter, &sub) == true, error = OTBR_ERROR_DBUS);
266 otbrError DBusMessageExtract(DBusMessageIter *aIter, MacCounters &aCounters)
268 auto args = std::tie(aCounters.mTxTotal, aCounters.mTxUnicast, aCounters.mTxBroadcast, aCounters.mTxAckRequested,
269 aCounters.mTxAcked, aCounters.mTxNoAckRequested, aCounters.mTxData, aCounters.mTxDataPoll,
270 aCounters.mTxBeacon, aCounters.mTxBeaconRequest, aCounters.mTxOther, aCounters.mTxRetry,
271 aCounters.mTxErrCca, aCounters.mTxErrAbort, aCounters.mTxErrBusyChannel, aCounters.mRxTotal,
272 aCounters.mRxUnicast, aCounters.mRxBroadcast, aCounters.mRxData, aCounters.mRxDataPoll,
273 aCounters.mRxBeacon, aCounters.mRxBeaconRequest, aCounters.mRxOther,
274 aCounters.mRxAddressFiltered, aCounters.mRxDestAddrFiltered, aCounters.mRxDuplicated,
275 aCounters.mRxErrNoFrame, aCounters.mRxErrUnknownNeighbor, aCounters.mRxErrInvalidSrcAddr,
276 aCounters.mRxErrSec, aCounters.mRxErrFcs, aCounters.mRxErrOther);
278 otbrError error = OTBR_ERROR_NONE;
280 VerifyOrExit(dbus_message_iter_get_arg_type(aIter) == DBUS_TYPE_STRUCT, error = OTBR_ERROR_DBUS);
281 dbus_message_iter_recurse(aIter, &sub);
282 SuccessOrExit(error = ConvertToTuple(&sub, args));
283 dbus_message_iter_next(aIter);
288 otbrError DBusMessageEncode(DBusMessageIter *aIter, const IpCounters &aCounters)
291 otbrError error = OTBR_ERROR_NONE;
292 auto args = std::tie(aCounters.mTxSuccess, aCounters.mRxSuccess, aCounters.mTxFailure, aCounters.mRxFailure);
294 VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_STRUCT, nullptr, &sub), error = OTBR_ERROR_DBUS);
295 SuccessOrExit(error = ConvertToDBusMessage(&sub, args));
296 VerifyOrExit(dbus_message_iter_close_container(aIter, &sub) == true, error = OTBR_ERROR_DBUS);
301 otbrError DBusMessageExtract(DBusMessageIter *aIter, IpCounters &aCounters)
304 otbrError error = OTBR_ERROR_NONE;
305 auto args = std::tie(aCounters.mTxSuccess, aCounters.mRxSuccess, aCounters.mTxFailure, aCounters.mRxFailure);
307 VerifyOrExit(dbus_message_iter_get_arg_type(aIter) == DBUS_TYPE_STRUCT, error = OTBR_ERROR_DBUS);
308 dbus_message_iter_recurse(aIter, &sub);
309 SuccessOrExit(error = ConvertToTuple(&sub, args));
310 dbus_message_iter_next(aIter);
315 otbrError DBusMessageEncode(DBusMessageIter *aIter, const ChildInfo &aChildInfo)
318 otbrError error = OTBR_ERROR_NONE;
319 auto args = std::tie(aChildInfo.mExtAddress, aChildInfo.mTimeout, aChildInfo.mAge, aChildInfo.mRloc16,
320 aChildInfo.mChildId, aChildInfo.mNetworkDataVersion, aChildInfo.mLinkQualityIn,
321 aChildInfo.mAverageRssi, aChildInfo.mLastRssi, aChildInfo.mFrameErrorRate,
322 aChildInfo.mMessageErrorRate, aChildInfo.mRxOnWhenIdle, aChildInfo.mFullThreadDevice,
323 aChildInfo.mFullNetworkData, aChildInfo.mIsStateRestoring);
325 VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_STRUCT, nullptr, &sub), error = OTBR_ERROR_DBUS);
326 SuccessOrExit(error = ConvertToDBusMessage(&sub, args));
327 VerifyOrExit(dbus_message_iter_close_container(aIter, &sub) == true, error = OTBR_ERROR_DBUS);
332 otbrError DBusMessageExtract(DBusMessageIter *aIter, ChildInfo &aChildInfo)
335 otbrError error = OTBR_ERROR_NONE;
336 auto args = std::tie(aChildInfo.mExtAddress, aChildInfo.mTimeout, aChildInfo.mAge, aChildInfo.mRloc16,
337 aChildInfo.mChildId, aChildInfo.mNetworkDataVersion, aChildInfo.mLinkQualityIn,
338 aChildInfo.mAverageRssi, aChildInfo.mLastRssi, aChildInfo.mFrameErrorRate,
339 aChildInfo.mMessageErrorRate, aChildInfo.mRxOnWhenIdle, aChildInfo.mFullThreadDevice,
340 aChildInfo.mFullNetworkData, aChildInfo.mIsStateRestoring);
342 VerifyOrExit(dbus_message_iter_get_arg_type(aIter) == DBUS_TYPE_STRUCT, error = OTBR_ERROR_DBUS);
343 dbus_message_iter_recurse(aIter, &sub);
344 SuccessOrExit(error = ConvertToTuple(&sub, args));
345 dbus_message_iter_next(aIter);
350 otbrError DBusMessageEncode(DBusMessageIter *aIter, const NeighborInfo &aNeighborInfo)
353 otbrError error = OTBR_ERROR_NONE;
354 auto args = std::tie(aNeighborInfo.mExtAddress, aNeighborInfo.mAge, aNeighborInfo.mRloc16,
355 aNeighborInfo.mLinkFrameCounter, aNeighborInfo.mMleFrameCounter, aNeighborInfo.mLinkQualityIn,
356 aNeighborInfo.mAverageRssi, aNeighborInfo.mLastRssi, aNeighborInfo.mFrameErrorRate,
357 aNeighborInfo.mMessageErrorRate, aNeighborInfo.mRxOnWhenIdle, aNeighborInfo.mFullThreadDevice,
358 aNeighborInfo.mFullNetworkData, aNeighborInfo.mIsChild);
360 VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_STRUCT, nullptr, &sub), error = OTBR_ERROR_DBUS);
361 SuccessOrExit(error = ConvertToDBusMessage(&sub, args));
362 VerifyOrExit(dbus_message_iter_close_container(aIter, &sub) == true, error = OTBR_ERROR_DBUS);
367 otbrError DBusMessageExtract(DBusMessageIter *aIter, NeighborInfo &aNeighborInfo)
370 otbrError error = OTBR_ERROR_NONE;
371 auto args = std::tie(aNeighborInfo.mExtAddress, aNeighborInfo.mAge, aNeighborInfo.mRloc16,
372 aNeighborInfo.mLinkFrameCounter, aNeighborInfo.mMleFrameCounter, aNeighborInfo.mLinkQualityIn,
373 aNeighborInfo.mAverageRssi, aNeighborInfo.mLastRssi, aNeighborInfo.mFrameErrorRate,
374 aNeighborInfo.mMessageErrorRate, aNeighborInfo.mRxOnWhenIdle, aNeighborInfo.mFullThreadDevice,
375 aNeighborInfo.mFullNetworkData, aNeighborInfo.mIsChild);
377 VerifyOrExit(dbus_message_iter_get_arg_type(aIter) == DBUS_TYPE_STRUCT, error = OTBR_ERROR_DBUS);
378 dbus_message_iter_recurse(aIter, &sub);
379 SuccessOrExit(error = ConvertToTuple(&sub, args));
380 dbus_message_iter_next(aIter);
385 otbrError DBusMessageEncode(DBusMessageIter *aIter, const LeaderData &aLeaderData)
388 otbrError error = OTBR_ERROR_NONE;
389 auto args = std::tie(aLeaderData.mPartitionId, aLeaderData.mWeighting, aLeaderData.mDataVersion,
390 aLeaderData.mStableDataVersion, aLeaderData.mLeaderRouterId);
392 VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_STRUCT, nullptr, &sub), error = OTBR_ERROR_DBUS);
393 SuccessOrExit(error = ConvertToDBusMessage(&sub, args));
394 VerifyOrExit(dbus_message_iter_close_container(aIter, &sub) == true, error = OTBR_ERROR_DBUS);
399 otbrError DBusMessageExtract(DBusMessageIter *aIter, LeaderData &aLeaderData)
402 otbrError error = OTBR_ERROR_NONE;
403 auto args = std::tie(aLeaderData.mPartitionId, aLeaderData.mWeighting, aLeaderData.mDataVersion,
404 aLeaderData.mStableDataVersion, aLeaderData.mLeaderRouterId);
406 VerifyOrExit(dbus_message_iter_get_arg_type(aIter) == DBUS_TYPE_STRUCT, error = OTBR_ERROR_DBUS);
407 dbus_message_iter_recurse(aIter, &sub);
408 SuccessOrExit(error = ConvertToTuple(&sub, args));
409 dbus_message_iter_next(aIter);
414 otbrError DBusMessageEncode(DBusMessageIter *aIter, const ChannelQuality &aQuality)
417 otbrError error = OTBR_ERROR_NONE;
418 auto args = std::tie(aQuality.mChannel, aQuality.mOccupancy);
420 VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_STRUCT, nullptr, &sub));
421 SuccessOrExit(error = ConvertToDBusMessage(&sub, args));
422 VerifyOrExit(dbus_message_iter_close_container(aIter, &sub) == true, error = OTBR_ERROR_DBUS);
427 otbrError DBusMessageExtract(DBusMessageIter *aIter, ChannelQuality &aQuality)
430 otbrError error = OTBR_ERROR_NONE;
431 auto args = std::tie(aQuality.mChannel, aQuality.mOccupancy);
433 VerifyOrExit(dbus_message_iter_get_arg_type(aIter) == DBUS_TYPE_STRUCT, error = OTBR_ERROR_DBUS);
434 dbus_message_iter_recurse(aIter, &sub);
435 SuccessOrExit(error = ConvertToTuple(&sub, args));
436 dbus_message_iter_next(aIter);