xref: /aosp_15_r20/external/ot-br-posix/src/dbus/common/dbus_message_helper.hpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
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