Matter SDK Coverage Report
Current view: top level - lib/dnssd - Advertiser.h (source / functions) Coverage Total Hit
Test: SHA:b8ad71b307eba306a40d8f059f81ff9adbdfdc64 Lines: 96.7 % 90 87
Test Date: 2025-08-15 07:11:25 Functions: 96.1 % 51 49

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

Generated by: LCOV version 2.0-1