Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / ot-br-posix / repo / tests / dbus / test_dbus_client.cpp
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 #include <assert.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #include <memory>
35
36 #include <dbus/dbus.h>
37 #include <unistd.h>
38
39 #include "common/code_utils.hpp"
40 #include "dbus/client/thread_api_dbus.hpp"
41 #include "dbus/common/constants.hpp"
42
43 using otbr::DBus::ActiveScanResult;
44 using otbr::DBus::ClientError;
45 using otbr::DBus::DeviceRole;
46 using otbr::DBus::ExternalRoute;
47 using otbr::DBus::Ip6Prefix;
48 using otbr::DBus::LinkModeConfig;
49 using otbr::DBus::OnMeshPrefix;
50 using otbr::DBus::ThreadApiDBus;
51
52 #define TEST_ASSERT(x)                                              \
53     do                                                              \
54     {                                                               \
55         if (!(x))                                                   \
56         {                                                           \
57             printf("Assert failed at %s:%d\n", __FILE__, __LINE__); \
58             exit(EXIT_FAILURE);                                     \
59         }                                                           \
60     } while (false)
61
62 struct DBusConnectionDeleter
63 {
64     void operator()(DBusConnection *aConnection) { dbus_connection_unref(aConnection); }
65 };
66
67 using UniqueDBusConnection = std::unique_ptr<DBusConnection, DBusConnectionDeleter>;
68
69 static bool operator==(const otbr::DBus::Ip6Prefix &aLhs, const otbr::DBus::Ip6Prefix &aRhs)
70 {
71     bool prefixDataEquality = (aLhs.mPrefix.size() == aRhs.mPrefix.size()) &&
72                               (memcmp(&aLhs.mPrefix[0], &aRhs.mPrefix[0], aLhs.mPrefix.size()) == 0);
73
74     return prefixDataEquality && aLhs.mLength == aRhs.mLength;
75 }
76
77 static void CheckExternalRoute(ThreadApiDBus *aApi, const Ip6Prefix &aPrefix)
78 {
79     ExternalRoute              route;
80     std::vector<ExternalRoute> externalRouteTable;
81
82     route.mPrefix     = aPrefix;
83     route.mStable     = true;
84     route.mPreference = 0;
85
86     TEST_ASSERT(aApi->AddExternalRoute(route) == OTBR_ERROR_NONE);
87     TEST_ASSERT(aApi->GetExternalRoutes(externalRouteTable) == OTBR_ERROR_NONE);
88     TEST_ASSERT(externalRouteTable.size() == 1);
89     TEST_ASSERT(externalRouteTable[0].mPrefix == aPrefix);
90     TEST_ASSERT(externalRouteTable[0].mPreference == 0);
91     TEST_ASSERT(externalRouteTable[0].mStable);
92     TEST_ASSERT(externalRouteTable[0].mNextHopIsThisDevice);
93     TEST_ASSERT(aApi->RemoveExternalRoute(aPrefix) == OTBR_ERROR_NONE);
94 }
95
96 int main()
97 {
98     DBusError                      error;
99     UniqueDBusConnection           connection;
100     std::unique_ptr<ThreadApiDBus> api;
101     uint64_t                       extpanid = 0xdead00beaf00cafe;
102     std::string                    region;
103
104     dbus_error_init(&error);
105     connection = UniqueDBusConnection(dbus_bus_get(DBUS_BUS_SYSTEM, &error));
106
107     VerifyOrExit(connection != nullptr);
108
109     VerifyOrExit(dbus_bus_register(connection.get(), &error) == true);
110
111     api = std::unique_ptr<ThreadApiDBus>(new ThreadApiDBus(connection.get()));
112
113     api->AddDeviceRoleHandler(
114         [](DeviceRole aRole) { printf("Device role changed to %d\n", static_cast<uint8_t>(aRole)); });
115
116     TEST_ASSERT(api->SetRadioRegion("US") == ClientError::ERROR_NONE);
117     TEST_ASSERT(api->GetRadioRegion(region) == ClientError::ERROR_NONE);
118     TEST_ASSERT(region == "US");
119
120     api->Scan([&api, extpanid](const std::vector<ActiveScanResult> &aResult) {
121         LinkModeConfig       cfg       = {true, false, true};
122         std::vector<uint8_t> masterKey = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
123                                           0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
124         uint16_t             channel   = 11;
125
126         for (auto &&result : aResult)
127         {
128             printf("%s channel %d rssi %d\n", result.mNetworkName.c_str(), result.mChannel, result.mRssi);
129         }
130
131         api->SetLinkMode(cfg);
132         api->GetLinkMode(cfg);
133         printf("LinkMode %d %d %d\n", cfg.mRxOnWhenIdle, cfg.mDeviceType, cfg.mNetworkData);
134
135         cfg.mDeviceType = true;
136         api->SetLinkMode(cfg);
137
138         api->Attach("Test", 0x3456, extpanid, masterKey, {}, 1 << channel,
139                     [&api, channel, extpanid](ClientError aError) {
140                         printf("Attach result %d\n", static_cast<int>(aError));
141                         sleep(10);
142                         uint64_t             extpanidCheck;
143                         std::vector<uint8_t> activeDataset;
144
145                         if (aError == OTBR_ERROR_NONE)
146                         {
147                             std::string                           name;
148                             uint64_t                              extAddress = 0;
149                             uint16_t                              rloc16     = 0xffff;
150                             std::vector<uint8_t>                  networkData;
151                             std::vector<uint8_t>                  stableNetworkData;
152                             int8_t                                rssi;
153                             int8_t                                txPower;
154                             std::vector<otbr::DBus::ChildInfo>    childTable;
155                             std::vector<otbr::DBus::NeighborInfo> neighborTable;
156                             uint32_t                              partitionId;
157                             uint16_t                              channelResult;
158
159                             TEST_ASSERT(api->GetChannel(channelResult) == OTBR_ERROR_NONE);
160                             TEST_ASSERT(channelResult == channel);
161                             TEST_ASSERT(api->GetNetworkName(name) == OTBR_ERROR_NONE);
162                             TEST_ASSERT(api->GetExtPanId(extpanidCheck) == OTBR_ERROR_NONE);
163                             TEST_ASSERT(api->GetRloc16(rloc16) == OTBR_ERROR_NONE);
164                             TEST_ASSERT(api->GetExtendedAddress(extAddress) == OTBR_ERROR_NONE);
165                             TEST_ASSERT(api->GetNetworkData(networkData) == OTBR_ERROR_NONE);
166                             TEST_ASSERT(api->GetStableNetworkData(stableNetworkData) == OTBR_ERROR_NONE);
167                             TEST_ASSERT(api->GetChildTable(childTable) == OTBR_ERROR_NONE);
168                             TEST_ASSERT(api->GetNeighborTable(neighborTable) == OTBR_ERROR_NONE);
169                             printf("neighborTable size %zu\n", neighborTable.size());
170                             printf("childTable size %zu\n", childTable.size());
171                             TEST_ASSERT(neighborTable.size() == 1);
172                             TEST_ASSERT(childTable.size() == 1);
173                             TEST_ASSERT(api->GetPartitionId(partitionId) == OTBR_ERROR_NONE);
174                             TEST_ASSERT(api->GetInstantRssi(rssi) == OTBR_ERROR_NONE);
175                             TEST_ASSERT(api->GetRadioTxPower(txPower) == OTBR_ERROR_NONE);
176                             TEST_ASSERT(api->GetActiveDatasetTlvs(activeDataset) == OTBR_ERROR_NONE);
177                             api->FactoryReset(nullptr);
178                             sleep(1);
179                             TEST_ASSERT(api->GetNetworkName(name) == OTBR_ERROR_NONE);
180                             TEST_ASSERT(rloc16 != 0xffff);
181                             TEST_ASSERT(extAddress != 0);
182                             TEST_ASSERT(!networkData.empty());
183                             TEST_ASSERT(api->GetNeighborTable(neighborTable) == OTBR_ERROR_NONE);
184                             TEST_ASSERT(neighborTable.empty());
185                         }
186                         if (aError != OTBR_ERROR_NONE || extpanidCheck != extpanid)
187                         {
188                             exit(-1);
189                         }
190                         TEST_ASSERT(api->SetActiveDatasetTlvs(activeDataset) == OTBR_ERROR_NONE);
191                         api->Attach([&api, channel, extpanid](ClientError aErr) {
192                             uint8_t                routerId;
193                             otbr::DBus::LeaderData leaderData;
194                             uint8_t                leaderWeight;
195                             uint16_t               channelResult;
196                             uint64_t               extpanidCheck;
197                             Ip6Prefix              prefix;
198                             OnMeshPrefix           onMeshPrefix = {};
199
200                             prefix.mPrefix = {0xfd, 0xcd, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
201                             prefix.mLength = 64;
202
203                             onMeshPrefix.mPrefix     = prefix;
204                             onMeshPrefix.mPreference = 0;
205                             onMeshPrefix.mStable     = true;
206
207                             TEST_ASSERT(aErr == ClientError::ERROR_NONE);
208                             TEST_ASSERT(api->GetChannel(channelResult) == OTBR_ERROR_NONE);
209                             TEST_ASSERT(channelResult == channel);
210                             TEST_ASSERT(api->GetExtPanId(extpanidCheck) == OTBR_ERROR_NONE);
211                             TEST_ASSERT(extpanidCheck == extpanid);
212
213                             TEST_ASSERT(api->GetLocalLeaderWeight(leaderWeight) == OTBR_ERROR_NONE);
214                             TEST_ASSERT(api->GetLeaderData(leaderData) == OTBR_ERROR_NONE);
215                             TEST_ASSERT(api->GetRouterId(routerId) == OTBR_ERROR_NONE);
216                             TEST_ASSERT(routerId == leaderData.mLeaderRouterId);
217
218                             CheckExternalRoute(api.get(), prefix);
219                             TEST_ASSERT(api->AddOnMeshPrefix(onMeshPrefix) == OTBR_ERROR_NONE);
220                             TEST_ASSERT(api->RemoveOnMeshPrefix(onMeshPrefix.mPrefix) == OTBR_ERROR_NONE);
221
222                             api->FactoryReset(nullptr);
223                             sleep(1);
224                             TEST_ASSERT(api->JoinerStart("ABCDEF", "", "", "", "", "", nullptr) ==
225                                         ClientError::OT_ERROR_NOT_FOUND);
226                             TEST_ASSERT(api->JoinerStart("ABCDEF", "", "", "", "", "", [](ClientError aJoinError) {
227                                 TEST_ASSERT(aJoinError == ClientError::OT_ERROR_NOT_FOUND);
228                                 exit(0);
229                             }) == ClientError::ERROR_NONE);
230                         });
231                     });
232     });
233
234     while (true)
235     {
236         dbus_connection_read_write_dispatch(connection.get(), 0);
237     }
238
239 exit:
240     dbus_error_free(&error);
241     return 0;
242 };