1*4a64e381SAndroid Build Coastguard Worker /*
2*4a64e381SAndroid Build Coastguard Worker * Copyright (c) 2017, The OpenThread Authors.
3*4a64e381SAndroid Build Coastguard Worker * All rights reserved.
4*4a64e381SAndroid Build Coastguard Worker *
5*4a64e381SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*4a64e381SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
7*4a64e381SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
8*4a64e381SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
9*4a64e381SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
10*4a64e381SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
11*4a64e381SAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
12*4a64e381SAndroid Build Coastguard Worker * 3. Neither the name of the copyright holder nor the
13*4a64e381SAndroid Build Coastguard Worker * names of its contributors may be used to endorse or promote products
14*4a64e381SAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
15*4a64e381SAndroid Build Coastguard Worker *
16*4a64e381SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*4a64e381SAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*4a64e381SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*4a64e381SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*4a64e381SAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*4a64e381SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*4a64e381SAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*4a64e381SAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*4a64e381SAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*4a64e381SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*4a64e381SAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE.
27*4a64e381SAndroid Build Coastguard Worker */
28*4a64e381SAndroid Build Coastguard Worker
29*4a64e381SAndroid Build Coastguard Worker #define OTBR_LOG_TAG "TEST"
30*4a64e381SAndroid Build Coastguard Worker
31*4a64e381SAndroid Build Coastguard Worker #include <assert.h>
32*4a64e381SAndroid Build Coastguard Worker #include <errno.h>
33*4a64e381SAndroid Build Coastguard Worker #include <limits.h>
34*4a64e381SAndroid Build Coastguard Worker #include <stdio.h>
35*4a64e381SAndroid Build Coastguard Worker #include <string.h>
36*4a64e381SAndroid Build Coastguard Worker #include <time.h>
37*4a64e381SAndroid Build Coastguard Worker
38*4a64e381SAndroid Build Coastguard Worker #include <netinet/in.h>
39*4a64e381SAndroid Build Coastguard Worker #include <signal.h>
40*4a64e381SAndroid Build Coastguard Worker
41*4a64e381SAndroid Build Coastguard Worker #include <functional>
42*4a64e381SAndroid Build Coastguard Worker #include <vector>
43*4a64e381SAndroid Build Coastguard Worker
44*4a64e381SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
45*4a64e381SAndroid Build Coastguard Worker #include "common/logging.hpp"
46*4a64e381SAndroid Build Coastguard Worker #include "common/mainloop.hpp"
47*4a64e381SAndroid Build Coastguard Worker #include "common/mainloop_manager.hpp"
48*4a64e381SAndroid Build Coastguard Worker #include "mdns/mdns.hpp"
49*4a64e381SAndroid Build Coastguard Worker
50*4a64e381SAndroid Build Coastguard Worker using namespace otbr;
51*4a64e381SAndroid Build Coastguard Worker using namespace otbr::Mdns;
52*4a64e381SAndroid Build Coastguard Worker
53*4a64e381SAndroid Build Coastguard Worker static Publisher *sPublisher = nullptr;
54*4a64e381SAndroid Build Coastguard Worker
55*4a64e381SAndroid Build Coastguard Worker typedef std::function<void(void)> TestRunner;
56*4a64e381SAndroid Build Coastguard Worker
RunMainloop(void)57*4a64e381SAndroid Build Coastguard Worker int RunMainloop(void)
58*4a64e381SAndroid Build Coastguard Worker {
59*4a64e381SAndroid Build Coastguard Worker int rval = 0;
60*4a64e381SAndroid Build Coastguard Worker
61*4a64e381SAndroid Build Coastguard Worker while (true)
62*4a64e381SAndroid Build Coastguard Worker {
63*4a64e381SAndroid Build Coastguard Worker MainloopContext mainloop;
64*4a64e381SAndroid Build Coastguard Worker
65*4a64e381SAndroid Build Coastguard Worker mainloop.mMaxFd = -1;
66*4a64e381SAndroid Build Coastguard Worker mainloop.mTimeout = {INT_MAX, INT_MAX};
67*4a64e381SAndroid Build Coastguard Worker FD_ZERO(&mainloop.mReadFdSet);
68*4a64e381SAndroid Build Coastguard Worker FD_ZERO(&mainloop.mWriteFdSet);
69*4a64e381SAndroid Build Coastguard Worker FD_ZERO(&mainloop.mErrorFdSet);
70*4a64e381SAndroid Build Coastguard Worker
71*4a64e381SAndroid Build Coastguard Worker MainloopManager::GetInstance().Update(mainloop);
72*4a64e381SAndroid Build Coastguard Worker rval = select(mainloop.mMaxFd + 1, &mainloop.mReadFdSet, &mainloop.mWriteFdSet, &mainloop.mErrorFdSet,
73*4a64e381SAndroid Build Coastguard Worker (mainloop.mTimeout.tv_sec == INT_MAX ? nullptr : &mainloop.mTimeout));
74*4a64e381SAndroid Build Coastguard Worker
75*4a64e381SAndroid Build Coastguard Worker if (rval < 0)
76*4a64e381SAndroid Build Coastguard Worker {
77*4a64e381SAndroid Build Coastguard Worker perror("select");
78*4a64e381SAndroid Build Coastguard Worker break;
79*4a64e381SAndroid Build Coastguard Worker }
80*4a64e381SAndroid Build Coastguard Worker
81*4a64e381SAndroid Build Coastguard Worker MainloopManager::GetInstance().Process(mainloop);
82*4a64e381SAndroid Build Coastguard Worker }
83*4a64e381SAndroid Build Coastguard Worker
84*4a64e381SAndroid Build Coastguard Worker return rval;
85*4a64e381SAndroid Build Coastguard Worker }
86*4a64e381SAndroid Build Coastguard Worker
ErrorChecker(std::string aMessage)87*4a64e381SAndroid Build Coastguard Worker std::function<void(otbrError aError)> ErrorChecker(std::string aMessage)
88*4a64e381SAndroid Build Coastguard Worker {
89*4a64e381SAndroid Build Coastguard Worker return [aMessage](otbrError aError) {
90*4a64e381SAndroid Build Coastguard Worker if (aError == OTBR_ERROR_NONE)
91*4a64e381SAndroid Build Coastguard Worker {
92*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Got success callback: %s", aMessage.c_str());
93*4a64e381SAndroid Build Coastguard Worker }
94*4a64e381SAndroid Build Coastguard Worker else
95*4a64e381SAndroid Build Coastguard Worker {
96*4a64e381SAndroid Build Coastguard Worker otbrLogEmerg("Got error %d callback: %s", aError, aMessage.c_str());
97*4a64e381SAndroid Build Coastguard Worker exit(-1);
98*4a64e381SAndroid Build Coastguard Worker }
99*4a64e381SAndroid Build Coastguard Worker };
100*4a64e381SAndroid Build Coastguard Worker }
101*4a64e381SAndroid Build Coastguard Worker
PublishSingleServiceWithCustomHost(void)102*4a64e381SAndroid Build Coastguard Worker void PublishSingleServiceWithCustomHost(void)
103*4a64e381SAndroid Build Coastguard Worker {
104*4a64e381SAndroid Build Coastguard Worker uint8_t xpanid[kSizeExtPanId] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
105*4a64e381SAndroid Build Coastguard Worker uint8_t extAddr[kSizeExtAddr] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
106*4a64e381SAndroid Build Coastguard Worker uint8_t hostAddr[OTBR_IP6_ADDRESS_SIZE] = {0};
107*4a64e381SAndroid Build Coastguard Worker const char hostName[] = "custom-host";
108*4a64e381SAndroid Build Coastguard Worker std::vector<uint8_t> keyData = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
109*4a64e381SAndroid Build Coastguard Worker Publisher::TxtData txtData;
110*4a64e381SAndroid Build Coastguard Worker Publisher::TxtList txtList{
111*4a64e381SAndroid Build Coastguard Worker {"nn", "cool"},
112*4a64e381SAndroid Build Coastguard Worker {"xp", xpanid, sizeof(xpanid)},
113*4a64e381SAndroid Build Coastguard Worker {"tv", "1.1.1"},
114*4a64e381SAndroid Build Coastguard Worker {"xa", extAddr, sizeof(extAddr)},
115*4a64e381SAndroid Build Coastguard Worker };
116*4a64e381SAndroid Build Coastguard Worker
117*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("PublishSingleServiceWithCustomHost");
118*4a64e381SAndroid Build Coastguard Worker
119*4a64e381SAndroid Build Coastguard Worker hostAddr[0] = 0x20;
120*4a64e381SAndroid Build Coastguard Worker hostAddr[1] = 0x02;
121*4a64e381SAndroid Build Coastguard Worker hostAddr[15] = 0x01;
122*4a64e381SAndroid Build Coastguard Worker
123*4a64e381SAndroid Build Coastguard Worker Publisher::EncodeTxtData(txtList, txtData);
124*4a64e381SAndroid Build Coastguard Worker
125*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishKey(hostName, keyData, ErrorChecker("publish key for host"));
126*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishHost(hostName, {Ip6Address(hostAddr)}, ErrorChecker("publish the host"));
127*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishService(hostName, "SingleService", "_meshcop._udp", Publisher::SubTypeList{}, 12345, txtData,
128*4a64e381SAndroid Build Coastguard Worker ErrorChecker("publish the service"));
129*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishKey("SingleService._meshcop._udp", keyData, ErrorChecker("publish key for service"));
130*4a64e381SAndroid Build Coastguard Worker }
131*4a64e381SAndroid Build Coastguard Worker
PublishSingleServiceWithKeyAfterwards(void)132*4a64e381SAndroid Build Coastguard Worker void PublishSingleServiceWithKeyAfterwards(void)
133*4a64e381SAndroid Build Coastguard Worker {
134*4a64e381SAndroid Build Coastguard Worker uint8_t hostAddr[OTBR_IP6_ADDRESS_SIZE] = {0};
135*4a64e381SAndroid Build Coastguard Worker const char hostName[] = "custom-host";
136*4a64e381SAndroid Build Coastguard Worker Publisher::TxtData txtData;
137*4a64e381SAndroid Build Coastguard Worker
138*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("PublishSingleServiceWithKeyAfterwards");
139*4a64e381SAndroid Build Coastguard Worker
140*4a64e381SAndroid Build Coastguard Worker hostAddr[0] = 0x20;
141*4a64e381SAndroid Build Coastguard Worker hostAddr[1] = 0x02;
142*4a64e381SAndroid Build Coastguard Worker hostAddr[15] = 0x01;
143*4a64e381SAndroid Build Coastguard Worker
144*4a64e381SAndroid Build Coastguard Worker txtData.push_back(0);
145*4a64e381SAndroid Build Coastguard Worker
146*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishHost(hostName, {Ip6Address(hostAddr)}, ErrorChecker("publish the host"));
147*4a64e381SAndroid Build Coastguard Worker
148*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishService(
149*4a64e381SAndroid Build Coastguard Worker hostName, "SingleService", "_meshcop._udp", Publisher::SubTypeList{}, 12345, txtData, [](otbrError aError) {
150*4a64e381SAndroid Build Coastguard Worker std::vector<uint8_t> keyData = {0x55, 0xaa, 0xbb, 0xcc, 0x77, 0x33};
151*4a64e381SAndroid Build Coastguard Worker
152*4a64e381SAndroid Build Coastguard Worker SuccessOrDie(aError, "publish the service");
153*4a64e381SAndroid Build Coastguard Worker
154*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishKey("SingleService._meshcop._udp", keyData, ErrorChecker("publish key for service"));
155*4a64e381SAndroid Build Coastguard Worker });
156*4a64e381SAndroid Build Coastguard Worker }
157*4a64e381SAndroid Build Coastguard Worker
PublishMultipleServicesWithCustomHost(void)158*4a64e381SAndroid Build Coastguard Worker void PublishMultipleServicesWithCustomHost(void)
159*4a64e381SAndroid Build Coastguard Worker {
160*4a64e381SAndroid Build Coastguard Worker uint8_t xpanid[kSizeExtPanId] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
161*4a64e381SAndroid Build Coastguard Worker uint8_t extAddr[kSizeExtAddr] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
162*4a64e381SAndroid Build Coastguard Worker uint8_t hostAddr[OTBR_IP6_ADDRESS_SIZE] = {0};
163*4a64e381SAndroid Build Coastguard Worker const char hostName1[] = "custom-host-1";
164*4a64e381SAndroid Build Coastguard Worker const char hostName2[] = "custom-host-2";
165*4a64e381SAndroid Build Coastguard Worker std::vector<uint8_t> keyData1 = {0x10, 0x20, 0x03, 0x15};
166*4a64e381SAndroid Build Coastguard Worker std::vector<uint8_t> keyData2 = {0xCA, 0xFE, 0xBE, 0xEF};
167*4a64e381SAndroid Build Coastguard Worker Publisher::TxtData txtData;
168*4a64e381SAndroid Build Coastguard Worker Publisher::TxtList txtList{
169*4a64e381SAndroid Build Coastguard Worker {"nn", "cool"},
170*4a64e381SAndroid Build Coastguard Worker {"xp", xpanid, sizeof(xpanid)},
171*4a64e381SAndroid Build Coastguard Worker {"tv", "1.1.1"},
172*4a64e381SAndroid Build Coastguard Worker {"xa", extAddr, sizeof(extAddr)},
173*4a64e381SAndroid Build Coastguard Worker };
174*4a64e381SAndroid Build Coastguard Worker
175*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("PublishMultipleServicesWithCustomHost");
176*4a64e381SAndroid Build Coastguard Worker
177*4a64e381SAndroid Build Coastguard Worker hostAddr[0] = 0x20;
178*4a64e381SAndroid Build Coastguard Worker hostAddr[1] = 0x02;
179*4a64e381SAndroid Build Coastguard Worker hostAddr[15] = 0x01;
180*4a64e381SAndroid Build Coastguard Worker
181*4a64e381SAndroid Build Coastguard Worker Publisher::EncodeTxtData(txtList, txtData);
182*4a64e381SAndroid Build Coastguard Worker
183*4a64e381SAndroid Build Coastguard Worker // For host1 and its services we register keys first, then host/services
184*4a64e381SAndroid Build Coastguard Worker
185*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishKey(hostName1, keyData1, ErrorChecker("publish key for host1"));
186*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishKey("MultipleService11._meshcop._udp", keyData1, ErrorChecker("publish key for service11"));
187*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishKey("MultipleService12._meshcop._udp", keyData1, ErrorChecker("publish key for service12"));
188*4a64e381SAndroid Build Coastguard Worker
189*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishHost(hostName1, {Ip6Address(hostAddr)}, ErrorChecker("publish the host1"));
190*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishService(hostName1, "MultipleService11", "_meshcop._udp", Publisher::SubTypeList{}, 12345,
191*4a64e381SAndroid Build Coastguard Worker txtData, ErrorChecker("publish service11"));
192*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishService(hostName1, "MultipleService12", "_meshcop._udp", Publisher::SubTypeList{}, 12345,
193*4a64e381SAndroid Build Coastguard Worker txtData, ErrorChecker("publish service12"));
194*4a64e381SAndroid Build Coastguard Worker
195*4a64e381SAndroid Build Coastguard Worker // For host2 and its services we register host and services first, then keys.
196*4a64e381SAndroid Build Coastguard Worker
197*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishHost(hostName2, {Ip6Address(hostAddr)}, ErrorChecker("publish host2"));
198*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishService(hostName2, "MultipleService21", "_meshcop._udp", Publisher::SubTypeList{}, 12345,
199*4a64e381SAndroid Build Coastguard Worker txtData, ErrorChecker("publish service21"));
200*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishService(hostName2, "MultipleService22", "_meshcop._udp", Publisher::SubTypeList{}, 12345,
201*4a64e381SAndroid Build Coastguard Worker txtData, ErrorChecker("publish service22"));
202*4a64e381SAndroid Build Coastguard Worker
203*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishKey(hostName2, keyData2, ErrorChecker("publish key for host2"));
204*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishKey("MultipleService21._meshcop._udp", keyData2, ErrorChecker("publish key for service21"));
205*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishKey("MultipleService22._meshcop._udp", keyData2, ErrorChecker("publish key for service22"));
206*4a64e381SAndroid Build Coastguard Worker }
207*4a64e381SAndroid Build Coastguard Worker
PublishSingleService(void)208*4a64e381SAndroid Build Coastguard Worker void PublishSingleService(void)
209*4a64e381SAndroid Build Coastguard Worker {
210*4a64e381SAndroid Build Coastguard Worker uint8_t xpanid[kSizeExtPanId] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
211*4a64e381SAndroid Build Coastguard Worker uint8_t extAddr[kSizeExtAddr] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
212*4a64e381SAndroid Build Coastguard Worker Publisher::TxtData txtData;
213*4a64e381SAndroid Build Coastguard Worker Publisher::TxtList txtList{
214*4a64e381SAndroid Build Coastguard Worker {"nn", "cool"},
215*4a64e381SAndroid Build Coastguard Worker {"xp", xpanid, sizeof(xpanid)},
216*4a64e381SAndroid Build Coastguard Worker {"tv", "1.1.1"},
217*4a64e381SAndroid Build Coastguard Worker {"xa", extAddr, sizeof(extAddr)},
218*4a64e381SAndroid Build Coastguard Worker };
219*4a64e381SAndroid Build Coastguard Worker
220*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("PublishSingleService");
221*4a64e381SAndroid Build Coastguard Worker
222*4a64e381SAndroid Build Coastguard Worker Publisher::EncodeTxtData(txtList, txtData);
223*4a64e381SAndroid Build Coastguard Worker
224*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishService("", "SingleService", "_meshcop._udp", Publisher::SubTypeList{}, 12345, txtData,
225*4a64e381SAndroid Build Coastguard Worker ErrorChecker("publish service"));
226*4a64e381SAndroid Build Coastguard Worker }
227*4a64e381SAndroid Build Coastguard Worker
PublishSingleServiceWithEmptyName(void)228*4a64e381SAndroid Build Coastguard Worker void PublishSingleServiceWithEmptyName(void)
229*4a64e381SAndroid Build Coastguard Worker {
230*4a64e381SAndroid Build Coastguard Worker uint8_t xpanid[kSizeExtPanId] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
231*4a64e381SAndroid Build Coastguard Worker uint8_t extAddr[kSizeExtAddr] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
232*4a64e381SAndroid Build Coastguard Worker Publisher::TxtData txtData;
233*4a64e381SAndroid Build Coastguard Worker Publisher::TxtList txtList{
234*4a64e381SAndroid Build Coastguard Worker {"nn", "cool"},
235*4a64e381SAndroid Build Coastguard Worker {"xp", xpanid, sizeof(xpanid)},
236*4a64e381SAndroid Build Coastguard Worker {"tv", "1.1.1"},
237*4a64e381SAndroid Build Coastguard Worker {"xa", extAddr, sizeof(extAddr)},
238*4a64e381SAndroid Build Coastguard Worker };
239*4a64e381SAndroid Build Coastguard Worker
240*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("PublishSingleServiceWithEmptyName");
241*4a64e381SAndroid Build Coastguard Worker
242*4a64e381SAndroid Build Coastguard Worker Publisher::EncodeTxtData(txtList, txtData);
243*4a64e381SAndroid Build Coastguard Worker
244*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishService("", "", "_meshcop._udp", Publisher::SubTypeList{}, 12345, txtData,
245*4a64e381SAndroid Build Coastguard Worker ErrorChecker("publish (empty)._meshcop._udp"));
246*4a64e381SAndroid Build Coastguard Worker }
247*4a64e381SAndroid Build Coastguard Worker
PublishMultipleServices(void)248*4a64e381SAndroid Build Coastguard Worker void PublishMultipleServices(void)
249*4a64e381SAndroid Build Coastguard Worker {
250*4a64e381SAndroid Build Coastguard Worker uint8_t xpanid[kSizeExtPanId] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
251*4a64e381SAndroid Build Coastguard Worker uint8_t extAddr[kSizeExtAddr] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
252*4a64e381SAndroid Build Coastguard Worker Publisher::TxtData txtData;
253*4a64e381SAndroid Build Coastguard Worker Publisher::TxtList txtList1{
254*4a64e381SAndroid Build Coastguard Worker {"nn", "cool1"},
255*4a64e381SAndroid Build Coastguard Worker {"xp", xpanid, sizeof(xpanid)},
256*4a64e381SAndroid Build Coastguard Worker {"tv", "1.1.1"},
257*4a64e381SAndroid Build Coastguard Worker {"xa", extAddr, sizeof(extAddr)},
258*4a64e381SAndroid Build Coastguard Worker };
259*4a64e381SAndroid Build Coastguard Worker Publisher::TxtList txtList2{
260*4a64e381SAndroid Build Coastguard Worker {"nn", "cool2"},
261*4a64e381SAndroid Build Coastguard Worker {"xp", xpanid, sizeof(xpanid)},
262*4a64e381SAndroid Build Coastguard Worker {"tv", "1.1.1"},
263*4a64e381SAndroid Build Coastguard Worker {"xa", extAddr, sizeof(extAddr)},
264*4a64e381SAndroid Build Coastguard Worker };
265*4a64e381SAndroid Build Coastguard Worker
266*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("PublishMultipleServices");
267*4a64e381SAndroid Build Coastguard Worker
268*4a64e381SAndroid Build Coastguard Worker Publisher::EncodeTxtData(txtList1, txtData);
269*4a64e381SAndroid Build Coastguard Worker
270*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishService("", "MultipleService1", "_meshcop._udp", Publisher::SubTypeList{}, 12345, txtData,
271*4a64e381SAndroid Build Coastguard Worker ErrorChecker("publish MultipleService1._meshcop._udp"));
272*4a64e381SAndroid Build Coastguard Worker
273*4a64e381SAndroid Build Coastguard Worker Publisher::EncodeTxtData(txtList2, txtData);
274*4a64e381SAndroid Build Coastguard Worker
275*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishService("", "MultipleService2", "_meshcop._udp", Publisher::SubTypeList{}, 12345, txtData,
276*4a64e381SAndroid Build Coastguard Worker ErrorChecker("publish MultipleService2._meshcop._udp"));
277*4a64e381SAndroid Build Coastguard Worker }
278*4a64e381SAndroid Build Coastguard Worker
PublishUpdateServices(void)279*4a64e381SAndroid Build Coastguard Worker void PublishUpdateServices(void)
280*4a64e381SAndroid Build Coastguard Worker {
281*4a64e381SAndroid Build Coastguard Worker uint8_t xpanidOld[kSizeExtPanId] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
282*4a64e381SAndroid Build Coastguard Worker uint8_t xpanidNew[kSizeExtPanId] = {0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41};
283*4a64e381SAndroid Build Coastguard Worker uint8_t extAddr[kSizeExtAddr] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
284*4a64e381SAndroid Build Coastguard Worker Publisher::TxtData txtData;
285*4a64e381SAndroid Build Coastguard Worker Publisher::TxtList txtList1{
286*4a64e381SAndroid Build Coastguard Worker {"nn", "cool"},
287*4a64e381SAndroid Build Coastguard Worker {"xp", xpanidOld, sizeof(xpanidOld)},
288*4a64e381SAndroid Build Coastguard Worker {"tv", "1.1.1"},
289*4a64e381SAndroid Build Coastguard Worker {"xa", extAddr, sizeof(extAddr)},
290*4a64e381SAndroid Build Coastguard Worker };
291*4a64e381SAndroid Build Coastguard Worker Publisher::TxtList txtList2{
292*4a64e381SAndroid Build Coastguard Worker {"nn", "coolcool"},
293*4a64e381SAndroid Build Coastguard Worker {"xp", xpanidNew, sizeof(xpanidNew)},
294*4a64e381SAndroid Build Coastguard Worker {"tv", "1.1.1"},
295*4a64e381SAndroid Build Coastguard Worker {"xa", extAddr, sizeof(extAddr)},
296*4a64e381SAndroid Build Coastguard Worker };
297*4a64e381SAndroid Build Coastguard Worker
298*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("PublishUpdateServices");
299*4a64e381SAndroid Build Coastguard Worker
300*4a64e381SAndroid Build Coastguard Worker Publisher::EncodeTxtData(txtList1, txtData);
301*4a64e381SAndroid Build Coastguard Worker
302*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishService("", "UpdateService", "_meshcop._udp", Publisher::SubTypeList{}, 12345, txtData,
303*4a64e381SAndroid Build Coastguard Worker [](otbrError aError) { otbrLogResult(aError, "UpdateService._meshcop._udp"); });
304*4a64e381SAndroid Build Coastguard Worker
305*4a64e381SAndroid Build Coastguard Worker Publisher::EncodeTxtData(txtList2, txtData);
306*4a64e381SAndroid Build Coastguard Worker
307*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishService("", "UpdateService", "_meshcop._udp", Publisher::SubTypeList{}, 12345, txtData,
308*4a64e381SAndroid Build Coastguard Worker ErrorChecker("publish UpdateService._meshcop._udp"));
309*4a64e381SAndroid Build Coastguard Worker }
310*4a64e381SAndroid Build Coastguard Worker
PublishServiceSubTypes(void)311*4a64e381SAndroid Build Coastguard Worker void PublishServiceSubTypes(void)
312*4a64e381SAndroid Build Coastguard Worker {
313*4a64e381SAndroid Build Coastguard Worker Publisher::TxtData txtData;
314*4a64e381SAndroid Build Coastguard Worker Publisher::SubTypeList subTypeList{"_subtype1", "_SUBTYPE2"};
315*4a64e381SAndroid Build Coastguard Worker
316*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("PublishServiceSubTypes");
317*4a64e381SAndroid Build Coastguard Worker
318*4a64e381SAndroid Build Coastguard Worker txtData.push_back(0);
319*4a64e381SAndroid Build Coastguard Worker
320*4a64e381SAndroid Build Coastguard Worker subTypeList.back() = "_SUBTYPE3";
321*4a64e381SAndroid Build Coastguard Worker
322*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishService("", "ServiceWithSubTypes", "_meshcop._udp", subTypeList, 12345, txtData,
323*4a64e381SAndroid Build Coastguard Worker ErrorChecker("publish ServiceWithSubTypes._meshcop._udp"));
324*4a64e381SAndroid Build Coastguard Worker }
325*4a64e381SAndroid Build Coastguard Worker
PublishKey(void)326*4a64e381SAndroid Build Coastguard Worker void PublishKey(void)
327*4a64e381SAndroid Build Coastguard Worker {
328*4a64e381SAndroid Build Coastguard Worker std::vector<uint8_t> keyData = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
329*4a64e381SAndroid Build Coastguard Worker
330*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("PublishKey");
331*4a64e381SAndroid Build Coastguard Worker
332*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishKey("SingleService._meshcop._udp", keyData, ErrorChecker("publish key for service"));
333*4a64e381SAndroid Build Coastguard Worker }
334*4a64e381SAndroid Build Coastguard Worker
PublishKeyWithServiceRemoved(void)335*4a64e381SAndroid Build Coastguard Worker void PublishKeyWithServiceRemoved(void)
336*4a64e381SAndroid Build Coastguard Worker {
337*4a64e381SAndroid Build Coastguard Worker uint8_t hostAddr[OTBR_IP6_ADDRESS_SIZE] = {0};
338*4a64e381SAndroid Build Coastguard Worker const char hostName[] = "custom-host";
339*4a64e381SAndroid Build Coastguard Worker Publisher::TxtData txtData;
340*4a64e381SAndroid Build Coastguard Worker
341*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("PublishKeyWithServiceRemoved");
342*4a64e381SAndroid Build Coastguard Worker
343*4a64e381SAndroid Build Coastguard Worker hostAddr[0] = 0x20;
344*4a64e381SAndroid Build Coastguard Worker hostAddr[1] = 0x02;
345*4a64e381SAndroid Build Coastguard Worker hostAddr[15] = 0x01;
346*4a64e381SAndroid Build Coastguard Worker
347*4a64e381SAndroid Build Coastguard Worker txtData.push_back(0);
348*4a64e381SAndroid Build Coastguard Worker
349*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishHost(hostName, {Ip6Address(hostAddr)}, ErrorChecker("publish the host"));
350*4a64e381SAndroid Build Coastguard Worker
351*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishService(
352*4a64e381SAndroid Build Coastguard Worker hostName, "SingleService", "_meshcop._udp", Publisher::SubTypeList{}, 12345, txtData, [](otbrError aError) {
353*4a64e381SAndroid Build Coastguard Worker std::vector<uint8_t> keyData = {0x55, 0xaa, 0xbb, 0xcc, 0x77, 0x33};
354*4a64e381SAndroid Build Coastguard Worker
355*4a64e381SAndroid Build Coastguard Worker SuccessOrDie(aError, "publish the service");
356*4a64e381SAndroid Build Coastguard Worker
357*4a64e381SAndroid Build Coastguard Worker sPublisher->PublishKey("SingleService._meshcop._udp", keyData, [](otbrError aError) {
358*4a64e381SAndroid Build Coastguard Worker SuccessOrDie(aError, "publish key for service");
359*4a64e381SAndroid Build Coastguard Worker
360*4a64e381SAndroid Build Coastguard Worker sPublisher->UnpublishService("SingleService", "_meshcop._udp", ErrorChecker("unpublish service"));
361*4a64e381SAndroid Build Coastguard Worker });
362*4a64e381SAndroid Build Coastguard Worker });
363*4a64e381SAndroid Build Coastguard Worker }
364*4a64e381SAndroid Build Coastguard Worker
Test(TestRunner aTestRunner)365*4a64e381SAndroid Build Coastguard Worker otbrError Test(TestRunner aTestRunner)
366*4a64e381SAndroid Build Coastguard Worker {
367*4a64e381SAndroid Build Coastguard Worker otbrError error = OTBR_ERROR_NONE;
368*4a64e381SAndroid Build Coastguard Worker
369*4a64e381SAndroid Build Coastguard Worker sPublisher = Publisher::Create([aTestRunner](Publisher::State aState) {
370*4a64e381SAndroid Build Coastguard Worker if (aState == Publisher::State::kReady)
371*4a64e381SAndroid Build Coastguard Worker {
372*4a64e381SAndroid Build Coastguard Worker aTestRunner();
373*4a64e381SAndroid Build Coastguard Worker }
374*4a64e381SAndroid Build Coastguard Worker });
375*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = sPublisher->Start());
376*4a64e381SAndroid Build Coastguard Worker RunMainloop();
377*4a64e381SAndroid Build Coastguard Worker
378*4a64e381SAndroid Build Coastguard Worker exit:
379*4a64e381SAndroid Build Coastguard Worker Publisher::Destroy(sPublisher);
380*4a64e381SAndroid Build Coastguard Worker return error;
381*4a64e381SAndroid Build Coastguard Worker }
382*4a64e381SAndroid Build Coastguard Worker
RecoverSignal(int aSignal)383*4a64e381SAndroid Build Coastguard Worker void RecoverSignal(int aSignal)
384*4a64e381SAndroid Build Coastguard Worker {
385*4a64e381SAndroid Build Coastguard Worker if (aSignal == SIGUSR1)
386*4a64e381SAndroid Build Coastguard Worker {
387*4a64e381SAndroid Build Coastguard Worker signal(SIGUSR1, SIG_DFL);
388*4a64e381SAndroid Build Coastguard Worker }
389*4a64e381SAndroid Build Coastguard Worker else if (aSignal == SIGUSR2)
390*4a64e381SAndroid Build Coastguard Worker {
391*4a64e381SAndroid Build Coastguard Worker signal(SIGUSR2, SIG_DFL);
392*4a64e381SAndroid Build Coastguard Worker }
393*4a64e381SAndroid Build Coastguard Worker }
394*4a64e381SAndroid Build Coastguard Worker
TestStopService(void)395*4a64e381SAndroid Build Coastguard Worker otbrError TestStopService(void)
396*4a64e381SAndroid Build Coastguard Worker {
397*4a64e381SAndroid Build Coastguard Worker otbrError ret = OTBR_ERROR_NONE;
398*4a64e381SAndroid Build Coastguard Worker
399*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("TestStopService");
400*4a64e381SAndroid Build Coastguard Worker
401*4a64e381SAndroid Build Coastguard Worker sPublisher = Publisher::Create([](Publisher::State aState) {
402*4a64e381SAndroid Build Coastguard Worker if (aState == Publisher::State::kReady)
403*4a64e381SAndroid Build Coastguard Worker {
404*4a64e381SAndroid Build Coastguard Worker PublishSingleService();
405*4a64e381SAndroid Build Coastguard Worker }
406*4a64e381SAndroid Build Coastguard Worker });
407*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(ret = sPublisher->Start());
408*4a64e381SAndroid Build Coastguard Worker signal(SIGUSR1, RecoverSignal);
409*4a64e381SAndroid Build Coastguard Worker signal(SIGUSR2, RecoverSignal);
410*4a64e381SAndroid Build Coastguard Worker RunMainloop();
411*4a64e381SAndroid Build Coastguard Worker sPublisher->Stop();
412*4a64e381SAndroid Build Coastguard Worker RunMainloop();
413*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(ret = sPublisher->Start());
414*4a64e381SAndroid Build Coastguard Worker RunMainloop();
415*4a64e381SAndroid Build Coastguard Worker
416*4a64e381SAndroid Build Coastguard Worker exit:
417*4a64e381SAndroid Build Coastguard Worker Publisher::Destroy(sPublisher);
418*4a64e381SAndroid Build Coastguard Worker return ret;
419*4a64e381SAndroid Build Coastguard Worker }
420*4a64e381SAndroid Build Coastguard Worker
CheckTxtDataEncoderDecoder(void)421*4a64e381SAndroid Build Coastguard Worker otbrError CheckTxtDataEncoderDecoder(void)
422*4a64e381SAndroid Build Coastguard Worker {
423*4a64e381SAndroid Build Coastguard Worker otbrError error = OTBR_ERROR_NONE;
424*4a64e381SAndroid Build Coastguard Worker Publisher::TxtList txtList;
425*4a64e381SAndroid Build Coastguard Worker Publisher::TxtList parsedTxtList;
426*4a64e381SAndroid Build Coastguard Worker std::vector<uint8_t> txtData;
427*4a64e381SAndroid Build Coastguard Worker
428*4a64e381SAndroid Build Coastguard Worker // Encode empty `TxtList`
429*4a64e381SAndroid Build Coastguard Worker
430*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = Publisher::EncodeTxtData(txtList, txtData));
431*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(txtData.size() == 1, error = OTBR_ERROR_PARSE);
432*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(txtData[0] == 0, error = OTBR_ERROR_PARSE);
433*4a64e381SAndroid Build Coastguard Worker
434*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = Publisher::DecodeTxtData(parsedTxtList, txtData.data(), txtData.size()));
435*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(parsedTxtList.size() == 0, error = OTBR_ERROR_PARSE);
436*4a64e381SAndroid Build Coastguard Worker
437*4a64e381SAndroid Build Coastguard Worker // TxtList with one bool attribute
438*4a64e381SAndroid Build Coastguard Worker
439*4a64e381SAndroid Build Coastguard Worker txtList.clear();
440*4a64e381SAndroid Build Coastguard Worker txtList.emplace_back("b1");
441*4a64e381SAndroid Build Coastguard Worker
442*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = Publisher::EncodeTxtData(txtList, txtData));
443*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = Publisher::DecodeTxtData(parsedTxtList, txtData.data(), txtData.size()));
444*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(parsedTxtList == txtList, error = OTBR_ERROR_PARSE);
445*4a64e381SAndroid Build Coastguard Worker
446*4a64e381SAndroid Build Coastguard Worker // TxtList with one one key/value
447*4a64e381SAndroid Build Coastguard Worker
448*4a64e381SAndroid Build Coastguard Worker txtList.clear();
449*4a64e381SAndroid Build Coastguard Worker txtList.emplace_back("k1", "v1");
450*4a64e381SAndroid Build Coastguard Worker
451*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = Publisher::EncodeTxtData(txtList, txtData));
452*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = Publisher::DecodeTxtData(parsedTxtList, txtData.data(), txtData.size()));
453*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(parsedTxtList == txtList, error = OTBR_ERROR_PARSE);
454*4a64e381SAndroid Build Coastguard Worker
455*4a64e381SAndroid Build Coastguard Worker // TxtList with multiple entries
456*4a64e381SAndroid Build Coastguard Worker
457*4a64e381SAndroid Build Coastguard Worker txtList.clear();
458*4a64e381SAndroid Build Coastguard Worker txtList.emplace_back("k1", "v1");
459*4a64e381SAndroid Build Coastguard Worker txtList.emplace_back("b1");
460*4a64e381SAndroid Build Coastguard Worker txtList.emplace_back("b2");
461*4a64e381SAndroid Build Coastguard Worker txtList.emplace_back("k2", "valu2");
462*4a64e381SAndroid Build Coastguard Worker
463*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = Publisher::EncodeTxtData(txtList, txtData));
464*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = Publisher::DecodeTxtData(parsedTxtList, txtData.data(), txtData.size()));
465*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(parsedTxtList == txtList, error = OTBR_ERROR_PARSE);
466*4a64e381SAndroid Build Coastguard Worker
467*4a64e381SAndroid Build Coastguard Worker exit:
468*4a64e381SAndroid Build Coastguard Worker return error;
469*4a64e381SAndroid Build Coastguard Worker }
470*4a64e381SAndroid Build Coastguard Worker
main(int argc,char * argv[])471*4a64e381SAndroid Build Coastguard Worker int main(int argc, char *argv[])
472*4a64e381SAndroid Build Coastguard Worker {
473*4a64e381SAndroid Build Coastguard Worker int ret = 0;
474*4a64e381SAndroid Build Coastguard Worker
475*4a64e381SAndroid Build Coastguard Worker if (CheckTxtDataEncoderDecoder() != OTBR_ERROR_NONE)
476*4a64e381SAndroid Build Coastguard Worker {
477*4a64e381SAndroid Build Coastguard Worker return 1;
478*4a64e381SAndroid Build Coastguard Worker }
479*4a64e381SAndroid Build Coastguard Worker
480*4a64e381SAndroid Build Coastguard Worker if (argc < 2)
481*4a64e381SAndroid Build Coastguard Worker {
482*4a64e381SAndroid Build Coastguard Worker return 1;
483*4a64e381SAndroid Build Coastguard Worker }
484*4a64e381SAndroid Build Coastguard Worker
485*4a64e381SAndroid Build Coastguard Worker otbrLogInit("otbr-mdns", OTBR_LOG_DEBUG, true, false);
486*4a64e381SAndroid Build Coastguard Worker // allow quitting elegantly
487*4a64e381SAndroid Build Coastguard Worker signal(SIGTERM, RecoverSignal);
488*4a64e381SAndroid Build Coastguard Worker switch (argv[1][0])
489*4a64e381SAndroid Build Coastguard Worker {
490*4a64e381SAndroid Build Coastguard Worker case 's':
491*4a64e381SAndroid Build Coastguard Worker switch (argv[1][1])
492*4a64e381SAndroid Build Coastguard Worker {
493*4a64e381SAndroid Build Coastguard Worker case 'c':
494*4a64e381SAndroid Build Coastguard Worker ret = Test(PublishSingleServiceWithCustomHost);
495*4a64e381SAndroid Build Coastguard Worker break;
496*4a64e381SAndroid Build Coastguard Worker case 'e':
497*4a64e381SAndroid Build Coastguard Worker ret = Test(PublishSingleServiceWithEmptyName);
498*4a64e381SAndroid Build Coastguard Worker break;
499*4a64e381SAndroid Build Coastguard Worker case 'k':
500*4a64e381SAndroid Build Coastguard Worker ret = Test(PublishSingleServiceWithKeyAfterwards);
501*4a64e381SAndroid Build Coastguard Worker break;
502*4a64e381SAndroid Build Coastguard Worker default:
503*4a64e381SAndroid Build Coastguard Worker ret = Test(PublishSingleService);
504*4a64e381SAndroid Build Coastguard Worker break;
505*4a64e381SAndroid Build Coastguard Worker }
506*4a64e381SAndroid Build Coastguard Worker break;
507*4a64e381SAndroid Build Coastguard Worker
508*4a64e381SAndroid Build Coastguard Worker case 'm':
509*4a64e381SAndroid Build Coastguard Worker ret = argv[1][1] == 'c' ? Test(PublishMultipleServicesWithCustomHost) : Test(PublishMultipleServices);
510*4a64e381SAndroid Build Coastguard Worker break;
511*4a64e381SAndroid Build Coastguard Worker
512*4a64e381SAndroid Build Coastguard Worker case 'u':
513*4a64e381SAndroid Build Coastguard Worker ret = Test(PublishUpdateServices);
514*4a64e381SAndroid Build Coastguard Worker break;
515*4a64e381SAndroid Build Coastguard Worker
516*4a64e381SAndroid Build Coastguard Worker case 't':
517*4a64e381SAndroid Build Coastguard Worker ret = Test(PublishServiceSubTypes);
518*4a64e381SAndroid Build Coastguard Worker break;
519*4a64e381SAndroid Build Coastguard Worker
520*4a64e381SAndroid Build Coastguard Worker case 'k':
521*4a64e381SAndroid Build Coastguard Worker ret = TestStopService();
522*4a64e381SAndroid Build Coastguard Worker break;
523*4a64e381SAndroid Build Coastguard Worker
524*4a64e381SAndroid Build Coastguard Worker case 'y':
525*4a64e381SAndroid Build Coastguard Worker ret = Test(PublishKey);
526*4a64e381SAndroid Build Coastguard Worker break;
527*4a64e381SAndroid Build Coastguard Worker
528*4a64e381SAndroid Build Coastguard Worker case 'z':
529*4a64e381SAndroid Build Coastguard Worker ret = Test(PublishKeyWithServiceRemoved);
530*4a64e381SAndroid Build Coastguard Worker break;
531*4a64e381SAndroid Build Coastguard Worker
532*4a64e381SAndroid Build Coastguard Worker default:
533*4a64e381SAndroid Build Coastguard Worker ret = 1;
534*4a64e381SAndroid Build Coastguard Worker break;
535*4a64e381SAndroid Build Coastguard Worker }
536*4a64e381SAndroid Build Coastguard Worker
537*4a64e381SAndroid Build Coastguard Worker return ret;
538*4a64e381SAndroid Build Coastguard Worker }
539