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

Generated by: LCOV version 2.0-1