1*4a64e381SAndroid Build Coastguard Worker /*
2*4a64e381SAndroid Build Coastguard Worker * Copyright (c) 2020, The OpenThread Authors.
3*4a64e381SAndroid Build Coastguard Worker * All rights reserved.
4*4a64e381SAndroid Build Coastguard Worker *
5*4a64e381SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*4a64e381SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
7*4a64e381SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
8*4a64e381SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
9*4a64e381SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
10*4a64e381SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
11*4a64e381SAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
12*4a64e381SAndroid Build Coastguard Worker * 3. Neither the name of the copyright holder nor the
13*4a64e381SAndroid Build Coastguard Worker * names of its contributors may be used to endorse or promote products
14*4a64e381SAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
15*4a64e381SAndroid Build Coastguard Worker *
16*4a64e381SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*4a64e381SAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*4a64e381SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*4a64e381SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*4a64e381SAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*4a64e381SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*4a64e381SAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*4a64e381SAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*4a64e381SAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*4a64e381SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*4a64e381SAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE.
27*4a64e381SAndroid Build Coastguard Worker */
28*4a64e381SAndroid Build Coastguard Worker
29*4a64e381SAndroid Build Coastguard Worker /**
30*4a64e381SAndroid Build Coastguard Worker * @file
31*4a64e381SAndroid Build Coastguard Worker * The file implements the Advertising Proxy.
32*4a64e381SAndroid Build Coastguard Worker */
33*4a64e381SAndroid Build Coastguard Worker
34*4a64e381SAndroid Build Coastguard Worker #define OTBR_LOG_TAG "ADPROXY"
35*4a64e381SAndroid Build Coastguard Worker
36*4a64e381SAndroid Build Coastguard Worker #include "sdp_proxy/advertising_proxy.hpp"
37*4a64e381SAndroid Build Coastguard Worker
38*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_SRP_ADVERTISING_PROXY
39*4a64e381SAndroid Build Coastguard Worker
40*4a64e381SAndroid Build Coastguard Worker #if !OTBR_ENABLE_MDNS_AVAHI && !OTBR_ENABLE_MDNS_MDNSSD && !OTBR_ENABLE_MDNS_MOJO
41*4a64e381SAndroid Build Coastguard Worker #error "The Advertising Proxy requires OTBR_ENABLE_MDNS_AVAHI, OTBR_ENABLE_MDNS_MDNSSD or OTBR_ENABLE_MDNS_MOJO"
42*4a64e381SAndroid Build Coastguard Worker #endif
43*4a64e381SAndroid Build Coastguard Worker
44*4a64e381SAndroid Build Coastguard Worker #include <string>
45*4a64e381SAndroid Build Coastguard Worker
46*4a64e381SAndroid Build Coastguard Worker #include <assert.h>
47*4a64e381SAndroid Build Coastguard Worker
48*4a64e381SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
49*4a64e381SAndroid Build Coastguard Worker #include "common/dns_utils.hpp"
50*4a64e381SAndroid Build Coastguard Worker #include "common/logging.hpp"
51*4a64e381SAndroid Build Coastguard Worker
52*4a64e381SAndroid Build Coastguard Worker namespace otbr {
53*4a64e381SAndroid Build Coastguard Worker
AdvertisingProxy(Ncp::RcpHost & aHost,Mdns::Publisher & aPublisher)54*4a64e381SAndroid Build Coastguard Worker AdvertisingProxy::AdvertisingProxy(Ncp::RcpHost &aHost, Mdns::Publisher &aPublisher)
55*4a64e381SAndroid Build Coastguard Worker : mHost(aHost)
56*4a64e381SAndroid Build Coastguard Worker , mPublisher(aPublisher)
57*4a64e381SAndroid Build Coastguard Worker , mIsEnabled(false)
58*4a64e381SAndroid Build Coastguard Worker {
59*4a64e381SAndroid Build Coastguard Worker mHost.RegisterResetHandler(
60*4a64e381SAndroid Build Coastguard Worker [this]() { otSrpServerSetServiceUpdateHandler(GetInstance(), AdvertisingHandler, this); });
61*4a64e381SAndroid Build Coastguard Worker }
62*4a64e381SAndroid Build Coastguard Worker
SetEnabled(bool aIsEnabled)63*4a64e381SAndroid Build Coastguard Worker void AdvertisingProxy::SetEnabled(bool aIsEnabled)
64*4a64e381SAndroid Build Coastguard Worker {
65*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aIsEnabled != IsEnabled());
66*4a64e381SAndroid Build Coastguard Worker mIsEnabled = aIsEnabled;
67*4a64e381SAndroid Build Coastguard Worker if (mIsEnabled)
68*4a64e381SAndroid Build Coastguard Worker {
69*4a64e381SAndroid Build Coastguard Worker Start();
70*4a64e381SAndroid Build Coastguard Worker }
71*4a64e381SAndroid Build Coastguard Worker else
72*4a64e381SAndroid Build Coastguard Worker {
73*4a64e381SAndroid Build Coastguard Worker Stop();
74*4a64e381SAndroid Build Coastguard Worker }
75*4a64e381SAndroid Build Coastguard Worker
76*4a64e381SAndroid Build Coastguard Worker exit:
77*4a64e381SAndroid Build Coastguard Worker return;
78*4a64e381SAndroid Build Coastguard Worker }
79*4a64e381SAndroid Build Coastguard Worker
Start(void)80*4a64e381SAndroid Build Coastguard Worker void AdvertisingProxy::Start(void)
81*4a64e381SAndroid Build Coastguard Worker {
82*4a64e381SAndroid Build Coastguard Worker otSrpServerSetServiceUpdateHandler(GetInstance(), AdvertisingHandler, this);
83*4a64e381SAndroid Build Coastguard Worker
84*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Started");
85*4a64e381SAndroid Build Coastguard Worker }
86*4a64e381SAndroid Build Coastguard Worker
Stop(void)87*4a64e381SAndroid Build Coastguard Worker void AdvertisingProxy::Stop(void)
88*4a64e381SAndroid Build Coastguard Worker {
89*4a64e381SAndroid Build Coastguard Worker // Outstanding updates will fail on the SRP server because of timeout.
90*4a64e381SAndroid Build Coastguard Worker // TODO: handle this case gracefully.
91*4a64e381SAndroid Build Coastguard Worker
92*4a64e381SAndroid Build Coastguard Worker // Stop receiving SRP server events.
93*4a64e381SAndroid Build Coastguard Worker if (GetInstance() != nullptr)
94*4a64e381SAndroid Build Coastguard Worker {
95*4a64e381SAndroid Build Coastguard Worker otSrpServerSetServiceUpdateHandler(GetInstance(), nullptr, nullptr);
96*4a64e381SAndroid Build Coastguard Worker }
97*4a64e381SAndroid Build Coastguard Worker
98*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Stopped");
99*4a64e381SAndroid Build Coastguard Worker }
100*4a64e381SAndroid Build Coastguard Worker
AdvertisingHandler(otSrpServerServiceUpdateId aId,const otSrpServerHost * aHost,uint32_t aTimeout,void * aContext)101*4a64e381SAndroid Build Coastguard Worker void AdvertisingProxy::AdvertisingHandler(otSrpServerServiceUpdateId aId,
102*4a64e381SAndroid Build Coastguard Worker const otSrpServerHost *aHost,
103*4a64e381SAndroid Build Coastguard Worker uint32_t aTimeout,
104*4a64e381SAndroid Build Coastguard Worker void *aContext)
105*4a64e381SAndroid Build Coastguard Worker {
106*4a64e381SAndroid Build Coastguard Worker static_cast<AdvertisingProxy *>(aContext)->AdvertisingHandler(aId, aHost, aTimeout);
107*4a64e381SAndroid Build Coastguard Worker }
108*4a64e381SAndroid Build Coastguard Worker
AdvertisingHandler(otSrpServerServiceUpdateId aId,const otSrpServerHost * aHost,uint32_t aTimeout)109*4a64e381SAndroid Build Coastguard Worker void AdvertisingProxy::AdvertisingHandler(otSrpServerServiceUpdateId aId,
110*4a64e381SAndroid Build Coastguard Worker const otSrpServerHost *aHost,
111*4a64e381SAndroid Build Coastguard Worker uint32_t aTimeout)
112*4a64e381SAndroid Build Coastguard Worker {
113*4a64e381SAndroid Build Coastguard Worker OTBR_UNUSED_VARIABLE(aTimeout);
114*4a64e381SAndroid Build Coastguard Worker
115*4a64e381SAndroid Build Coastguard Worker OutstandingUpdate *update = nullptr;
116*4a64e381SAndroid Build Coastguard Worker otbrError error = OTBR_ERROR_NONE;
117*4a64e381SAndroid Build Coastguard Worker
118*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(IsEnabled());
119*4a64e381SAndroid Build Coastguard Worker
120*4a64e381SAndroid Build Coastguard Worker mOutstandingUpdates.emplace_back();
121*4a64e381SAndroid Build Coastguard Worker update = &mOutstandingUpdates.back();
122*4a64e381SAndroid Build Coastguard Worker update->mId = aId;
123*4a64e381SAndroid Build Coastguard Worker
124*4a64e381SAndroid Build Coastguard Worker error = PublishHostAndItsServices(aHost, update);
125*4a64e381SAndroid Build Coastguard Worker
126*4a64e381SAndroid Build Coastguard Worker if (error != OTBR_ERROR_NONE || update->mCallbackCount == 0)
127*4a64e381SAndroid Build Coastguard Worker {
128*4a64e381SAndroid Build Coastguard Worker mOutstandingUpdates.pop_back();
129*4a64e381SAndroid Build Coastguard Worker otSrpServerHandleServiceUpdateResult(GetInstance(), aId, OtbrErrorToOtError(error));
130*4a64e381SAndroid Build Coastguard Worker }
131*4a64e381SAndroid Build Coastguard Worker
132*4a64e381SAndroid Build Coastguard Worker exit:
133*4a64e381SAndroid Build Coastguard Worker return;
134*4a64e381SAndroid Build Coastguard Worker }
135*4a64e381SAndroid Build Coastguard Worker
OnMdnsPublishResult(otSrpServerServiceUpdateId aUpdateId,otbrError aError)136*4a64e381SAndroid Build Coastguard Worker void AdvertisingProxy::OnMdnsPublishResult(otSrpServerServiceUpdateId aUpdateId, otbrError aError)
137*4a64e381SAndroid Build Coastguard Worker {
138*4a64e381SAndroid Build Coastguard Worker for (auto update = mOutstandingUpdates.begin(); update != mOutstandingUpdates.end(); ++update)
139*4a64e381SAndroid Build Coastguard Worker {
140*4a64e381SAndroid Build Coastguard Worker if (update->mId != aUpdateId)
141*4a64e381SAndroid Build Coastguard Worker {
142*4a64e381SAndroid Build Coastguard Worker continue;
143*4a64e381SAndroid Build Coastguard Worker }
144*4a64e381SAndroid Build Coastguard Worker
145*4a64e381SAndroid Build Coastguard Worker if (aError != OTBR_ERROR_NONE || update->mCallbackCount == 1)
146*4a64e381SAndroid Build Coastguard Worker {
147*4a64e381SAndroid Build Coastguard Worker // Erase before notifying OpenThread, because there are chances that new
148*4a64e381SAndroid Build Coastguard Worker // elements may be added to `otSrpServerHandleServiceUpdateResult` and
149*4a64e381SAndroid Build Coastguard Worker // the iterator will be invalidated.
150*4a64e381SAndroid Build Coastguard Worker mOutstandingUpdates.erase(update);
151*4a64e381SAndroid Build Coastguard Worker otSrpServerHandleServiceUpdateResult(GetInstance(), aUpdateId, OtbrErrorToOtError(aError));
152*4a64e381SAndroid Build Coastguard Worker }
153*4a64e381SAndroid Build Coastguard Worker else
154*4a64e381SAndroid Build Coastguard Worker {
155*4a64e381SAndroid Build Coastguard Worker --update->mCallbackCount;
156*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Waiting for more publishing callbacks %d", update->mCallbackCount);
157*4a64e381SAndroid Build Coastguard Worker }
158*4a64e381SAndroid Build Coastguard Worker break;
159*4a64e381SAndroid Build Coastguard Worker }
160*4a64e381SAndroid Build Coastguard Worker }
161*4a64e381SAndroid Build Coastguard Worker
GetEligibleAddresses(const otIp6Address * aHostAddresses,uint8_t aHostAddressNum)162*4a64e381SAndroid Build Coastguard Worker std::vector<Ip6Address> AdvertisingProxy::GetEligibleAddresses(const otIp6Address *aHostAddresses,
163*4a64e381SAndroid Build Coastguard Worker uint8_t aHostAddressNum)
164*4a64e381SAndroid Build Coastguard Worker {
165*4a64e381SAndroid Build Coastguard Worker std::vector<Ip6Address> addresses;
166*4a64e381SAndroid Build Coastguard Worker const otIp6Address *meshLocalEid = otThreadGetMeshLocalEid(GetInstance());
167*4a64e381SAndroid Build Coastguard Worker
168*4a64e381SAndroid Build Coastguard Worker addresses.reserve(aHostAddressNum);
169*4a64e381SAndroid Build Coastguard Worker for (size_t i = 0; i < aHostAddressNum; ++i)
170*4a64e381SAndroid Build Coastguard Worker {
171*4a64e381SAndroid Build Coastguard Worker Ip6Address address(aHostAddresses[i].mFields.m8);
172*4a64e381SAndroid Build Coastguard Worker
173*4a64e381SAndroid Build Coastguard Worker if (otIp6PrefixMatch(meshLocalEid, &aHostAddresses[i]) >= OT_IP6_PREFIX_BITSIZE)
174*4a64e381SAndroid Build Coastguard Worker {
175*4a64e381SAndroid Build Coastguard Worker continue;
176*4a64e381SAndroid Build Coastguard Worker }
177*4a64e381SAndroid Build Coastguard Worker if (address.IsLinkLocal())
178*4a64e381SAndroid Build Coastguard Worker {
179*4a64e381SAndroid Build Coastguard Worker continue;
180*4a64e381SAndroid Build Coastguard Worker }
181*4a64e381SAndroid Build Coastguard Worker addresses.push_back(address);
182*4a64e381SAndroid Build Coastguard Worker }
183*4a64e381SAndroid Build Coastguard Worker
184*4a64e381SAndroid Build Coastguard Worker return addresses;
185*4a64e381SAndroid Build Coastguard Worker }
186*4a64e381SAndroid Build Coastguard Worker
HandleMdnsState(Mdns::Publisher::State aState)187*4a64e381SAndroid Build Coastguard Worker void AdvertisingProxy::HandleMdnsState(Mdns::Publisher::State aState)
188*4a64e381SAndroid Build Coastguard Worker {
189*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(IsEnabled());
190*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aState == Mdns::Publisher::State::kReady);
191*4a64e381SAndroid Build Coastguard Worker
192*4a64e381SAndroid Build Coastguard Worker PublishAllHostsAndServices();
193*4a64e381SAndroid Build Coastguard Worker
194*4a64e381SAndroid Build Coastguard Worker exit:
195*4a64e381SAndroid Build Coastguard Worker return;
196*4a64e381SAndroid Build Coastguard Worker }
197*4a64e381SAndroid Build Coastguard Worker
PublishAllHostsAndServices(void)198*4a64e381SAndroid Build Coastguard Worker void AdvertisingProxy::PublishAllHostsAndServices(void)
199*4a64e381SAndroid Build Coastguard Worker {
200*4a64e381SAndroid Build Coastguard Worker const otSrpServerHost *host = nullptr;
201*4a64e381SAndroid Build Coastguard Worker
202*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(IsEnabled());
203*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(mPublisher.IsStarted());
204*4a64e381SAndroid Build Coastguard Worker
205*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Publish all hosts and services");
206*4a64e381SAndroid Build Coastguard Worker while ((host = otSrpServerGetNextHost(GetInstance(), host)))
207*4a64e381SAndroid Build Coastguard Worker {
208*4a64e381SAndroid Build Coastguard Worker PublishHostAndItsServices(host, nullptr);
209*4a64e381SAndroid Build Coastguard Worker }
210*4a64e381SAndroid Build Coastguard Worker
211*4a64e381SAndroid Build Coastguard Worker exit:
212*4a64e381SAndroid Build Coastguard Worker return;
213*4a64e381SAndroid Build Coastguard Worker }
214*4a64e381SAndroid Build Coastguard Worker
PublishHostAndItsServices(const otSrpServerHost * aHost,OutstandingUpdate * aUpdate)215*4a64e381SAndroid Build Coastguard Worker otbrError AdvertisingProxy::PublishHostAndItsServices(const otSrpServerHost *aHost, OutstandingUpdate *aUpdate)
216*4a64e381SAndroid Build Coastguard Worker {
217*4a64e381SAndroid Build Coastguard Worker otbrError error = OTBR_ERROR_NONE;
218*4a64e381SAndroid Build Coastguard Worker std::string hostName;
219*4a64e381SAndroid Build Coastguard Worker std::string hostDomain;
220*4a64e381SAndroid Build Coastguard Worker const otIp6Address *hostAddresses;
221*4a64e381SAndroid Build Coastguard Worker uint8_t hostAddressNum;
222*4a64e381SAndroid Build Coastguard Worker bool hostDeleted;
223*4a64e381SAndroid Build Coastguard Worker const otSrpServerService *service;
224*4a64e381SAndroid Build Coastguard Worker otSrpServerServiceUpdateId updateId = 0;
225*4a64e381SAndroid Build Coastguard Worker bool hasUpdate = false;
226*4a64e381SAndroid Build Coastguard Worker std::string fullHostName = otSrpServerHostGetFullName(aHost);
227*4a64e381SAndroid Build Coastguard Worker
228*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Advertise SRP service updates: host=%s", fullHostName.c_str());
229*4a64e381SAndroid Build Coastguard Worker
230*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = SplitFullHostName(fullHostName, hostName, hostDomain));
231*4a64e381SAndroid Build Coastguard Worker hostAddresses = otSrpServerHostGetAddresses(aHost, &hostAddressNum);
232*4a64e381SAndroid Build Coastguard Worker hostDeleted = otSrpServerHostIsDeleted(aHost);
233*4a64e381SAndroid Build Coastguard Worker
234*4a64e381SAndroid Build Coastguard Worker if (aUpdate)
235*4a64e381SAndroid Build Coastguard Worker {
236*4a64e381SAndroid Build Coastguard Worker hasUpdate = true;
237*4a64e381SAndroid Build Coastguard Worker updateId = aUpdate->mId;
238*4a64e381SAndroid Build Coastguard Worker aUpdate->mCallbackCount++;
239*4a64e381SAndroid Build Coastguard Worker aUpdate->mHostName = hostName;
240*4a64e381SAndroid Build Coastguard Worker service = nullptr;
241*4a64e381SAndroid Build Coastguard Worker while ((service = otSrpServerHostGetNextService(aHost, service)) != nullptr)
242*4a64e381SAndroid Build Coastguard Worker {
243*4a64e381SAndroid Build Coastguard Worker aUpdate->mCallbackCount++;
244*4a64e381SAndroid Build Coastguard Worker }
245*4a64e381SAndroid Build Coastguard Worker }
246*4a64e381SAndroid Build Coastguard Worker
247*4a64e381SAndroid Build Coastguard Worker service = nullptr;
248*4a64e381SAndroid Build Coastguard Worker while ((service = otSrpServerHostGetNextService(aHost, service)) != nullptr)
249*4a64e381SAndroid Build Coastguard Worker {
250*4a64e381SAndroid Build Coastguard Worker std::string fullServiceName = otSrpServerServiceGetInstanceName(service);
251*4a64e381SAndroid Build Coastguard Worker std::string serviceName;
252*4a64e381SAndroid Build Coastguard Worker std::string serviceType;
253*4a64e381SAndroid Build Coastguard Worker std::string serviceDomain;
254*4a64e381SAndroid Build Coastguard Worker
255*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = SplitFullServiceInstanceName(fullServiceName, serviceName, serviceType, serviceDomain));
256*4a64e381SAndroid Build Coastguard Worker
257*4a64e381SAndroid Build Coastguard Worker if (!hostDeleted && !otSrpServerServiceIsDeleted(service))
258*4a64e381SAndroid Build Coastguard Worker {
259*4a64e381SAndroid Build Coastguard Worker Mdns::Publisher::TxtData txtData = MakeTxtData(service);
260*4a64e381SAndroid Build Coastguard Worker Mdns::Publisher::SubTypeList subTypeList = MakeSubTypeList(service);
261*4a64e381SAndroid Build Coastguard Worker
262*4a64e381SAndroid Build Coastguard Worker otbrLogDebug("Publish SRP service '%s'", fullServiceName.c_str());
263*4a64e381SAndroid Build Coastguard Worker mPublisher.PublishService(
264*4a64e381SAndroid Build Coastguard Worker hostName, serviceName, serviceType, subTypeList, otSrpServerServiceGetPort(service), txtData,
265*4a64e381SAndroid Build Coastguard Worker [this, hasUpdate, updateId, fullServiceName](otbrError aError) {
266*4a64e381SAndroid Build Coastguard Worker otbrLogResult(aError, "Handle publish SRP service '%s'", fullServiceName.c_str());
267*4a64e381SAndroid Build Coastguard Worker if (hasUpdate)
268*4a64e381SAndroid Build Coastguard Worker {
269*4a64e381SAndroid Build Coastguard Worker OnMdnsPublishResult(updateId, aError);
270*4a64e381SAndroid Build Coastguard Worker }
271*4a64e381SAndroid Build Coastguard Worker });
272*4a64e381SAndroid Build Coastguard Worker }
273*4a64e381SAndroid Build Coastguard Worker else
274*4a64e381SAndroid Build Coastguard Worker {
275*4a64e381SAndroid Build Coastguard Worker otbrLogDebug("Unpublish SRP service '%s'", fullServiceName.c_str());
276*4a64e381SAndroid Build Coastguard Worker mPublisher.UnpublishService(
277*4a64e381SAndroid Build Coastguard Worker serviceName, serviceType, [this, hasUpdate, updateId, fullServiceName](otbrError aError) {
278*4a64e381SAndroid Build Coastguard Worker // Treat `NOT_FOUND` as success when unpublishing service
279*4a64e381SAndroid Build Coastguard Worker aError = (aError == OTBR_ERROR_NOT_FOUND) ? OTBR_ERROR_NONE : aError;
280*4a64e381SAndroid Build Coastguard Worker otbrLogResult(aError, "Handle unpublish SRP service '%s'", fullServiceName.c_str());
281*4a64e381SAndroid Build Coastguard Worker if (hasUpdate)
282*4a64e381SAndroid Build Coastguard Worker {
283*4a64e381SAndroid Build Coastguard Worker OnMdnsPublishResult(updateId, aError);
284*4a64e381SAndroid Build Coastguard Worker }
285*4a64e381SAndroid Build Coastguard Worker });
286*4a64e381SAndroid Build Coastguard Worker }
287*4a64e381SAndroid Build Coastguard Worker }
288*4a64e381SAndroid Build Coastguard Worker
289*4a64e381SAndroid Build Coastguard Worker if (!hostDeleted)
290*4a64e381SAndroid Build Coastguard Worker {
291*4a64e381SAndroid Build Coastguard Worker std::vector<Ip6Address> addresses;
292*4a64e381SAndroid Build Coastguard Worker
293*4a64e381SAndroid Build Coastguard Worker // TODO: select a preferred address or advertise all addresses from SRP client.
294*4a64e381SAndroid Build Coastguard Worker otbrLogDebug("Publish SRP host '%s'", fullHostName.c_str());
295*4a64e381SAndroid Build Coastguard Worker
296*4a64e381SAndroid Build Coastguard Worker addresses = GetEligibleAddresses(hostAddresses, hostAddressNum);
297*4a64e381SAndroid Build Coastguard Worker mPublisher.PublishHost(
298*4a64e381SAndroid Build Coastguard Worker hostName, addresses,
299*4a64e381SAndroid Build Coastguard Worker Mdns::Publisher::ResultCallback([this, hasUpdate, updateId, fullHostName](otbrError aError) {
300*4a64e381SAndroid Build Coastguard Worker otbrLogResult(aError, "Handle publish SRP host '%s'", fullHostName.c_str());
301*4a64e381SAndroid Build Coastguard Worker if (hasUpdate)
302*4a64e381SAndroid Build Coastguard Worker {
303*4a64e381SAndroid Build Coastguard Worker OnMdnsPublishResult(updateId, aError);
304*4a64e381SAndroid Build Coastguard Worker }
305*4a64e381SAndroid Build Coastguard Worker }));
306*4a64e381SAndroid Build Coastguard Worker }
307*4a64e381SAndroid Build Coastguard Worker else
308*4a64e381SAndroid Build Coastguard Worker {
309*4a64e381SAndroid Build Coastguard Worker otbrLogDebug("Unpublish SRP host '%s'", fullHostName.c_str());
310*4a64e381SAndroid Build Coastguard Worker mPublisher.UnpublishHost(hostName, [this, hasUpdate, updateId, fullHostName](otbrError aError) {
311*4a64e381SAndroid Build Coastguard Worker // Treat `NOT_FOUND` as success when unpublishing host.
312*4a64e381SAndroid Build Coastguard Worker aError = (aError == OTBR_ERROR_NOT_FOUND) ? OTBR_ERROR_NONE : aError;
313*4a64e381SAndroid Build Coastguard Worker otbrLogResult(aError, "Handle unpublish SRP host '%s'", fullHostName.c_str());
314*4a64e381SAndroid Build Coastguard Worker if (hasUpdate)
315*4a64e381SAndroid Build Coastguard Worker {
316*4a64e381SAndroid Build Coastguard Worker OnMdnsPublishResult(updateId, aError);
317*4a64e381SAndroid Build Coastguard Worker }
318*4a64e381SAndroid Build Coastguard Worker });
319*4a64e381SAndroid Build Coastguard Worker }
320*4a64e381SAndroid Build Coastguard Worker
321*4a64e381SAndroid Build Coastguard Worker exit:
322*4a64e381SAndroid Build Coastguard Worker if (error != OTBR_ERROR_NONE)
323*4a64e381SAndroid Build Coastguard Worker {
324*4a64e381SAndroid Build Coastguard Worker if (hasUpdate)
325*4a64e381SAndroid Build Coastguard Worker {
326*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Failed to advertise SRP service updates (id = %u)", updateId);
327*4a64e381SAndroid Build Coastguard Worker }
328*4a64e381SAndroid Build Coastguard Worker }
329*4a64e381SAndroid Build Coastguard Worker return error;
330*4a64e381SAndroid Build Coastguard Worker }
331*4a64e381SAndroid Build Coastguard Worker
MakeTxtData(const otSrpServerService * aSrpService)332*4a64e381SAndroid Build Coastguard Worker Mdns::Publisher::TxtData AdvertisingProxy::MakeTxtData(const otSrpServerService *aSrpService)
333*4a64e381SAndroid Build Coastguard Worker {
334*4a64e381SAndroid Build Coastguard Worker const uint8_t *data;
335*4a64e381SAndroid Build Coastguard Worker uint16_t length = 0;
336*4a64e381SAndroid Build Coastguard Worker
337*4a64e381SAndroid Build Coastguard Worker data = otSrpServerServiceGetTxtData(aSrpService, &length);
338*4a64e381SAndroid Build Coastguard Worker
339*4a64e381SAndroid Build Coastguard Worker return Mdns::Publisher::TxtData(data, data + length);
340*4a64e381SAndroid Build Coastguard Worker }
341*4a64e381SAndroid Build Coastguard Worker
MakeSubTypeList(const otSrpServerService * aSrpService)342*4a64e381SAndroid Build Coastguard Worker Mdns::Publisher::SubTypeList AdvertisingProxy::MakeSubTypeList(const otSrpServerService *aSrpService)
343*4a64e381SAndroid Build Coastguard Worker {
344*4a64e381SAndroid Build Coastguard Worker Mdns::Publisher::SubTypeList subTypeList;
345*4a64e381SAndroid Build Coastguard Worker
346*4a64e381SAndroid Build Coastguard Worker for (uint16_t index = 0;; index++)
347*4a64e381SAndroid Build Coastguard Worker {
348*4a64e381SAndroid Build Coastguard Worker const char *subTypeName = otSrpServerServiceGetSubTypeServiceNameAt(aSrpService, index);
349*4a64e381SAndroid Build Coastguard Worker char subLabel[OT_DNS_MAX_LABEL_SIZE];
350*4a64e381SAndroid Build Coastguard Worker
351*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(subTypeName != nullptr);
352*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(otSrpServerParseSubTypeServiceName(subTypeName, subLabel, sizeof(subLabel)));
353*4a64e381SAndroid Build Coastguard Worker subTypeList.emplace_back(subLabel);
354*4a64e381SAndroid Build Coastguard Worker }
355*4a64e381SAndroid Build Coastguard Worker
356*4a64e381SAndroid Build Coastguard Worker exit:
357*4a64e381SAndroid Build Coastguard Worker return subTypeList;
358*4a64e381SAndroid Build Coastguard Worker }
359*4a64e381SAndroid Build Coastguard Worker
360*4a64e381SAndroid Build Coastguard Worker } // namespace otbr
361*4a64e381SAndroid Build Coastguard Worker
362*4a64e381SAndroid Build Coastguard Worker #endif // OTBR_ENABLE_SRP_ADVERTISING_PROXY
363