Matter SDK Coverage Report
Current view: top level - lib/dnssd - Advertiser.h (source / functions) Coverage Total Hit
Test: SHA:9151e79d6b5c010f18e3a3da0b048f38196f06c6 Lines: 80.2 % 81 65
Test Date: 2025-07-02 07:09:01 Functions: 79.6 % 49 39

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020 Project CHIP Authors
       4              :  *
       5              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6              :  *    you may not use this file except in compliance with the License.
       7              :  *    You may obtain a copy of the License at
       8              :  *
       9              :  *        http://www.apache.org/licenses/LICENSE-2.0
      10              :  *
      11              :  *    Unless required by applicable law or agreed to in writing, software
      12              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              :  *    See the License for the specific language governing permissions and
      15              :  *    limitations under the License.
      16              :  */
      17              : 
      18              : #pragma once
      19              : 
      20              : #include <algorithm>
      21              : #include <cstdint>
      22              : #include <optional>
      23              : 
      24              : #include <lib/core/CHIPError.h>
      25              : #include <lib/core/PeerId.h>
      26              : #include <lib/dnssd/TxtFields.h>
      27              : #include <lib/support/CHIPMemString.h>
      28              : #include <lib/support/SafeString.h>
      29              : #include <lib/support/Span.h>
      30              : #include <platform/CHIPDeviceConfig.h>
      31              : 
      32              : namespace chip {
      33              : namespace Dnssd {
      34              : 
      35              : static constexpr uint16_t kMdnsPort = 5353;
      36              : // Need 8 bytes to fit a thread mac.
      37              : static constexpr size_t kMaxMacSize = 8;
      38              : 
      39              : enum class CommssionAdvertiseMode : uint8_t
      40              : {
      41              :     kCommissionableNode,
      42              :     kCommissioner,
      43              : };
      44              : 
      45              : enum class CommissioningMode
      46              : {
      47              :     kDisabled,       // Commissioning Mode is disabled, CM=0 in DNS-SD key/value pairs
      48              :     kEnabledBasic,   // Basic Commissioning Mode, CM=1 in DNS-SD key/value pairs
      49              :     kEnabledEnhanced // Enhanced Commissioning Mode, CM=2 in DNS-SD key/value pairs
      50              : };
      51              : 
      52              : enum class ICDModeAdvertise : uint8_t
      53              : {
      54              :     kNone, // The device does not support the LIT feature-set. No ICD= key is advertised in DNS-SD.
      55              :     kSIT,  // The ICD supports the LIT feature-set, but is currently operating as a SIT. ICD=0 in DNS-SD key/value pairs.
      56              :     kLIT,  // The ICD is currently operating as a LIT. ICD=1 in DNS-SD key/value pairs.
      57              : };
      58              : 
      59              : enum class TCPModeAdvertise : uint16_t
      60              : {
      61              :     kNone            = 0,                         // The device does not support TCP.
      62              :     kTCPClient       = 1 << 1,                    // The device supports the TCP client.
      63              :     kTCPServer       = 1 << 2,                    // The device supports the TCP server.
      64              :     kTCPClientServer = (kTCPClient | kTCPServer), // The device supports both the TCP client and server.
      65              : };
      66              : 
      67              : template <class Derived>
      68              : class BaseAdvertisingParams
      69              : {
      70              : public:
      71              :     static constexpr uint8_t kCommonTxtMaxNumber     = KeyCount(TxtKeyUse::kCommon);
      72              :     static constexpr size_t kCommonTxtMaxKeySize     = MaxKeyLen(TxtKeyUse::kCommon);
      73              :     static constexpr size_t kCommonTxtMaxValueSize   = MaxValueLen(TxtKeyUse::kCommon);
      74              :     static constexpr size_t kCommonTxtTotalKeySize   = TotalKeyLen(TxtKeyUse::kCommon);
      75              :     static constexpr size_t kCommonTxtTotalValueSize = TotalValueLen(TxtKeyUse::kCommon);
      76              : 
      77            7 :     Derived & SetPort(uint16_t port)
      78              :     {
      79            7 :         mPort = port;
      80            7 :         return *reinterpret_cast<Derived *>(this);
      81              :     }
      82           19 :     uint16_t GetPort() const { return mPort; }
      83              : 
      84            7 :     Derived & SetInterfaceId(Inet::InterfaceId interfaceId)
      85              :     {
      86            7 :         mInterfaceId = interfaceId;
      87            7 :         return *reinterpret_cast<Derived *>(this);
      88              :     }
      89              : 
      90              :     Inet::InterfaceId GetInterfaceId() const { return mInterfaceId; }
      91              : 
      92            7 :     Derived & EnableIpV4(bool enable)
      93              :     {
      94            7 :         mEnableIPv4 = enable;
      95            7 :         return *reinterpret_cast<Derived *>(this);
      96              :     }
      97           19 :     bool IsIPv4Enabled() const { return mEnableIPv4; }
      98            7 :     Derived & SetMac(chip::ByteSpan mac)
      99              :     {
     100            7 :         mMacLength = std::min(mac.size(), kMaxMacSize);
     101            7 :         memcpy(mMacStorage, mac.data(), mMacLength);
     102            7 :         return *reinterpret_cast<Derived *>(this);
     103              :     }
     104           19 :     const chip::ByteSpan GetMac() const { return chip::ByteSpan(mMacStorage, mMacLength); }
     105              : 
     106              :     // Common Flags
     107            7 :     Derived & SetLocalMRPConfig(const std::optional<ReliableMessageProtocolConfig> & config)
     108              :     {
     109            7 :         mLocalMRPConfig = config;
     110            7 :         return *reinterpret_cast<Derived *>(this);
     111              :     }
     112           19 :     const std::optional<ReliableMessageProtocolConfig> & GetLocalMRPConfig() const { return mLocalMRPConfig; }
     113              : 
     114            0 :     Derived & SetTCPSupportModes(TCPModeAdvertise tcpSupportModes)
     115              :     {
     116            0 :         mTcpSupportModes = tcpSupportModes;
     117            0 :         return *reinterpret_cast<Derived *>(this);
     118              :     }
     119           22 :     TCPModeAdvertise GetTCPSupportModes() const { return mTcpSupportModes; }
     120              : 
     121              :     Derived & SetICDModeToAdvertise(ICDModeAdvertise operatingMode)
     122              :     {
     123              :         mICDModeAdvertise = operatingMode;
     124              :         return *reinterpret_cast<Derived *>(this);
     125              :     }
     126           26 :     ICDModeAdvertise GetICDModeToAdvertise() const { return mICDModeAdvertise; }
     127              : 
     128              : private:
     129              :     uint16_t mPort                   = CHIP_PORT;
     130              :     Inet::InterfaceId mInterfaceId   = Inet::InterfaceId::Null();
     131              :     bool mEnableIPv4                 = true;
     132              :     uint8_t mMacStorage[kMaxMacSize] = {};
     133              :     size_t mMacLength                = 0;
     134              :     std::optional<ReliableMessageProtocolConfig> mLocalMRPConfig;
     135              :     TCPModeAdvertise mTcpSupportModes  = TCPModeAdvertise::kNone;
     136              :     ICDModeAdvertise mICDModeAdvertise = ICDModeAdvertise::kNone;
     137              : };
     138              : 
     139              : /// Defines parameters required for advertising a CHIP node
     140              : /// over mDNS as an 'operationally ready' node.
     141              : class OperationalAdvertisingParameters : public BaseAdvertisingParams<OperationalAdvertisingParameters>
     142              : {
     143              : public:
     144              :     // Operational uses only common keys
     145              :     static constexpr uint8_t kTxtMaxNumber     = kCommonTxtMaxNumber;
     146              :     static constexpr uint8_t kTxtMaxKeySize    = kCommonTxtMaxKeySize;
     147              :     static constexpr uint8_t kTxtMaxValueSize  = kCommonTxtMaxValueSize;
     148              :     static constexpr size_t kTxtTotalKeySize   = kCommonTxtTotalKeySize;
     149              :     static constexpr size_t kTxtTotalValueSize = kCommonTxtTotalValueSize;
     150              : 
     151            0 :     OperationalAdvertisingParameters & SetPeerId(const PeerId & peerId)
     152              :     {
     153            0 :         mPeerId = peerId;
     154            0 :         return *this;
     155              :     }
     156           16 :     PeerId GetPeerId() const { return mPeerId; }
     157              : 
     158              :     CompressedFabricId GetCompressedFabricId() const { return mPeerId.GetCompressedFabricId(); }
     159              : 
     160              : private:
     161              :     PeerId mPeerId;
     162              : };
     163              : 
     164              : class CommissionAdvertisingParameters : public BaseAdvertisingParams<CommissionAdvertisingParameters>
     165              : {
     166              : public:
     167              :     static constexpr uint8_t kTxtMaxNumber     = kCommonTxtMaxNumber + KeyCount(TxtKeyUse::kCommission);
     168              :     static constexpr uint8_t kTxtMaxKeySize    = std::max(kCommonTxtMaxKeySize, MaxKeyLen(TxtKeyUse::kCommission));
     169              :     static constexpr uint8_t kTxtMaxValueSize  = std::max(kCommonTxtMaxValueSize, MaxValueLen(TxtKeyUse::kCommission));
     170              :     static constexpr size_t kTxtTotalKeySize   = kCommonTxtTotalKeySize + TotalKeyLen(TxtKeyUse::kCommission);
     171              :     static constexpr size_t kTxtTotalValueSize = kCommonTxtTotalValueSize + TotalValueLen(TxtKeyUse::kCommission);
     172              : 
     173            7 :     CommissionAdvertisingParameters & SetShortDiscriminator(uint8_t discriminator)
     174              :     {
     175            7 :         mShortDiscriminator = discriminator;
     176            7 :         return *this;
     177              :     }
     178           18 :     uint8_t GetShortDiscriminator() const { return mShortDiscriminator; }
     179              : 
     180            7 :     CommissionAdvertisingParameters & SetLongDiscriminator(uint16_t discriminator)
     181              :     {
     182            7 :         mLongDiscriminator = discriminator;
     183            7 :         return *this;
     184              :     }
     185           29 :     uint16_t GetLongDiscriminator() const { return mLongDiscriminator; }
     186              : 
     187            7 :     CommissionAdvertisingParameters & SetVendorId(std::optional<uint16_t> vendorId)
     188              :     {
     189            7 :         mVendorId = vendorId;
     190            7 :         return *this;
     191              :     }
     192           29 :     std::optional<uint16_t> GetVendorId() const { return mVendorId; }
     193              : 
     194            7 :     CommissionAdvertisingParameters & SetProductId(std::optional<uint16_t> productId)
     195              :     {
     196            7 :         mProductId = productId;
     197            7 :         return *this;
     198              :     }
     199           18 :     std::optional<uint16_t> GetProductId() const { return mProductId; }
     200              : 
     201            7 :     CommissionAdvertisingParameters & SetCommissioningMode(CommissioningMode mode)
     202              :     {
     203            7 :         mCommissioningMode = mode;
     204            7 :         return *this;
     205              :     }
     206           29 :     CommissioningMode GetCommissioningMode() const { return mCommissioningMode; }
     207              : 
     208              : #if CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
     209              :     CommissionAdvertisingParameters & SetJointFabricMode(BitFlags<JointFabricMode> mode)
     210              :     {
     211              :         mJointFabricMode = mode;
     212              :         return *this;
     213              :     }
     214              :     BitFlags<JointFabricMode> GetJointFabricMode() const { return mJointFabricMode; }
     215              : #endif // CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
     216              : 
     217            0 :     CommissionAdvertisingParameters & SetDeviceType(std::optional<uint32_t> deviceType)
     218              :     {
     219            0 :         mDeviceType = deviceType;
     220            0 :         return *this;
     221              :     }
     222           22 :     std::optional<uint32_t> GetDeviceType() const { return mDeviceType; }
     223              : 
     224            0 :     CommissionAdvertisingParameters & SetDeviceName(std::optional<const char *> deviceName)
     225              :     {
     226            0 :         if (deviceName.has_value())
     227              :         {
     228            0 :             Platform::CopyString(mDeviceName, sizeof(mDeviceName), *deviceName);
     229            0 :             mDeviceNameHasValue = true;
     230              :         }
     231              :         else
     232              :         {
     233            0 :             mDeviceNameHasValue = false;
     234              :         }
     235            0 :         return *this;
     236              :     }
     237           11 :     std::optional<const char *> GetDeviceName() const
     238              :     {
     239           22 :         return mDeviceNameHasValue ? std::make_optional<const char *>(mDeviceName) : std::nullopt;
     240              :     }
     241              : 
     242              :     CommissionAdvertisingParameters & SetRotatingDeviceId(std::optional<const char *> rotatingId)
     243              :     {
     244              :         if (rotatingId.has_value())
     245              :         {
     246              :             Platform::CopyString(mRotatingId, sizeof(mRotatingId), *rotatingId);
     247              :             mRotatingIdHasValue = true;
     248              :         }
     249              :         else
     250              :         {
     251              :             mRotatingIdHasValue = false;
     252              :         }
     253              :         return *this;
     254              :     }
     255           11 :     std::optional<const char *> GetRotatingDeviceId() const
     256              :     {
     257           22 :         return mRotatingIdHasValue ? std::make_optional<const char *>(mRotatingId) : std::nullopt;
     258              :     }
     259              : 
     260            7 :     CommissionAdvertisingParameters & SetPairingInstruction(std::optional<const char *> pairingInstr)
     261              :     {
     262            7 :         if (pairingInstr.has_value())
     263              :         {
     264            7 :             Platform::CopyString(mPairingInstr, sizeof(mPairingInstr), *pairingInstr);
     265            7 :             mPairingInstrHasValue = true;
     266              :         }
     267              :         else
     268              :         {
     269            0 :             mPairingInstrHasValue = false;
     270              :         }
     271            7 :         return *this;
     272              :     }
     273           11 :     std::optional<const char *> GetPairingInstruction() const
     274              :     {
     275           22 :         return mPairingInstrHasValue ? std::make_optional<const char *>(mPairingInstr) : std::nullopt;
     276              :     }
     277              : 
     278            7 :     CommissionAdvertisingParameters & SetPairingHint(std::optional<uint16_t> pairingHint)
     279              :     {
     280            7 :         mPairingHint = pairingHint;
     281            7 :         return *this;
     282              :     }
     283           11 :     std::optional<uint16_t> GetPairingHint() const { return mPairingHint; }
     284              : 
     285            7 :     CommissionAdvertisingParameters & SetCommissionAdvertiseMode(CommssionAdvertiseMode mode)
     286              :     {
     287            7 :         mMode = mode;
     288            7 :         return *this;
     289              :     }
     290           77 :     CommssionAdvertiseMode GetCommissionAdvertiseMode() const { return mMode; }
     291              : 
     292              :     CommissionAdvertisingParameters & SetCommissionerPasscodeSupported(std::optional<bool> commissionerPasscodeSupported)
     293              :     {
     294              :         mCommissionerPasscodeSupported = commissionerPasscodeSupported;
     295              :         return *this;
     296              :     }
     297            7 :     std::optional<bool> GetCommissionerPasscodeSupported() const { return mCommissionerPasscodeSupported; }
     298              : 
     299              : private:
     300              :     uint8_t mShortDiscriminator          = 0;
     301              :     uint16_t mLongDiscriminator          = 0; // 12-bit according to spec
     302              :     CommssionAdvertiseMode mMode         = CommssionAdvertiseMode::kCommissionableNode;
     303              :     CommissioningMode mCommissioningMode = CommissioningMode::kEnabledBasic;
     304              : #if CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
     305              :     BitFlags<JointFabricMode> mJointFabricMode;
     306              : #endif // CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
     307              :     std::optional<uint16_t> mVendorId;
     308              :     std::optional<uint16_t> mProductId;
     309              :     std::optional<uint32_t> mDeviceType;
     310              :     std::optional<uint16_t> mPairingHint;
     311              : 
     312              :     char mDeviceName[kKeyDeviceNameMaxLength + 1];
     313              :     bool mDeviceNameHasValue = false;
     314              : 
     315              :     char mRotatingId[kKeyRotatingDeviceIdMaxLength + 1];
     316              :     bool mRotatingIdHasValue = false;
     317              : 
     318              :     char mPairingInstr[kKeyPairingInstructionMaxLength + 1];
     319              :     bool mPairingInstrHasValue = false;
     320              : 
     321              :     std::optional<bool> mCommissionerPasscodeSupported;
     322              : };
     323              : 
     324              : /**
     325              :  * Interface for advertising CHIP DNS-SD services.
     326              :  *
     327              :  * A user of this interface must first initialize the advertiser using the `Init` method.
     328              :  *
     329              :  * Then, whenever advertised services need to be refreshed, the following sequence of events must
     330              :  * occur:
     331              :  * 1. Call the `RemoveServices` method.
     332              :  * 2. Call one of the `Advertise` methods for each service to be added or updated.
     333              :  * 3. Call the `FinalizeServiceUpdate` method to finalize the update and apply all pending changes.
     334              :  */
     335              : class ServiceAdvertiser
     336              : {
     337              : public:
     338           10 :     virtual ~ServiceAdvertiser() {}
     339              : 
     340              :     /**
     341              :      * Initializes the advertiser.
     342              :      *
     343              :      * The method must be called before other methods of this class.
     344              :      * If the advertiser has already been initialized, the method exits immediately with no error.
     345              :      */
     346              :     virtual CHIP_ERROR Init(chip::Inet::EndPointManager<chip::Inet::UDPEndPoint> * udpEndPointManager) = 0;
     347              : 
     348              :     /**
     349              :      * Returns whether the advertiser has completed the initialization.
     350              :      *
     351              :      * Returns true if the advertiser is ready to advertise services.
     352              :      */
     353              :     virtual bool IsInitialized() = 0;
     354              : 
     355              :     /**
     356              :      * Shuts down the advertiser.
     357              :      */
     358              :     virtual void Shutdown() = 0;
     359              : 
     360              :     /**
     361              :      * Removes or marks all services being advertised for removal.
     362              :      *
     363              :      * Depending on the implementation, the method may either stop advertising existing services
     364              :      * immediately, or mark them for removal upon the subsequent `FinalizeServiceUpdate` method call.
     365              :      */
     366              :     virtual CHIP_ERROR RemoveServices() = 0;
     367              : 
     368              :     /**
     369              :      * Advertises the given operational node service.
     370              :      */
     371              :     virtual CHIP_ERROR Advertise(const OperationalAdvertisingParameters & params) = 0;
     372              : 
     373              :     /**
     374              :      * Advertises the given commissionable/commissioner node service.
     375              :      */
     376              :     virtual CHIP_ERROR Advertise(const CommissionAdvertisingParameters & params) = 0;
     377              : 
     378              :     /**
     379              :      * Finalizes updating advertised services.
     380              :      *
     381              :      * This method can be used by some implementations to apply changes made with the `RemoveServices`
     382              :      * and `Advertise` methods in case they could not be applied immediately.
     383              :      */
     384              :     virtual CHIP_ERROR FinalizeServiceUpdate() = 0;
     385              : 
     386              :     /**
     387              :      * Returns the commissionable node service instance name formatted as hex string.
     388              :      */
     389              :     virtual CHIP_ERROR GetCommissionableInstanceName(char * instanceName, size_t maxLength) const = 0;
     390              : 
     391              :     /**
     392              :      * Generates an updated commissionable instance name.  This happens
     393              :      * automatically when Init() is called, but may be needed at other times as
     394              :      * well.
     395              :      */
     396              :     virtual CHIP_ERROR UpdateCommissionableInstanceName() = 0;
     397              : 
     398              :     /**
     399              :      * Returns the system-wide implementation of the service advertiser.
     400              :      *
     401              :      * The method returns a reference to the advertiser object configured by
     402              :      * a user using the \c ServiceAdvertiser::SetInstance() method, or the
     403              :      * default advertiser returned by the \c GetDefaultAdvertiser() function.
     404              :      */
     405              :     static ServiceAdvertiser & Instance();
     406              : 
     407              :     /**
     408              :      * Sets the system-wide implementation of the service advertiser.
     409              :      */
     410              :     static void SetInstance(ServiceAdvertiser & advertiser);
     411              : 
     412              : private:
     413              :     static ServiceAdvertiser * sInstance;
     414              : };
     415              : 
     416              : /**
     417              :  * Returns the default implementation of the service advertiser.
     418              :  */
     419              : extern ServiceAdvertiser & GetDefaultAdvertiser();
     420              : 
     421              : } // namespace Dnssd
     422              : } // namespace chip
        

Generated by: LCOV version 2.0-1