Matter SDK Coverage Report
Current view: top level - setup_payload - SetupPayload.h (source / functions) Coverage Total Hit
Test: SHA:e021a368d10ac6f3f201c101585146211fdcdaa2 Lines: 100.0 % 2 2
Test Date: 2026-02-13 08:13:38 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              :     kThread    = 1 << 5, ///< Device supports Thread
     108              : };
     109              : using RendezvousInformationFlags = chip::BitFlags<RendezvousInformationFlag, uint8_t>;
     110              : 
     111              : enum class CommissioningFlow : uint8_t
     112              : {
     113              :     kStandard = 0,       ///< Device automatically enters pairing mode upon power-up
     114              :     kUserActionRequired, ///< Device requires a user interaction to enter pairing mode
     115              :     kCustom,             ///< Commissioning steps should be retrieved from the distributed compliance ledger
     116              : };
     117              : 
     118              : /**
     119              :  * A parent struct to hold onboarding payload contents without optional info,
     120              :  * for compatibility with devices that don't support std::string or STL.
     121              :  */
     122              : struct PayloadContents
     123              : {
     124              :     uint8_t version                     = 0;
     125              :     uint16_t vendorID                   = 0;
     126              :     uint16_t productID                  = 0;
     127              :     CommissioningFlow commissioningFlow = CommissioningFlow::kStandard;
     128              :     // rendezvousInformation is Optional, because a payload parsed from a manual
     129              :     // numeric code would not have any rendezvousInformation available.  A
     130              :     // payload parsed from a QR code would always have a value for
     131              :     // rendezvousInformation.
     132              :     Optional<RendezvousInformationFlags> rendezvousInformation;
     133              :     SetupDiscriminator discriminator{};
     134              :     uint32_t setUpPINCode = 0;
     135              : 
     136              :     enum class ValidationMode : uint8_t
     137              :     {
     138              :         kProduce, ///< Only flags or values allowed by the current spec version are allowed.
     139              :                   ///  Producers of a Setup Payload should use this mode to ensure the
     140              :                   //   payload is valid according to the current spec version.
     141              :         kConsume, ///< Flags or values that are reserved for future use, or were allowed in
     142              :                   ///  a previous spec version may be present. Consumers of a Setup Payload
     143              :                   ///  should use this mode to ensure they are forward and backwards
     144              :                   ///  compatible with payloads from older or newer Matter devices.
     145              :     };
     146              : 
     147              :     bool isValidQRCodePayload(ValidationMode mode = ValidationMode::kProduce) const;
     148              :     bool isValidManualCode(ValidationMode mode = ValidationMode::kProduce) const;
     149              : 
     150              :     bool operator==(const PayloadContents & input) const;
     151              : 
     152              :     static bool IsValidSetupPIN(uint32_t setupPIN);
     153              : 
     154              : private:
     155              :     bool CheckPayloadCommonConstraints() const;
     156              : };
     157              : 
     158              : enum optionalQRCodeInfoType
     159              : {
     160              :     optionalQRCodeInfoTypeUnknown,
     161              :     optionalQRCodeInfoTypeString,
     162              :     optionalQRCodeInfoTypeInt32,
     163              :     optionalQRCodeInfoTypeInt64,
     164              :     optionalQRCodeInfoTypeUInt32,
     165              :     optionalQRCodeInfoTypeUInt64
     166              : };
     167              : 
     168              : /**
     169              :  * A structure to hold optional QR Code info
     170              :  */
     171              : struct OptionalQRCodeInfo
     172              : {
     173              :     /*@{*/
     174              :     uint8_t tag;                      /**< the tag number of the optional info */
     175              :     enum optionalQRCodeInfoType type; /**< the type (String or Int) of the optional info */
     176              :     std::string data;                 /**< the string value if type is optionalQRCodeInfoTypeString, otherwise should not be set */
     177              :     int32_t int32 = 0;                /**< the integer value if type is optionalQRCodeInfoTypeInt32, otherwise should not be set */
     178              :     /*@}*/
     179              : };
     180              : 
     181              : struct OptionalQRCodeInfoExtension : OptionalQRCodeInfo
     182              : {
     183              :     int64_t int64   = 0; /**< the integer value if type is optionalQRCodeInfoTypeInt64, otherwise should not be set */
     184              :     uint64_t uint32 = 0; /**< the integer value if type is optionalQRCodeInfoTypeUInt32, otherwise should not be set */
     185              :     uint64_t uint64 = 0; /**< the integer value if type is optionalQRCodeInfoTypeUInt64, otherwise should not be set */
     186              : };
     187              : 
     188              : class SetupPayload : public PayloadContents
     189              : {
     190              : 
     191              :     friend class QRCodeSetupPayloadGenerator;
     192              :     friend class QRCodeSetupPayloadParser;
     193              : 
     194              : public:
     195              :     /** @brief A function to add an optional vendor data
     196              :      * @param tag tag number in the [0x80-0xFF] range
     197              :      * @param data String representation of data to add
     198              :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     199              :      **/
     200              :     CHIP_ERROR addOptionalVendorData(uint8_t tag, std::string data);
     201              : 
     202              :     /** @brief A function to add an optional vendor data
     203              :      * @param tag tag number in the [0x80-0xFF] range
     204              :      * @param data Integer representation of data to add
     205              :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     206              :      **/
     207              :     CHIP_ERROR addOptionalVendorData(uint8_t tag, int32_t data);
     208              : 
     209              :     /** @brief A function to remove an optional vendor data
     210              :      * @param tag tag number in the [0x80-0xFF] range
     211              :      * @return Returns a CHIP_ERROR_KEY_NOT_FOUND on error, CHIP_NO_ERROR otherwise
     212              :      **/
     213              :     CHIP_ERROR removeOptionalVendorData(uint8_t tag);
     214              : 
     215              :     /** @brief A function to retrieve an optional QR Code info vendor object
     216              :      * @param tag tag number in the [0x80-0xFF] range
     217              :      * @param info retrieved OptionalQRCodeInfo object
     218              :      * @return Returns a CHIP_ERROR_KEY_NOT_FOUND on error, CHIP_NO_ERROR otherwise
     219              :      **/
     220              :     CHIP_ERROR getOptionalVendorData(uint8_t tag, OptionalQRCodeInfo & info) const;
     221              : 
     222              :     /**
     223              :      * @brief A function to retrieve the vector of OptionalQRCodeInfo infos
     224              :      * @return Returns a vector of optionalQRCodeInfos
     225              :      **/
     226              :     std::vector<OptionalQRCodeInfo> getAllOptionalVendorData() const;
     227              : 
     228              :     /** @brief A function to add a string serial number
     229              :      * @param serialNumber string serial number
     230              :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     231              :      **/
     232              :     CHIP_ERROR addSerialNumber(std::string serialNumber);
     233              : 
     234              :     /** @brief A function to add a uint32_t serial number
     235              :      * @param serialNumber uint32_t serial number
     236              :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     237              :      **/
     238              :     CHIP_ERROR addSerialNumber(uint32_t serialNumber);
     239              : 
     240              :     /** @brief A function to retrieve serial number as a string
     241              :      * @param outSerialNumber retrieved string serial number
     242              :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     243              :      **/
     244              :     CHIP_ERROR getSerialNumber(std::string & outSerialNumber) const;
     245              : 
     246              :     /** @brief A function to remove the serial number from the payload
     247              :      * @return Returns a CHIP_ERROR_KEY_NOT_FOUND on error, CHIP_NO_ERROR otherwise
     248              :      **/
     249              :     CHIP_ERROR removeSerialNumber();
     250              : 
     251              :     bool operator==(const SetupPayload & input) const;
     252              : 
     253              :     /** @brief Checks if the tag is CHIP Common type
     254              :      * @param tag Tag to be checked
     255              :      * @return Returns True if the tag is of Common type
     256              :      **/
     257           43 :     static bool IsCommonTag(uint8_t tag) { return tag < 0x80; }
     258              : 
     259              :     /** @brief Checks if the tag is vendor-specific
     260              :      * @param tag Tag to be checked
     261              :      * @return Returns True if the tag is Vendor-specific
     262              :      **/
     263           24 :     static bool IsVendorTag(uint8_t tag) { return !IsCommonTag(tag); }
     264              : 
     265              :     /** @brief Generate a Random Setup Pin Code (Passcode)
     266              :      *
     267              :      * This function generates a random passcode within the defined limits (00000001 to 99999998)
     268              :      * It also checks that the generated passcode is not equal to any invalid passcode values as defined in 5.1.7.1.
     269              :      *
     270              :      * @param[out] setupPINCode The generated random setup PIN code.
     271              :      * @return Returns a CHIP_ERROR_INTERNAL if unable to generate a valid passcode within a reasonable number of attempts,
     272              :      * CHIP_NO_ERROR otherwise
     273              :      **/
     274              :     static CHIP_ERROR generateRandomSetupPin(uint32_t & setupPINCode);
     275              : 
     276              :     /**
     277              :      * @brief Get a list of setup payloads from a string representation.
     278              :      *
     279              :      * @param[in] stringRepresentation The string representing the payloads.
     280              : 
     281              :      * @param[out] outPayloads On success, the contents of this vector will be
     282              :      *                         replaces with the list of parsed payloads.  The
     283              :      *                         result may have only one entry, or multiple
     284              :      *                         entries if concatenated QR codes are used.
     285              :      *
     286              :      *                         On failure, the value of the out param should not
     287              :      *                         be relied on to be anything in particular.
     288              :      */
     289              :     static CHIP_ERROR FromStringRepresentation(std::string stringRepresentation, std::vector<SetupPayload> & outPayloads);
     290              : 
     291              : private:
     292              :     std::map<uint8_t, OptionalQRCodeInfo> optionalVendorData;
     293              :     std::map<uint8_t, OptionalQRCodeInfoExtension> optionalExtensionData;
     294              : 
     295              :     /** @brief A function to add an optional QR Code info vendor object
     296              :      * @param info Optional QR code info object to add
     297              :      * @return Returns a CHIP_ERROR_INVALID_ARGUMENT on error, CHIP_NO_ERROR otherwise
     298              :      **/
     299              :     CHIP_ERROR addOptionalVendorData(const OptionalQRCodeInfo & info);
     300              : 
     301              :     /** @brief A function to add an optional QR Code info CHIP object
     302              :      * @param info Optional QR code info object to add
     303              :      * @return Returns a CHIP_ERROR_INVALID_ARGUMENT on error, CHIP_NO_ERROR otherwise
     304              :      **/
     305              :     CHIP_ERROR addOptionalExtensionData(const OptionalQRCodeInfoExtension & info);
     306              : 
     307              :     /**
     308              :      * @brief A function to retrieve the vector of CHIPQRCodeInfo infos
     309              :      * @return Returns a vector of CHIPQRCodeInfos
     310              :      **/
     311              :     std::vector<OptionalQRCodeInfoExtension> getAllOptionalExtensionData() const;
     312              : 
     313              :     /** @brief A function to retrieve an optional QR Code info extended object
     314              :      * @param tag 8 bit [128-255] tag number
     315              :      * @param info retrieved OptionalQRCodeInfoExtension object
     316              :      * @return Returns a CHIP_ERROR_KEY_NOT_FOUND on error, CHIP_NO_ERROR otherwise
     317              :      **/
     318              :     CHIP_ERROR getOptionalExtensionData(uint8_t tag, OptionalQRCodeInfoExtension & info) const;
     319              : 
     320              :     /** @brief A function to retrieve the associated expected numeric value for a tag
     321              :      * @param tag 8 bit [0-255] tag number
     322              :      * @return Returns an optionalQRCodeInfoType value
     323              :      **/
     324              :     optionalQRCodeInfoType getNumericTypeFor(uint8_t tag) const;
     325              : };
     326              : 
     327              : } // namespace chip
        

Generated by: LCOV version 2.0-1