1 /*
2 * Copyright (c) 2020, 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 #define OTBR_LOG_TAG "DBUS"
30
31 #include "dbus_message_dump.hpp"
32
33 #include <sstream>
34
35 #include "common/code_utils.hpp"
36 #include "common/logging.hpp"
37
38 namespace otbr {
39 namespace DBus {
40
DumpDBusMessage(std::ostringstream & sout,DBusMessageIter * aIter)41 static void DumpDBusMessage(std::ostringstream &sout, DBusMessageIter *aIter)
42 {
43 int type = dbus_message_iter_get_arg_type(aIter);
44
45 while (type != DBUS_TYPE_INVALID)
46 {
47 switch (type)
48 {
49 case DBUS_TYPE_BOOLEAN:
50 {
51 dbus_bool_t value;
52
53 dbus_message_iter_get_basic(aIter, &value);
54 sout << (value ? "true, " : "false, ");
55 break;
56 }
57 case DBUS_TYPE_BYTE:
58 {
59 uint8_t value;
60
61 dbus_message_iter_get_basic(aIter, &value);
62 sout << static_cast<int>(value) << ", ";
63 break;
64 }
65 case DBUS_TYPE_INT16:
66 {
67 int16_t value;
68
69 dbus_message_iter_get_basic(aIter, &value);
70 sout << value << ", ";
71 break;
72 }
73 case DBUS_TYPE_UINT16:
74 {
75 uint16_t value;
76
77 dbus_message_iter_get_basic(aIter, &value);
78 sout << value << ", ";
79 break;
80 }
81 case DBUS_TYPE_INT32:
82 {
83 int32_t value;
84
85 dbus_message_iter_get_basic(aIter, &value);
86 sout << value << ", ";
87 break;
88 }
89 case DBUS_TYPE_UINT32:
90 {
91 uint32_t value;
92
93 dbus_message_iter_get_basic(aIter, &value);
94 sout << value << ", ";
95 break;
96 }
97 case DBUS_TYPE_INT64:
98 {
99 int64_t value;
100
101 dbus_message_iter_get_basic(aIter, &value);
102 sout << value << ", ";
103 break;
104 }
105 case DBUS_TYPE_UINT64:
106 {
107 uint64_t value;
108
109 dbus_message_iter_get_basic(aIter, &value);
110 sout << value << ", ";
111 break;
112 }
113 case DBUS_TYPE_STRING:
114 {
115 const char *buf;
116
117 dbus_message_iter_get_basic(aIter, &buf);
118 sout << "\"" << buf << "\", ";
119 break;
120 }
121 case DBUS_TYPE_ARRAY:
122 {
123 DBusMessageIter subIter;
124
125 dbus_message_iter_recurse(aIter, &subIter);
126 sout << "[ ";
127 DumpDBusMessage(sout, &subIter);
128 sout << "], ";
129 break;
130 }
131 case DBUS_TYPE_STRUCT:
132 case DBUS_TYPE_VARIANT:
133 {
134 DBusMessageIter subIter;
135
136 dbus_message_iter_recurse(aIter, &subIter);
137 sout << "{ ";
138 DumpDBusMessage(sout, &subIter);
139 sout << " }, ";
140 break;
141 }
142 case DBUS_TYPE_DICT_ENTRY:
143 {
144 DBusMessageIter subIter;
145 char *key;
146
147 dbus_message_iter_recurse(aIter, &subIter);
148 dbus_message_iter_get_basic(&subIter, &key);
149 sout << key << ":{ ";
150 dbus_message_iter_next(&subIter);
151 if (dbus_message_iter_get_arg_type(&subIter) == DBUS_TYPE_VARIANT)
152 {
153 DBusMessageIter valueIter;
154 dbus_message_iter_recurse(&subIter, &valueIter);
155 DumpDBusMessage(sout, &valueIter);
156 }
157 sout << "}, ";
158 break;
159 }
160 case DBUS_TYPE_INVALID:
161 default:
162 break;
163 }
164 dbus_message_iter_next(aIter);
165 type = dbus_message_iter_get_arg_type(aIter);
166 }
167 return;
168 }
169
DumpDBusMessage(DBusMessage & aMessage)170 void DumpDBusMessage(DBusMessage &aMessage)
171 {
172 DBusMessageIter iter;
173 std::ostringstream sout;
174
175 VerifyOrExit(dbus_message_iter_init(&aMessage, &iter), otbrLogDebug("Failed to iterate dbus message during dump"));
176 sout << "{ ";
177 DumpDBusMessage(sout, &iter);
178 sout << "}";
179 otbrLogDebug(sout.str().c_str());
180 exit:
181 return;
182 }
183
184 } // namespace DBus
185 } // namespace otbr
186