1 /*
2 * Copyright (c) 2019, The OpenThread Authors.
3 * All rights reserved.
4 *
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.
15 *
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.
27 */
28
29 /**
30 * @file
31 * This file includes utilities for manipulate d-bus message.
32 */
33
34 #ifndef DBUS_MESSAGE_HELPER_HPP_
35 #define DBUS_MESSAGE_HELPER_HPP_
36
37 #include "openthread-br/config.h"
38
39 #include <array>
40 #include <string>
41 #include <tuple>
42 #include <vector>
43
44 #include <dbus/dbus.h>
45
46 #include "common/code_utils.hpp"
47 #include "common/types.hpp"
48 #include "dbus/common/dbus_resources.hpp"
49 #include "dbus/common/types.hpp"
50
51 namespace otbr {
52 namespace DBus {
53
54 otbrError DBusMessageEncode(DBusMessageIter *aIter, const otbrError &aError);
55 otbrError DBusMessageExtract(DBusMessageIter *aIter, otbrError &aError);
56 otbrError DBusMessageEncode(DBusMessageIter *aIter, const ActiveScanResult &aScanResult);
57 otbrError DBusMessageExtract(DBusMessageIter *aIter, ActiveScanResult &aScanResult);
58 otbrError DBusMessageEncode(DBusMessageIter *aIter, const EnergyScanResult &aResult);
59 otbrError DBusMessageExtract(DBusMessageIter *aIter, EnergyScanResult &aResult);
60 otbrError DBusMessageEncode(DBusMessageIter *aIter, const LinkModeConfig &aConfig);
61 otbrError DBusMessageExtract(DBusMessageIter *aIter, LinkModeConfig &aConfig);
62 otbrError DBusMessageEncode(DBusMessageIter *aIter, const Ip6Prefix &aPrefix);
63 otbrError DBusMessageExtract(DBusMessageIter *aIter, Ip6Prefix &aPrefix);
64 otbrError DBusMessageEncode(DBusMessageIter *aIter, const ExternalRoute &aRoute);
65 otbrError DBusMessageExtract(DBusMessageIter *aIter, ExternalRoute &aRoute);
66 otbrError DBusMessageEncode(DBusMessageIter *aIter, const OnMeshPrefix &aPrefix);
67 otbrError DBusMessageExtract(DBusMessageIter *aIter, OnMeshPrefix &aPrefix);
68 otbrError DBusMessageEncode(DBusMessageIter *aIter, const MacCounters &aCounters);
69 otbrError DBusMessageExtract(DBusMessageIter *aIter, MacCounters &aCounters);
70 otbrError DBusMessageEncode(DBusMessageIter *aIter, const IpCounters &aCounters);
71 otbrError DBusMessageExtract(DBusMessageIter *aIter, IpCounters &aCounters);
72 otbrError DBusMessageEncode(DBusMessageIter *aIter, const ChildInfo &aChildInfo);
73 otbrError DBusMessageExtract(DBusMessageIter *aIter, ChildInfo &aChildInfo);
74 otbrError DBusMessageEncode(DBusMessageIter *aIter, const NeighborInfo &aNeighborInfo);
75 otbrError DBusMessageExtract(DBusMessageIter *aIter, NeighborInfo &aNeighborInfo);
76 otbrError DBusMessageEncode(DBusMessageIter *aIter, const LeaderData &aLeaderData);
77 otbrError DBusMessageExtract(DBusMessageIter *aIter, LeaderData &aLeaderData);
78 otbrError DBusMessageEncode(DBusMessageIter *aIter, const ChannelQuality &aQuality);
79 otbrError DBusMessageExtract(DBusMessageIter *aIter, ChannelQuality &aQuality);
80 otbrError DBusMessageEncode(DBusMessageIter *aIter, const TxtEntry &aTxtEntry);
81 otbrError DBusMessageExtract(DBusMessageIter *aIter, TxtEntry &aTxtEntry);
82 otbrError DBusMessageEncode(DBusMessageIter *aIter, const SrpServerInfo::Registration &aRegistration);
83 otbrError DBusMessageExtract(DBusMessageIter *aIter, SrpServerInfo::Registration &aRegistration);
84 otbrError DBusMessageEncode(DBusMessageIter *aIter, const SrpServerInfo::ResponseCounters &aResponseCounters);
85 otbrError DBusMessageExtract(DBusMessageIter *aIter, SrpServerInfo::ResponseCounters &aResponseCounters);
86 otbrError DBusMessageEncode(DBusMessageIter *aIter, const SrpServerInfo &aSrpServerInfo);
87 otbrError DBusMessageExtract(DBusMessageIter *aIter, SrpServerInfo &aSrpServerInfo);
88 otbrError DBusMessageEncode(DBusMessageIter *aIter, const MdnsResponseCounters &aMdnsResponseCounters);
89 otbrError DBusMessageExtract(DBusMessageIter *aIter, MdnsResponseCounters &aMdnsResponseCounters);
90 otbrError DBusMessageEncode(DBusMessageIter *aIter, const MdnsTelemetryInfo &aMdnsTelemetryInfo);
91 otbrError DBusMessageExtract(DBusMessageIter *aIter, MdnsTelemetryInfo &aMdnsTelemetryInfo);
92 otbrError DBusMessageEncode(DBusMessageIter *aIter, const DnssdCounters &aDnssdCounters);
93 otbrError DBusMessageExtract(DBusMessageIter *aIter, DnssdCounters &aDnssdCounters);
94 otbrError DBusMessageEncode(DBusMessageIter *aIter, const RadioSpinelMetrics &aRadioSpinelMetrics);
95 otbrError DBusMessageExtract(DBusMessageIter *aIter, RadioSpinelMetrics &RadioSpinelMetrics);
96 otbrError DBusMessageEncode(DBusMessageIter *aIter, const RcpInterfaceMetrics &aRcpInterfaceMetrics);
97 otbrError DBusMessageExtract(DBusMessageIter *aIter, RcpInterfaceMetrics &aRcpInterfaceMetrics);
98 otbrError DBusMessageEncode(DBusMessageIter *aIter, const RadioCoexMetrics &aRadioCoexMetrics);
99 otbrError DBusMessageExtract(DBusMessageIter *aIter, RadioCoexMetrics &aRadioCoexMetrics);
100 otbrError DBusMessageEncode(DBusMessageIter *aIter, const BorderRoutingCounters::PacketsAndBytes &aPacketAndBytes);
101 otbrError DBusMessageExtract(DBusMessageIter *aIter, BorderRoutingCounters::PacketsAndBytes &aPacketAndBytes);
102 otbrError DBusMessageEncode(DBusMessageIter *aIter, const BorderRoutingCounters &aBorderRoutingCounters);
103 otbrError DBusMessageExtract(DBusMessageIter *aIter, BorderRoutingCounters &aBorderRoutingCounters);
104 otbrError DBusMessageEncode(DBusMessageIter *aIter, const Nat64ComponentState &aNat64State);
105 otbrError DBusMessageExtract(DBusMessageIter *aIter, Nat64ComponentState &aNat64State);
106 otbrError DBusMessageEncode(DBusMessageIter *aIter, const Nat64TrafficCounters &aCounters);
107 otbrError DBusMessageExtract(DBusMessageIter *aIter, Nat64TrafficCounters &aCounters);
108 otbrError DBusMessageEncode(DBusMessageIter *aIter, const Nat64PacketCounters &aCounters);
109 otbrError DBusMessageExtract(DBusMessageIter *aIter, Nat64PacketCounters &aCounters);
110 otbrError DBusMessageEncode(DBusMessageIter *aIter, const Nat64ProtocolCounters &aCounters);
111 otbrError DBusMessageExtract(DBusMessageIter *aIter, Nat64ProtocolCounters &aCounters);
112 otbrError DBusMessageEncode(DBusMessageIter *aIter, const Nat64AddressMapping &aMapping);
113 otbrError DBusMessageExtract(DBusMessageIter *aIter, Nat64AddressMapping &aMapping);
114 otbrError DBusMessageEncode(DBusMessageIter *aIter, const Nat64ErrorCounters &aCounters);
115 otbrError DBusMessageExtract(DBusMessageIter *aIter, Nat64ErrorCounters &aCounters);
116 otbrError DBusMessageEncode(DBusMessageIter *aIter, const InfraLinkInfo &aInfraLinkInfo);
117 otbrError DBusMessageExtract(DBusMessageIter *aIter, InfraLinkInfo &aInfraLinkInfo);
118 otbrError DBusMessageEncode(DBusMessageIter *aIter, const TrelInfo &aTrelInfo);
119 otbrError DBusMessageExtract(DBusMessageIter *aIter, TrelInfo &aTrelInfo);
120 otbrError DBusMessageEncode(DBusMessageIter *aIter, const TrelInfo::TrelPacketCounters &aCounters);
121 otbrError DBusMessageExtract(DBusMessageIter *aIter, TrelInfo::TrelPacketCounters &aCounters);
122
123 template <typename T> struct DBusTypeTrait;
124
125 template <> struct DBusTypeTrait<IpCounters>
126 {
127 // struct of 32 bytes
128 static constexpr const char *TYPE_AS_STRING = "(uuuu)";
129 };
130
131 template <> struct DBusTypeTrait<MacCounters>
132 {
133 // struct of 32 bytes
134 static constexpr const char *TYPE_AS_STRING = "(uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu)";
135 };
136
137 template <> struct DBusTypeTrait<LinkModeConfig>
138 {
139 // struct of four booleans
140 static constexpr const char *TYPE_AS_STRING = "(bbb)";
141 };
142
143 template <> struct DBusTypeTrait<std::vector<uint8_t>>
144 {
145 // array of bytes
146 static constexpr const char *TYPE_AS_STRING = "ay";
147 };
148
149 template <size_t SIZE> struct DBusTypeTrait<std::array<uint8_t, SIZE>>
150 {
151 // array of bytes
152 static constexpr const char *TYPE_AS_STRING = "ay";
153 };
154
155 template <> struct DBusTypeTrait<Ip6Prefix>
156 {
157 // struct of {array of bytes, byte}
158 static constexpr const char *TYPE_AS_STRING = "(ayy)";
159 };
160
161 template <> struct DBusTypeTrait<ExternalRoute>
162 {
163 // struct of {{array of bytes, byte}, uint16, byte, bool, bool}
164 static constexpr const char *TYPE_AS_STRING = "((ayy)qybb)";
165 };
166
167 template <> struct DBusTypeTrait<std::vector<ExternalRoute>>
168 {
169 // array of {{array of bytes, byte}, uint16, byte, bool, bool}
170 static constexpr const char *TYPE_AS_STRING = "a((ayy)qybb)";
171 };
172
173 template <> struct DBusTypeTrait<OnMeshPrefix>
174 {
175 // struct of {{array of bytes, byte}, uint16, byte, bool, bool, bool, bool, bool, bool, bool, bool, bool}
176 static constexpr const char *TYPE_AS_STRING = "((ayy)qybbbbbbbbb)";
177 };
178
179 template <> struct DBusTypeTrait<std::vector<OnMeshPrefix>>
180 {
181 // array of {{array of bytes, byte}, uint16, byte, bool, bool, bool, bool, bool, bool, bool, bool, bool}
182 static constexpr const char *TYPE_AS_STRING = "a((ayy)qybbbbbbbbb)";
183 };
184
185 template <> struct DBusTypeTrait<LeaderData>
186 {
187 // struct of { uint32, byte, byte, byte, byte }
188 static constexpr const char *TYPE_AS_STRING = "(uyyyy)";
189 };
190
191 template <> struct DBusTypeTrait<std::vector<ChannelQuality>>
192 {
193 // array of struct of { uint8, uint16 }
194 static constexpr const char *TYPE_AS_STRING = "a(yq)";
195 };
196
197 template <> struct DBusTypeTrait<NeighborInfo>
198 {
199 // struct of { uint64, uint32, uint16, uint32, uint32, uint8,
200 // uint8, uint8, uint16, uint16, uint16, bool, bool, bool, bool }
201 static constexpr const char *TYPE_AS_STRING = "(tuquuyyyqqqbbbb)";
202 };
203
204 template <> struct DBusTypeTrait<std::vector<NeighborInfo>>
205 {
206 // array of struct of { uint64, uint32, uint16, uint32, uint32, uint8,
207 // uint8, uint8, uint16, uint16, uint16, bool, bool, bool }
208 static constexpr const char *TYPE_AS_STRING = "a(tuquuyyyqqqbbbb)";
209 };
210
211 template <> struct DBusTypeTrait<ChildInfo>
212 {
213 // struct of { uint64, uint32, uint32, uint16, uint16, uint8, uint8,
214 // uint8, uint8, uint16, uint16, bool, bool, bool, bool }
215 static constexpr const char *TYPE_AS_STRING = "(tuuqqyyyyqqbbbb)";
216 };
217
218 template <> struct DBusTypeTrait<ActiveScanResult>
219 {
220 // struct of { uint64, string, uint64, array<uint8>, uint16, uint16, uint8,
221 // int16, uint8, uint8, bool, bool }
222 static constexpr const char *TYPE_AS_STRING = "(tstayqqynyybb)";
223 };
224
225 template <> struct DBusTypeTrait<EnergyScanResult>
226 {
227 // struct of { uint8, int8_t }
228 static constexpr const char *TYPE_AS_STRING = "(yy)";
229 };
230
231 template <> struct DBusTypeTrait<ChannelQuality>
232 {
233 // struct of { uint8, uint16}
234 static constexpr const char *TYPE_AS_STRING = "(yq)";
235 };
236
237 template <> struct DBusTypeTrait<std::vector<ChildInfo>>
238 {
239 // array of struct of { uint64, uint32, uint32, uint16, uint16, uint8, uint8,
240 // uint8, uint8, uint16, uint16, bool, bool, bool, bool }
241 static constexpr const char *TYPE_AS_STRING = "a(tuuqqyyyyqqbbbb)";
242 };
243
244 template <> struct DBusTypeTrait<TxtEntry>
245 {
246 // struct of { string, array<uint8> }
247 static constexpr const char *TYPE_AS_STRING = "(say)";
248 };
249
250 template <> struct DBusTypeTrait<std::vector<TxtEntry>>
251 {
252 // array of struct of { string, array<uint8> }
253 static constexpr const char *TYPE_AS_STRING = "a(say)";
254 };
255
256 template <> struct DBusTypeTrait<SrpServerState>
257 {
258 static constexpr int TYPE = DBUS_TYPE_BYTE;
259 static constexpr const char *TYPE_AS_STRING = DBUS_TYPE_BYTE_AS_STRING;
260 };
261
262 template <> struct DBusTypeTrait<SrpServerAddressMode>
263 {
264 static constexpr int TYPE = DBUS_TYPE_BYTE;
265 static constexpr const char *TYPE_AS_STRING = DBUS_TYPE_BYTE_AS_STRING;
266 };
267
268 template <> struct DBusTypeTrait<SrpServerInfo>
269 {
270 // struct of { uint8, uint16, uint8,
271 // struct of { uint32, uint32, uint64, uint64, uint64, uint64 },
272 // struct of { uint32, uint32, uint64, uint64, uint64, uint64 },
273 // struct of { uint32, uint32, uint32, uint32, uint32, uint32} }
274 static constexpr const char *TYPE_AS_STRING = "(yqy(uutttt)(uutttt)(uuuuuu))";
275 };
276
277 template <> struct DBusTypeTrait<MdnsTelemetryInfo>
278 {
279 // struct of { struct of { uint32, uint32, uint32, uint32, uint32, uint32, uint32, uint32 },
280 // struct of { uint32, uint32, uint32, uint32, uint32, uint32, uint32, uint32 },
281 // struct of { uint32, uint32, uint32, uint32, uint32, uint32, uint32, uint32 },
282 // struct of { uint32, uint32, uint32, uint32, uint32, uint32, uint32, uint32 },
283 // uint32, uint32, uint32, uint32 }
284 static constexpr const char *TYPE_AS_STRING = "((uuuuuuuu)(uuuuuuuu)(uuuuuuuu)(uuuuuuuu)uuuu)";
285 };
286
287 template <> struct DBusTypeTrait<DnssdCounters>
288 {
289 // struct of { uint32, uint32, uint32, uint32, uint32, uint32, uint32 }
290 static constexpr const char *TYPE_AS_STRING = "(uuuuuuu)";
291 };
292
293 template <> struct DBusTypeTrait<RadioSpinelMetrics>
294 {
295 // struct of { uint32, uint32, uint32, uint32 }
296 static constexpr const char *TYPE_AS_STRING = "(uuuu)";
297 };
298
299 template <> struct DBusTypeTrait<RcpInterfaceMetrics>
300 {
301 // struct of { uint8, uint64, uint64, uint64, uint64, uint64, uint64, uint64 }
302 static constexpr const char *TYPE_AS_STRING = "(yttttttt)";
303 };
304
305 template <> struct DBusTypeTrait<RadioCoexMetrics>
306 {
307 // struct of { uint32, uint32, uint32, uint32, uint32, uint32, uint32, uint32,
308 // uint32, uint32, uint32, uint32, uint32, uint32, uint32, uint32,
309 // uint32, uint32, bool }
310 static constexpr const char *TYPE_AS_STRING = "(uuuuuuuuuuuuuuuuuub)";
311 };
312
313 template <> struct DBusTypeTrait<BorderRoutingCounters>
314 {
315 // struct of { struct of { uint64, uint64 },
316 // struct of { uint64, uint64 },
317 // struct of { uint64, uint64 },
318 // struct of { uint64, uint64 },
319 // uint32, uint32, uint32, uint32, uint32, uint32 }
320 static constexpr const char *TYPE_AS_STRING = "((tt)(tt)(tt)(tt)uuuuuu)";
321 };
322
323 template <> struct DBusTypeTrait<Nat64ComponentState>
324 {
325 // struct of { uint8, uint8 }
326 static constexpr const char *TYPE_AS_STRING = "(ss)";
327 };
328
329 template <> struct DBusTypeTrait<Nat64TrafficCounters>
330 {
331 // struct of { uint64, uint64, uint64, uint64 }
332 static constexpr const char *TYPE_AS_STRING = "(tttt)";
333 };
334
335 template <> struct DBusTypeTrait<Nat64PacketCounters>
336 {
337 // struct of { uint64, uint64 }
338 static constexpr const char *TYPE_AS_STRING = "(tt)";
339 };
340
341 template <> struct DBusTypeTrait<Nat64ProtocolCounters>
342 {
343 // struct of { struct of { uint64, uint64, uint64, uint64 }
344 // struct of { uint64, uint64, uint64, uint64 }
345 // struct of { uint64, uint64, uint64, uint64 }
346 // struct of { uint64, uint64, uint64, uint64 } }
347 static constexpr const char *TYPE_AS_STRING = "((tttt)(tttt)(tttt)(tttt))";
348 };
349
350 template <> struct DBusTypeTrait<Nat64AddressMapping>
351 {
352 // struct of {
353 // uint64,
354 // array of uint8,
355 // array of uint8,
356 // uint32,
357 // struct of {
358 // struct of { uint64, uint64, uint64, uint64 }
359 // struct of { uint64, uint64, uint64, uint64 }
360 // struct of { uint64, uint64, uint64, uint64 }
361 // struct of { uint64, uint64, uint64, uint64 } } }
362 static constexpr const char *TYPE_AS_STRING = "(tayayu((tttt)(tttt)(tttt)(tttt)))";
363 };
364
365 template <> struct DBusTypeTrait<std::vector<Nat64AddressMapping>>
366 {
367 // array of struct of {
368 // uint64,
369 // array of uint8,
370 // array of uint8,
371 // uint32,
372 // struct of {
373 // struct of { uint64, uint64, uint64, uint64 }
374 // struct of { uint64, uint64, uint64, uint64 }
375 // struct of { uint64, uint64, uint64, uint64 }
376 // struct of { uint64, uint64, uint64, uint64 } } }
377 static constexpr const char *TYPE_AS_STRING = "a(tayayu((tttt)(tttt)(tttt)(tttt)))";
378 };
379
380 template <> struct DBusTypeTrait<Nat64ErrorCounters>
381 {
382 // struct of { struct of { uint64, uint64 }
383 // struct of { uint64, uint64 }
384 // struct of { uint64, uint64 }
385 // struct of { uint64, uint64 } }
386 static constexpr const char *TYPE_AS_STRING = "((tt)(tt)(tt)(tt))";
387 };
388
389 template <> struct DBusTypeTrait<TrelInfo>
390 {
391 // struct of { bool,
392 // uint16,
393 // struct of {
394 // uint64, uint64, uint64, uint64, uint64 } }
395 static constexpr const char *TYPE_AS_STRING = "(bq(ttttt))";
396 };
397
398 template <> struct DBusTypeTrait<TrelInfo::TrelPacketCounters>
399 {
400 // struct of { uint64, uint64, uint64, uint64, uint64 }
401 static constexpr const char *TYPE_AS_STRING = "(ttttt)";
402 };
403
404 template <> struct DBusTypeTrait<InfraLinkInfo>
405 {
406 // struct of { string, bool, bool, bool, uint32, uint32, uint32 }
407 static constexpr const char *TYPE_AS_STRING = "(sbbbuuu)";
408 };
409
410 template <> struct DBusTypeTrait<int8_t>
411 {
412 static constexpr int TYPE = DBUS_TYPE_BYTE;
413 static constexpr const char *TYPE_AS_STRING = DBUS_TYPE_BYTE_AS_STRING;
414 };
415
416 template <> struct DBusTypeTrait<uint8_t>
417 {
418 static constexpr int TYPE = DBUS_TYPE_BYTE;
419 static constexpr const char *TYPE_AS_STRING = DBUS_TYPE_BYTE_AS_STRING;
420 };
421
422 template <> struct DBusTypeTrait<uint16_t>
423 {
424 static constexpr int TYPE = DBUS_TYPE_UINT16;
425 static constexpr const char *TYPE_AS_STRING = DBUS_TYPE_UINT16_AS_STRING;
426 };
427
428 template <> struct DBusTypeTrait<uint32_t>
429 {
430 static constexpr int TYPE = DBUS_TYPE_UINT32;
431 static constexpr const char *TYPE_AS_STRING = DBUS_TYPE_UINT32_AS_STRING;
432 };
433
434 template <> struct DBusTypeTrait<uint64_t>
435 {
436 static constexpr int TYPE = DBUS_TYPE_UINT64;
437 static constexpr const char *TYPE_AS_STRING = DBUS_TYPE_UINT64_AS_STRING;
438 };
439
440 template <> struct DBusTypeTrait<int16_t>
441 {
442 static constexpr int TYPE = DBUS_TYPE_INT16;
443 static constexpr const char *TYPE_AS_STRING = DBUS_TYPE_INT16_AS_STRING;
444 };
445
446 template <> struct DBusTypeTrait<int32_t>
447 {
448 static constexpr int TYPE = DBUS_TYPE_INT32;
449 static constexpr const char *TYPE_AS_STRING = DBUS_TYPE_INT32_AS_STRING;
450 };
451
452 template <> struct DBusTypeTrait<int64_t>
453 {
454 static constexpr int TYPE = DBUS_TYPE_INT64;
455 static constexpr const char *TYPE_AS_STRING = DBUS_TYPE_INT64_AS_STRING;
456 };
457
458 template <> struct DBusTypeTrait<std::string>
459 {
460 static constexpr int TYPE = DBUS_TYPE_STRING;
461 static constexpr const char *TYPE_AS_STRING = DBUS_TYPE_STRING_AS_STRING;
462 };
463
464 template <> struct DBusTypeTrait<bool>
465 {
466 static constexpr int TYPE = DBUS_TYPE_BOOLEAN;
467 static constexpr const char *TYPE_AS_STRING = DBUS_TYPE_BOOLEAN_AS_STRING;
468 };
469
470 otbrError DbusMessageIterRecurse(DBusMessageIter *aIter, DBusMessageIter *aSubIter, int aType);
471
472 otbrError DBusMessageEncode(DBusMessageIter *aIter, bool aValue);
473 otbrError DBusMessageEncode(DBusMessageIter *aIter, int8_t aValue);
474 otbrError DBusMessageEncode(DBusMessageIter *aIter, const std::string &aValue);
475 otbrError DBusMessageEncode(DBusMessageIter *aIter, const char *aValue);
476 otbrError DBusMessageEncode(DBusMessageIter *aIter, const std::vector<uint8_t> &aValue);
477 otbrError DBusMessageEncode(DBusMessageIter *aIter, const std::vector<uint16_t> &aValue);
478 otbrError DBusMessageEncode(DBusMessageIter *aIter, const std::vector<uint32_t> &aValue);
479 otbrError DBusMessageEncode(DBusMessageIter *aIter, const std::vector<uint64_t> &aValue);
480 otbrError DBusMessageEncode(DBusMessageIter *aIter, const std::vector<int16_t> &aValue);
481 otbrError DBusMessageEncode(DBusMessageIter *aIter, const std::vector<int32_t> &aValue);
482 otbrError DBusMessageEncode(DBusMessageIter *aIter, const std::vector<int64_t> &aValue);
483 otbrError DBusMessageExtract(DBusMessageIter *aIter, bool &aValue);
484 otbrError DBusMessageExtract(DBusMessageIter *aIter, int8_t &aValue);
485 otbrError DBusMessageExtract(DBusMessageIter *aIter, std::string &aValue);
486 otbrError DBusMessageExtract(DBusMessageIter *aIter, std::vector<uint8_t> &aValue);
487 otbrError DBusMessageExtract(DBusMessageIter *aIter, std::vector<uint16_t> &aValue);
488 otbrError DBusMessageExtract(DBusMessageIter *aIter, std::vector<uint32_t> &aValue);
489 otbrError DBusMessageExtract(DBusMessageIter *aIter, std::vector<uint64_t> &aValue);
490 otbrError DBusMessageExtract(DBusMessageIter *aIter, std::vector<int16_t> &aValue);
491 otbrError DBusMessageExtract(DBusMessageIter *aIter, std::vector<int32_t> &aValue);
492 otbrError DBusMessageExtract(DBusMessageIter *aIter, std::vector<int64_t> &aValue);
493
DBusMessageExtract(DBusMessageIter * aIter,T & aValue)494 template <typename T> otbrError DBusMessageExtract(DBusMessageIter *aIter, T &aValue)
495 {
496 otbrError error = OTBR_ERROR_DBUS;
497
498 VerifyOrExit(dbus_message_iter_get_arg_type(aIter) == DBusTypeTrait<T>::TYPE);
499 dbus_message_iter_get_basic(aIter, &aValue);
500 dbus_message_iter_next(aIter);
501 error = OTBR_ERROR_NONE;
502
503 exit:
504 return error;
505 }
506
DBusMessageExtract(DBusMessageIter * aIter,std::vector<T> & aValue)507 template <typename T> otbrError DBusMessageExtract(DBusMessageIter *aIter, std::vector<T> &aValue)
508 {
509 otbrError error = OTBR_ERROR_NONE;
510 DBusMessageIter subIter;
511
512 VerifyOrExit(dbus_message_iter_get_arg_type(aIter) == DBUS_TYPE_ARRAY, error = OTBR_ERROR_DBUS);
513 dbus_message_iter_recurse(aIter, &subIter);
514
515 aValue.clear();
516 while (dbus_message_iter_get_arg_type(&subIter) != DBUS_TYPE_INVALID)
517 {
518 T val;
519 SuccessOrExit(error = DBusMessageExtract(&subIter, val));
520 aValue.push_back(val);
521 }
522 dbus_message_iter_next(aIter);
523
524 exit:
525 return error;
526 }
527
DBusMessageExtractPrimitive(DBusMessageIter * aIter,std::vector<T> & aValue)528 template <typename T> otbrError DBusMessageExtractPrimitive(DBusMessageIter *aIter, std::vector<T> &aValue)
529 {
530 DBusMessageIter subIter;
531 otbrError error = OTBR_ERROR_NONE;
532 T *val;
533 int n;
534 int subtype;
535
536 VerifyOrExit(dbus_message_iter_get_arg_type(aIter) == DBUS_TYPE_ARRAY, error = OTBR_ERROR_DBUS);
537 dbus_message_iter_recurse(aIter, &subIter);
538
539 subtype = dbus_message_iter_get_arg_type(&subIter);
540 if (subtype != DBUS_TYPE_INVALID)
541 {
542 VerifyOrExit(dbus_message_iter_get_arg_type(&subIter) == DBusTypeTrait<T>::TYPE, error = OTBR_ERROR_DBUS);
543 dbus_message_iter_get_fixed_array(&subIter, &val, &n);
544
545 if (val != nullptr)
546 {
547 aValue = std::vector<T>(val, val + n);
548 }
549 }
550 dbus_message_iter_next(aIter);
551
552 exit:
553 return error;
554 }
555
DBusMessageExtract(DBusMessageIter * aIter,std::array<T,SIZE> & aValue)556 template <typename T, size_t SIZE> otbrError DBusMessageExtract(DBusMessageIter *aIter, std::array<T, SIZE> &aValue)
557 {
558 DBusMessageIter subIter;
559 otbrError error = OTBR_ERROR_NONE;
560 T *val;
561 int n;
562 int subtype;
563
564 VerifyOrExit(dbus_message_iter_get_arg_type(aIter) == DBUS_TYPE_ARRAY, error = OTBR_ERROR_DBUS);
565 dbus_message_iter_recurse(aIter, &subIter);
566
567 subtype = dbus_message_iter_get_arg_type(&subIter);
568 if (subtype != DBUS_TYPE_INVALID)
569 {
570 VerifyOrExit(dbus_message_iter_get_arg_type(&subIter) == DBusTypeTrait<T>::TYPE, error = OTBR_ERROR_DBUS);
571 dbus_message_iter_get_fixed_array(&subIter, &val, &n);
572 VerifyOrExit(n == SIZE, error = OTBR_ERROR_DBUS);
573
574 if (val != nullptr)
575 {
576 std::copy(val, val + n, aValue.begin());
577 }
578 }
579 dbus_message_iter_next(aIter);
580
581 exit:
582 return error;
583 }
584
DBusMessageEncode(DBusMessageIter * aIter,T aValue)585 template <typename T> otbrError DBusMessageEncode(DBusMessageIter *aIter, T aValue)
586 {
587 otbrError error = OTBR_ERROR_NONE;
588 VerifyOrExit(dbus_message_iter_append_basic(aIter, DBusTypeTrait<T>::TYPE, &aValue), error = OTBR_ERROR_DBUS);
589
590 exit:
591 return error;
592 }
593
DBusMessageEncode(DBusMessageIter * aIter,const std::vector<T> & aValue)594 template <typename T> otbrError DBusMessageEncode(DBusMessageIter *aIter, const std::vector<T> &aValue)
595 {
596 otbrError error = OTBR_ERROR_NONE;
597 DBusMessageIter subIter;
598
599 VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_ARRAY, DBusTypeTrait<T>::TYPE_AS_STRING, &subIter),
600 error = OTBR_ERROR_DBUS);
601
602 for (const auto &v : aValue)
603 {
604 SuccessOrExit(error = DBusMessageEncode(&subIter, v));
605 }
606
607 VerifyOrExit(dbus_message_iter_close_container(aIter, &subIter), error = OTBR_ERROR_DBUS);
608 exit:
609 return error;
610 }
611
DBusMessageEncodePrimitive(DBusMessageIter * aIter,const std::vector<T> & aValue)612 template <typename T> otbrError DBusMessageEncodePrimitive(DBusMessageIter *aIter, const std::vector<T> &aValue)
613 {
614 DBusMessageIter subIter;
615 otbrError error = OTBR_ERROR_NONE;
616
617 VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_ARRAY, DBusTypeTrait<T>::TYPE_AS_STRING, &subIter),
618 error = OTBR_ERROR_DBUS);
619
620 if (!aValue.empty())
621 {
622 const T *buf = &aValue.front();
623
624 VerifyOrExit(dbus_message_iter_append_fixed_array(&subIter, DBusTypeTrait<T>::TYPE, &buf,
625 static_cast<int>(aValue.size())),
626 error = OTBR_ERROR_DBUS);
627 }
628 VerifyOrExit(dbus_message_iter_close_container(aIter, &subIter), error = OTBR_ERROR_DBUS);
629 exit:
630 return error;
631 }
632
633 template <typename T, size_t SIZE>
DBusMessageEncode(DBusMessageIter * aIter,const std::array<T,SIZE> & aValue)634 otbrError DBusMessageEncode(DBusMessageIter *aIter, const std::array<T, SIZE> &aValue)
635 {
636 DBusMessageIter subIter;
637 otbrError error = OTBR_ERROR_NONE;
638
639 VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_ARRAY, DBusTypeTrait<T>::TYPE_AS_STRING, &subIter),
640 error = OTBR_ERROR_DBUS);
641
642 if (!aValue.empty())
643 {
644 const T *buf = &aValue.front();
645
646 VerifyOrExit(dbus_message_iter_append_fixed_array(&subIter, DBusTypeTrait<T>::TYPE, &buf,
647 static_cast<int>(aValue.size())),
648 error = OTBR_ERROR_DBUS);
649 }
650 VerifyOrExit(dbus_message_iter_close_container(aIter, &subIter), error = OTBR_ERROR_DBUS);
651 exit:
652 return error;
653 }
654
655 template <size_t I, typename... FieldTypes> struct ElementType
656 {
657 using ValueType = typename std::tuple_element<I, std::tuple<FieldTypes...>>::type;
658 using NonconstValueType = typename std::remove_cv<ValueType>::type;
659 using RawValueType = typename std::remove_reference<NonconstValueType>::type;
660 };
661
662 template <size_t I, size_t N, typename... FieldTypes> class DBusMessageIterFor
663 {
664 public:
ConvertToTuple(DBusMessageIter * aIter,std::tuple<FieldTypes...> & aValues)665 static otbrError ConvertToTuple(DBusMessageIter *aIter, std::tuple<FieldTypes...> &aValues)
666 {
667 using RawValueType = typename ElementType<N - I, FieldTypes...>::RawValueType;
668 RawValueType &val = std::get<N - I>(aValues);
669 otbrError error = DBusMessageExtract(aIter, val);
670
671 SuccessOrExit(error);
672 error = DBusMessageIterFor<I - 1, N, FieldTypes...>::ConvertToTuple(aIter, aValues);
673
674 exit:
675 return error;
676 }
677
ConvertToDBusMessage(DBusMessageIter * aIter,const std::tuple<FieldTypes...> & aValues)678 static otbrError ConvertToDBusMessage(DBusMessageIter *aIter, const std::tuple<FieldTypes...> &aValues)
679 {
680 otbrError error = DBusMessageEncode(aIter, std::get<N - I>(aValues));
681
682 SuccessOrExit(error);
683 error = DBusMessageIterFor<I - 1, N, FieldTypes...>::ConvertToDBusMessage(aIter, aValues);
684
685 exit:
686 return error;
687 }
688 };
689
690 template <> class DBusMessageIterFor<0, 0>
691 {
692 public:
ConvertToTuple(DBusMessageIter * aIter,std::tuple<> & aValues)693 static otbrError ConvertToTuple(DBusMessageIter *aIter, std::tuple<> &aValues)
694 {
695 OTBR_UNUSED_VARIABLE(aIter);
696 OTBR_UNUSED_VARIABLE(aValues);
697 return OTBR_ERROR_NONE;
698 }
699
ConvertToDBusMessage(DBusMessageIter * aIter,const std::tuple<> & aValues)700 static otbrError ConvertToDBusMessage(DBusMessageIter *aIter, const std::tuple<> &aValues)
701 {
702 OTBR_UNUSED_VARIABLE(aIter);
703 OTBR_UNUSED_VARIABLE(aValues);
704 return OTBR_ERROR_NONE;
705 }
706 };
707
708 template <size_t N, typename... FieldTypes> class DBusMessageIterFor<1, N, FieldTypes...>
709 {
710 public:
ConvertToTuple(DBusMessageIter * aIter,std::tuple<FieldTypes...> & aValues)711 static otbrError ConvertToTuple(DBusMessageIter *aIter, std::tuple<FieldTypes...> &aValues)
712 {
713 using RawValueType = typename ElementType<N - 1, FieldTypes...>::RawValueType;
714 RawValueType &val = std::get<N - 1>(aValues);
715 otbrError error = DBusMessageExtract(aIter, val);
716
717 return error;
718 }
719
ConvertToDBusMessage(DBusMessageIter * aIter,const std::tuple<FieldTypes...> & aValues)720 static otbrError ConvertToDBusMessage(DBusMessageIter *aIter, const std::tuple<FieldTypes...> &aValues)
721 {
722 otbrError error = DBusMessageEncode(aIter, std::get<N - 1>(aValues));
723
724 return error;
725 }
726 };
727
728 template <typename... FieldTypes>
ConvertToDBusMessage(DBusMessageIter * aIter,const std::tuple<FieldTypes...> & aValues)729 otbrError ConvertToDBusMessage(DBusMessageIter *aIter, const std::tuple<FieldTypes...> &aValues)
730 {
731 return DBusMessageIterFor<sizeof...(FieldTypes), sizeof...(FieldTypes), FieldTypes...>::ConvertToDBusMessage(
732 aIter, aValues);
733 }
734
735 template <typename... FieldTypes>
ConvertToTuple(DBusMessageIter * aIter,std::tuple<FieldTypes...> & aValues)736 constexpr otbrError ConvertToTuple(DBusMessageIter *aIter, std::tuple<FieldTypes...> &aValues)
737 {
738 return DBusMessageIterFor<sizeof...(FieldTypes), sizeof...(FieldTypes), FieldTypes...>::ConvertToTuple(aIter,
739 aValues);
740 }
741
742 /**
743 * This function converts a value to a d-bus variant.
744 *
745 * @param[out] aIter The message iterator pointing to the variant.
746 * @param[in] aValue The value input.
747 *
748 * @retval OTBR_ERROR_NONE Successfully encoded to the variant.
749 * @retval OTBR_ERROR_DBUS Failed to encode to the variant.
750 */
DBusMessageEncodeToVariant(DBusMessageIter * aIter,const ValueType & aValue)751 template <typename ValueType> otbrError DBusMessageEncodeToVariant(DBusMessageIter *aIter, const ValueType &aValue)
752 {
753 otbrError error = OTBR_ERROR_NONE;
754 DBusMessageIter subIter;
755
756 VerifyOrExit(
757 dbus_message_iter_open_container(aIter, DBUS_TYPE_VARIANT, DBusTypeTrait<ValueType>::TYPE_AS_STRING, &subIter),
758 error = OTBR_ERROR_DBUS);
759
760 SuccessOrExit(error = DBusMessageEncode(&subIter, aValue));
761
762 VerifyOrExit(dbus_message_iter_close_container(aIter, &subIter), error = OTBR_ERROR_DBUS);
763
764 exit:
765 return error;
766 }
767
768 /**
769 * This function converts a d-bus variant to a value.
770 *
771 * @param[in] aIter The message iterator pointing to the variant.
772 * @param[out] aValue The value output.
773 *
774 * @retval OTBR_ERROR_NONE Successfully decoded the variant.
775 * @retval OTBR_ERROR_DBUS Failed to decode the variant.
776 */
DBusMessageExtractFromVariant(DBusMessageIter * aIter,ValueType & aValue)777 template <typename ValueType> otbrError DBusMessageExtractFromVariant(DBusMessageIter *aIter, ValueType &aValue)
778 {
779 otbrError error = OTBR_ERROR_NONE;
780 DBusMessageIter subIter;
781
782 VerifyOrExit(dbus_message_iter_get_arg_type(aIter) == DBUS_TYPE_VARIANT, error = OTBR_ERROR_DBUS);
783 dbus_message_iter_recurse(aIter, &subIter);
784
785 SuccessOrExit(error = DBusMessageExtract(&subIter, aValue));
786
787 exit:
788 return error;
789 }
790
791 /**
792 * This function converts a d-bus message to a tuple of C++ types.
793 *
794 * @param[in] aMessage The dbus message to decode.
795 * @param[out] aValues The tuple output.
796 *
797 * @retval OTBR_ERROR_NONE Successfully decoded the message.
798 * @retval OTBR_ERROR_DBUS Failed to decode the message.
799 */
800 template <typename... FieldTypes>
DBusMessageToTuple(DBusMessage & aMessage,std::tuple<FieldTypes...> & aValues)801 otbrError DBusMessageToTuple(DBusMessage &aMessage, std::tuple<FieldTypes...> &aValues)
802 {
803 otbrError error = OTBR_ERROR_NONE;
804 DBusMessageIter iter;
805
806 VerifyOrExit(dbus_message_iter_init(&aMessage, &iter), error = OTBR_ERROR_DBUS);
807
808 error = ConvertToTuple(&iter, aValues);
809
810 exit:
811 return error;
812 }
813
814 /**
815 * This function converts a tuple of C++ types to a d-bus message.
816 *
817 * @param[out] aMessage The dbus message output.
818 * @param[in] aValues The tuple to encode.
819 *
820 * @retval OTBR_ERROR_NONE Successfully encoded the message.
821 * @retval OTBR_ERROR_DBUS Failed to encode the message.
822 */
823 template <typename... FieldTypes>
TupleToDBusMessage(DBusMessage & aMessage,const std::tuple<FieldTypes...> & aValues)824 otbrError TupleToDBusMessage(DBusMessage &aMessage, const std::tuple<FieldTypes...> &aValues)
825 {
826 DBusMessageIter iter;
827
828 dbus_message_iter_init_append(&aMessage, &iter);
829 return ConvertToDBusMessage(&iter, aValues);
830 }
831
832 /**
833 * This function converts a d-bus message to a tuple of C++ types.
834 *
835 * @param[in] aMessage The dbus message to decode.
836 * @param[out] aValues The tuple output.
837 *
838 * @retval OTBR_ERROR_NONE Successfully decoded the message.
839 * @retval OTBR_ERROR_DBUS Failed to decode the message.
840 */
841 template <typename... FieldTypes>
DBusMessageToTuple(UniqueDBusMessage const & aMessage,std::tuple<FieldTypes...> & aValues)842 otbrError DBusMessageToTuple(UniqueDBusMessage const &aMessage, std::tuple<FieldTypes...> &aValues)
843 {
844 return DBusMessageToTuple(*aMessage.get(), aValues);
845 }
846
847 bool IsDBusMessageEmpty(DBusMessage &aMessage);
848
849 } // namespace DBus
850 } // namespace otbr
851
852 #endif // DBUS_MESSAGE_HELPER_HPP_
853