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

Generated by: LCOV version 2.0-1