xref: /aosp_15_r20/external/openthread/tests/unit/test_dns_client.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker  *  Copyright (c) 2023, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker  *  All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker  *
5*cfb92d14SAndroid Build Coastguard Worker  *  Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker  *  modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker  *  1. Redistributions of source code must retain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker  *  2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker  *     documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker  *  3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker  *     names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker  *     derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker  *
16*cfb92d14SAndroid Build Coastguard Worker  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*cfb92d14SAndroid Build Coastguard Worker  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker  *  POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker  */
28*cfb92d14SAndroid Build Coastguard Worker 
29*cfb92d14SAndroid Build Coastguard Worker #include <openthread/config.h>
30*cfb92d14SAndroid Build Coastguard Worker 
31*cfb92d14SAndroid Build Coastguard Worker #include "test_platform.h"
32*cfb92d14SAndroid Build Coastguard Worker #include "test_util.hpp"
33*cfb92d14SAndroid Build Coastguard Worker 
34*cfb92d14SAndroid Build Coastguard Worker #include <openthread/dataset_ftd.h>
35*cfb92d14SAndroid Build Coastguard Worker #include <openthread/dns_client.h>
36*cfb92d14SAndroid Build Coastguard Worker #include <openthread/srp_client.h>
37*cfb92d14SAndroid Build Coastguard Worker #include <openthread/srp_server.h>
38*cfb92d14SAndroid Build Coastguard Worker #include <openthread/thread.h>
39*cfb92d14SAndroid Build Coastguard Worker 
40*cfb92d14SAndroid Build Coastguard Worker #include "common/arg_macros.hpp"
41*cfb92d14SAndroid Build Coastguard Worker #include "common/array.hpp"
42*cfb92d14SAndroid Build Coastguard Worker #include "common/string.hpp"
43*cfb92d14SAndroid Build Coastguard Worker #include "common/time.hpp"
44*cfb92d14SAndroid Build Coastguard Worker #include "instance/instance.hpp"
45*cfb92d14SAndroid Build Coastguard Worker 
46*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE && OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE &&                 \
47*cfb92d14SAndroid Build Coastguard Worker     OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_SERVER_ADDRESS_AUTO_SET_ENABLE && OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE && \
48*cfb92d14SAndroid Build Coastguard Worker     OPENTHREAD_CONFIG_SRP_SERVER_ENABLE && OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE &&                                   \
49*cfb92d14SAndroid Build Coastguard Worker     !OPENTHREAD_CONFIG_TIME_SYNC_ENABLE && !OPENTHREAD_PLATFORM_POSIX
50*cfb92d14SAndroid Build Coastguard Worker #define ENABLE_DNS_TEST 1
51*cfb92d14SAndroid Build Coastguard Worker #else
52*cfb92d14SAndroid Build Coastguard Worker #define ENABLE_DNS_TEST 0
53*cfb92d14SAndroid Build Coastguard Worker #endif
54*cfb92d14SAndroid Build Coastguard Worker 
55*cfb92d14SAndroid Build Coastguard Worker #if ENABLE_DNS_TEST
56*cfb92d14SAndroid Build Coastguard Worker 
57*cfb92d14SAndroid Build Coastguard Worker using namespace ot;
58*cfb92d14SAndroid Build Coastguard Worker 
59*cfb92d14SAndroid Build Coastguard Worker // Logs a message and adds current time (sNow) as "<hours>:<min>:<secs>.<msec>"
60*cfb92d14SAndroid Build Coastguard Worker #define Log(...)                                                                                          \
61*cfb92d14SAndroid Build Coastguard Worker     printf("%02u:%02u:%02u.%03u " OT_FIRST_ARG(__VA_ARGS__) "\n", (sNow / 36000000), (sNow / 60000) % 60, \
62*cfb92d14SAndroid Build Coastguard Worker            (sNow / 1000) % 60, sNow % 1000 OT_REST_ARGS(__VA_ARGS__))
63*cfb92d14SAndroid Build Coastguard Worker 
64*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kMaxRaSize = 800;
65*cfb92d14SAndroid Build Coastguard Worker 
66*cfb92d14SAndroid Build Coastguard Worker static ot::Instance *sInstance;
67*cfb92d14SAndroid Build Coastguard Worker 
68*cfb92d14SAndroid Build Coastguard Worker static uint32_t sNow = 0;
69*cfb92d14SAndroid Build Coastguard Worker static uint32_t sAlarmTime;
70*cfb92d14SAndroid Build Coastguard Worker static bool     sAlarmOn = false;
71*cfb92d14SAndroid Build Coastguard Worker 
72*cfb92d14SAndroid Build Coastguard Worker static otRadioFrame sRadioTxFrame;
73*cfb92d14SAndroid Build Coastguard Worker static uint8_t      sRadioTxFramePsdu[OT_RADIO_FRAME_MAX_SIZE];
74*cfb92d14SAndroid Build Coastguard Worker static bool         sRadioTxOngoing = false;
75*cfb92d14SAndroid Build Coastguard Worker 
76*cfb92d14SAndroid Build Coastguard Worker //----------------------------------------------------------------------------------------------------------------------
77*cfb92d14SAndroid Build Coastguard Worker // Function prototypes
78*cfb92d14SAndroid Build Coastguard Worker 
79*cfb92d14SAndroid Build Coastguard Worker void ProcessRadioTxAndTasklets(void);
80*cfb92d14SAndroid Build Coastguard Worker void AdvanceTime(uint32_t aDuration);
81*cfb92d14SAndroid Build Coastguard Worker 
82*cfb92d14SAndroid Build Coastguard Worker //----------------------------------------------------------------------------------------------------------------------
83*cfb92d14SAndroid Build Coastguard Worker // `otPlatRadio`
84*cfb92d14SAndroid Build Coastguard Worker 
85*cfb92d14SAndroid Build Coastguard Worker extern "C" {
86*cfb92d14SAndroid Build Coastguard Worker 
otPlatRadioGetCaps(otInstance *)87*cfb92d14SAndroid Build Coastguard Worker otRadioCaps otPlatRadioGetCaps(otInstance *) { return OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_CSMA_BACKOFF; }
88*cfb92d14SAndroid Build Coastguard Worker 
otPlatRadioTransmit(otInstance *,otRadioFrame *)89*cfb92d14SAndroid Build Coastguard Worker otError otPlatRadioTransmit(otInstance *, otRadioFrame *)
90*cfb92d14SAndroid Build Coastguard Worker {
91*cfb92d14SAndroid Build Coastguard Worker     sRadioTxOngoing = true;
92*cfb92d14SAndroid Build Coastguard Worker 
93*cfb92d14SAndroid Build Coastguard Worker     return OT_ERROR_NONE;
94*cfb92d14SAndroid Build Coastguard Worker }
95*cfb92d14SAndroid Build Coastguard Worker 
otPlatRadioGetTransmitBuffer(otInstance *)96*cfb92d14SAndroid Build Coastguard Worker otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *) { return &sRadioTxFrame; }
97*cfb92d14SAndroid Build Coastguard Worker 
98*cfb92d14SAndroid Build Coastguard Worker //----------------------------------------------------------------------------------------------------------------------
99*cfb92d14SAndroid Build Coastguard Worker // `otPlatAlaram`
100*cfb92d14SAndroid Build Coastguard Worker 
otPlatAlarmMilliStop(otInstance *)101*cfb92d14SAndroid Build Coastguard Worker void otPlatAlarmMilliStop(otInstance *) { sAlarmOn = false; }
102*cfb92d14SAndroid Build Coastguard Worker 
otPlatAlarmMilliStartAt(otInstance *,uint32_t aT0,uint32_t aDt)103*cfb92d14SAndroid Build Coastguard Worker void otPlatAlarmMilliStartAt(otInstance *, uint32_t aT0, uint32_t aDt)
104*cfb92d14SAndroid Build Coastguard Worker {
105*cfb92d14SAndroid Build Coastguard Worker     sAlarmOn   = true;
106*cfb92d14SAndroid Build Coastguard Worker     sAlarmTime = aT0 + aDt;
107*cfb92d14SAndroid Build Coastguard Worker }
108*cfb92d14SAndroid Build Coastguard Worker 
otPlatAlarmMilliGetNow(void)109*cfb92d14SAndroid Build Coastguard Worker uint32_t otPlatAlarmMilliGetNow(void) { return sNow; }
110*cfb92d14SAndroid Build Coastguard Worker 
111*cfb92d14SAndroid Build Coastguard Worker //----------------------------------------------------------------------------------------------------------------------
112*cfb92d14SAndroid Build Coastguard Worker 
113*cfb92d14SAndroid Build Coastguard Worker Array<void *, 500> sHeapAllocatedPtrs;
114*cfb92d14SAndroid Build Coastguard Worker 
115*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
otPlatCAlloc(size_t aNum,size_t aSize)116*cfb92d14SAndroid Build Coastguard Worker void *otPlatCAlloc(size_t aNum, size_t aSize)
117*cfb92d14SAndroid Build Coastguard Worker {
118*cfb92d14SAndroid Build Coastguard Worker     void *ptr = calloc(aNum, aSize);
119*cfb92d14SAndroid Build Coastguard Worker 
120*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(sHeapAllocatedPtrs.PushBack(ptr));
121*cfb92d14SAndroid Build Coastguard Worker 
122*cfb92d14SAndroid Build Coastguard Worker     return ptr;
123*cfb92d14SAndroid Build Coastguard Worker }
124*cfb92d14SAndroid Build Coastguard Worker 
otPlatFree(void * aPtr)125*cfb92d14SAndroid Build Coastguard Worker void otPlatFree(void *aPtr)
126*cfb92d14SAndroid Build Coastguard Worker {
127*cfb92d14SAndroid Build Coastguard Worker     if (aPtr != nullptr)
128*cfb92d14SAndroid Build Coastguard Worker     {
129*cfb92d14SAndroid Build Coastguard Worker         void **entry = sHeapAllocatedPtrs.Find(aPtr);
130*cfb92d14SAndroid Build Coastguard Worker 
131*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(entry != nullptr, "A heap allocated item is freed twice");
132*cfb92d14SAndroid Build Coastguard Worker         sHeapAllocatedPtrs.Remove(*entry);
133*cfb92d14SAndroid Build Coastguard Worker     }
134*cfb92d14SAndroid Build Coastguard Worker 
135*cfb92d14SAndroid Build Coastguard Worker     free(aPtr);
136*cfb92d14SAndroid Build Coastguard Worker }
137*cfb92d14SAndroid Build Coastguard Worker #endif
138*cfb92d14SAndroid Build Coastguard Worker 
139*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
otPlatLog(otLogLevel aLogLevel,otLogRegion aLogRegion,const char * aFormat,...)140*cfb92d14SAndroid Build Coastguard Worker void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
141*cfb92d14SAndroid Build Coastguard Worker {
142*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aLogLevel);
143*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aLogRegion);
144*cfb92d14SAndroid Build Coastguard Worker 
145*cfb92d14SAndroid Build Coastguard Worker     va_list args;
146*cfb92d14SAndroid Build Coastguard Worker 
147*cfb92d14SAndroid Build Coastguard Worker     printf("   ");
148*cfb92d14SAndroid Build Coastguard Worker     va_start(args, aFormat);
149*cfb92d14SAndroid Build Coastguard Worker     vprintf(aFormat, args);
150*cfb92d14SAndroid Build Coastguard Worker     va_end(args);
151*cfb92d14SAndroid Build Coastguard Worker     printf("\n");
152*cfb92d14SAndroid Build Coastguard Worker }
153*cfb92d14SAndroid Build Coastguard Worker #endif
154*cfb92d14SAndroid Build Coastguard Worker 
155*cfb92d14SAndroid Build Coastguard Worker } // extern "C"
156*cfb92d14SAndroid Build Coastguard Worker 
157*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
158*cfb92d14SAndroid Build Coastguard Worker 
ProcessRadioTxAndTasklets(void)159*cfb92d14SAndroid Build Coastguard Worker void ProcessRadioTxAndTasklets(void)
160*cfb92d14SAndroid Build Coastguard Worker {
161*cfb92d14SAndroid Build Coastguard Worker     do
162*cfb92d14SAndroid Build Coastguard Worker     {
163*cfb92d14SAndroid Build Coastguard Worker         if (sRadioTxOngoing)
164*cfb92d14SAndroid Build Coastguard Worker         {
165*cfb92d14SAndroid Build Coastguard Worker             sRadioTxOngoing = false;
166*cfb92d14SAndroid Build Coastguard Worker             otPlatRadioTxStarted(sInstance, &sRadioTxFrame);
167*cfb92d14SAndroid Build Coastguard Worker             otPlatRadioTxDone(sInstance, &sRadioTxFrame, nullptr, OT_ERROR_NONE);
168*cfb92d14SAndroid Build Coastguard Worker         }
169*cfb92d14SAndroid Build Coastguard Worker 
170*cfb92d14SAndroid Build Coastguard Worker         otTaskletsProcess(sInstance);
171*cfb92d14SAndroid Build Coastguard Worker     } while (otTaskletsArePending(sInstance));
172*cfb92d14SAndroid Build Coastguard Worker }
173*cfb92d14SAndroid Build Coastguard Worker 
AdvanceTime(uint32_t aDuration)174*cfb92d14SAndroid Build Coastguard Worker void AdvanceTime(uint32_t aDuration)
175*cfb92d14SAndroid Build Coastguard Worker {
176*cfb92d14SAndroid Build Coastguard Worker     uint32_t time = sNow + aDuration;
177*cfb92d14SAndroid Build Coastguard Worker 
178*cfb92d14SAndroid Build Coastguard Worker     Log("AdvanceTime for %u.%03u", aDuration / 1000, aDuration % 1000);
179*cfb92d14SAndroid Build Coastguard Worker 
180*cfb92d14SAndroid Build Coastguard Worker     while (TimeMilli(sAlarmTime) <= TimeMilli(time))
181*cfb92d14SAndroid Build Coastguard Worker     {
182*cfb92d14SAndroid Build Coastguard Worker         ProcessRadioTxAndTasklets();
183*cfb92d14SAndroid Build Coastguard Worker         sNow = sAlarmTime;
184*cfb92d14SAndroid Build Coastguard Worker         otPlatAlarmMilliFired(sInstance);
185*cfb92d14SAndroid Build Coastguard Worker     }
186*cfb92d14SAndroid Build Coastguard Worker 
187*cfb92d14SAndroid Build Coastguard Worker     ProcessRadioTxAndTasklets();
188*cfb92d14SAndroid Build Coastguard Worker     sNow = time;
189*cfb92d14SAndroid Build Coastguard Worker }
190*cfb92d14SAndroid Build Coastguard Worker 
InitTest(void)191*cfb92d14SAndroid Build Coastguard Worker void InitTest(void)
192*cfb92d14SAndroid Build Coastguard Worker {
193*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
194*cfb92d14SAndroid Build Coastguard Worker     // Initialize OT instance.
195*cfb92d14SAndroid Build Coastguard Worker 
196*cfb92d14SAndroid Build Coastguard Worker     sNow      = 0;
197*cfb92d14SAndroid Build Coastguard Worker     sAlarmOn  = false;
198*cfb92d14SAndroid Build Coastguard Worker     sInstance = static_cast<Instance *>(testInitInstance());
199*cfb92d14SAndroid Build Coastguard Worker 
200*cfb92d14SAndroid Build Coastguard Worker     memset(&sRadioTxFrame, 0, sizeof(sRadioTxFrame));
201*cfb92d14SAndroid Build Coastguard Worker     sRadioTxFrame.mPsdu = sRadioTxFramePsdu;
202*cfb92d14SAndroid Build Coastguard Worker     sRadioTxOngoing     = false;
203*cfb92d14SAndroid Build Coastguard Worker 
204*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
205*cfb92d14SAndroid Build Coastguard Worker     // Initialize Border Router and start Thread operation.
206*cfb92d14SAndroid Build Coastguard Worker 
207*cfb92d14SAndroid Build Coastguard Worker     otOperationalDataset     dataset;
208*cfb92d14SAndroid Build Coastguard Worker     otOperationalDatasetTlvs datasetTlvs;
209*cfb92d14SAndroid Build Coastguard Worker 
210*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(otDatasetCreateNewNetwork(sInstance, &dataset));
211*cfb92d14SAndroid Build Coastguard Worker     otDatasetConvertToTlvs(&dataset, &datasetTlvs);
212*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(otDatasetSetActiveTlvs(sInstance, &datasetTlvs));
213*cfb92d14SAndroid Build Coastguard Worker 
214*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(otIp6SetEnabled(sInstance, true));
215*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(otThreadSetEnabled(sInstance, true));
216*cfb92d14SAndroid Build Coastguard Worker 
217*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
218*cfb92d14SAndroid Build Coastguard Worker     // Ensure device starts as leader.
219*cfb92d14SAndroid Build Coastguard Worker 
220*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10000);
221*cfb92d14SAndroid Build Coastguard Worker 
222*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(otThreadGetDeviceRole(sInstance) == OT_DEVICE_ROLE_LEADER);
223*cfb92d14SAndroid Build Coastguard Worker }
224*cfb92d14SAndroid Build Coastguard Worker 
FinalizeTest(void)225*cfb92d14SAndroid Build Coastguard Worker void FinalizeTest(void)
226*cfb92d14SAndroid Build Coastguard Worker {
227*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(otIp6SetEnabled(sInstance, false));
228*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(otThreadSetEnabled(sInstance, false));
229*cfb92d14SAndroid Build Coastguard Worker     // Make sure there is no message/buffer leak
230*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sInstance->Get<MessagePool>().GetFreeBufferCount() ==
231*cfb92d14SAndroid Build Coastguard Worker                  sInstance->Get<MessagePool>().GetTotalBufferCount());
232*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(otInstanceErasePersistentInfo(sInstance));
233*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
234*cfb92d14SAndroid Build Coastguard Worker }
235*cfb92d14SAndroid Build Coastguard Worker 
236*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
237*cfb92d14SAndroid Build Coastguard Worker 
238*cfb92d14SAndroid Build Coastguard Worker static const char kHostName[]     = "elden";
239*cfb92d14SAndroid Build Coastguard Worker static const char kHostFullName[] = "elden.default.service.arpa.";
240*cfb92d14SAndroid Build Coastguard Worker 
241*cfb92d14SAndroid Build Coastguard Worker static const char kService1Name[]      = "_srv._udp";
242*cfb92d14SAndroid Build Coastguard Worker static const char kService1FullName[]  = "_srv._udp.default.service.arpa.";
243*cfb92d14SAndroid Build Coastguard Worker static const char kInstance1Label[]    = "srv-instance";
244*cfb92d14SAndroid Build Coastguard Worker static const char kInstance1FullName[] = "srv-instance._srv._udp.default.service.arpa.";
245*cfb92d14SAndroid Build Coastguard Worker 
246*cfb92d14SAndroid Build Coastguard Worker static const char kService2Name[]            = "_game._udp";
247*cfb92d14SAndroid Build Coastguard Worker static const char kService2FullName[]        = "_game._udp.default.service.arpa.";
248*cfb92d14SAndroid Build Coastguard Worker static const char kService2SubTypeFullName[] = "_best._sub._game._udp.default.service.arpa.";
249*cfb92d14SAndroid Build Coastguard Worker static const char kInstance2Label[]          = "last-ninja";
250*cfb92d14SAndroid Build Coastguard Worker static const char kInstance2FullName[]       = "last-ninja._game._udp.default.service.arpa.";
251*cfb92d14SAndroid Build Coastguard Worker 
PrepareService1(Srp::Client::Service & aService)252*cfb92d14SAndroid Build Coastguard Worker void PrepareService1(Srp::Client::Service &aService)
253*cfb92d14SAndroid Build Coastguard Worker {
254*cfb92d14SAndroid Build Coastguard Worker     static const char          kSub1[]       = "_sub1";
255*cfb92d14SAndroid Build Coastguard Worker     static const char          kSub2[]       = "_V1234567";
256*cfb92d14SAndroid Build Coastguard Worker     static const char          kSub3[]       = "_XYZWS";
257*cfb92d14SAndroid Build Coastguard Worker     static const char         *kSubLabels[]  = {kSub1, kSub2, kSub3, nullptr};
258*cfb92d14SAndroid Build Coastguard Worker     static const char          kTxtKey1[]    = "ABCD";
259*cfb92d14SAndroid Build Coastguard Worker     static const uint8_t       kTxtValue1[]  = {'a', '0'};
260*cfb92d14SAndroid Build Coastguard Worker     static const char          kTxtKey2[]    = "Z0";
261*cfb92d14SAndroid Build Coastguard Worker     static const uint8_t       kTxtValue2[]  = {'1', '2', '3'};
262*cfb92d14SAndroid Build Coastguard Worker     static const char          kTxtKey3[]    = "D";
263*cfb92d14SAndroid Build Coastguard Worker     static const uint8_t       kTxtValue3[]  = {0};
264*cfb92d14SAndroid Build Coastguard Worker     static const otDnsTxtEntry kTxtEntries[] = {
265*cfb92d14SAndroid Build Coastguard Worker         {kTxtKey1, kTxtValue1, sizeof(kTxtValue1)},
266*cfb92d14SAndroid Build Coastguard Worker         {kTxtKey2, kTxtValue2, sizeof(kTxtValue2)},
267*cfb92d14SAndroid Build Coastguard Worker         {kTxtKey3, kTxtValue3, sizeof(kTxtValue3)},
268*cfb92d14SAndroid Build Coastguard Worker     };
269*cfb92d14SAndroid Build Coastguard Worker 
270*cfb92d14SAndroid Build Coastguard Worker     memset(&aService, 0, sizeof(aService));
271*cfb92d14SAndroid Build Coastguard Worker     aService.mName          = kService1Name;
272*cfb92d14SAndroid Build Coastguard Worker     aService.mInstanceName  = kInstance1Label;
273*cfb92d14SAndroid Build Coastguard Worker     aService.mSubTypeLabels = kSubLabels;
274*cfb92d14SAndroid Build Coastguard Worker     aService.mTxtEntries    = kTxtEntries;
275*cfb92d14SAndroid Build Coastguard Worker     aService.mNumTxtEntries = 3;
276*cfb92d14SAndroid Build Coastguard Worker     aService.mPort          = 777;
277*cfb92d14SAndroid Build Coastguard Worker     aService.mWeight        = 1;
278*cfb92d14SAndroid Build Coastguard Worker     aService.mPriority      = 2;
279*cfb92d14SAndroid Build Coastguard Worker }
280*cfb92d14SAndroid Build Coastguard Worker 
PrepareService2(Srp::Client::Service & aService)281*cfb92d14SAndroid Build Coastguard Worker void PrepareService2(Srp::Client::Service &aService)
282*cfb92d14SAndroid Build Coastguard Worker {
283*cfb92d14SAndroid Build Coastguard Worker     static const char  kSub4[]       = "_best";
284*cfb92d14SAndroid Build Coastguard Worker     static const char *kSubLabels2[] = {kSub4, nullptr};
285*cfb92d14SAndroid Build Coastguard Worker 
286*cfb92d14SAndroid Build Coastguard Worker     memset(&aService, 0, sizeof(aService));
287*cfb92d14SAndroid Build Coastguard Worker     aService.mName          = kService2Name;
288*cfb92d14SAndroid Build Coastguard Worker     aService.mInstanceName  = kInstance2Label;
289*cfb92d14SAndroid Build Coastguard Worker     aService.mSubTypeLabels = kSubLabels2;
290*cfb92d14SAndroid Build Coastguard Worker     aService.mTxtEntries    = nullptr;
291*cfb92d14SAndroid Build Coastguard Worker     aService.mNumTxtEntries = 0;
292*cfb92d14SAndroid Build Coastguard Worker     aService.mPort          = 555;
293*cfb92d14SAndroid Build Coastguard Worker     aService.mWeight        = 0;
294*cfb92d14SAndroid Build Coastguard Worker     aService.mPriority      = 3;
295*cfb92d14SAndroid Build Coastguard Worker }
296*cfb92d14SAndroid Build Coastguard Worker 
ValidateHost(Srp::Server & aServer,const char * aHostName)297*cfb92d14SAndroid Build Coastguard Worker void ValidateHost(Srp::Server &aServer, const char *aHostName)
298*cfb92d14SAndroid Build Coastguard Worker {
299*cfb92d14SAndroid Build Coastguard Worker     // Validate that only a host with `aHostName` is
300*cfb92d14SAndroid Build Coastguard Worker     // registered on SRP server.
301*cfb92d14SAndroid Build Coastguard Worker 
302*cfb92d14SAndroid Build Coastguard Worker     const Srp::Server::Host *host;
303*cfb92d14SAndroid Build Coastguard Worker     const char              *name;
304*cfb92d14SAndroid Build Coastguard Worker 
305*cfb92d14SAndroid Build Coastguard Worker     Log("ValidateHost()");
306*cfb92d14SAndroid Build Coastguard Worker 
307*cfb92d14SAndroid Build Coastguard Worker     host = aServer.GetNextHost(nullptr);
308*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(host != nullptr);
309*cfb92d14SAndroid Build Coastguard Worker 
310*cfb92d14SAndroid Build Coastguard Worker     name = host->GetFullName();
311*cfb92d14SAndroid Build Coastguard Worker     Log("Hostname: %s", name);
312*cfb92d14SAndroid Build Coastguard Worker 
313*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(StringStartsWith(name, aHostName, kStringCaseInsensitiveMatch));
314*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(name[strlen(aHostName)] == '.');
315*cfb92d14SAndroid Build Coastguard Worker 
316*cfb92d14SAndroid Build Coastguard Worker     // Only one host on server
317*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aServer.GetNextHost(host) == nullptr);
318*cfb92d14SAndroid Build Coastguard Worker }
319*cfb92d14SAndroid Build Coastguard Worker 
320*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
321*cfb92d14SAndroid Build Coastguard Worker 
LogServiceInfo(const Dns::Client::ServiceInfo & aInfo)322*cfb92d14SAndroid Build Coastguard Worker void LogServiceInfo(const Dns::Client::ServiceInfo &aInfo)
323*cfb92d14SAndroid Build Coastguard Worker {
324*cfb92d14SAndroid Build Coastguard Worker     Log("   TTL: %u", aInfo.mTtl);
325*cfb92d14SAndroid Build Coastguard Worker     Log("   Port: %u", aInfo.mPort);
326*cfb92d14SAndroid Build Coastguard Worker     Log("   Weight: %u", aInfo.mWeight);
327*cfb92d14SAndroid Build Coastguard Worker     Log("   HostName: %s", aInfo.mHostNameBuffer);
328*cfb92d14SAndroid Build Coastguard Worker     Log("   HostAddr: %s", AsCoreType(&aInfo.mHostAddress).ToString().AsCString());
329*cfb92d14SAndroid Build Coastguard Worker     Log("   TxtDataLength: %u", aInfo.mTxtDataSize);
330*cfb92d14SAndroid Build Coastguard Worker     Log("   TxtDataTTL: %u", aInfo.mTxtDataTtl);
331*cfb92d14SAndroid Build Coastguard Worker }
332*cfb92d14SAndroid Build Coastguard Worker 
ServiceModeToString(Dns::Client::QueryConfig::ServiceMode aMode)333*cfb92d14SAndroid Build Coastguard Worker const char *ServiceModeToString(Dns::Client::QueryConfig::ServiceMode aMode)
334*cfb92d14SAndroid Build Coastguard Worker {
335*cfb92d14SAndroid Build Coastguard Worker     static const char *const kServiceModeStrings[] = {
336*cfb92d14SAndroid Build Coastguard Worker         "unspec",      // kServiceModeUnspecified     (0)
337*cfb92d14SAndroid Build Coastguard Worker         "srv",         // kServiceModeSrv             (1)
338*cfb92d14SAndroid Build Coastguard Worker         "txt",         // kServiceModeTxt             (2)
339*cfb92d14SAndroid Build Coastguard Worker         "srv_txt",     // kServiceModeSrvTxt          (3)
340*cfb92d14SAndroid Build Coastguard Worker         "srv_txt_sep", // kServiceModeSrvTxtSeparate  (4)
341*cfb92d14SAndroid Build Coastguard Worker         "srv_txt_opt", // kServiceModeSrvTxtOptimize  (5)
342*cfb92d14SAndroid Build Coastguard Worker     };
343*cfb92d14SAndroid Build Coastguard Worker 
344*cfb92d14SAndroid Build Coastguard Worker     static_assert(Dns::Client::QueryConfig::kServiceModeUnspecified == 0, "Unspecified value is incorrect");
345*cfb92d14SAndroid Build Coastguard Worker     static_assert(Dns::Client::QueryConfig::kServiceModeSrv == 1, "Srv value is incorrect");
346*cfb92d14SAndroid Build Coastguard Worker     static_assert(Dns::Client::QueryConfig::kServiceModeTxt == 2, "Txt value is incorrect");
347*cfb92d14SAndroid Build Coastguard Worker     static_assert(Dns::Client::QueryConfig::kServiceModeSrvTxt == 3, "SrvTxt value is incorrect");
348*cfb92d14SAndroid Build Coastguard Worker     static_assert(Dns::Client::QueryConfig::kServiceModeSrvTxtSeparate == 4, "SrvTxtSeparate value is incorrect");
349*cfb92d14SAndroid Build Coastguard Worker     static_assert(Dns::Client::QueryConfig::kServiceModeSrvTxtOptimize == 5, "SrvTxtOptimize value is incorrect");
350*cfb92d14SAndroid Build Coastguard Worker 
351*cfb92d14SAndroid Build Coastguard Worker     return kServiceModeStrings[aMode];
352*cfb92d14SAndroid Build Coastguard Worker }
353*cfb92d14SAndroid Build Coastguard Worker 
354*cfb92d14SAndroid Build Coastguard Worker //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
355*cfb92d14SAndroid Build Coastguard Worker 
356*cfb92d14SAndroid Build Coastguard Worker struct BrowseInfo
357*cfb92d14SAndroid Build Coastguard Worker {
ResetBrowseInfo358*cfb92d14SAndroid Build Coastguard Worker     void Reset(void) { mCallbackCount = 0; }
359*cfb92d14SAndroid Build Coastguard Worker 
360*cfb92d14SAndroid Build Coastguard Worker     uint16_t          mCallbackCount;
361*cfb92d14SAndroid Build Coastguard Worker     Error             mError;
362*cfb92d14SAndroid Build Coastguard Worker     Dns::Name::Buffer mServiceName;
363*cfb92d14SAndroid Build Coastguard Worker     uint16_t          mNumInstances;
364*cfb92d14SAndroid Build Coastguard Worker };
365*cfb92d14SAndroid Build Coastguard Worker 
366*cfb92d14SAndroid Build Coastguard Worker static BrowseInfo sBrowseInfo;
367*cfb92d14SAndroid Build Coastguard Worker 
BrowseCallback(otError aError,const otDnsBrowseResponse * aResponse,void * aContext)368*cfb92d14SAndroid Build Coastguard Worker void BrowseCallback(otError aError, const otDnsBrowseResponse *aResponse, void *aContext)
369*cfb92d14SAndroid Build Coastguard Worker {
370*cfb92d14SAndroid Build Coastguard Worker     const Dns::Client::BrowseResponse &response = AsCoreType(aResponse);
371*cfb92d14SAndroid Build Coastguard Worker 
372*cfb92d14SAndroid Build Coastguard Worker     Log("BrowseCallback");
373*cfb92d14SAndroid Build Coastguard Worker     Log("   Error: %s", ErrorToString(aError));
374*cfb92d14SAndroid Build Coastguard Worker 
375*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aContext == sInstance);
376*cfb92d14SAndroid Build Coastguard Worker 
377*cfb92d14SAndroid Build Coastguard Worker     sBrowseInfo.mCallbackCount++;
378*cfb92d14SAndroid Build Coastguard Worker     sBrowseInfo.mError = aError;
379*cfb92d14SAndroid Build Coastguard Worker 
380*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(aError);
381*cfb92d14SAndroid Build Coastguard Worker 
382*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(response.GetServiceName(sBrowseInfo.mServiceName, sizeof(sBrowseInfo.mServiceName)));
383*cfb92d14SAndroid Build Coastguard Worker     Log("   ServiceName: %s", sBrowseInfo.mServiceName);
384*cfb92d14SAndroid Build Coastguard Worker 
385*cfb92d14SAndroid Build Coastguard Worker     for (uint16_t index = 0;; index++)
386*cfb92d14SAndroid Build Coastguard Worker     {
387*cfb92d14SAndroid Build Coastguard Worker         Dns::Name::LabelBuffer instLabel;
388*cfb92d14SAndroid Build Coastguard Worker         Error                  error;
389*cfb92d14SAndroid Build Coastguard Worker 
390*cfb92d14SAndroid Build Coastguard Worker         error = response.GetServiceInstance(index, instLabel, sizeof(instLabel));
391*cfb92d14SAndroid Build Coastguard Worker 
392*cfb92d14SAndroid Build Coastguard Worker         if (error == kErrorNotFound)
393*cfb92d14SAndroid Build Coastguard Worker         {
394*cfb92d14SAndroid Build Coastguard Worker             sBrowseInfo.mNumInstances = index;
395*cfb92d14SAndroid Build Coastguard Worker             break;
396*cfb92d14SAndroid Build Coastguard Worker         }
397*cfb92d14SAndroid Build Coastguard Worker 
398*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(error);
399*cfb92d14SAndroid Build Coastguard Worker 
400*cfb92d14SAndroid Build Coastguard Worker         Log("  %2u) %s", index + 1, instLabel);
401*cfb92d14SAndroid Build Coastguard Worker     }
402*cfb92d14SAndroid Build Coastguard Worker 
403*cfb92d14SAndroid Build Coastguard Worker exit:
404*cfb92d14SAndroid Build Coastguard Worker     return;
405*cfb92d14SAndroid Build Coastguard Worker }
406*cfb92d14SAndroid Build Coastguard Worker 
407*cfb92d14SAndroid Build Coastguard Worker //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
408*cfb92d14SAndroid Build Coastguard Worker 
409*cfb92d14SAndroid Build Coastguard Worker static constexpr uint8_t  kMaxHostAddresses = 10;
410*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kMaxTxtBuffer     = 256;
411*cfb92d14SAndroid Build Coastguard Worker 
412*cfb92d14SAndroid Build Coastguard Worker struct ResolveServiceInfo
413*cfb92d14SAndroid Build Coastguard Worker {
ResetResolveServiceInfo414*cfb92d14SAndroid Build Coastguard Worker     void Reset(void)
415*cfb92d14SAndroid Build Coastguard Worker     {
416*cfb92d14SAndroid Build Coastguard Worker         memset(this, 0, sizeof(*this));
417*cfb92d14SAndroid Build Coastguard Worker         mInfo.mHostNameBuffer     = mNameBuffer;
418*cfb92d14SAndroid Build Coastguard Worker         mInfo.mHostNameBufferSize = sizeof(mNameBuffer);
419*cfb92d14SAndroid Build Coastguard Worker         mInfo.mTxtData            = mTxtBuffer;
420*cfb92d14SAndroid Build Coastguard Worker         mInfo.mTxtDataSize        = sizeof(mTxtBuffer);
421*cfb92d14SAndroid Build Coastguard Worker     };
422*cfb92d14SAndroid Build Coastguard Worker 
423*cfb92d14SAndroid Build Coastguard Worker     uint16_t                 mCallbackCount;
424*cfb92d14SAndroid Build Coastguard Worker     Error                    mError;
425*cfb92d14SAndroid Build Coastguard Worker     Dns::Client::ServiceInfo mInfo;
426*cfb92d14SAndroid Build Coastguard Worker     Dns::Name::Buffer        mNameBuffer;
427*cfb92d14SAndroid Build Coastguard Worker     uint8_t                  mTxtBuffer[kMaxTxtBuffer];
428*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address             mHostAddresses[kMaxHostAddresses];
429*cfb92d14SAndroid Build Coastguard Worker     uint8_t                  mNumHostAddresses;
430*cfb92d14SAndroid Build Coastguard Worker };
431*cfb92d14SAndroid Build Coastguard Worker 
432*cfb92d14SAndroid Build Coastguard Worker static ResolveServiceInfo sResolveServiceInfo;
433*cfb92d14SAndroid Build Coastguard Worker 
ServiceCallback(otError aError,const otDnsServiceResponse * aResponse,void * aContext)434*cfb92d14SAndroid Build Coastguard Worker void ServiceCallback(otError aError, const otDnsServiceResponse *aResponse, void *aContext)
435*cfb92d14SAndroid Build Coastguard Worker {
436*cfb92d14SAndroid Build Coastguard Worker     const Dns::Client::ServiceResponse &response = AsCoreType(aResponse);
437*cfb92d14SAndroid Build Coastguard Worker     Dns::Name::LabelBuffer              instLabel;
438*cfb92d14SAndroid Build Coastguard Worker     Dns::Name::Buffer                   serviceName;
439*cfb92d14SAndroid Build Coastguard Worker 
440*cfb92d14SAndroid Build Coastguard Worker     Log("ServiceCallback");
441*cfb92d14SAndroid Build Coastguard Worker     Log("   Error: %s", ErrorToString(aError));
442*cfb92d14SAndroid Build Coastguard Worker 
443*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aContext == sInstance);
444*cfb92d14SAndroid Build Coastguard Worker 
445*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(response.GetServiceName(instLabel, sizeof(instLabel), serviceName, sizeof(serviceName)));
446*cfb92d14SAndroid Build Coastguard Worker     Log("   InstLabel: %s", instLabel);
447*cfb92d14SAndroid Build Coastguard Worker     Log("   ServiceName: %s", serviceName);
448*cfb92d14SAndroid Build Coastguard Worker 
449*cfb92d14SAndroid Build Coastguard Worker     sResolveServiceInfo.mCallbackCount++;
450*cfb92d14SAndroid Build Coastguard Worker     sResolveServiceInfo.mError = aError;
451*cfb92d14SAndroid Build Coastguard Worker 
452*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(aError);
453*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(response.GetServiceInfo(sResolveServiceInfo.mInfo));
454*cfb92d14SAndroid Build Coastguard Worker 
455*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t index = 0; index < kMaxHostAddresses; index++)
456*cfb92d14SAndroid Build Coastguard Worker     {
457*cfb92d14SAndroid Build Coastguard Worker         Error    error;
458*cfb92d14SAndroid Build Coastguard Worker         uint32_t ttl;
459*cfb92d14SAndroid Build Coastguard Worker 
460*cfb92d14SAndroid Build Coastguard Worker         error = response.GetHostAddress(sResolveServiceInfo.mInfo.mHostNameBuffer, index,
461*cfb92d14SAndroid Build Coastguard Worker                                         sResolveServiceInfo.mHostAddresses[index], ttl);
462*cfb92d14SAndroid Build Coastguard Worker 
463*cfb92d14SAndroid Build Coastguard Worker         if (error == kErrorNotFound)
464*cfb92d14SAndroid Build Coastguard Worker         {
465*cfb92d14SAndroid Build Coastguard Worker             sResolveServiceInfo.mNumHostAddresses = index;
466*cfb92d14SAndroid Build Coastguard Worker             break;
467*cfb92d14SAndroid Build Coastguard Worker         }
468*cfb92d14SAndroid Build Coastguard Worker 
469*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(error);
470*cfb92d14SAndroid Build Coastguard Worker     }
471*cfb92d14SAndroid Build Coastguard Worker 
472*cfb92d14SAndroid Build Coastguard Worker     LogServiceInfo(sResolveServiceInfo.mInfo);
473*cfb92d14SAndroid Build Coastguard Worker     Log("   NumHostAddresses: %u", sResolveServiceInfo.mNumHostAddresses);
474*cfb92d14SAndroid Build Coastguard Worker 
475*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t index = 0; index < sResolveServiceInfo.mNumHostAddresses; index++)
476*cfb92d14SAndroid Build Coastguard Worker     {
477*cfb92d14SAndroid Build Coastguard Worker         Log("      %s", sResolveServiceInfo.mHostAddresses[index].ToString().AsCString());
478*cfb92d14SAndroid Build Coastguard Worker     }
479*cfb92d14SAndroid Build Coastguard Worker 
480*cfb92d14SAndroid Build Coastguard Worker exit:
481*cfb92d14SAndroid Build Coastguard Worker     return;
482*cfb92d14SAndroid Build Coastguard Worker }
483*cfb92d14SAndroid Build Coastguard Worker 
484*cfb92d14SAndroid Build Coastguard Worker //----------------------------------------------------------------------------------------------------------------------
485*cfb92d14SAndroid Build Coastguard Worker 
TestDnsClient(void)486*cfb92d14SAndroid Build Coastguard Worker void TestDnsClient(void)
487*cfb92d14SAndroid Build Coastguard Worker {
488*cfb92d14SAndroid Build Coastguard Worker     static constexpr uint8_t kNumAddresses = 2;
489*cfb92d14SAndroid Build Coastguard Worker 
490*cfb92d14SAndroid Build Coastguard Worker     static const char *const kAddresses[kNumAddresses] = {"2001::beef:cafe", "fd00:1234:5678:9abc::1"};
491*cfb92d14SAndroid Build Coastguard Worker 
492*cfb92d14SAndroid Build Coastguard Worker     const Dns::Client::QueryConfig::ServiceMode kServiceModes[] = {
493*cfb92d14SAndroid Build Coastguard Worker         Dns::Client::QueryConfig::kServiceModeSrv,
494*cfb92d14SAndroid Build Coastguard Worker         Dns::Client::QueryConfig::kServiceModeTxt,
495*cfb92d14SAndroid Build Coastguard Worker         Dns::Client::QueryConfig::kServiceModeSrvTxt,
496*cfb92d14SAndroid Build Coastguard Worker         Dns::Client::QueryConfig::kServiceModeSrvTxtSeparate,
497*cfb92d14SAndroid Build Coastguard Worker         Dns::Client::QueryConfig::kServiceModeSrvTxtOptimize,
498*cfb92d14SAndroid Build Coastguard Worker     };
499*cfb92d14SAndroid Build Coastguard Worker 
500*cfb92d14SAndroid Build Coastguard Worker     Array<Ip6::Address, kNumAddresses>      addresses;
501*cfb92d14SAndroid Build Coastguard Worker     Srp::Server                            *srpServer;
502*cfb92d14SAndroid Build Coastguard Worker     Srp::Client                            *srpClient;
503*cfb92d14SAndroid Build Coastguard Worker     Srp::Client::Service                    service1;
504*cfb92d14SAndroid Build Coastguard Worker     Srp::Client::Service                    service2;
505*cfb92d14SAndroid Build Coastguard Worker     Dns::Client                            *dnsClient;
506*cfb92d14SAndroid Build Coastguard Worker     Dns::Client::QueryConfig                queryConfig;
507*cfb92d14SAndroid Build Coastguard Worker     Dns::ServiceDiscovery::Server          *dnsServer;
508*cfb92d14SAndroid Build Coastguard Worker     Dns::ServiceDiscovery::Server::Counters oldServerCounters;
509*cfb92d14SAndroid Build Coastguard Worker     Dns::ServiceDiscovery::Server::Counters newServerCounters;
510*cfb92d14SAndroid Build Coastguard Worker     uint16_t                                heapAllocations;
511*cfb92d14SAndroid Build Coastguard Worker 
512*cfb92d14SAndroid Build Coastguard Worker     Log("--------------------------------------------------------------------------------------------");
513*cfb92d14SAndroid Build Coastguard Worker     Log("TestDnsClient");
514*cfb92d14SAndroid Build Coastguard Worker 
515*cfb92d14SAndroid Build Coastguard Worker     InitTest();
516*cfb92d14SAndroid Build Coastguard Worker 
517*cfb92d14SAndroid Build Coastguard Worker     for (const char *addrString : kAddresses)
518*cfb92d14SAndroid Build Coastguard Worker     {
519*cfb92d14SAndroid Build Coastguard Worker         otNetifAddress netifAddr;
520*cfb92d14SAndroid Build Coastguard Worker 
521*cfb92d14SAndroid Build Coastguard Worker         memset(&netifAddr, 0, sizeof(netifAddr));
522*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(AsCoreType(&netifAddr.mAddress).FromString(addrString));
523*cfb92d14SAndroid Build Coastguard Worker         netifAddr.mPrefixLength  = 64;
524*cfb92d14SAndroid Build Coastguard Worker         netifAddr.mAddressOrigin = OT_ADDRESS_ORIGIN_MANUAL;
525*cfb92d14SAndroid Build Coastguard Worker         netifAddr.mPreferred     = true;
526*cfb92d14SAndroid Build Coastguard Worker         netifAddr.mValid         = true;
527*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(otIp6AddUnicastAddress(sInstance, &netifAddr));
528*cfb92d14SAndroid Build Coastguard Worker 
529*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(addresses.PushBack(AsCoreType(&netifAddr.mAddress)));
530*cfb92d14SAndroid Build Coastguard Worker     }
531*cfb92d14SAndroid Build Coastguard Worker 
532*cfb92d14SAndroid Build Coastguard Worker     srpServer = &sInstance->Get<Srp::Server>();
533*cfb92d14SAndroid Build Coastguard Worker     srpClient = &sInstance->Get<Srp::Client>();
534*cfb92d14SAndroid Build Coastguard Worker     dnsClient = &sInstance->Get<Dns::Client>();
535*cfb92d14SAndroid Build Coastguard Worker     dnsServer = &sInstance->Get<Dns::ServiceDiscovery::Server>();
536*cfb92d14SAndroid Build Coastguard Worker 
537*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
538*cfb92d14SAndroid Build Coastguard Worker 
539*cfb92d14SAndroid Build Coastguard Worker     PrepareService1(service1);
540*cfb92d14SAndroid Build Coastguard Worker     PrepareService2(service2);
541*cfb92d14SAndroid Build Coastguard Worker 
542*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
543*cfb92d14SAndroid Build Coastguard Worker     // Start SRP server.
544*cfb92d14SAndroid Build Coastguard Worker 
545*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(srpServer->SetAddressMode(Srp::Server::kAddressModeUnicast));
546*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateDisabled);
547*cfb92d14SAndroid Build Coastguard Worker 
548*cfb92d14SAndroid Build Coastguard Worker     srpServer->SetEnabled(true);
549*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srpServer->GetState() != Srp::Server::kStateDisabled);
550*cfb92d14SAndroid Build Coastguard Worker 
551*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10000);
552*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
553*cfb92d14SAndroid Build Coastguard Worker 
554*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
555*cfb92d14SAndroid Build Coastguard Worker     // Start SRP client.
556*cfb92d14SAndroid Build Coastguard Worker 
557*cfb92d14SAndroid Build Coastguard Worker     srpClient->EnableAutoStartMode(nullptr, nullptr);
558*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srpClient->IsAutoStartModeEnabled());
559*cfb92d14SAndroid Build Coastguard Worker 
560*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
561*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srpClient->IsRunning());
562*cfb92d14SAndroid Build Coastguard Worker 
563*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(srpClient->SetHostName(kHostName));
564*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(srpClient->EnableAutoHostAddress());
565*cfb92d14SAndroid Build Coastguard Worker 
566*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
567*cfb92d14SAndroid Build Coastguard Worker     // Register two services on SRP.
568*cfb92d14SAndroid Build Coastguard Worker 
569*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(srpClient->AddService(service1));
570*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(srpClient->AddService(service2));
571*cfb92d14SAndroid Build Coastguard Worker 
572*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2 * 1000);
573*cfb92d14SAndroid Build Coastguard Worker 
574*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
575*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(service2.GetState() == Srp::Client::kRegistered);
576*cfb92d14SAndroid Build Coastguard Worker     ValidateHost(*srpServer, kHostName);
577*cfb92d14SAndroid Build Coastguard Worker 
578*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
579*cfb92d14SAndroid Build Coastguard Worker 
580*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
581*cfb92d14SAndroid Build Coastguard Worker     // Check DNS Client's default config
582*cfb92d14SAndroid Build Coastguard Worker 
583*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsClient->GetDefaultConfig().GetServiceMode() ==
584*cfb92d14SAndroid Build Coastguard Worker                  Dns::Client::QueryConfig::kServiceModeSrvTxtOptimize);
585*cfb92d14SAndroid Build Coastguard Worker 
586*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
587*cfb92d14SAndroid Build Coastguard Worker     // Validate DNS Client `Browse()`
588*cfb92d14SAndroid Build Coastguard Worker 
589*cfb92d14SAndroid Build Coastguard Worker     sBrowseInfo.Reset();
590*cfb92d14SAndroid Build Coastguard Worker     Log("Browse(%s)", kService1FullName);
591*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(dnsClient->Browse(kService1FullName, BrowseCallback, sInstance));
592*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(100);
593*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mCallbackCount == 1);
594*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(sBrowseInfo.mError);
595*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mNumInstances == 1);
596*cfb92d14SAndroid Build Coastguard Worker 
597*cfb92d14SAndroid Build Coastguard Worker     sBrowseInfo.Reset();
598*cfb92d14SAndroid Build Coastguard Worker 
599*cfb92d14SAndroid Build Coastguard Worker     Log("Browse(%s)", kService2FullName);
600*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(dnsClient->Browse(kService2FullName, BrowseCallback, sInstance));
601*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(100);
602*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mCallbackCount == 1);
603*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(sBrowseInfo.mError);
604*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mNumInstances == 1);
605*cfb92d14SAndroid Build Coastguard Worker 
606*cfb92d14SAndroid Build Coastguard Worker     sBrowseInfo.Reset();
607*cfb92d14SAndroid Build Coastguard Worker 
608*cfb92d14SAndroid Build Coastguard Worker     Log("Browse(%s)", kService2SubTypeFullName);
609*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(dnsClient->Browse(kService2SubTypeFullName, BrowseCallback, sInstance));
610*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(100);
611*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mCallbackCount == 1);
612*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(sBrowseInfo.mError);
613*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mNumInstances == 1);
614*cfb92d14SAndroid Build Coastguard Worker 
615*cfb92d14SAndroid Build Coastguard Worker     sBrowseInfo.Reset();
616*cfb92d14SAndroid Build Coastguard Worker     Log("Browse() for unknown service");
617*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(dnsClient->Browse("_unknown._udp.default.service.arpa.", BrowseCallback, sInstance));
618*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(100);
619*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mCallbackCount == 1);
620*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mError == kErrorNotFound);
621*cfb92d14SAndroid Build Coastguard Worker 
622*cfb92d14SAndroid Build Coastguard Worker     Log("Issue four parallel `Browse()` at the same time");
623*cfb92d14SAndroid Build Coastguard Worker     sBrowseInfo.Reset();
624*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(dnsClient->Browse(kService1FullName, BrowseCallback, sInstance));
625*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(dnsClient->Browse(kService2FullName, BrowseCallback, sInstance));
626*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(dnsClient->Browse("_unknown._udp.default.service.arpa.", BrowseCallback, sInstance));
627*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(dnsClient->Browse("_unknown2._udp.default.service.arpa.", BrowseCallback, sInstance));
628*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(100);
629*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mCallbackCount == 4);
630*cfb92d14SAndroid Build Coastguard Worker 
631*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
632*cfb92d14SAndroid Build Coastguard Worker     // Validate DNS Client `ResolveService()` using all service modes
633*cfb92d14SAndroid Build Coastguard Worker 
634*cfb92d14SAndroid Build Coastguard Worker     for (Dns::Client::QueryConfig::ServiceMode mode : kServiceModes)
635*cfb92d14SAndroid Build Coastguard Worker     {
636*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
637*cfb92d14SAndroid Build Coastguard Worker         Log("ResolveService(%s,%s) with ServiceMode: %s", kInstance1Label, kService1FullName,
638*cfb92d14SAndroid Build Coastguard Worker             ServiceModeToString(mode));
639*cfb92d14SAndroid Build Coastguard Worker 
640*cfb92d14SAndroid Build Coastguard Worker         queryConfig.Clear();
641*cfb92d14SAndroid Build Coastguard Worker         queryConfig.mServiceMode = static_cast<otDnsServiceMode>(mode);
642*cfb92d14SAndroid Build Coastguard Worker 
643*cfb92d14SAndroid Build Coastguard Worker         sResolveServiceInfo.Reset();
644*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(
645*cfb92d14SAndroid Build Coastguard Worker             dnsClient->ResolveService(kInstance1Label, kService1FullName, ServiceCallback, sInstance, &queryConfig));
646*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(100);
647*cfb92d14SAndroid Build Coastguard Worker 
648*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sResolveServiceInfo.mCallbackCount == 1);
649*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(sResolveServiceInfo.mError);
650*cfb92d14SAndroid Build Coastguard Worker 
651*cfb92d14SAndroid Build Coastguard Worker         if (mode != Dns::Client::QueryConfig::kServiceModeTxt)
652*cfb92d14SAndroid Build Coastguard Worker         {
653*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sResolveServiceInfo.mInfo.mTtl != 0);
654*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sResolveServiceInfo.mInfo.mPort == service1.mPort);
655*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sResolveServiceInfo.mInfo.mWeight == service1.mWeight);
656*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(strcmp(sResolveServiceInfo.mInfo.mHostNameBuffer, kHostFullName) == 0);
657*cfb92d14SAndroid Build Coastguard Worker 
658*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sResolveServiceInfo.mNumHostAddresses == kNumAddresses);
659*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(AsCoreType(&sResolveServiceInfo.mInfo.mHostAddress) == sResolveServiceInfo.mHostAddresses[0]);
660*cfb92d14SAndroid Build Coastguard Worker 
661*cfb92d14SAndroid Build Coastguard Worker             for (uint8_t index = 0; index < kNumAddresses; index++)
662*cfb92d14SAndroid Build Coastguard Worker             {
663*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(addresses.Contains(sResolveServiceInfo.mHostAddresses[index]));
664*cfb92d14SAndroid Build Coastguard Worker             }
665*cfb92d14SAndroid Build Coastguard Worker         }
666*cfb92d14SAndroid Build Coastguard Worker 
667*cfb92d14SAndroid Build Coastguard Worker         if (mode != Dns::Client::QueryConfig::kServiceModeSrv)
668*cfb92d14SAndroid Build Coastguard Worker         {
669*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sResolveServiceInfo.mInfo.mTxtDataTtl != 0);
670*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sResolveServiceInfo.mInfo.mTxtDataSize != 0);
671*cfb92d14SAndroid Build Coastguard Worker         }
672*cfb92d14SAndroid Build Coastguard Worker     }
673*cfb92d14SAndroid Build Coastguard Worker 
674*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
675*cfb92d14SAndroid Build Coastguard Worker 
676*cfb92d14SAndroid Build Coastguard Worker     Log("Set TestMode on server to reject multi-question queries and send error");
677*cfb92d14SAndroid Build Coastguard Worker     dnsServer->SetTestMode(Dns::ServiceDiscovery::Server::kTestModeRejectMultiQuestionQuery);
678*cfb92d14SAndroid Build Coastguard Worker 
679*cfb92d14SAndroid Build Coastguard Worker     Log("ResolveService(%s,%s) with ServiceMode %s", kInstance1Label, kService1FullName,
680*cfb92d14SAndroid Build Coastguard Worker         ServiceModeToString(Dns::Client::QueryConfig::kServiceModeSrvTxtOptimize));
681*cfb92d14SAndroid Build Coastguard Worker 
682*cfb92d14SAndroid Build Coastguard Worker     queryConfig.Clear();
683*cfb92d14SAndroid Build Coastguard Worker     queryConfig.mServiceMode = static_cast<otDnsServiceMode>(Dns::Client::QueryConfig::kServiceModeSrvTxtOptimize);
684*cfb92d14SAndroid Build Coastguard Worker 
685*cfb92d14SAndroid Build Coastguard Worker     sResolveServiceInfo.Reset();
686*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(
687*cfb92d14SAndroid Build Coastguard Worker         dnsClient->ResolveService(kInstance1Label, kService1FullName, ServiceCallback, sInstance, &queryConfig));
688*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200);
689*cfb92d14SAndroid Build Coastguard Worker 
690*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mCallbackCount == 1);
691*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(sResolveServiceInfo.mError);
692*cfb92d14SAndroid Build Coastguard Worker 
693*cfb92d14SAndroid Build Coastguard Worker     // Use `kServiceModeSrvTxt` and check that server does reject two questions.
694*cfb92d14SAndroid Build Coastguard Worker 
695*cfb92d14SAndroid Build Coastguard Worker     Log("ResolveService(%s,%s) with ServiceMode %s", kInstance1Label, kService1FullName,
696*cfb92d14SAndroid Build Coastguard Worker         ServiceModeToString(Dns::Client::QueryConfig::kServiceModeSrvTxt));
697*cfb92d14SAndroid Build Coastguard Worker 
698*cfb92d14SAndroid Build Coastguard Worker     queryConfig.Clear();
699*cfb92d14SAndroid Build Coastguard Worker     queryConfig.mServiceMode = static_cast<otDnsServiceMode>(Dns::Client::QueryConfig::kServiceModeSrvTxt);
700*cfb92d14SAndroid Build Coastguard Worker 
701*cfb92d14SAndroid Build Coastguard Worker     sResolveServiceInfo.Reset();
702*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(
703*cfb92d14SAndroid Build Coastguard Worker         dnsClient->ResolveService(kInstance1Label, kService1FullName, ServiceCallback, sInstance, &queryConfig));
704*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200);
705*cfb92d14SAndroid Build Coastguard Worker 
706*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mCallbackCount == 1);
707*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mError != kErrorNone);
708*cfb92d14SAndroid Build Coastguard Worker 
709*cfb92d14SAndroid Build Coastguard Worker     dnsServer->SetTestMode(Dns::ServiceDiscovery::Server::kTestModeDisabled);
710*cfb92d14SAndroid Build Coastguard Worker 
711*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
712*cfb92d14SAndroid Build Coastguard Worker 
713*cfb92d14SAndroid Build Coastguard Worker     Log("Set TestMode on server to ignore multi-question queries (send no response)");
714*cfb92d14SAndroid Build Coastguard Worker     dnsServer->SetTestMode(Dns::ServiceDiscovery::Server::kTestModeIgnoreMultiQuestionQuery);
715*cfb92d14SAndroid Build Coastguard Worker 
716*cfb92d14SAndroid Build Coastguard Worker     Log("ResolveService(%s,%s) with ServiceMode %s", kInstance1Label, kService1FullName,
717*cfb92d14SAndroid Build Coastguard Worker         ServiceModeToString(Dns::Client::QueryConfig::kServiceModeSrvTxtOptimize));
718*cfb92d14SAndroid Build Coastguard Worker 
719*cfb92d14SAndroid Build Coastguard Worker     queryConfig.Clear();
720*cfb92d14SAndroid Build Coastguard Worker     queryConfig.mServiceMode = static_cast<otDnsServiceMode>(Dns::Client::QueryConfig::kServiceModeSrvTxtOptimize);
721*cfb92d14SAndroid Build Coastguard Worker 
722*cfb92d14SAndroid Build Coastguard Worker     sResolveServiceInfo.Reset();
723*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(
724*cfb92d14SAndroid Build Coastguard Worker         dnsClient->ResolveService(kInstance1Label, kService1FullName, ServiceCallback, sInstance, &queryConfig));
725*cfb92d14SAndroid Build Coastguard Worker 
726*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10 * 1000); // Wait longer than client response timeout.
727*cfb92d14SAndroid Build Coastguard Worker 
728*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mCallbackCount == 1);
729*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(sResolveServiceInfo.mError);
730*cfb92d14SAndroid Build Coastguard Worker 
731*cfb92d14SAndroid Build Coastguard Worker     // Use `kServiceModeSrvTxt` and check that server does ignore two questions.
732*cfb92d14SAndroid Build Coastguard Worker 
733*cfb92d14SAndroid Build Coastguard Worker     Log("ResolveService(%s,%s) with ServiceMode %s", kInstance1Label, kService1FullName,
734*cfb92d14SAndroid Build Coastguard Worker         ServiceModeToString(Dns::Client::QueryConfig::kServiceModeSrvTxt));
735*cfb92d14SAndroid Build Coastguard Worker 
736*cfb92d14SAndroid Build Coastguard Worker     queryConfig.Clear();
737*cfb92d14SAndroid Build Coastguard Worker     queryConfig.mServiceMode = static_cast<otDnsServiceMode>(Dns::Client::QueryConfig::kServiceModeSrvTxt);
738*cfb92d14SAndroid Build Coastguard Worker 
739*cfb92d14SAndroid Build Coastguard Worker     sResolveServiceInfo.Reset();
740*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(
741*cfb92d14SAndroid Build Coastguard Worker         dnsClient->ResolveService(kInstance1Label, kService1FullName, ServiceCallback, sInstance, &queryConfig));
742*cfb92d14SAndroid Build Coastguard Worker 
743*cfb92d14SAndroid Build Coastguard Worker     // Wait for the client to time out after exhausting all retry attempts, and
744*cfb92d14SAndroid Build Coastguard Worker     // ensure that a `kErrorResponseTimeout` error is reported.
745*cfb92d14SAndroid Build Coastguard Worker 
746*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(45 * 1000);
747*cfb92d14SAndroid Build Coastguard Worker 
748*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mCallbackCount == 1);
749*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mError == kErrorResponseTimeout);
750*cfb92d14SAndroid Build Coastguard Worker 
751*cfb92d14SAndroid Build Coastguard Worker     dnsServer->SetTestMode(Dns::ServiceDiscovery::Server::kTestModeDisabled);
752*cfb92d14SAndroid Build Coastguard Worker 
753*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
754*cfb92d14SAndroid Build Coastguard Worker     // Validate DNS Client `ResolveService()` using all service modes
755*cfb92d14SAndroid Build Coastguard Worker     // when sever does not provide any RR in the addition data section.
756*cfb92d14SAndroid Build Coastguard Worker 
757*cfb92d14SAndroid Build Coastguard Worker     for (Dns::Client::QueryConfig::ServiceMode mode : kServiceModes)
758*cfb92d14SAndroid Build Coastguard Worker     {
759*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
760*cfb92d14SAndroid Build Coastguard Worker         Log("Set TestMode on server to not include any RR in additional section");
761*cfb92d14SAndroid Build Coastguard Worker         dnsServer->SetTestMode(Dns::ServiceDiscovery::Server::kTestModeEmptyAdditionalSection);
762*cfb92d14SAndroid Build Coastguard Worker         Log("ResolveService(%s,%s) with ServiceMode: %s", kInstance1Label, kService1FullName,
763*cfb92d14SAndroid Build Coastguard Worker             ServiceModeToString(mode));
764*cfb92d14SAndroid Build Coastguard Worker 
765*cfb92d14SAndroid Build Coastguard Worker         queryConfig.Clear();
766*cfb92d14SAndroid Build Coastguard Worker         queryConfig.mServiceMode = static_cast<otDnsServiceMode>(mode);
767*cfb92d14SAndroid Build Coastguard Worker 
768*cfb92d14SAndroid Build Coastguard Worker         sResolveServiceInfo.Reset();
769*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(
770*cfb92d14SAndroid Build Coastguard Worker             dnsClient->ResolveService(kInstance1Label, kService1FullName, ServiceCallback, sInstance, &queryConfig));
771*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(100);
772*cfb92d14SAndroid Build Coastguard Worker 
773*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sResolveServiceInfo.mCallbackCount == 1);
774*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(sResolveServiceInfo.mError);
775*cfb92d14SAndroid Build Coastguard Worker 
776*cfb92d14SAndroid Build Coastguard Worker         if (mode != Dns::Client::QueryConfig::kServiceModeTxt)
777*cfb92d14SAndroid Build Coastguard Worker         {
778*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sResolveServiceInfo.mInfo.mTtl != 0);
779*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sResolveServiceInfo.mInfo.mPort == service1.mPort);
780*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sResolveServiceInfo.mInfo.mWeight == service1.mWeight);
781*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(strcmp(sResolveServiceInfo.mInfo.mHostNameBuffer, kHostFullName) == 0);
782*cfb92d14SAndroid Build Coastguard Worker         }
783*cfb92d14SAndroid Build Coastguard Worker 
784*cfb92d14SAndroid Build Coastguard Worker         if (mode != Dns::Client::QueryConfig::kServiceModeSrv)
785*cfb92d14SAndroid Build Coastguard Worker         {
786*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sResolveServiceInfo.mInfo.mTxtDataTtl != 0);
787*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sResolveServiceInfo.mInfo.mTxtDataSize != 0);
788*cfb92d14SAndroid Build Coastguard Worker         }
789*cfb92d14SAndroid Build Coastguard Worker 
790*cfb92d14SAndroid Build Coastguard Worker         // Since server is using `kTestModeEmptyAdditionalSection`, there
791*cfb92d14SAndroid Build Coastguard Worker         // should be no AAAA records for host address.
792*cfb92d14SAndroid Build Coastguard Worker 
793*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(AsCoreType(&sResolveServiceInfo.mInfo.mHostAddress).IsUnspecified());
794*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sResolveServiceInfo.mNumHostAddresses == 0);
795*cfb92d14SAndroid Build Coastguard Worker     }
796*cfb92d14SAndroid Build Coastguard Worker 
797*cfb92d14SAndroid Build Coastguard Worker     dnsServer->SetTestMode(Dns::ServiceDiscovery::Server::kTestModeDisabled);
798*cfb92d14SAndroid Build Coastguard Worker 
799*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
800*cfb92d14SAndroid Build Coastguard Worker     // Validate DNS Client `ResolveServiceAndHostAddress()` using all service modes
801*cfb92d14SAndroid Build Coastguard Worker     // with different TestMode configs on server:
802*cfb92d14SAndroid Build Coastguard Worker     // - Normal behavior when server provides AAAA records for host in
803*cfb92d14SAndroid Build Coastguard Worker     //   additional section.
804*cfb92d14SAndroid Build Coastguard Worker     // - Server provides no records in additional section. We validate that
805*cfb92d14SAndroid Build Coastguard Worker     //   client will send separate query to resolve host address.
806*cfb92d14SAndroid Build Coastguard Worker 
807*cfb92d14SAndroid Build Coastguard Worker     for (Dns::Client::QueryConfig::ServiceMode mode : kServiceModes)
808*cfb92d14SAndroid Build Coastguard Worker     {
809*cfb92d14SAndroid Build Coastguard Worker         for (uint8_t testIter = 0; testIter <= 1; testIter++)
810*cfb92d14SAndroid Build Coastguard Worker         {
811*cfb92d14SAndroid Build Coastguard Worker             Error error;
812*cfb92d14SAndroid Build Coastguard Worker 
813*cfb92d14SAndroid Build Coastguard Worker             Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
814*cfb92d14SAndroid Build Coastguard Worker 
815*cfb92d14SAndroid Build Coastguard Worker             if (testIter == 1)
816*cfb92d14SAndroid Build Coastguard Worker             {
817*cfb92d14SAndroid Build Coastguard Worker                 Log("Set TestMode on server to not include any RR in additional section");
818*cfb92d14SAndroid Build Coastguard Worker                 dnsServer->SetTestMode(Dns::ServiceDiscovery::Server::kTestModeEmptyAdditionalSection);
819*cfb92d14SAndroid Build Coastguard Worker             }
820*cfb92d14SAndroid Build Coastguard Worker             else
821*cfb92d14SAndroid Build Coastguard Worker             {
822*cfb92d14SAndroid Build Coastguard Worker                 dnsServer->SetTestMode(Dns::ServiceDiscovery::Server::kTestModeDisabled);
823*cfb92d14SAndroid Build Coastguard Worker             }
824*cfb92d14SAndroid Build Coastguard Worker 
825*cfb92d14SAndroid Build Coastguard Worker             Log("ResolveServiceAndHostAddress(%s,%s) with ServiceMode: %s", kInstance1Label, kService1FullName,
826*cfb92d14SAndroid Build Coastguard Worker                 ServiceModeToString(mode));
827*cfb92d14SAndroid Build Coastguard Worker 
828*cfb92d14SAndroid Build Coastguard Worker             queryConfig.Clear();
829*cfb92d14SAndroid Build Coastguard Worker             queryConfig.mServiceMode = static_cast<otDnsServiceMode>(mode);
830*cfb92d14SAndroid Build Coastguard Worker 
831*cfb92d14SAndroid Build Coastguard Worker             sResolveServiceInfo.Reset();
832*cfb92d14SAndroid Build Coastguard Worker             error = dnsClient->ResolveServiceAndHostAddress(kInstance1Label, kService1FullName, ServiceCallback,
833*cfb92d14SAndroid Build Coastguard Worker                                                             sInstance, &queryConfig);
834*cfb92d14SAndroid Build Coastguard Worker 
835*cfb92d14SAndroid Build Coastguard Worker             if (mode == Dns::Client::QueryConfig::kServiceModeTxt)
836*cfb92d14SAndroid Build Coastguard Worker             {
837*cfb92d14SAndroid Build Coastguard Worker                 Log("ResolveServiceAndHostAddress() with ServiceMode: %s failed correctly", ServiceModeToString(mode));
838*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(error == kErrorInvalidArgs);
839*cfb92d14SAndroid Build Coastguard Worker                 continue;
840*cfb92d14SAndroid Build Coastguard Worker             }
841*cfb92d14SAndroid Build Coastguard Worker 
842*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(error);
843*cfb92d14SAndroid Build Coastguard Worker 
844*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime(100);
845*cfb92d14SAndroid Build Coastguard Worker 
846*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sResolveServiceInfo.mCallbackCount == 1);
847*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(sResolveServiceInfo.mError);
848*cfb92d14SAndroid Build Coastguard Worker 
849*cfb92d14SAndroid Build Coastguard Worker             if (mode != Dns::Client::QueryConfig::kServiceModeTxt)
850*cfb92d14SAndroid Build Coastguard Worker             {
851*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(sResolveServiceInfo.mInfo.mTtl != 0);
852*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(sResolveServiceInfo.mInfo.mPort == service1.mPort);
853*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(sResolveServiceInfo.mInfo.mWeight == service1.mWeight);
854*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(strcmp(sResolveServiceInfo.mInfo.mHostNameBuffer, kHostFullName) == 0);
855*cfb92d14SAndroid Build Coastguard Worker 
856*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(sResolveServiceInfo.mNumHostAddresses == kNumAddresses);
857*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(AsCoreType(&sResolveServiceInfo.mInfo.mHostAddress) ==
858*cfb92d14SAndroid Build Coastguard Worker                              sResolveServiceInfo.mHostAddresses[0]);
859*cfb92d14SAndroid Build Coastguard Worker 
860*cfb92d14SAndroid Build Coastguard Worker                 for (uint8_t index = 0; index < kNumAddresses; index++)
861*cfb92d14SAndroid Build Coastguard Worker                 {
862*cfb92d14SAndroid Build Coastguard Worker                     VerifyOrQuit(addresses.Contains(sResolveServiceInfo.mHostAddresses[index]));
863*cfb92d14SAndroid Build Coastguard Worker                 }
864*cfb92d14SAndroid Build Coastguard Worker             }
865*cfb92d14SAndroid Build Coastguard Worker 
866*cfb92d14SAndroid Build Coastguard Worker             if (mode != Dns::Client::QueryConfig::kServiceModeSrv)
867*cfb92d14SAndroid Build Coastguard Worker             {
868*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(sResolveServiceInfo.mInfo.mTxtDataTtl != 0);
869*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(sResolveServiceInfo.mInfo.mTxtDataSize != 0);
870*cfb92d14SAndroid Build Coastguard Worker             }
871*cfb92d14SAndroid Build Coastguard Worker         }
872*cfb92d14SAndroid Build Coastguard Worker     }
873*cfb92d14SAndroid Build Coastguard Worker 
874*cfb92d14SAndroid Build Coastguard Worker     dnsServer->SetTestMode(Dns::ServiceDiscovery::Server::kTestModeDisabled);
875*cfb92d14SAndroid Build Coastguard Worker 
876*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
877*cfb92d14SAndroid Build Coastguard Worker     Log("Set TestMode on server to not include any RR in additional section AND to only accept single question");
878*cfb92d14SAndroid Build Coastguard Worker     dnsServer->SetTestMode(Dns::ServiceDiscovery::Server::kTestModeEmptyAdditionalSection +
879*cfb92d14SAndroid Build Coastguard Worker                            Dns::ServiceDiscovery::Server::kTestModeRejectMultiQuestionQuery);
880*cfb92d14SAndroid Build Coastguard Worker 
881*cfb92d14SAndroid Build Coastguard Worker     Log("ResolveServiceAndHostAddress(%s,%s) with ServiceMode: %s", kInstance1Label, kService1FullName,
882*cfb92d14SAndroid Build Coastguard Worker         ServiceModeToString(Dns::Client::QueryConfig::kServiceModeSrvTxtOptimize));
883*cfb92d14SAndroid Build Coastguard Worker 
884*cfb92d14SAndroid Build Coastguard Worker     queryConfig.Clear();
885*cfb92d14SAndroid Build Coastguard Worker     queryConfig.mServiceMode = static_cast<otDnsServiceMode>(Dns::Client::QueryConfig::kServiceModeSrvTxtOptimize);
886*cfb92d14SAndroid Build Coastguard Worker 
887*cfb92d14SAndroid Build Coastguard Worker     oldServerCounters = dnsServer->GetCounters();
888*cfb92d14SAndroid Build Coastguard Worker 
889*cfb92d14SAndroid Build Coastguard Worker     sResolveServiceInfo.Reset();
890*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(dnsClient->ResolveServiceAndHostAddress(kInstance1Label, kService1FullName, ServiceCallback,
891*cfb92d14SAndroid Build Coastguard Worker                                                           sInstance, &queryConfig));
892*cfb92d14SAndroid Build Coastguard Worker 
893*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(100);
894*cfb92d14SAndroid Build Coastguard Worker 
895*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mCallbackCount == 1);
896*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(sResolveServiceInfo.mError);
897*cfb92d14SAndroid Build Coastguard Worker 
898*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mInfo.mTtl != 0);
899*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mInfo.mPort == service1.mPort);
900*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mInfo.mWeight == service1.mWeight);
901*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(strcmp(sResolveServiceInfo.mInfo.mHostNameBuffer, kHostFullName) == 0);
902*cfb92d14SAndroid Build Coastguard Worker 
903*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mInfo.mTxtDataTtl != 0);
904*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mInfo.mTxtDataSize != 0);
905*cfb92d14SAndroid Build Coastguard Worker 
906*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mNumHostAddresses == kNumAddresses);
907*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(AsCoreType(&sResolveServiceInfo.mInfo.mHostAddress) == sResolveServiceInfo.mHostAddresses[0]);
908*cfb92d14SAndroid Build Coastguard Worker 
909*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t index = 0; index < kNumAddresses; index++)
910*cfb92d14SAndroid Build Coastguard Worker     {
911*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(addresses.Contains(sResolveServiceInfo.mHostAddresses[index]));
912*cfb92d14SAndroid Build Coastguard Worker     }
913*cfb92d14SAndroid Build Coastguard Worker 
914*cfb92d14SAndroid Build Coastguard Worker     newServerCounters = dnsServer->GetCounters();
915*cfb92d14SAndroid Build Coastguard Worker 
916*cfb92d14SAndroid Build Coastguard Worker     Log("Validate (using server counter) that client first tried to query SRV/TXT together and failed");
917*cfb92d14SAndroid Build Coastguard Worker     Log("and then send separate queries (for SRV, TXT and AAAA)");
918*cfb92d14SAndroid Build Coastguard Worker     Log("  Total : %2u -> %2u", oldServerCounters.GetTotalQueries(), newServerCounters.GetTotalQueries());
919*cfb92d14SAndroid Build Coastguard Worker     Log("  Failed: %2u -> %2u", oldServerCounters.GetTotalFailedQueries(), newServerCounters.GetTotalFailedQueries());
920*cfb92d14SAndroid Build Coastguard Worker 
921*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(newServerCounters.GetTotalFailedQueries() == 1 + oldServerCounters.GetTotalFailedQueries());
922*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(newServerCounters.GetTotalQueries() == 4 + oldServerCounters.GetTotalQueries());
923*cfb92d14SAndroid Build Coastguard Worker 
924*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
925*cfb92d14SAndroid Build Coastguard Worker     Log("Resolve service again now using `kServiceModeSrvTxtOptimize` as default config");
926*cfb92d14SAndroid Build Coastguard Worker     Log("Client should already know that server is not capable of handling multi-question query");
927*cfb92d14SAndroid Build Coastguard Worker 
928*cfb92d14SAndroid Build Coastguard Worker     queryConfig.Clear();
929*cfb92d14SAndroid Build Coastguard Worker     queryConfig.mServiceMode = static_cast<otDnsServiceMode>(Dns::Client::QueryConfig::kServiceModeSrvTxtOptimize);
930*cfb92d14SAndroid Build Coastguard Worker 
931*cfb92d14SAndroid Build Coastguard Worker     dnsClient->SetDefaultConfig(queryConfig);
932*cfb92d14SAndroid Build Coastguard Worker 
933*cfb92d14SAndroid Build Coastguard Worker     Log("ResolveService(%s,%s)", kInstance1Label, kService1FullName);
934*cfb92d14SAndroid Build Coastguard Worker 
935*cfb92d14SAndroid Build Coastguard Worker     oldServerCounters = dnsServer->GetCounters();
936*cfb92d14SAndroid Build Coastguard Worker 
937*cfb92d14SAndroid Build Coastguard Worker     sResolveServiceInfo.Reset();
938*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(dnsClient->ResolveService(kInstance1Label, kService1FullName, ServiceCallback, sInstance, nullptr));
939*cfb92d14SAndroid Build Coastguard Worker 
940*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(100);
941*cfb92d14SAndroid Build Coastguard Worker 
942*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mCallbackCount == 1);
943*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(sResolveServiceInfo.mError);
944*cfb92d14SAndroid Build Coastguard Worker 
945*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mInfo.mTtl != 0);
946*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mInfo.mPort == service1.mPort);
947*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mInfo.mWeight == service1.mWeight);
948*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(strcmp(sResolveServiceInfo.mInfo.mHostNameBuffer, kHostFullName) == 0);
949*cfb92d14SAndroid Build Coastguard Worker 
950*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mInfo.mTxtDataTtl != 0);
951*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mInfo.mTxtDataSize != 0);
952*cfb92d14SAndroid Build Coastguard Worker 
953*cfb92d14SAndroid Build Coastguard Worker     newServerCounters = dnsServer->GetCounters();
954*cfb92d14SAndroid Build Coastguard Worker 
955*cfb92d14SAndroid Build Coastguard Worker     Log("Client should already know that server is not capable of handling multi-question query");
956*cfb92d14SAndroid Build Coastguard Worker     Log("Check server counters to validate that client did send separate queries for TXT and SRV");
957*cfb92d14SAndroid Build Coastguard Worker     Log("  Total : %2u -> %2u", oldServerCounters.GetTotalQueries(), newServerCounters.GetTotalQueries());
958*cfb92d14SAndroid Build Coastguard Worker     Log("  Failed: %2u -> %2u", oldServerCounters.GetTotalFailedQueries(), newServerCounters.GetTotalFailedQueries());
959*cfb92d14SAndroid Build Coastguard Worker 
960*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(newServerCounters.GetTotalFailedQueries() == oldServerCounters.GetTotalFailedQueries());
961*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(newServerCounters.GetTotalQueries() == 2 + oldServerCounters.GetTotalQueries());
962*cfb92d14SAndroid Build Coastguard Worker 
963*cfb92d14SAndroid Build Coastguard Worker     dnsServer->SetTestMode(Dns::ServiceDiscovery::Server::kTestModeDisabled);
964*cfb92d14SAndroid Build Coastguard Worker 
965*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
966*cfb92d14SAndroid Build Coastguard Worker 
967*cfb92d14SAndroid Build Coastguard Worker     Log("Stop DNS-SD server");
968*cfb92d14SAndroid Build Coastguard Worker     dnsServer->Stop();
969*cfb92d14SAndroid Build Coastguard Worker 
970*cfb92d14SAndroid Build Coastguard Worker     Log("ResolveService(%s,%s) with ServiceMode %s", kInstance1Label, kService1FullName,
971*cfb92d14SAndroid Build Coastguard Worker         ServiceModeToString(Dns::Client::QueryConfig::kServiceModeSrvTxtSeparate));
972*cfb92d14SAndroid Build Coastguard Worker 
973*cfb92d14SAndroid Build Coastguard Worker     queryConfig.Clear();
974*cfb92d14SAndroid Build Coastguard Worker     queryConfig.mServiceMode = static_cast<otDnsServiceMode>(Dns::Client::QueryConfig::kServiceModeSrvTxtSeparate);
975*cfb92d14SAndroid Build Coastguard Worker 
976*cfb92d14SAndroid Build Coastguard Worker     sResolveServiceInfo.Reset();
977*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(
978*cfb92d14SAndroid Build Coastguard Worker         dnsClient->ResolveService(kInstance1Label, kService1FullName, ServiceCallback, sInstance, &queryConfig));
979*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(25 * 1000);
980*cfb92d14SAndroid Build Coastguard Worker 
981*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mCallbackCount == 1);
982*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sResolveServiceInfo.mError == kErrorResponseTimeout);
983*cfb92d14SAndroid Build Coastguard Worker 
984*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
985*cfb92d14SAndroid Build Coastguard Worker 
986*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
987*cfb92d14SAndroid Build Coastguard Worker     // Disable SRP server, verify that all heap allocations by SRP server
988*cfb92d14SAndroid Build Coastguard Worker     // and/or by DNS Client are freed.
989*cfb92d14SAndroid Build Coastguard Worker 
990*cfb92d14SAndroid Build Coastguard Worker     Log("Disabling SRP server");
991*cfb92d14SAndroid Build Coastguard Worker 
992*cfb92d14SAndroid Build Coastguard Worker     srpServer->SetEnabled(false);
993*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(100);
994*cfb92d14SAndroid Build Coastguard Worker 
995*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
996*cfb92d14SAndroid Build Coastguard Worker 
997*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
998*cfb92d14SAndroid Build Coastguard Worker     // Finalize OT instance and validate all heap allocations are freed.
999*cfb92d14SAndroid Build Coastguard Worker 
1000*cfb92d14SAndroid Build Coastguard Worker     Log("Finalizing OT instance");
1001*cfb92d14SAndroid Build Coastguard Worker     FinalizeTest();
1002*cfb92d14SAndroid Build Coastguard Worker 
1003*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.IsEmpty());
1004*cfb92d14SAndroid Build Coastguard Worker 
1005*cfb92d14SAndroid Build Coastguard Worker     Log("End of TestDnsClient");
1006*cfb92d14SAndroid Build Coastguard Worker }
1007*cfb92d14SAndroid Build Coastguard Worker 
1008*cfb92d14SAndroid Build Coastguard Worker //----------------------------------------------------------------------------------------------------------------------
1009*cfb92d14SAndroid Build Coastguard Worker 
1010*cfb92d14SAndroid Build Coastguard Worker Dns::Name::Buffer sLastSubscribeName;
1011*cfb92d14SAndroid Build Coastguard Worker Dns::Name::Buffer sLastUnsubscribeName;
1012*cfb92d14SAndroid Build Coastguard Worker 
QuerySubscribe(void * aContext,const char * aFullName)1013*cfb92d14SAndroid Build Coastguard Worker void QuerySubscribe(void *aContext, const char *aFullName)
1014*cfb92d14SAndroid Build Coastguard Worker {
1015*cfb92d14SAndroid Build Coastguard Worker     uint16_t length = StringLength(aFullName, Dns::Name::kMaxNameSize);
1016*cfb92d14SAndroid Build Coastguard Worker 
1017*cfb92d14SAndroid Build Coastguard Worker     Log("QuerySubscribe(%s)", aFullName);
1018*cfb92d14SAndroid Build Coastguard Worker 
1019*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aContext == sInstance);
1020*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(length < Dns::Name::kMaxNameSize);
1021*cfb92d14SAndroid Build Coastguard Worker     strcpy(sLastSubscribeName, aFullName);
1022*cfb92d14SAndroid Build Coastguard Worker }
1023*cfb92d14SAndroid Build Coastguard Worker 
QueryUnsubscribe(void * aContext,const char * aFullName)1024*cfb92d14SAndroid Build Coastguard Worker void QueryUnsubscribe(void *aContext, const char *aFullName)
1025*cfb92d14SAndroid Build Coastguard Worker {
1026*cfb92d14SAndroid Build Coastguard Worker     uint16_t length = StringLength(aFullName, Dns::Name::kMaxNameSize);
1027*cfb92d14SAndroid Build Coastguard Worker 
1028*cfb92d14SAndroid Build Coastguard Worker     Log("QueryUnsubscribe(%s)", aFullName);
1029*cfb92d14SAndroid Build Coastguard Worker 
1030*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aContext == sInstance);
1031*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(length < Dns::Name::kMaxNameSize);
1032*cfb92d14SAndroid Build Coastguard Worker     strcpy(sLastUnsubscribeName, aFullName);
1033*cfb92d14SAndroid Build Coastguard Worker }
1034*cfb92d14SAndroid Build Coastguard Worker 
TestDnssdServerProxyCallback(void)1035*cfb92d14SAndroid Build Coastguard Worker void TestDnssdServerProxyCallback(void)
1036*cfb92d14SAndroid Build Coastguard Worker {
1037*cfb92d14SAndroid Build Coastguard Worker     Srp::Server                   *srpServer;
1038*cfb92d14SAndroid Build Coastguard Worker     Srp::Client                   *srpClient;
1039*cfb92d14SAndroid Build Coastguard Worker     Dns::Client                   *dnsClient;
1040*cfb92d14SAndroid Build Coastguard Worker     Dns::ServiceDiscovery::Server *dnsServer;
1041*cfb92d14SAndroid Build Coastguard Worker     otDnssdServiceInstanceInfo     instanceInfo;
1042*cfb92d14SAndroid Build Coastguard Worker 
1043*cfb92d14SAndroid Build Coastguard Worker     Log("--------------------------------------------------------------------------------------------");
1044*cfb92d14SAndroid Build Coastguard Worker     Log("TestDnssdServerProxyCallback");
1045*cfb92d14SAndroid Build Coastguard Worker 
1046*cfb92d14SAndroid Build Coastguard Worker     InitTest();
1047*cfb92d14SAndroid Build Coastguard Worker 
1048*cfb92d14SAndroid Build Coastguard Worker     srpServer = &sInstance->Get<Srp::Server>();
1049*cfb92d14SAndroid Build Coastguard Worker     srpClient = &sInstance->Get<Srp::Client>();
1050*cfb92d14SAndroid Build Coastguard Worker     dnsClient = &sInstance->Get<Dns::Client>();
1051*cfb92d14SAndroid Build Coastguard Worker     dnsServer = &sInstance->Get<Dns::ServiceDiscovery::Server>();
1052*cfb92d14SAndroid Build Coastguard Worker 
1053*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1054*cfb92d14SAndroid Build Coastguard Worker     // Start SRP server.
1055*cfb92d14SAndroid Build Coastguard Worker 
1056*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(srpServer->SetAddressMode(Srp::Server::kAddressModeUnicast));
1057*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateDisabled);
1058*cfb92d14SAndroid Build Coastguard Worker 
1059*cfb92d14SAndroid Build Coastguard Worker     srpServer->SetEnabled(true);
1060*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srpServer->GetState() != Srp::Server::kStateDisabled);
1061*cfb92d14SAndroid Build Coastguard Worker 
1062*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10000);
1063*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
1064*cfb92d14SAndroid Build Coastguard Worker 
1065*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1066*cfb92d14SAndroid Build Coastguard Worker     // Start SRP client.
1067*cfb92d14SAndroid Build Coastguard Worker 
1068*cfb92d14SAndroid Build Coastguard Worker     srpClient->EnableAutoStartMode(nullptr, nullptr);
1069*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srpClient->IsAutoStartModeEnabled());
1070*cfb92d14SAndroid Build Coastguard Worker 
1071*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
1072*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srpClient->IsRunning());
1073*cfb92d14SAndroid Build Coastguard Worker 
1074*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1075*cfb92d14SAndroid Build Coastguard Worker     // Set the query subscribe/unsubscribe callbacks on server
1076*cfb92d14SAndroid Build Coastguard Worker 
1077*cfb92d14SAndroid Build Coastguard Worker     dnsServer->SetQueryCallbacks(QuerySubscribe, QueryUnsubscribe, sInstance);
1078*cfb92d14SAndroid Build Coastguard Worker 
1079*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1080*cfb92d14SAndroid Build Coastguard Worker 
1081*cfb92d14SAndroid Build Coastguard Worker     sLastSubscribeName[0]   = '\0';
1082*cfb92d14SAndroid Build Coastguard Worker     sLastUnsubscribeName[0] = '\0';
1083*cfb92d14SAndroid Build Coastguard Worker 
1084*cfb92d14SAndroid Build Coastguard Worker     sBrowseInfo.Reset();
1085*cfb92d14SAndroid Build Coastguard Worker     Log("Browse(%s)", kService1FullName);
1086*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(dnsClient->Browse(kService1FullName, BrowseCallback, sInstance));
1087*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10);
1088*cfb92d14SAndroid Build Coastguard Worker 
1089*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(strcmp(sLastSubscribeName, kService1FullName) == 0);
1090*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(strcmp(sLastUnsubscribeName, "") == 0);
1091*cfb92d14SAndroid Build Coastguard Worker 
1092*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mCallbackCount == 0);
1093*cfb92d14SAndroid Build Coastguard Worker 
1094*cfb92d14SAndroid Build Coastguard Worker     Log("Invoke subscribe callback");
1095*cfb92d14SAndroid Build Coastguard Worker 
1096*cfb92d14SAndroid Build Coastguard Worker     memset(&instanceInfo, 0, sizeof(instanceInfo));
1097*cfb92d14SAndroid Build Coastguard Worker     instanceInfo.mFullName = kInstance1FullName;
1098*cfb92d14SAndroid Build Coastguard Worker     instanceInfo.mHostName = kHostFullName;
1099*cfb92d14SAndroid Build Coastguard Worker     instanceInfo.mPort     = 200;
1100*cfb92d14SAndroid Build Coastguard Worker 
1101*cfb92d14SAndroid Build Coastguard Worker     dnsServer->HandleDiscoveredServiceInstance(kService1FullName, instanceInfo);
1102*cfb92d14SAndroid Build Coastguard Worker 
1103*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10);
1104*cfb92d14SAndroid Build Coastguard Worker 
1105*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mCallbackCount == 1);
1106*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(sBrowseInfo.mError);
1107*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mNumInstances == 1);
1108*cfb92d14SAndroid Build Coastguard Worker 
1109*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(strcmp(sLastUnsubscribeName, kService1FullName) == 0);
1110*cfb92d14SAndroid Build Coastguard Worker 
1111*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1112*cfb92d14SAndroid Build Coastguard Worker 
1113*cfb92d14SAndroid Build Coastguard Worker     sLastSubscribeName[0]   = '\0';
1114*cfb92d14SAndroid Build Coastguard Worker     sLastUnsubscribeName[0] = '\0';
1115*cfb92d14SAndroid Build Coastguard Worker 
1116*cfb92d14SAndroid Build Coastguard Worker     sBrowseInfo.Reset();
1117*cfb92d14SAndroid Build Coastguard Worker     Log("Browse(%s)", kService2FullName);
1118*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(dnsClient->Browse(kService2FullName, BrowseCallback, sInstance));
1119*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10);
1120*cfb92d14SAndroid Build Coastguard Worker 
1121*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(strcmp(sLastSubscribeName, kService2FullName) == 0);
1122*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(strcmp(sLastUnsubscribeName, "") == 0);
1123*cfb92d14SAndroid Build Coastguard Worker 
1124*cfb92d14SAndroid Build Coastguard Worker     Log("Invoke subscribe callback for wrong name");
1125*cfb92d14SAndroid Build Coastguard Worker 
1126*cfb92d14SAndroid Build Coastguard Worker     memset(&instanceInfo, 0, sizeof(instanceInfo));
1127*cfb92d14SAndroid Build Coastguard Worker     instanceInfo.mFullName = kInstance1FullName;
1128*cfb92d14SAndroid Build Coastguard Worker     instanceInfo.mHostName = kHostFullName;
1129*cfb92d14SAndroid Build Coastguard Worker     instanceInfo.mPort     = 200;
1130*cfb92d14SAndroid Build Coastguard Worker 
1131*cfb92d14SAndroid Build Coastguard Worker     dnsServer->HandleDiscoveredServiceInstance(kService1FullName, instanceInfo);
1132*cfb92d14SAndroid Build Coastguard Worker 
1133*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10);
1134*cfb92d14SAndroid Build Coastguard Worker 
1135*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mCallbackCount == 0);
1136*cfb92d14SAndroid Build Coastguard Worker 
1137*cfb92d14SAndroid Build Coastguard Worker     Log("Invoke subscribe callback for correct name");
1138*cfb92d14SAndroid Build Coastguard Worker 
1139*cfb92d14SAndroid Build Coastguard Worker     memset(&instanceInfo, 0, sizeof(instanceInfo));
1140*cfb92d14SAndroid Build Coastguard Worker     instanceInfo.mFullName = kInstance2FullName;
1141*cfb92d14SAndroid Build Coastguard Worker     instanceInfo.mHostName = kHostFullName;
1142*cfb92d14SAndroid Build Coastguard Worker     instanceInfo.mPort     = 200;
1143*cfb92d14SAndroid Build Coastguard Worker 
1144*cfb92d14SAndroid Build Coastguard Worker     dnsServer->HandleDiscoveredServiceInstance(kService2FullName, instanceInfo);
1145*cfb92d14SAndroid Build Coastguard Worker 
1146*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10);
1147*cfb92d14SAndroid Build Coastguard Worker 
1148*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mCallbackCount == 1);
1149*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(sBrowseInfo.mError);
1150*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mNumInstances == 1);
1151*cfb92d14SAndroid Build Coastguard Worker 
1152*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(strcmp(sLastUnsubscribeName, kService2FullName) == 0);
1153*cfb92d14SAndroid Build Coastguard Worker 
1154*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1155*cfb92d14SAndroid Build Coastguard Worker 
1156*cfb92d14SAndroid Build Coastguard Worker     sLastSubscribeName[0]   = '\0';
1157*cfb92d14SAndroid Build Coastguard Worker     sLastUnsubscribeName[0] = '\0';
1158*cfb92d14SAndroid Build Coastguard Worker 
1159*cfb92d14SAndroid Build Coastguard Worker     sBrowseInfo.Reset();
1160*cfb92d14SAndroid Build Coastguard Worker     Log("Browse(%s)", kService2FullName);
1161*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(dnsClient->Browse(kService2FullName, BrowseCallback, sInstance));
1162*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10);
1163*cfb92d14SAndroid Build Coastguard Worker 
1164*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(strcmp(sLastSubscribeName, kService2FullName) == 0);
1165*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(strcmp(sLastUnsubscribeName, "") == 0);
1166*cfb92d14SAndroid Build Coastguard Worker 
1167*cfb92d14SAndroid Build Coastguard Worker     Log("Do not invoke subscribe callback and let query to timeout");
1168*cfb92d14SAndroid Build Coastguard Worker 
1169*cfb92d14SAndroid Build Coastguard Worker     // Query timeout is set to 6 seconds
1170*cfb92d14SAndroid Build Coastguard Worker 
1171*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(5000);
1172*cfb92d14SAndroid Build Coastguard Worker 
1173*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mCallbackCount == 0);
1174*cfb92d14SAndroid Build Coastguard Worker 
1175*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
1176*cfb92d14SAndroid Build Coastguard Worker 
1177*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mCallbackCount == 1);
1178*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(sBrowseInfo.mError);
1179*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mNumInstances == 0);
1180*cfb92d14SAndroid Build Coastguard Worker 
1181*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(strcmp(sLastUnsubscribeName, kService2FullName) == 0);
1182*cfb92d14SAndroid Build Coastguard Worker 
1183*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1184*cfb92d14SAndroid Build Coastguard Worker 
1185*cfb92d14SAndroid Build Coastguard Worker     sLastSubscribeName[0]   = '\0';
1186*cfb92d14SAndroid Build Coastguard Worker     sLastUnsubscribeName[0] = '\0';
1187*cfb92d14SAndroid Build Coastguard Worker 
1188*cfb92d14SAndroid Build Coastguard Worker     sBrowseInfo.Reset();
1189*cfb92d14SAndroid Build Coastguard Worker     Log("Browse(%s)", kService2FullName);
1190*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(dnsClient->Browse(kService2FullName, BrowseCallback, sInstance));
1191*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10);
1192*cfb92d14SAndroid Build Coastguard Worker 
1193*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(strcmp(sLastSubscribeName, kService2FullName) == 0);
1194*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(strcmp(sLastUnsubscribeName, "") == 0);
1195*cfb92d14SAndroid Build Coastguard Worker 
1196*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mCallbackCount == 0);
1197*cfb92d14SAndroid Build Coastguard Worker 
1198*cfb92d14SAndroid Build Coastguard Worker     Log("Do not invoke subscribe callback and stop server");
1199*cfb92d14SAndroid Build Coastguard Worker 
1200*cfb92d14SAndroid Build Coastguard Worker     dnsServer->Stop();
1201*cfb92d14SAndroid Build Coastguard Worker 
1202*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10);
1203*cfb92d14SAndroid Build Coastguard Worker 
1204*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mCallbackCount == 1);
1205*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseInfo.mError != kErrorNone);
1206*cfb92d14SAndroid Build Coastguard Worker 
1207*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(strcmp(sLastUnsubscribeName, kService2FullName) == 0);
1208*cfb92d14SAndroid Build Coastguard Worker 
1209*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1210*cfb92d14SAndroid Build Coastguard Worker 
1211*cfb92d14SAndroid Build Coastguard Worker     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1212*cfb92d14SAndroid Build Coastguard Worker     // Finalize OT instance and validate all heap allocations are freed.
1213*cfb92d14SAndroid Build Coastguard Worker 
1214*cfb92d14SAndroid Build Coastguard Worker     Log("Finalizing OT instance");
1215*cfb92d14SAndroid Build Coastguard Worker     FinalizeTest();
1216*cfb92d14SAndroid Build Coastguard Worker 
1217*cfb92d14SAndroid Build Coastguard Worker     Log("End of TestDnssdServerProxyCallback");
1218*cfb92d14SAndroid Build Coastguard Worker }
1219*cfb92d14SAndroid Build Coastguard Worker 
1220*cfb92d14SAndroid Build Coastguard Worker #endif // ENABLE_DNS_TEST
1221*cfb92d14SAndroid Build Coastguard Worker 
main(void)1222*cfb92d14SAndroid Build Coastguard Worker int main(void)
1223*cfb92d14SAndroid Build Coastguard Worker {
1224*cfb92d14SAndroid Build Coastguard Worker #if ENABLE_DNS_TEST
1225*cfb92d14SAndroid Build Coastguard Worker     TestDnsClient();
1226*cfb92d14SAndroid Build Coastguard Worker     TestDnssdServerProxyCallback();
1227*cfb92d14SAndroid Build Coastguard Worker     printf("All tests passed\n");
1228*cfb92d14SAndroid Build Coastguard Worker #else
1229*cfb92d14SAndroid Build Coastguard Worker     printf("DNS_CLIENT or DSNSSD_SERVER feature is not enabled\n");
1230*cfb92d14SAndroid Build Coastguard Worker #endif
1231*cfb92d14SAndroid Build Coastguard Worker 
1232*cfb92d14SAndroid Build Coastguard Worker     return 0;
1233*cfb92d14SAndroid Build Coastguard Worker }
1234