Matter SDK Coverage Report
Current view: top level - setup_payload - SetupPayload.h (source / functions) Coverage Total Hit
Test: SHA:2508d476d47c2acf8c9945ac0b2c5618ebc1d93f Lines: 100.0 % 2 2
Test Date: 2026-01-21 08:11:12 Functions: 100.0 % 2 2

            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              : /**
      19              :  *    @file
      20              :  *      This file describes a QRCode Setup Payload class to hold
      21              :  *      data enumerated from a byte stream
      22              :  */
      23              : 
      24              : #pragma once
      25              : 
      26              : #include <cstdint>
      27              : #include <map>
      28              : #include <string>
      29              : #include <vector>
      30              : 
      31              : #include <lib/core/CHIPError.h>
      32              : #include <lib/core/Optional.h>
      33              : #include <lib/support/BitFlags.h>
      34              : #include <lib/support/SetupDiscriminator.h>
      35              : 
      36              : namespace chip {
      37              : 
      38              : // See section 5.1.2. QR Code in the Matter specification
      39              : const int kVersionFieldLengthInBits              = 3;
      40              : const int kVendorIDFieldLengthInBits             = 16;
      41              : const int kProductIDFieldLengthInBits            = 16;
      42              : const int kCommissioningFlowFieldLengthInBits    = 2;
      43              : const int kRendezvousInfoFieldLengthInBits       = 8;
      44              : const int kPayloadDiscriminatorFieldLengthInBits = SetupDiscriminator::kLongBits;
      45              : const int kSetupPINCodeFieldLengthInBits         = 27;
      46              : const int kPaddingFieldLengthInBits              = 4;
      47              : const int kRawVendorTagLengthInBits              = 7;
      48              : 
      49              : // See section 5.1.3. Manual Pairing Code in the Matter specification
      50              : const int kManualSetupDiscriminatorFieldLengthInBits  = SetupDiscriminator::kShortBits;
      51              : const int kManualSetupChunk1DiscriminatorMsbitsPos    = 0;
      52              : const int kManualSetupChunk1DiscriminatorMsbitsLength = 2;
      53              : const int kManualSetupChunk1VidPidPresentBitPos =
      54              :     (kManualSetupChunk1DiscriminatorMsbitsPos + kManualSetupChunk1DiscriminatorMsbitsLength);
      55              : const int kManualSetupChunk2PINCodeLsbitsPos       = 0;
      56              : const int kManualSetupChunk2PINCodeLsbitsLength    = 14;
      57              : const int kManualSetupChunk2DiscriminatorLsbitsPos = (kManualSetupChunk2PINCodeLsbitsPos + kManualSetupChunk2PINCodeLsbitsLength);
      58              : const int kManualSetupChunk2DiscriminatorLsbitsLength = 2;
      59              : const int kManualSetupChunk3PINCodeMsbitsPos          = 0;
      60              : const int kManualSetupChunk3PINCodeMsbitsLength       = 13;
      61              : 
      62              : const int kManualSetupShortCodeCharLength  = 10;
      63              : const int kManualSetupLongCodeCharLength   = 20;
      64              : const int kManualSetupCodeChunk1CharLength = 1;
      65              : const int kManualSetupCodeChunk2CharLength = 5;
      66              : const int kManualSetupCodeChunk3CharLength = 4;
      67              : const int kManualSetupVendorIdCharLength   = 5;
      68              : const int kManualSetupProductIdCharLength  = 5;
      69              : 
      70              : // Spec 5.1.4.2 CHIP-Common Reserved Tags
      71              : inline constexpr uint8_t kSerialNumberTag         = 0x00;
      72              : inline constexpr uint8_t kPBKDFIterationsTag      = 0x01;
      73              : inline constexpr uint8_t kBPKFSaltTag             = 0x02;
      74              : inline constexpr uint8_t kNumberOFDevicesTag      = 0x03;
      75              : inline constexpr uint8_t kCommissioningTimeoutTag = 0x04;
      76              : 
      77              : inline constexpr uint32_t kSetupPINCodeMaximumValue   = 99999998;
      78              : inline constexpr uint32_t kSetupPINCodeUndefinedValue = 0;
      79              : static_assert(kSetupPINCodeMaximumValue < (1 << kSetupPINCodeFieldLengthInBits));
      80              : 
      81              : // clang-format off
      82              : const int kTotalPayloadDataSizeInBits =
      83              :     kVersionFieldLengthInBits +
      84              :     kVendorIDFieldLengthInBits +
      85              :     kProductIDFieldLengthInBits +
      86              :     kCommissioningFlowFieldLengthInBits +
      87              :     kRendezvousInfoFieldLengthInBits +
      88              :     kPayloadDiscriminatorFieldLengthInBits +
      89              :     kSetupPINCodeFieldLengthInBits +
      90              :     kPaddingFieldLengthInBits;
      91              : // clang-format on
      92              : 
      93              : const int kTotalPayloadDataSizeInBytes = kTotalPayloadDataSizeInBits / 8;
      94              : 
      95              : inline constexpr const char * kQRCodePrefix = "MT:";
      96              : inline constexpr char kPayloadDelimiter     = '*';
      97              : 
      98              : /// The rendezvous type this device supports.
      99              : enum class RendezvousInformationFlag : uint8_t
     100              : {
     101              :     kNone      = 0,      ///< Device does not support any method for rendezvous
     102              :     kSoftAP    = 1 << 0, ///< Device supports Wi-Fi softAP
     103              :     kBLE       = 1 << 1, ///< Device supports BLE
     104              :     kOnNetwork = 1 << 2, ///< Device supports Setup on network
     105              :     kWiFiPAF   = 1 << 3, ///< Device supports Wi-Fi Public Action Frame for discovery
     106              :     kNFC       = 1 << 4, ///< Device supports NFC-based Commissioning
     107              : };
     108              : using RendezvousInformationFlags = chip::BitFlags<RendezvousInformationFlag, uint8_t>;
     109              : 
     110              : enum class CommissioningFlow : uint8_t
     111              : {
     112              :     kStandard = 0,       ///< Device automatically enters pairing mode upon power-up
     113              :     kUserActionRequired, ///< Device requires a user interaction to enter pairing mode
     114              :     kCustom,             ///< Commissioning steps should be retrieved from the distributed compliance ledger
     115              : };
     116              : 
     117              : /**
     118              :  * A parent struct to hold onboarding payload contents without optional info,
     119              :  * for compatibility with devices that don't support std::string or STL.
     120              :  */
     121              : struct PayloadContents
     122              : {
     123              :     uint8_t version                     = 0;
     124              :     uint16_t vendorID                   = 0;
     125              :     uint16_t productID                  = 0;
     126              :     CommissioningFlow commissioningFlow = CommissioningFlow::kStandard;
     127              :     // rendezvousInformation is Optional, because a payload parsed from a manual
     128              :     // numeric code would not have any rendezvousInformation available.  A
     129              :     // payload parsed from a QR code would always have a value for
     130              :     // rendezvousInformation.
     131              :     Optional<RendezvousInformationFlags> rendezvousInformation;
     132              :     SetupDiscriminator discriminator{};
     133              :     uint32_t setUpPINCode = 0;
     134              : 
     135              :     enum class ValidationMode : uint8_t
     136              :     {
     137              :         kProduce, ///< Only flags or values allowed by the current spec version are allowed.
     138              :                   ///  Producers of a Setup Payload should use this mode to ensure the
     139              :                   //   payload is valid according to the current spec version.
     140              :         kConsume, ///< Flags or values that are reserved for future use, or were allowed in
     141              :                   ///  a previous spec version may be present. Consumers of a Setup Payload
     142              :                   ///  should use this mode to ensure they are forward and backwards
     143              :                   ///  compatible with payloads from older or newer Matter devices.
     144              :     };
     145              : 
     146              :     bool isValidQRCodePayload(ValidationMode mode = ValidationMode::kProduce) const;
     147              :     bool isValidManualCode(ValidationMode mode = ValidationMode::kProduce) const;
     148              : 
     149              :     bool operator==(const PayloadContents & input) const;
     150              : 
     151              :     static bool IsValidSetupPIN(uint32_t setupPIN);
     152              : 
     153              : private:
     154              :     bool CheckPayloadCommonConstraints() const;
     155              : };
     156              : 
     157              : enum optionalQRCodeInfoType
     158              : {
     159              :     optionalQRCodeInfoTypeUnknown,
     160              :     optionalQRCodeInfoTypeString,
     161              :     optionalQRCodeInfoTypeInt32,
     162              :     optionalQRCodeInfoTypeInt64,
     163              :     optionalQRCodeInfoTypeUInt32,
     164              :     optionalQRCodeInfoTypeUInt64
     165              : };
     166              : 
     167              : /**
     168              :  * A structure to hold optional QR Code info
     169              :  */
     170              : struct OptionalQRCodeInfo
     171              : {
     172              :     /*@{*/
     173              :     uint8_t tag;                      /**< the tag number of the optional info */
     174              :     enum optionalQRCodeInfoType type; /**< the type (String or Int) of the optional info */
     175              :     std::string data;                 /**< the string value if type is optionalQRCodeInfoTypeString, otherwise should not be set */
     176              :     int32_t int32 = 0;                /**< the integer value if type is optionalQRCodeInfoTypeInt32, otherwise should not be set */
     177              :     /*@}*/
     178              : };
     179              : 
     180              : struct OptionalQRCodeInfoExtension : OptionalQRCodeInfo
     181              : {
     182              :     int64_t int64   = 0; /**< the integer value if type is optionalQRCodeInfoTypeInt64, otherwise should not be set */
     183              :     uint64_t uint32 = 0; /**< the integer value if type is optionalQRCodeInfoTypeUInt32, otherwise should not be set */
     184              :     uint64_t uint64 = 0; /**< the integer value if type is optionalQRCodeInfoTypeUInt64, otherwise should not be set */
     185              : };
     186              : 
     187              : class SetupPayload : public PayloadContents
     188              : {
     189              : 
     190              :     friend class QRCodeSetupPayloadGenerator;
     191              :     friend class QRCodeSetupPayloadParser;
     192              : 
     193              : public:
     194              :     /** @brief A function to add an optional vendor data
     195              :      * @param tag tag number in the [0x80-0xFF] range
     196              :      * @param data String representation of data to add
     197              :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     198              :      **/
     199              :     CHIP_ERROR addOptionalVendorData(uint8_t tag, std::string data);
     200              : 
     201              :     /** @brief A function to add an optional vendor data
     202              :      * @param tag tag number in the [0x80-0xFF] range
     203              :      * @param data Integer representation of data to add
     204              :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     205              :      **/
     206              :     CHIP_ERROR addOptionalVendorData(uint8_t tag, int32_t data);
     207              : 
     208              :     /** @brief A function to remove an optional vendor data
     209              :      * @param tag tag number in the [0x80-0xFF] range
     210              :      * @return Returns a CHIP_ERROR_KEY_NOT_FOUND on error, CHIP_NO_ERROR otherwise
     211              :      **/
     212              :     CHIP_ERROR removeOptionalVendorData(uint8_t tag);
     213              : 
     214              :     /** @brief A function to retrieve an optional QR Code info vendor object
     215              :      * @param tag tag number in the [0x80-0xFF] range
     216              :      * @param info retrieved OptionalQRCodeInfo object
     217              :      * @return Returns a CHIP_ERROR_KEY_NOT_FOUND on error, CHIP_NO_ERROR otherwise
     218              :      **/
     219              :     CHIP_ERROR getOptionalVendorData(uint8_t tag, OptionalQRCodeInfo & info) const;
     220              : 
     221              :     /**
     222              :      * @brief A function to retrieve the vector of OptionalQRCodeInfo infos
     223              :      * @return Returns a vector of optionalQRCodeInfos
     224              :      **/
     225              :     std::vector<OptionalQRCodeInfo> getAllOptionalVendorData() const;
     226              : 
     227              :     /** @brief A function to add a string serial number
     228              :      * @param serialNumber string serial number
     229              :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     230              :      **/
     231              :     CHIP_ERROR addSerialNumber(std::string serialNumber);
     232              : 
     233              :     /** @brief A function to add a uint32_t serial number
     234              :      * @param serialNumber uint32_t serial number
     235              :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     236              :      **/
     237              :     CHIP_ERROR addSerialNumber(uint32_t serialNumber);
     238              : 
     239              :     /** @brief A function to retrieve serial number as a string
     240              :      * @param outSerialNumber retrieved string serial number
     241              :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     242              :      **/
     243              :     CHIP_ERROR getSerialNumber(std::string & outSerialNumber) const;
     244              : 
     245              :     /** @brief A function to remove the serial number from the payload
     246              :      * @return Returns a CHIP_ERROR_KEY_NOT_FOUND on error, CHIP_NO_ERROR otherwise
     247              :      **/
     248              :     CHIP_ERROR removeSerialNumber();
     249              : 
     250              :     bool operator==(const SetupPayload & input) const;
     251              : 
     252              :     /** @brief Checks if the tag is CHIP Common type
     253              :      * @param tag Tag to be checked
     254              :      * @return Returns True if the tag is of Common type
     255              :      **/
     256           43 :     static bool IsCommonTag(uint8_t tag) { return tag < 0x80; }
     257              : 
     258              :     /** @brief Checks if the tag is vendor-specific
     259              :      * @param tag Tag to be checked
     260              :      * @return Returns True if the tag is Vendor-specific
     261              :      **/
     262           24 :     static bool IsVendorTag(uint8_t tag) { return !IsCommonTag(tag); }
     263              : 
     264              :     /** @brief Generate a Random Setup Pin Code (Passcode)
     265              :      *
     266              :      * This function generates a random passcode within the defined limits (00000001 to 99999998)
     267              :      * It also checks that the generated passcode is not equal to any invalid passcode values as defined in 5.1.7.1.
     268              :      *
     269              :      * @param[out] setupPINCode The generated random setup PIN code.
     270              :      * @return Returns a CHIP_ERROR_INTERNAL if unable to generate a valid passcode within a reasonable number of attempts,
     271              :      * CHIP_NO_ERROR otherwise
     272              :      **/
     273              :     static CHIP_ERROR generateRandomSetupPin(uint32_t & setupPINCode);
     274              : 
     275              :     /**
     276              :      * @brief Get a list of setup payloads from a string representation.
     277              :      *
     278              :      * @param[in] stringRepresentation The string representing the payloads.
     279              : 
     280              :      * @param[out] outPayloads On success, the contents of this vector will be
     281              :      *                         replaces with the list of parsed payloads.  The
     282              :      *                         result may have only one entry, or multiple
     283              :      *                         entries if concatenated QR codes are used.
     284              :      *
     285              :      *                         On failure, the value of the out param should not
     286              :      *                         be relied on to be anything in particular.
     287              :      */
     288              :     static CHIP_ERROR FromStringRepresentation(std::string stringRepresentation, std::vector<SetupPayload> & outPayloads);
     289              : 
     290              : private:
     291              :     std::map<uint8_t, OptionalQRCodeInfo> optionalVendorData;
     292              :     std::map<uint8_t, OptionalQRCodeInfoExtension> optionalExtensionData;
     293              : 
     294              :     /** @brief A function to add an optional QR Code info vendor object
     295              :      * @param info Optional QR code info object to add
     296              :      * @return Returns a CHIP_ERROR_INVALID_ARGUMENT on error, CHIP_NO_ERROR otherwise
     297              :      **/
     298              :     CHIP_ERROR addOptionalVendorData(const OptionalQRCodeInfo & info);
     299              : 
     300              :     /** @brief A function to add an optional QR Code info CHIP object
     301              :      * @param info Optional QR code info object to add
     302              :      * @return Returns a CHIP_ERROR_INVALID_ARGUMENT on error, CHIP_NO_ERROR otherwise
     303              :      **/
     304              :     CHIP_ERROR addOptionalExtensionData(const OptionalQRCodeInfoExtension & info);
     305              : 
     306              :     /**
     307              :      * @brief A function to retrieve the vector of CHIPQRCodeInfo infos
     308              :      * @return Returns a vector of CHIPQRCodeInfos
     309              :      **/
     310              :     std::vector<OptionalQRCodeInfoExtension> getAllOptionalExtensionData() const;
     311              : 
     312              :     /** @brief A function to retrieve an optional QR Code info extended object
     313              :      * @param tag 8 bit [128-255] tag number
     314              :      * @param info retrieved OptionalQRCodeInfoExtension object
     315              :      * @return Returns a CHIP_ERROR_KEY_NOT_FOUND on error, CHIP_NO_ERROR otherwise
     316              :      **/
     317              :     CHIP_ERROR getOptionalExtensionData(uint8_t tag, OptionalQRCodeInfoExtension & info) const;
     318              : 
     319              :     /** @brief A function to retrieve the associated expected numeric value for a tag
     320              :      * @param tag 8 bit [0-255] tag number
     321              :      * @return Returns an optionalQRCodeInfoType value
     322              :      **/
     323              :     optionalQRCodeInfoType getNumericTypeFor(uint8_t tag) const;
     324              : };
     325              : 
     326              : } // namespace chip
        

Generated by: LCOV version 2.0-1