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

Generated by: LCOV version 2.0-1