xref: /aosp_15_r20/external/ot-br-posix/src/mdns/mdns.hpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
1*4a64e381SAndroid Build Coastguard Worker /*
2*4a64e381SAndroid Build Coastguard Worker  *    Copyright (c) 2017, The OpenThread Authors.
3*4a64e381SAndroid Build Coastguard Worker  *    All rights reserved.
4*4a64e381SAndroid Build Coastguard Worker  *
5*4a64e381SAndroid Build Coastguard Worker  *    Redistribution and use in source and binary forms, with or without
6*4a64e381SAndroid Build Coastguard Worker  *    modification, are permitted provided that the following conditions are met:
7*4a64e381SAndroid Build Coastguard Worker  *    1. Redistributions of source code must retain the above copyright
8*4a64e381SAndroid Build Coastguard Worker  *       notice, this list of conditions and the following disclaimer.
9*4a64e381SAndroid Build Coastguard Worker  *    2. Redistributions in binary form must reproduce the above copyright
10*4a64e381SAndroid Build Coastguard Worker  *       notice, this list of conditions and the following disclaimer in the
11*4a64e381SAndroid Build Coastguard Worker  *       documentation and/or other materials provided with the distribution.
12*4a64e381SAndroid Build Coastguard Worker  *    3. Neither the name of the copyright holder nor the
13*4a64e381SAndroid Build Coastguard Worker  *       names of its contributors may be used to endorse or promote products
14*4a64e381SAndroid Build Coastguard Worker  *       derived from this software without specific prior written permission.
15*4a64e381SAndroid Build Coastguard Worker  *
16*4a64e381SAndroid Build Coastguard Worker  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*4a64e381SAndroid Build Coastguard Worker  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*4a64e381SAndroid Build Coastguard Worker  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*4a64e381SAndroid Build Coastguard Worker  *    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*4a64e381SAndroid Build Coastguard Worker  *    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*4a64e381SAndroid Build Coastguard Worker  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*4a64e381SAndroid Build Coastguard Worker  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*4a64e381SAndroid Build Coastguard Worker  *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*4a64e381SAndroid Build Coastguard Worker  *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*4a64e381SAndroid Build Coastguard Worker  *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*4a64e381SAndroid Build Coastguard Worker  *    POSSIBILITY OF SUCH DAMAGE.
27*4a64e381SAndroid Build Coastguard Worker  */
28*4a64e381SAndroid Build Coastguard Worker 
29*4a64e381SAndroid Build Coastguard Worker /**
30*4a64e381SAndroid Build Coastguard Worker  * @file
31*4a64e381SAndroid Build Coastguard Worker  *   This file includes definitions for mDNS publisher.
32*4a64e381SAndroid Build Coastguard Worker  */
33*4a64e381SAndroid Build Coastguard Worker 
34*4a64e381SAndroid Build Coastguard Worker #ifndef OTBR_AGENT_MDNS_HPP_
35*4a64e381SAndroid Build Coastguard Worker #define OTBR_AGENT_MDNS_HPP_
36*4a64e381SAndroid Build Coastguard Worker 
37*4a64e381SAndroid Build Coastguard Worker #include "openthread-br/config.h"
38*4a64e381SAndroid Build Coastguard Worker 
39*4a64e381SAndroid Build Coastguard Worker #ifndef OTBR_ENABLE_MDNS
40*4a64e381SAndroid Build Coastguard Worker #define OTBR_ENABLE_MDNS (OTBR_ENABLE_MDNS_AVAHI || OTBR_ENABLE_MDNS_MDNSSD)
41*4a64e381SAndroid Build Coastguard Worker #endif
42*4a64e381SAndroid Build Coastguard Worker 
43*4a64e381SAndroid Build Coastguard Worker #include <functional>
44*4a64e381SAndroid Build Coastguard Worker #include <list>
45*4a64e381SAndroid Build Coastguard Worker #include <map>
46*4a64e381SAndroid Build Coastguard Worker #include <memory>
47*4a64e381SAndroid Build Coastguard Worker #include <string>
48*4a64e381SAndroid Build Coastguard Worker #include <vector>
49*4a64e381SAndroid Build Coastguard Worker 
50*4a64e381SAndroid Build Coastguard Worker #include <sys/select.h>
51*4a64e381SAndroid Build Coastguard Worker 
52*4a64e381SAndroid Build Coastguard Worker #include "common/callback.hpp"
53*4a64e381SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
54*4a64e381SAndroid Build Coastguard Worker #include "common/time.hpp"
55*4a64e381SAndroid Build Coastguard Worker #include "common/types.hpp"
56*4a64e381SAndroid Build Coastguard Worker 
57*4a64e381SAndroid Build Coastguard Worker namespace otbr {
58*4a64e381SAndroid Build Coastguard Worker 
59*4a64e381SAndroid Build Coastguard Worker namespace Mdns {
60*4a64e381SAndroid Build Coastguard Worker 
61*4a64e381SAndroid Build Coastguard Worker /**
62*4a64e381SAndroid Build Coastguard Worker  * @addtogroup border-router-mdns
63*4a64e381SAndroid Build Coastguard Worker  *
64*4a64e381SAndroid Build Coastguard Worker  * @brief
65*4a64e381SAndroid Build Coastguard Worker  *   This module includes definition for mDNS publisher.
66*4a64e381SAndroid Build Coastguard Worker  *
67*4a64e381SAndroid Build Coastguard Worker  * @{
68*4a64e381SAndroid Build Coastguard Worker  */
69*4a64e381SAndroid Build Coastguard Worker 
70*4a64e381SAndroid Build Coastguard Worker /**
71*4a64e381SAndroid Build Coastguard Worker  * This interface defines the functionality of mDNS publisher.
72*4a64e381SAndroid Build Coastguard Worker  */
73*4a64e381SAndroid Build Coastguard Worker class Publisher : private NonCopyable
74*4a64e381SAndroid Build Coastguard Worker {
75*4a64e381SAndroid Build Coastguard Worker public:
76*4a64e381SAndroid Build Coastguard Worker     /**
77*4a64e381SAndroid Build Coastguard Worker      * This structure represents a key/value pair of the TXT record.
78*4a64e381SAndroid Build Coastguard Worker      */
79*4a64e381SAndroid Build Coastguard Worker     struct TxtEntry
80*4a64e381SAndroid Build Coastguard Worker     {
81*4a64e381SAndroid Build Coastguard Worker         std::string          mKey;                ///< The key of the TXT entry.
82*4a64e381SAndroid Build Coastguard Worker         std::vector<uint8_t> mValue;              ///< The value of the TXT entry. Can be empty.
83*4a64e381SAndroid Build Coastguard Worker         bool                 mIsBooleanAttribute; ///< This entry is boolean attribute (encoded as `key` without `=`).
84*4a64e381SAndroid Build Coastguard Worker 
TxtEntryotbr::Mdns::Publisher::TxtEntry85*4a64e381SAndroid Build Coastguard Worker         TxtEntry(const char *aKey, const char *aValue)
86*4a64e381SAndroid Build Coastguard Worker             : TxtEntry(aKey, reinterpret_cast<const uint8_t *>(aValue), strlen(aValue))
87*4a64e381SAndroid Build Coastguard Worker         {
88*4a64e381SAndroid Build Coastguard Worker         }
89*4a64e381SAndroid Build Coastguard Worker 
TxtEntryotbr::Mdns::Publisher::TxtEntry90*4a64e381SAndroid Build Coastguard Worker         TxtEntry(const char *aKey, const uint8_t *aValue, size_t aValueLength)
91*4a64e381SAndroid Build Coastguard Worker             : TxtEntry(aKey, strlen(aKey), aValue, aValueLength)
92*4a64e381SAndroid Build Coastguard Worker         {
93*4a64e381SAndroid Build Coastguard Worker         }
94*4a64e381SAndroid Build Coastguard Worker 
TxtEntryotbr::Mdns::Publisher::TxtEntry95*4a64e381SAndroid Build Coastguard Worker         TxtEntry(const char *aKey, size_t aKeyLength, const uint8_t *aValue, size_t aValueLength)
96*4a64e381SAndroid Build Coastguard Worker             : mKey(aKey, aKeyLength)
97*4a64e381SAndroid Build Coastguard Worker             , mValue(aValue, aValue + aValueLength)
98*4a64e381SAndroid Build Coastguard Worker             , mIsBooleanAttribute(false)
99*4a64e381SAndroid Build Coastguard Worker         {
100*4a64e381SAndroid Build Coastguard Worker         }
101*4a64e381SAndroid Build Coastguard Worker 
TxtEntryotbr::Mdns::Publisher::TxtEntry102*4a64e381SAndroid Build Coastguard Worker         TxtEntry(const char *aKey)
103*4a64e381SAndroid Build Coastguard Worker             : TxtEntry(aKey, strlen(aKey))
104*4a64e381SAndroid Build Coastguard Worker         {
105*4a64e381SAndroid Build Coastguard Worker         }
106*4a64e381SAndroid Build Coastguard Worker 
TxtEntryotbr::Mdns::Publisher::TxtEntry107*4a64e381SAndroid Build Coastguard Worker         TxtEntry(const char *aKey, size_t aKeyLength)
108*4a64e381SAndroid Build Coastguard Worker             : mKey(aKey, aKeyLength)
109*4a64e381SAndroid Build Coastguard Worker             , mIsBooleanAttribute(true)
110*4a64e381SAndroid Build Coastguard Worker         {
111*4a64e381SAndroid Build Coastguard Worker         }
112*4a64e381SAndroid Build Coastguard Worker 
operator ==otbr::Mdns::Publisher::TxtEntry113*4a64e381SAndroid Build Coastguard Worker         bool operator==(const TxtEntry &aOther) const
114*4a64e381SAndroid Build Coastguard Worker         {
115*4a64e381SAndroid Build Coastguard Worker             return (mKey == aOther.mKey) && (mValue == aOther.mValue) &&
116*4a64e381SAndroid Build Coastguard Worker                    (mIsBooleanAttribute == aOther.mIsBooleanAttribute);
117*4a64e381SAndroid Build Coastguard Worker         }
118*4a64e381SAndroid Build Coastguard Worker     };
119*4a64e381SAndroid Build Coastguard Worker 
120*4a64e381SAndroid Build Coastguard Worker     typedef std::vector<uint8_t>     TxtData;
121*4a64e381SAndroid Build Coastguard Worker     typedef std::vector<TxtEntry>    TxtList;
122*4a64e381SAndroid Build Coastguard Worker     typedef std::vector<std::string> SubTypeList;
123*4a64e381SAndroid Build Coastguard Worker     typedef std::vector<Ip6Address>  AddressList;
124*4a64e381SAndroid Build Coastguard Worker     typedef std::vector<uint8_t>     KeyData;
125*4a64e381SAndroid Build Coastguard Worker 
126*4a64e381SAndroid Build Coastguard Worker     /**
127*4a64e381SAndroid Build Coastguard Worker      * This structure represents information of a discovered service instance.
128*4a64e381SAndroid Build Coastguard Worker      */
129*4a64e381SAndroid Build Coastguard Worker     struct DiscoveredInstanceInfo
130*4a64e381SAndroid Build Coastguard Worker     {
131*4a64e381SAndroid Build Coastguard Worker         bool        mRemoved    = false; ///< The Service Instance is removed.
132*4a64e381SAndroid Build Coastguard Worker         uint32_t    mNetifIndex = 0;     ///< Network interface.
133*4a64e381SAndroid Build Coastguard Worker         std::string mName;               ///< Instance name.
134*4a64e381SAndroid Build Coastguard Worker         std::string mHostName;           ///< Full host name.
135*4a64e381SAndroid Build Coastguard Worker         AddressList mAddresses;          ///< IPv6 addresses.
136*4a64e381SAndroid Build Coastguard Worker         uint16_t    mPort     = 0;       ///< Port.
137*4a64e381SAndroid Build Coastguard Worker         uint16_t    mPriority = 0;       ///< Service priority.
138*4a64e381SAndroid Build Coastguard Worker         uint16_t    mWeight   = 0;       ///< Service weight.
139*4a64e381SAndroid Build Coastguard Worker         TxtData     mTxtData;            ///< TXT RDATA bytes.
140*4a64e381SAndroid Build Coastguard Worker         uint32_t    mTtl = 0;            ///< Service TTL.
141*4a64e381SAndroid Build Coastguard Worker 
AddAddressotbr::Mdns::Publisher::DiscoveredInstanceInfo142*4a64e381SAndroid Build Coastguard Worker         void AddAddress(const Ip6Address &aAddress) { Publisher::AddAddress(mAddresses, aAddress); }
RemoveAddressotbr::Mdns::Publisher::DiscoveredInstanceInfo143*4a64e381SAndroid Build Coastguard Worker         void RemoveAddress(const Ip6Address &aAddress) { Publisher::RemoveAddress(mAddresses, aAddress); }
144*4a64e381SAndroid Build Coastguard Worker     };
145*4a64e381SAndroid Build Coastguard Worker 
146*4a64e381SAndroid Build Coastguard Worker     /**
147*4a64e381SAndroid Build Coastguard Worker      * This structure represents information of a discovered host.
148*4a64e381SAndroid Build Coastguard Worker      */
149*4a64e381SAndroid Build Coastguard Worker     struct DiscoveredHostInfo
150*4a64e381SAndroid Build Coastguard Worker     {
151*4a64e381SAndroid Build Coastguard Worker         std::string mHostName;       ///< Full host name.
152*4a64e381SAndroid Build Coastguard Worker         AddressList mAddresses;      ///< IP6 addresses.
153*4a64e381SAndroid Build Coastguard Worker         uint32_t    mNetifIndex = 0; ///< Network interface.
154*4a64e381SAndroid Build Coastguard Worker         uint32_t    mTtl        = 0; ///< Host TTL.
155*4a64e381SAndroid Build Coastguard Worker 
AddAddressotbr::Mdns::Publisher::DiscoveredHostInfo156*4a64e381SAndroid Build Coastguard Worker         void AddAddress(const Ip6Address &aAddress) { Publisher::AddAddress(mAddresses, aAddress); }
RemoveAddressotbr::Mdns::Publisher::DiscoveredHostInfo157*4a64e381SAndroid Build Coastguard Worker         void RemoveAddress(const Ip6Address &aAddress) { Publisher::RemoveAddress(mAddresses, aAddress); }
158*4a64e381SAndroid Build Coastguard Worker     };
159*4a64e381SAndroid Build Coastguard Worker 
160*4a64e381SAndroid Build Coastguard Worker     /**
161*4a64e381SAndroid Build Coastguard Worker      * This function is called to notify a discovered service instance.
162*4a64e381SAndroid Build Coastguard Worker      */
163*4a64e381SAndroid Build Coastguard Worker     using DiscoveredServiceInstanceCallback =
164*4a64e381SAndroid Build Coastguard Worker         std::function<void(const std::string &aType, const DiscoveredInstanceInfo &aInstanceInfo)>;
165*4a64e381SAndroid Build Coastguard Worker 
166*4a64e381SAndroid Build Coastguard Worker     /**
167*4a64e381SAndroid Build Coastguard Worker      * This function is called to notify a discovered host.
168*4a64e381SAndroid Build Coastguard Worker      */
169*4a64e381SAndroid Build Coastguard Worker     using DiscoveredHostCallback =
170*4a64e381SAndroid Build Coastguard Worker         std::function<void(const std::string &aHostName, const DiscoveredHostInfo &aHostInfo)>;
171*4a64e381SAndroid Build Coastguard Worker 
172*4a64e381SAndroid Build Coastguard Worker     /**
173*4a64e381SAndroid Build Coastguard Worker      * mDNS state values.
174*4a64e381SAndroid Build Coastguard Worker      */
175*4a64e381SAndroid Build Coastguard Worker     enum class State
176*4a64e381SAndroid Build Coastguard Worker     {
177*4a64e381SAndroid Build Coastguard Worker         kIdle,  ///< Unable to publish service.
178*4a64e381SAndroid Build Coastguard Worker         kReady, ///< Ready to publish service.
179*4a64e381SAndroid Build Coastguard Worker     };
180*4a64e381SAndroid Build Coastguard Worker 
181*4a64e381SAndroid Build Coastguard Worker     /** The callback for receiving mDNS publisher state changes. */
182*4a64e381SAndroid Build Coastguard Worker     using StateCallback = std::function<void(State aNewState)>;
183*4a64e381SAndroid Build Coastguard Worker 
184*4a64e381SAndroid Build Coastguard Worker     /** The callback for receiving the result of a operation. */
185*4a64e381SAndroid Build Coastguard Worker     using ResultCallback = OnceCallback<void(otbrError aError)>;
186*4a64e381SAndroid Build Coastguard Worker 
187*4a64e381SAndroid Build Coastguard Worker     /**
188*4a64e381SAndroid Build Coastguard Worker      * This method starts the mDNS publisher.
189*4a64e381SAndroid Build Coastguard Worker      *
190*4a64e381SAndroid Build Coastguard Worker      * @retval OTBR_ERROR_NONE  Successfully started mDNS publisher;
191*4a64e381SAndroid Build Coastguard Worker      * @retval OTBR_ERROR_MDNS  Failed to start mDNS publisher.
192*4a64e381SAndroid Build Coastguard Worker      */
193*4a64e381SAndroid Build Coastguard Worker     virtual otbrError Start(void) = 0;
194*4a64e381SAndroid Build Coastguard Worker 
195*4a64e381SAndroid Build Coastguard Worker     /**
196*4a64e381SAndroid Build Coastguard Worker      * This method stops the mDNS publisher.
197*4a64e381SAndroid Build Coastguard Worker      */
198*4a64e381SAndroid Build Coastguard Worker     virtual void Stop(void) = 0;
199*4a64e381SAndroid Build Coastguard Worker 
200*4a64e381SAndroid Build Coastguard Worker     /**
201*4a64e381SAndroid Build Coastguard Worker      * This method checks if publisher has been started.
202*4a64e381SAndroid Build Coastguard Worker      *
203*4a64e381SAndroid Build Coastguard Worker      * @retval true   Already started.
204*4a64e381SAndroid Build Coastguard Worker      * @retval false  Not started.
205*4a64e381SAndroid Build Coastguard Worker      */
206*4a64e381SAndroid Build Coastguard Worker     virtual bool IsStarted(void) const = 0;
207*4a64e381SAndroid Build Coastguard Worker 
208*4a64e381SAndroid Build Coastguard Worker     /**
209*4a64e381SAndroid Build Coastguard Worker      * This method publishes or updates a service.
210*4a64e381SAndroid Build Coastguard Worker      *
211*4a64e381SAndroid Build Coastguard Worker      * @param[in] aHostName     The name of the host which this service resides on. If an empty string is
212*4a64e381SAndroid Build Coastguard Worker      *                          provided, this service resides on local host and it is the implementation
213*4a64e381SAndroid Build Coastguard Worker      *                          to provide specific host name. Otherwise, the caller MUST publish the host
214*4a64e381SAndroid Build Coastguard Worker      *                          with method PublishHost.
215*4a64e381SAndroid Build Coastguard Worker      * @param[in] aName         The name of this service. If an empty string is provided, the service's name will be the
216*4a64e381SAndroid Build Coastguard Worker      *                          same as the platform's hostname.
217*4a64e381SAndroid Build Coastguard Worker      * @param[in] aType         The type of this service, e.g., "_srv._udp" (MUST NOT end with dot).
218*4a64e381SAndroid Build Coastguard Worker      * @param[in] aSubTypeList  A list of service subtypes.
219*4a64e381SAndroid Build Coastguard Worker      * @param[in] aPort         The port number of this service.
220*4a64e381SAndroid Build Coastguard Worker      * @param[in] aTxtData      The encoded TXT data for this service.
221*4a64e381SAndroid Build Coastguard Worker      * @param[in] aCallback     The callback for receiving the publishing result. `OTBR_ERROR_NONE` will be
222*4a64e381SAndroid Build Coastguard Worker      *                          returned if the operation is successful and all other values indicate a
223*4a64e381SAndroid Build Coastguard Worker      *                          failure. Specifically, `OTBR_ERROR_DUPLICATED` indicates that the name has
224*4a64e381SAndroid Build Coastguard Worker      *                          already been published and the caller can re-publish with a new name if an
225*4a64e381SAndroid Build Coastguard Worker      *                          alternative name is available/acceptable.
226*4a64e381SAndroid Build Coastguard Worker      */
227*4a64e381SAndroid Build Coastguard Worker     void PublishService(const std::string &aHostName,
228*4a64e381SAndroid Build Coastguard Worker                         const std::string &aName,
229*4a64e381SAndroid Build Coastguard Worker                         const std::string &aType,
230*4a64e381SAndroid Build Coastguard Worker                         const SubTypeList &aSubTypeList,
231*4a64e381SAndroid Build Coastguard Worker                         uint16_t           aPort,
232*4a64e381SAndroid Build Coastguard Worker                         const TxtData     &aTxtData,
233*4a64e381SAndroid Build Coastguard Worker                         ResultCallback   &&aCallback);
234*4a64e381SAndroid Build Coastguard Worker 
235*4a64e381SAndroid Build Coastguard Worker     /**
236*4a64e381SAndroid Build Coastguard Worker      * This method un-publishes a service.
237*4a64e381SAndroid Build Coastguard Worker      *
238*4a64e381SAndroid Build Coastguard Worker      * @param[in] aName      The name of this service.
239*4a64e381SAndroid Build Coastguard Worker      * @param[in] aType      The type of this service, e.g., "_srv._udp" (MUST NOT end with dot).
240*4a64e381SAndroid Build Coastguard Worker      * @param[in] aCallback  The callback for receiving the publishing result.
241*4a64e381SAndroid Build Coastguard Worker      */
242*4a64e381SAndroid Build Coastguard Worker     virtual void UnpublishService(const std::string &aName, const std::string &aType, ResultCallback &&aCallback) = 0;
243*4a64e381SAndroid Build Coastguard Worker 
244*4a64e381SAndroid Build Coastguard Worker     /**
245*4a64e381SAndroid Build Coastguard Worker      * This method publishes or updates a host.
246*4a64e381SAndroid Build Coastguard Worker      *
247*4a64e381SAndroid Build Coastguard Worker      * Publishing a host is advertising an AAAA RR for the host name. This method should be called
248*4a64e381SAndroid Build Coastguard Worker      * before a service with non-empty host name is published.
249*4a64e381SAndroid Build Coastguard Worker      *
250*4a64e381SAndroid Build Coastguard Worker      * @param[in] aName       The name of the host.
251*4a64e381SAndroid Build Coastguard Worker      * @param[in] aAddresses  The addresses of the host.
252*4a64e381SAndroid Build Coastguard Worker      * @param[in] aCallback   The callback for receiving the publishing result.`OTBR_ERROR_NONE` will be
253*4a64e381SAndroid Build Coastguard Worker      *                        returned if the operation is successful and all other values indicate a
254*4a64e381SAndroid Build Coastguard Worker      *                        failure. Specifically, `OTBR_ERROR_DUPLICATED` indicates that the name has
255*4a64e381SAndroid Build Coastguard Worker      *                        already been published and the caller can re-publish with a new name if an
256*4a64e381SAndroid Build Coastguard Worker      *                        alternative name is available/acceptable.
257*4a64e381SAndroid Build Coastguard Worker      */
258*4a64e381SAndroid Build Coastguard Worker     void PublishHost(const std::string &aName, const AddressList &aAddresses, ResultCallback &&aCallback);
259*4a64e381SAndroid Build Coastguard Worker 
260*4a64e381SAndroid Build Coastguard Worker     /**
261*4a64e381SAndroid Build Coastguard Worker      * This method un-publishes a host.
262*4a64e381SAndroid Build Coastguard Worker      *
263*4a64e381SAndroid Build Coastguard Worker      * @param[in] aName      A host name (MUST not end with dot).
264*4a64e381SAndroid Build Coastguard Worker      * @param[in] aCallback  The callback for receiving the publishing result.
265*4a64e381SAndroid Build Coastguard Worker      */
266*4a64e381SAndroid Build Coastguard Worker     virtual void UnpublishHost(const std::string &aName, ResultCallback &&aCallback) = 0;
267*4a64e381SAndroid Build Coastguard Worker 
268*4a64e381SAndroid Build Coastguard Worker     /**
269*4a64e381SAndroid Build Coastguard Worker      * This method publishes or updates a key record for a name.
270*4a64e381SAndroid Build Coastguard Worker      *
271*4a64e381SAndroid Build Coastguard Worker      * @param[in] aName       The name associated with key record (can be host name or service instance name).
272*4a64e381SAndroid Build Coastguard Worker      * @param[in] aKeyData    The key data to publish.
273*4a64e381SAndroid Build Coastguard Worker      * @param[in] aCallback   The callback for receiving the publishing result.`OTBR_ERROR_NONE` will be
274*4a64e381SAndroid Build Coastguard Worker      *                        returned if the operation is successful and all other values indicate a
275*4a64e381SAndroid Build Coastguard Worker      *                        failure. Specifically, `OTBR_ERROR_DUPLICATED` indicates that the name has
276*4a64e381SAndroid Build Coastguard Worker      *                        already been published and the caller can re-publish with a new name if an
277*4a64e381SAndroid Build Coastguard Worker      *                        alternative name is available/acceptable.
278*4a64e381SAndroid Build Coastguard Worker      */
279*4a64e381SAndroid Build Coastguard Worker     void PublishKey(const std::string &aName, const KeyData &aKeyData, ResultCallback &&aCallback);
280*4a64e381SAndroid Build Coastguard Worker 
281*4a64e381SAndroid Build Coastguard Worker     /**
282*4a64e381SAndroid Build Coastguard Worker      * This method un-publishes a key record
283*4a64e381SAndroid Build Coastguard Worker      *
284*4a64e381SAndroid Build Coastguard Worker      * @param[in] aName      The name associated with key record.
285*4a64e381SAndroid Build Coastguard Worker      * @param[in] aCallback  The callback for receiving the publishing result.
286*4a64e381SAndroid Build Coastguard Worker      */
287*4a64e381SAndroid Build Coastguard Worker     virtual void UnpublishKey(const std::string &aName, ResultCallback &&aCallback) = 0;
288*4a64e381SAndroid Build Coastguard Worker 
289*4a64e381SAndroid Build Coastguard Worker     /**
290*4a64e381SAndroid Build Coastguard Worker      * This method subscribes a given service or service instance.
291*4a64e381SAndroid Build Coastguard Worker      *
292*4a64e381SAndroid Build Coastguard Worker      * If @p aInstanceName is not empty, this method subscribes the service instance. Otherwise, this method subscribes
293*4a64e381SAndroid Build Coastguard Worker      * the service. mDNS implementations should use the `DiscoveredServiceInstanceCallback` function to notify
294*4a64e381SAndroid Build Coastguard Worker      * discovered service instances.
295*4a64e381SAndroid Build Coastguard Worker      *
296*4a64e381SAndroid Build Coastguard Worker      * @note Discovery Proxy implementation guarantees no duplicate subscriptions for the same service or service
297*4a64e381SAndroid Build Coastguard Worker      * instance.
298*4a64e381SAndroid Build Coastguard Worker      *
299*4a64e381SAndroid Build Coastguard Worker      * @param[in] aType          The service type, e.g., "_srv._udp" (MUST NOT end with dot).
300*4a64e381SAndroid Build Coastguard Worker      * @param[in] aInstanceName  The service instance to subscribe, or empty to subscribe the service.
301*4a64e381SAndroid Build Coastguard Worker      */
302*4a64e381SAndroid Build Coastguard Worker     virtual void SubscribeService(const std::string &aType, const std::string &aInstanceName) = 0;
303*4a64e381SAndroid Build Coastguard Worker 
304*4a64e381SAndroid Build Coastguard Worker     /**
305*4a64e381SAndroid Build Coastguard Worker      * This method unsubscribes a given service or service instance.
306*4a64e381SAndroid Build Coastguard Worker      *
307*4a64e381SAndroid Build Coastguard Worker      * If @p aInstanceName is not empty, this method unsubscribes the service instance. Otherwise, this method
308*4a64e381SAndroid Build Coastguard Worker      * unsubscribes the service.
309*4a64e381SAndroid Build Coastguard Worker      *
310*4a64e381SAndroid Build Coastguard Worker      * @note Discovery Proxy implementation guarantees no redundant unsubscription for a service or service instance.
311*4a64e381SAndroid Build Coastguard Worker      *
312*4a64e381SAndroid Build Coastguard Worker      * @param[in] aType          The service type, e.g., "_srv._udp" (MUST NOT end with dot).
313*4a64e381SAndroid Build Coastguard Worker      * @param[in] aInstanceName  The service instance to unsubscribe, or empty to unsubscribe the service.
314*4a64e381SAndroid Build Coastguard Worker      */
315*4a64e381SAndroid Build Coastguard Worker     virtual void UnsubscribeService(const std::string &aType, const std::string &aInstanceName) = 0;
316*4a64e381SAndroid Build Coastguard Worker 
317*4a64e381SAndroid Build Coastguard Worker     /**
318*4a64e381SAndroid Build Coastguard Worker      * This method subscribes a given host.
319*4a64e381SAndroid Build Coastguard Worker      *
320*4a64e381SAndroid Build Coastguard Worker      * mDNS implementations should use the `DiscoveredHostCallback` function to notify discovered hosts.
321*4a64e381SAndroid Build Coastguard Worker      *
322*4a64e381SAndroid Build Coastguard Worker      * @note Discovery Proxy implementation guarantees no duplicate subscriptions for the same host.
323*4a64e381SAndroid Build Coastguard Worker      *
324*4a64e381SAndroid Build Coastguard Worker      * @param[in] aHostName  The host name (without domain).
325*4a64e381SAndroid Build Coastguard Worker      */
326*4a64e381SAndroid Build Coastguard Worker     virtual void SubscribeHost(const std::string &aHostName) = 0;
327*4a64e381SAndroid Build Coastguard Worker 
328*4a64e381SAndroid Build Coastguard Worker     /**
329*4a64e381SAndroid Build Coastguard Worker      * This method unsubscribes a given host.
330*4a64e381SAndroid Build Coastguard Worker      *
331*4a64e381SAndroid Build Coastguard Worker      * @note Discovery Proxy implementation guarantees no redundant unsubscription for a host.
332*4a64e381SAndroid Build Coastguard Worker      *
333*4a64e381SAndroid Build Coastguard Worker      * @param[in] aHostName  The host name (without domain).
334*4a64e381SAndroid Build Coastguard Worker      */
335*4a64e381SAndroid Build Coastguard Worker     virtual void UnsubscribeHost(const std::string &aHostName) = 0;
336*4a64e381SAndroid Build Coastguard Worker 
337*4a64e381SAndroid Build Coastguard Worker     /**
338*4a64e381SAndroid Build Coastguard Worker      * This method sets the callbacks for subscriptions.
339*4a64e381SAndroid Build Coastguard Worker      *
340*4a64e381SAndroid Build Coastguard Worker      * @param[in] aInstanceCallback  The callback function to receive discovered service instances.
341*4a64e381SAndroid Build Coastguard Worker      * @param[in] aHostCallback      The callback function to receive discovered hosts.
342*4a64e381SAndroid Build Coastguard Worker      *
343*4a64e381SAndroid Build Coastguard Worker      * @returns  The Subscriber ID for the callbacks.
344*4a64e381SAndroid Build Coastguard Worker      */
345*4a64e381SAndroid Build Coastguard Worker     uint64_t AddSubscriptionCallbacks(DiscoveredServiceInstanceCallback aInstanceCallback,
346*4a64e381SAndroid Build Coastguard Worker                                       DiscoveredHostCallback            aHostCallback);
347*4a64e381SAndroid Build Coastguard Worker 
348*4a64e381SAndroid Build Coastguard Worker     /**
349*4a64e381SAndroid Build Coastguard Worker      * This method cancels callbacks for subscriptions.
350*4a64e381SAndroid Build Coastguard Worker      *
351*4a64e381SAndroid Build Coastguard Worker      * @param[in] aSubscriberId  The Subscriber ID previously returned by `AddSubscriptionCallbacks`.
352*4a64e381SAndroid Build Coastguard Worker      */
353*4a64e381SAndroid Build Coastguard Worker     void RemoveSubscriptionCallbacks(uint64_t aSubscriberId);
354*4a64e381SAndroid Build Coastguard Worker 
355*4a64e381SAndroid Build Coastguard Worker     /**
356*4a64e381SAndroid Build Coastguard Worker      * This method returns the mDNS statistics information of the publisher.
357*4a64e381SAndroid Build Coastguard Worker      *
358*4a64e381SAndroid Build Coastguard Worker      * @returns  The MdnsTelemetryInfo of the publisher.
359*4a64e381SAndroid Build Coastguard Worker      */
GetMdnsTelemetryInfo(void) const360*4a64e381SAndroid Build Coastguard Worker     const MdnsTelemetryInfo &GetMdnsTelemetryInfo(void) const { return mTelemetryInfo; }
361*4a64e381SAndroid Build Coastguard Worker 
362*4a64e381SAndroid Build Coastguard Worker     virtual ~Publisher(void) = default;
363*4a64e381SAndroid Build Coastguard Worker 
364*4a64e381SAndroid Build Coastguard Worker     /**
365*4a64e381SAndroid Build Coastguard Worker      * This function creates a mDNS publisher.
366*4a64e381SAndroid Build Coastguard Worker      *
367*4a64e381SAndroid Build Coastguard Worker      * @param[in] aCallback  The callback for receiving mDNS publisher state changes.
368*4a64e381SAndroid Build Coastguard Worker      *
369*4a64e381SAndroid Build Coastguard Worker      * @returns A pointer to the newly created mDNS publisher.
370*4a64e381SAndroid Build Coastguard Worker      */
371*4a64e381SAndroid Build Coastguard Worker     static Publisher *Create(StateCallback aCallback);
372*4a64e381SAndroid Build Coastguard Worker 
373*4a64e381SAndroid Build Coastguard Worker     /**
374*4a64e381SAndroid Build Coastguard Worker      * This function destroys the mDNS publisher.
375*4a64e381SAndroid Build Coastguard Worker      *
376*4a64e381SAndroid Build Coastguard Worker      * @param[in] aPublisher  A pointer to the publisher.
377*4a64e381SAndroid Build Coastguard Worker      */
378*4a64e381SAndroid Build Coastguard Worker     static void Destroy(Publisher *aPublisher);
379*4a64e381SAndroid Build Coastguard Worker 
380*4a64e381SAndroid Build Coastguard Worker     /**
381*4a64e381SAndroid Build Coastguard Worker      * This function writes the TXT entry list to a TXT data buffer. The TXT entries
382*4a64e381SAndroid Build Coastguard Worker      * will be sorted by their keys.
383*4a64e381SAndroid Build Coastguard Worker      *
384*4a64e381SAndroid Build Coastguard Worker      * The output data is in standard DNS-SD TXT data format.
385*4a64e381SAndroid Build Coastguard Worker      * See RFC 6763 for details: https://tools.ietf.org/html/rfc6763#section-6.
386*4a64e381SAndroid Build Coastguard Worker      *
387*4a64e381SAndroid Build Coastguard Worker      * @param[in]  aTxtList  A TXT entry list.
388*4a64e381SAndroid Build Coastguard Worker      * @param[out] aTxtData  A TXT data buffer. Will be cleared.
389*4a64e381SAndroid Build Coastguard Worker      *
390*4a64e381SAndroid Build Coastguard Worker      * @retval OTBR_ERROR_NONE          Successfully write the TXT entry list.
391*4a64e381SAndroid Build Coastguard Worker      * @retval OTBR_ERROR_INVALID_ARGS  The @p aTxtList includes invalid TXT entry.
392*4a64e381SAndroid Build Coastguard Worker      *
393*4a64e381SAndroid Build Coastguard Worker      * @sa DecodeTxtData
394*4a64e381SAndroid Build Coastguard Worker      */
395*4a64e381SAndroid Build Coastguard Worker     static otbrError EncodeTxtData(const TxtList &aTxtList, TxtData &aTxtData);
396*4a64e381SAndroid Build Coastguard Worker 
397*4a64e381SAndroid Build Coastguard Worker     /**
398*4a64e381SAndroid Build Coastguard Worker      * This function decodes a TXT entry list from a TXT data buffer.
399*4a64e381SAndroid Build Coastguard Worker      *
400*4a64e381SAndroid Build Coastguard Worker      * The input data should be in standard DNS-SD TXT data format.
401*4a64e381SAndroid Build Coastguard Worker      * See RFC 6763 for details: https://tools.ietf.org/html/rfc6763#section-6.
402*4a64e381SAndroid Build Coastguard Worker      *
403*4a64e381SAndroid Build Coastguard Worker      * @param[out]  aTxtList    A TXT entry list.
404*4a64e381SAndroid Build Coastguard Worker      * @param[in]   aTxtData    A pointer to TXT data.
405*4a64e381SAndroid Build Coastguard Worker      * @param[in]   aTxtLength  The TXT data length.
406*4a64e381SAndroid Build Coastguard Worker      *
407*4a64e381SAndroid Build Coastguard Worker      * @retval OTBR_ERROR_NONE          Successfully decoded the TXT data.
408*4a64e381SAndroid Build Coastguard Worker      * @retval OTBR_ERROR_INVALID_ARGS  The @p aTxtdata has invalid TXT format.
409*4a64e381SAndroid Build Coastguard Worker      *
410*4a64e381SAndroid Build Coastguard Worker      * @sa EncodeTxtData
411*4a64e381SAndroid Build Coastguard Worker      */
412*4a64e381SAndroid Build Coastguard Worker     static otbrError DecodeTxtData(TxtList &aTxtList, const uint8_t *aTxtData, uint16_t aTxtLength);
413*4a64e381SAndroid Build Coastguard Worker 
414*4a64e381SAndroid Build Coastguard Worker protected:
415*4a64e381SAndroid Build Coastguard Worker     static constexpr uint8_t kMaxTextEntrySize = 255;
416*4a64e381SAndroid Build Coastguard Worker 
417*4a64e381SAndroid Build Coastguard Worker     class Registration
418*4a64e381SAndroid Build Coastguard Worker     {
419*4a64e381SAndroid Build Coastguard Worker     public:
420*4a64e381SAndroid Build Coastguard Worker         ResultCallback mCallback;
421*4a64e381SAndroid Build Coastguard Worker         Publisher     *mPublisher;
422*4a64e381SAndroid Build Coastguard Worker 
Registration(ResultCallback && aCallback,Publisher * aPublisher)423*4a64e381SAndroid Build Coastguard Worker         Registration(ResultCallback &&aCallback, Publisher *aPublisher)
424*4a64e381SAndroid Build Coastguard Worker             : mCallback(std::move(aCallback))
425*4a64e381SAndroid Build Coastguard Worker             , mPublisher(aPublisher)
426*4a64e381SAndroid Build Coastguard Worker         {
427*4a64e381SAndroid Build Coastguard Worker         }
428*4a64e381SAndroid Build Coastguard Worker         virtual ~Registration(void);
429*4a64e381SAndroid Build Coastguard Worker 
430*4a64e381SAndroid Build Coastguard Worker         // Tells whether the service registration has been completed (typically by calling
431*4a64e381SAndroid Build Coastguard Worker         // `ServiceRegistration::Complete`).
IsCompleted() const432*4a64e381SAndroid Build Coastguard Worker         bool IsCompleted() const { return mCallback.IsNull(); }
433*4a64e381SAndroid Build Coastguard Worker 
434*4a64e381SAndroid Build Coastguard Worker     protected:
435*4a64e381SAndroid Build Coastguard Worker         // Completes the service registration with given result/error.
TriggerCompleteCallback(otbrError aError)436*4a64e381SAndroid Build Coastguard Worker         void TriggerCompleteCallback(otbrError aError)
437*4a64e381SAndroid Build Coastguard Worker         {
438*4a64e381SAndroid Build Coastguard Worker             if (!IsCompleted())
439*4a64e381SAndroid Build Coastguard Worker             {
440*4a64e381SAndroid Build Coastguard Worker                 std::move(mCallback)(aError);
441*4a64e381SAndroid Build Coastguard Worker             }
442*4a64e381SAndroid Build Coastguard Worker         }
443*4a64e381SAndroid Build Coastguard Worker     };
444*4a64e381SAndroid Build Coastguard Worker 
445*4a64e381SAndroid Build Coastguard Worker     // TODO: We may need a registration ID to fetch the information of a registration.
446*4a64e381SAndroid Build Coastguard Worker     class ServiceRegistration : public Registration
447*4a64e381SAndroid Build Coastguard Worker     {
448*4a64e381SAndroid Build Coastguard Worker     public:
449*4a64e381SAndroid Build Coastguard Worker         std::string mHostName;
450*4a64e381SAndroid Build Coastguard Worker         std::string mName;
451*4a64e381SAndroid Build Coastguard Worker         std::string mType;
452*4a64e381SAndroid Build Coastguard Worker         SubTypeList mSubTypeList;
453*4a64e381SAndroid Build Coastguard Worker         uint16_t    mPort;
454*4a64e381SAndroid Build Coastguard Worker         TxtData     mTxtData;
455*4a64e381SAndroid Build Coastguard Worker 
ServiceRegistration(std::string aHostName,std::string aName,std::string aType,SubTypeList aSubTypeList,uint16_t aPort,TxtData aTxtData,ResultCallback && aCallback,Publisher * aPublisher)456*4a64e381SAndroid Build Coastguard Worker         ServiceRegistration(std::string      aHostName,
457*4a64e381SAndroid Build Coastguard Worker                             std::string      aName,
458*4a64e381SAndroid Build Coastguard Worker                             std::string      aType,
459*4a64e381SAndroid Build Coastguard Worker                             SubTypeList      aSubTypeList,
460*4a64e381SAndroid Build Coastguard Worker                             uint16_t         aPort,
461*4a64e381SAndroid Build Coastguard Worker                             TxtData          aTxtData,
462*4a64e381SAndroid Build Coastguard Worker                             ResultCallback &&aCallback,
463*4a64e381SAndroid Build Coastguard Worker                             Publisher       *aPublisher)
464*4a64e381SAndroid Build Coastguard Worker             : Registration(std::move(aCallback), aPublisher)
465*4a64e381SAndroid Build Coastguard Worker             , mHostName(std::move(aHostName))
466*4a64e381SAndroid Build Coastguard Worker             , mName(std::move(aName))
467*4a64e381SAndroid Build Coastguard Worker             , mType(std::move(aType))
468*4a64e381SAndroid Build Coastguard Worker             , mSubTypeList(SortSubTypeList(std::move(aSubTypeList)))
469*4a64e381SAndroid Build Coastguard Worker             , mPort(aPort)
470*4a64e381SAndroid Build Coastguard Worker             , mTxtData(std::move(aTxtData))
471*4a64e381SAndroid Build Coastguard Worker         {
472*4a64e381SAndroid Build Coastguard Worker         }
~ServiceRegistration(void)473*4a64e381SAndroid Build Coastguard Worker         ~ServiceRegistration(void) override { OnComplete(OTBR_ERROR_ABORTED); }
474*4a64e381SAndroid Build Coastguard Worker 
475*4a64e381SAndroid Build Coastguard Worker         void Complete(otbrError aError);
476*4a64e381SAndroid Build Coastguard Worker 
477*4a64e381SAndroid Build Coastguard Worker         // Tells whether this `ServiceRegistration` object is outdated comparing to the given parameters.
478*4a64e381SAndroid Build Coastguard Worker         bool IsOutdated(const std::string &aHostName,
479*4a64e381SAndroid Build Coastguard Worker                         const std::string &aName,
480*4a64e381SAndroid Build Coastguard Worker                         const std::string &aType,
481*4a64e381SAndroid Build Coastguard Worker                         const SubTypeList &aSubTypeList,
482*4a64e381SAndroid Build Coastguard Worker                         uint16_t           aPort,
483*4a64e381SAndroid Build Coastguard Worker                         const TxtData     &aTxtData) const;
484*4a64e381SAndroid Build Coastguard Worker 
485*4a64e381SAndroid Build Coastguard Worker     private:
486*4a64e381SAndroid Build Coastguard Worker         void OnComplete(otbrError aError);
487*4a64e381SAndroid Build Coastguard Worker     };
488*4a64e381SAndroid Build Coastguard Worker 
489*4a64e381SAndroid Build Coastguard Worker     class HostRegistration : public Registration
490*4a64e381SAndroid Build Coastguard Worker     {
491*4a64e381SAndroid Build Coastguard Worker     public:
492*4a64e381SAndroid Build Coastguard Worker         std::string mName;
493*4a64e381SAndroid Build Coastguard Worker         AddressList mAddresses;
494*4a64e381SAndroid Build Coastguard Worker 
HostRegistration(std::string aName,AddressList aAddresses,ResultCallback && aCallback,Publisher * aPublisher)495*4a64e381SAndroid Build Coastguard Worker         HostRegistration(std::string aName, AddressList aAddresses, ResultCallback &&aCallback, Publisher *aPublisher)
496*4a64e381SAndroid Build Coastguard Worker             : Registration(std::move(aCallback), aPublisher)
497*4a64e381SAndroid Build Coastguard Worker             , mName(std::move(aName))
498*4a64e381SAndroid Build Coastguard Worker             , mAddresses(SortAddressList(std::move(aAddresses)))
499*4a64e381SAndroid Build Coastguard Worker         {
500*4a64e381SAndroid Build Coastguard Worker         }
501*4a64e381SAndroid Build Coastguard Worker 
~HostRegistration(void)502*4a64e381SAndroid Build Coastguard Worker         ~HostRegistration(void) override { OnComplete(OTBR_ERROR_ABORTED); }
503*4a64e381SAndroid Build Coastguard Worker 
504*4a64e381SAndroid Build Coastguard Worker         void Complete(otbrError aError);
505*4a64e381SAndroid Build Coastguard Worker 
506*4a64e381SAndroid Build Coastguard Worker         // Tells whether this `HostRegistration` object is outdated comparing to the given parameters.
507*4a64e381SAndroid Build Coastguard Worker         bool IsOutdated(const std::string &aName, const AddressList &aAddresses) const;
508*4a64e381SAndroid Build Coastguard Worker 
509*4a64e381SAndroid Build Coastguard Worker     private:
510*4a64e381SAndroid Build Coastguard Worker         void OnComplete(otbrError aError);
511*4a64e381SAndroid Build Coastguard Worker     };
512*4a64e381SAndroid Build Coastguard Worker 
513*4a64e381SAndroid Build Coastguard Worker     class KeyRegistration : public Registration
514*4a64e381SAndroid Build Coastguard Worker     {
515*4a64e381SAndroid Build Coastguard Worker     public:
516*4a64e381SAndroid Build Coastguard Worker         std::string mName;
517*4a64e381SAndroid Build Coastguard Worker         KeyData     mKeyData;
518*4a64e381SAndroid Build Coastguard Worker 
KeyRegistration(std::string aName,KeyData aKeyData,ResultCallback && aCallback,Publisher * aPublisher)519*4a64e381SAndroid Build Coastguard Worker         KeyRegistration(std::string aName, KeyData aKeyData, ResultCallback &&aCallback, Publisher *aPublisher)
520*4a64e381SAndroid Build Coastguard Worker             : Registration(std::move(aCallback), aPublisher)
521*4a64e381SAndroid Build Coastguard Worker             , mName(std::move(aName))
522*4a64e381SAndroid Build Coastguard Worker             , mKeyData(std::move(aKeyData))
523*4a64e381SAndroid Build Coastguard Worker         {
524*4a64e381SAndroid Build Coastguard Worker         }
525*4a64e381SAndroid Build Coastguard Worker 
~KeyRegistration(void)526*4a64e381SAndroid Build Coastguard Worker         ~KeyRegistration(void) { OnComplete(OTBR_ERROR_ABORTED); }
527*4a64e381SAndroid Build Coastguard Worker 
528*4a64e381SAndroid Build Coastguard Worker         void Complete(otbrError aError);
529*4a64e381SAndroid Build Coastguard Worker 
530*4a64e381SAndroid Build Coastguard Worker         // Tells whether this `KeyRegistration` object is outdated comparing to the given parameters.
531*4a64e381SAndroid Build Coastguard Worker         bool IsOutdated(const std::string &aName, const KeyData &aKeyData) const;
532*4a64e381SAndroid Build Coastguard Worker 
533*4a64e381SAndroid Build Coastguard Worker     private:
534*4a64e381SAndroid Build Coastguard Worker         void OnComplete(otbrError aError);
535*4a64e381SAndroid Build Coastguard Worker     };
536*4a64e381SAndroid Build Coastguard Worker 
537*4a64e381SAndroid Build Coastguard Worker     using ServiceRegistrationPtr = std::unique_ptr<ServiceRegistration>;
538*4a64e381SAndroid Build Coastguard Worker     using ServiceRegistrationMap = std::map<std::string, ServiceRegistrationPtr>;
539*4a64e381SAndroid Build Coastguard Worker     using HostRegistrationPtr    = std::unique_ptr<HostRegistration>;
540*4a64e381SAndroid Build Coastguard Worker     using HostRegistrationMap    = std::map<std::string, HostRegistrationPtr>;
541*4a64e381SAndroid Build Coastguard Worker     using KeyRegistrationPtr     = std::unique_ptr<KeyRegistration>;
542*4a64e381SAndroid Build Coastguard Worker     using KeyRegistrationMap     = std::map<std::string, KeyRegistrationPtr>;
543*4a64e381SAndroid Build Coastguard Worker 
544*4a64e381SAndroid Build Coastguard Worker     static SubTypeList SortSubTypeList(SubTypeList aSubTypeList);
545*4a64e381SAndroid Build Coastguard Worker     static AddressList SortAddressList(AddressList aAddressList);
546*4a64e381SAndroid Build Coastguard Worker     static std::string MakeFullName(const std::string &aName);
547*4a64e381SAndroid Build Coastguard Worker     static std::string MakeFullServiceName(const std::string &aName, const std::string &aType);
MakeFullHostName(const std::string & aName)548*4a64e381SAndroid Build Coastguard Worker     static std::string MakeFullHostName(const std::string &aName) { return MakeFullName(aName); }
MakeFullKeyName(const std::string & aName)549*4a64e381SAndroid Build Coastguard Worker     static std::string MakeFullKeyName(const std::string &aName) { return MakeFullName(aName); }
550*4a64e381SAndroid Build Coastguard Worker 
551*4a64e381SAndroid Build Coastguard Worker     virtual otbrError PublishServiceImpl(const std::string &aHostName,
552*4a64e381SAndroid Build Coastguard Worker                                          const std::string &aName,
553*4a64e381SAndroid Build Coastguard Worker                                          const std::string &aType,
554*4a64e381SAndroid Build Coastguard Worker                                          const SubTypeList &aSubTypeList,
555*4a64e381SAndroid Build Coastguard Worker                                          uint16_t           aPort,
556*4a64e381SAndroid Build Coastguard Worker                                          const TxtData     &aTxtData,
557*4a64e381SAndroid Build Coastguard Worker                                          ResultCallback   &&aCallback) = 0;
558*4a64e381SAndroid Build Coastguard Worker 
559*4a64e381SAndroid Build Coastguard Worker     virtual otbrError PublishHostImpl(const std::string &aName,
560*4a64e381SAndroid Build Coastguard Worker                                       const AddressList &aAddresses,
561*4a64e381SAndroid Build Coastguard Worker                                       ResultCallback   &&aCallback) = 0;
562*4a64e381SAndroid Build Coastguard Worker 
563*4a64e381SAndroid Build Coastguard Worker     virtual otbrError PublishKeyImpl(const std::string &aName, const KeyData &aKeyData, ResultCallback &&aCallback) = 0;
564*4a64e381SAndroid Build Coastguard Worker 
565*4a64e381SAndroid Build Coastguard Worker     virtual void OnServiceResolveFailedImpl(const std::string &aType,
566*4a64e381SAndroid Build Coastguard Worker                                             const std::string &aInstanceName,
567*4a64e381SAndroid Build Coastguard Worker                                             int32_t            aErrorCode) = 0;
568*4a64e381SAndroid Build Coastguard Worker 
569*4a64e381SAndroid Build Coastguard Worker     virtual void OnHostResolveFailedImpl(const std::string &aHostName, int32_t aErrorCode) = 0;
570*4a64e381SAndroid Build Coastguard Worker 
571*4a64e381SAndroid Build Coastguard Worker     virtual otbrError DnsErrorToOtbrError(int32_t aError) = 0;
572*4a64e381SAndroid Build Coastguard Worker 
573*4a64e381SAndroid Build Coastguard Worker     void AddServiceRegistration(ServiceRegistrationPtr &&aServiceReg);
574*4a64e381SAndroid Build Coastguard Worker     void RemoveServiceRegistration(const std::string &aName, const std::string &aType, otbrError aError);
575*4a64e381SAndroid Build Coastguard Worker     ServiceRegistration *FindServiceRegistration(const std::string &aName, const std::string &aType);
576*4a64e381SAndroid Build Coastguard Worker     ServiceRegistration *FindServiceRegistration(const std::string &aNameAndType);
577*4a64e381SAndroid Build Coastguard Worker 
578*4a64e381SAndroid Build Coastguard Worker     void OnServiceResolved(std::string aType, DiscoveredInstanceInfo aInstanceInfo);
579*4a64e381SAndroid Build Coastguard Worker     void OnServiceResolveFailed(std::string aType, std::string aInstanceName, int32_t aErrorCode);
580*4a64e381SAndroid Build Coastguard Worker     void OnServiceRemoved(uint32_t aNetifIndex, std::string aType, std::string aInstanceName);
581*4a64e381SAndroid Build Coastguard Worker     void OnHostResolved(std::string aHostName, DiscoveredHostInfo aHostInfo);
582*4a64e381SAndroid Build Coastguard Worker     void OnHostResolveFailed(std::string aHostName, int32_t aErrorCode);
583*4a64e381SAndroid Build Coastguard Worker 
584*4a64e381SAndroid Build Coastguard Worker     // Handles the cases that there is already a registration for the same service.
585*4a64e381SAndroid Build Coastguard Worker     // If the returned callback is completed, current registration should be considered
586*4a64e381SAndroid Build Coastguard Worker     // success and no further action should be performed.
587*4a64e381SAndroid Build Coastguard Worker     ResultCallback HandleDuplicateServiceRegistration(const std::string &aHostName,
588*4a64e381SAndroid Build Coastguard Worker                                                       const std::string &aName,
589*4a64e381SAndroid Build Coastguard Worker                                                       const std::string &aType,
590*4a64e381SAndroid Build Coastguard Worker                                                       const SubTypeList &aSubTypeList,
591*4a64e381SAndroid Build Coastguard Worker                                                       uint16_t           aPort,
592*4a64e381SAndroid Build Coastguard Worker                                                       const TxtData     &aTxtData,
593*4a64e381SAndroid Build Coastguard Worker                                                       ResultCallback   &&aCallback);
594*4a64e381SAndroid Build Coastguard Worker 
595*4a64e381SAndroid Build Coastguard Worker     ResultCallback HandleDuplicateHostRegistration(const std::string &aName,
596*4a64e381SAndroid Build Coastguard Worker                                                    const AddressList &aAddresses,
597*4a64e381SAndroid Build Coastguard Worker                                                    ResultCallback   &&aCallback);
598*4a64e381SAndroid Build Coastguard Worker 
599*4a64e381SAndroid Build Coastguard Worker     ResultCallback HandleDuplicateKeyRegistration(const std::string &aName,
600*4a64e381SAndroid Build Coastguard Worker                                                   const KeyData     &aKeyData,
601*4a64e381SAndroid Build Coastguard Worker                                                   ResultCallback   &&aCallback);
602*4a64e381SAndroid Build Coastguard Worker 
603*4a64e381SAndroid Build Coastguard Worker     void              AddHostRegistration(HostRegistrationPtr &&aHostReg);
604*4a64e381SAndroid Build Coastguard Worker     void              RemoveHostRegistration(const std::string &aName, otbrError aError);
605*4a64e381SAndroid Build Coastguard Worker     HostRegistration *FindHostRegistration(const std::string &aName);
606*4a64e381SAndroid Build Coastguard Worker 
607*4a64e381SAndroid Build Coastguard Worker     void             AddKeyRegistration(KeyRegistrationPtr &&aKeyReg);
608*4a64e381SAndroid Build Coastguard Worker     void             RemoveKeyRegistration(const std::string &aName, otbrError aError);
609*4a64e381SAndroid Build Coastguard Worker     KeyRegistration *FindKeyRegistration(const std::string &aName);
610*4a64e381SAndroid Build Coastguard Worker     KeyRegistration *FindKeyRegistration(const std::string &aName, const std::string &aType);
611*4a64e381SAndroid Build Coastguard Worker 
612*4a64e381SAndroid Build Coastguard Worker     static void UpdateMdnsResponseCounters(MdnsResponseCounters &aCounters, otbrError aError);
613*4a64e381SAndroid Build Coastguard Worker     static void UpdateEmaLatency(uint32_t &aEmaLatency, uint32_t aLatency, otbrError aError);
614*4a64e381SAndroid Build Coastguard Worker 
615*4a64e381SAndroid Build Coastguard Worker     void UpdateServiceRegistrationEmaLatency(const std::string &aInstanceName,
616*4a64e381SAndroid Build Coastguard Worker                                              const std::string &aType,
617*4a64e381SAndroid Build Coastguard Worker                                              otbrError          aError);
618*4a64e381SAndroid Build Coastguard Worker     void UpdateHostRegistrationEmaLatency(const std::string &aHostName, otbrError aError);
619*4a64e381SAndroid Build Coastguard Worker     void UpdateKeyRegistrationEmaLatency(const std::string &aKeyName, otbrError aError);
620*4a64e381SAndroid Build Coastguard Worker     void UpdateServiceInstanceResolutionEmaLatency(const std::string &aInstanceName,
621*4a64e381SAndroid Build Coastguard Worker                                                    const std::string &aType,
622*4a64e381SAndroid Build Coastguard Worker                                                    otbrError          aError);
623*4a64e381SAndroid Build Coastguard Worker     void UpdateHostResolutionEmaLatency(const std::string &aHostName, otbrError aError);
624*4a64e381SAndroid Build Coastguard Worker 
625*4a64e381SAndroid Build Coastguard Worker     static void AddAddress(AddressList &aAddressList, const Ip6Address &aAddress);
626*4a64e381SAndroid Build Coastguard Worker     static void RemoveAddress(AddressList &aAddressList, const Ip6Address &aAddress);
627*4a64e381SAndroid Build Coastguard Worker 
628*4a64e381SAndroid Build Coastguard Worker     ServiceRegistrationMap mServiceRegistrations;
629*4a64e381SAndroid Build Coastguard Worker     HostRegistrationMap    mHostRegistrations;
630*4a64e381SAndroid Build Coastguard Worker     KeyRegistrationMap     mKeyRegistrations;
631*4a64e381SAndroid Build Coastguard Worker 
632*4a64e381SAndroid Build Coastguard Worker     struct DiscoverCallback
633*4a64e381SAndroid Build Coastguard Worker     {
DiscoverCallbackotbr::Mdns::Publisher::DiscoverCallback634*4a64e381SAndroid Build Coastguard Worker         DiscoverCallback(uint64_t                          aId,
635*4a64e381SAndroid Build Coastguard Worker                          DiscoveredServiceInstanceCallback aServiceCallback,
636*4a64e381SAndroid Build Coastguard Worker                          DiscoveredHostCallback            aHostCallback)
637*4a64e381SAndroid Build Coastguard Worker             : mId(aId)
638*4a64e381SAndroid Build Coastguard Worker             , mServiceCallback(std::move(aServiceCallback))
639*4a64e381SAndroid Build Coastguard Worker             , mHostCallback(std::move(aHostCallback))
640*4a64e381SAndroid Build Coastguard Worker             , mShouldInvoke(false)
641*4a64e381SAndroid Build Coastguard Worker         {
642*4a64e381SAndroid Build Coastguard Worker         }
643*4a64e381SAndroid Build Coastguard Worker 
644*4a64e381SAndroid Build Coastguard Worker         uint64_t                          mId;
645*4a64e381SAndroid Build Coastguard Worker         DiscoveredServiceInstanceCallback mServiceCallback;
646*4a64e381SAndroid Build Coastguard Worker         DiscoveredHostCallback            mHostCallback;
647*4a64e381SAndroid Build Coastguard Worker         bool                              mShouldInvoke;
648*4a64e381SAndroid Build Coastguard Worker     };
649*4a64e381SAndroid Build Coastguard Worker 
650*4a64e381SAndroid Build Coastguard Worker     uint64_t mNextSubscriberId = 1;
651*4a64e381SAndroid Build Coastguard Worker 
652*4a64e381SAndroid Build Coastguard Worker     std::list<DiscoverCallback> mDiscoverCallbacks;
653*4a64e381SAndroid Build Coastguard Worker 
654*4a64e381SAndroid Build Coastguard Worker     // {instance name, service type} -> the timepoint to begin service registration
655*4a64e381SAndroid Build Coastguard Worker     std::map<std::pair<std::string, std::string>, Timepoint> mServiceRegistrationBeginTime;
656*4a64e381SAndroid Build Coastguard Worker     // host name -> the timepoint to begin host registration
657*4a64e381SAndroid Build Coastguard Worker     std::map<std::string, Timepoint> mHostRegistrationBeginTime;
658*4a64e381SAndroid Build Coastguard Worker     // key name -> the timepoint to begin key registration
659*4a64e381SAndroid Build Coastguard Worker     std::map<std::string, Timepoint> mKeyRegistrationBeginTime;
660*4a64e381SAndroid Build Coastguard Worker     // {instance name, service type} -> the timepoint to begin service resolution
661*4a64e381SAndroid Build Coastguard Worker     std::map<std::pair<std::string, std::string>, Timepoint> mServiceInstanceResolutionBeginTime;
662*4a64e381SAndroid Build Coastguard Worker     // host name -> the timepoint to begin host resolution
663*4a64e381SAndroid Build Coastguard Worker     std::map<std::string, Timepoint> mHostResolutionBeginTime;
664*4a64e381SAndroid Build Coastguard Worker 
665*4a64e381SAndroid Build Coastguard Worker     MdnsTelemetryInfo mTelemetryInfo{};
666*4a64e381SAndroid Build Coastguard Worker };
667*4a64e381SAndroid Build Coastguard Worker 
668*4a64e381SAndroid Build Coastguard Worker /**
669*4a64e381SAndroid Build Coastguard Worker  * @}
670*4a64e381SAndroid Build Coastguard Worker  */
671*4a64e381SAndroid Build Coastguard Worker 
672*4a64e381SAndroid Build Coastguard Worker } // namespace Mdns
673*4a64e381SAndroid Build Coastguard Worker 
674*4a64e381SAndroid Build Coastguard Worker } // namespace otbr
675*4a64e381SAndroid Build Coastguard Worker 
676*4a64e381SAndroid Build Coastguard Worker #endif // OTBR_AGENT_MDNS_HPP_
677