LCOV - code coverage report
Current view: top level - setup_payload - SetupPayload.h (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 8 8 100.0 %
Date: 2024-02-15 08:20:41 Functions: 2 2 100.0 %

          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             : 
      80             : // clang-format off
      81             : const int kTotalPayloadDataSizeInBits =
      82             :     kVersionFieldLengthInBits +
      83             :     kVendorIDFieldLengthInBits +
      84             :     kProductIDFieldLengthInBits +
      85             :     kCommissioningFlowFieldLengthInBits +
      86             :     kRendezvousInfoFieldLengthInBits +
      87             :     kPayloadDiscriminatorFieldLengthInBits +
      88             :     kSetupPINCodeFieldLengthInBits +
      89             :     kPaddingFieldLengthInBits;
      90             : // clang-format on
      91             : 
      92             : const int kTotalPayloadDataSizeInBytes = kTotalPayloadDataSizeInBits / 8;
      93             : 
      94             : const char * const kQRCodePrefix = "MT:";
      95             : 
      96             : /// The rendezvous type this device supports.
      97             : enum class RendezvousInformationFlag : uint8_t
      98             : {
      99             :     kNone      = 0,      ///< Device does not support any method for rendezvous
     100             :     kSoftAP    = 1 << 0, ///< Device supports Wi-Fi softAP
     101             :     kBLE       = 1 << 1, ///< Device supports BLE
     102             :     kOnNetwork = 1 << 2, ///< Device supports Setup on network
     103             : };
     104             : using RendezvousInformationFlags = chip::BitFlags<RendezvousInformationFlag, uint8_t>;
     105             : 
     106             : enum class CommissioningFlow : uint8_t
     107             : {
     108             :     kStandard = 0,       ///< Device automatically enters pairing mode upon power-up
     109             :     kUserActionRequired, ///< Device requires a user interaction to enter pairing mode
     110             :     kCustom,             ///< Commissioning steps should be retrieved from the distributed compliance ledger
     111             : };
     112             : 
     113             : /**
     114             :  * A parent struct to hold onboarding payload contents without optional info,
     115             :  * for compatibility with devices that don't support std::string or STL.
     116             :  */
     117             : struct PayloadContents
     118             : {
     119             :     uint8_t version                     = 0;
     120             :     uint16_t vendorID                   = 0;
     121             :     uint16_t productID                  = 0;
     122             :     CommissioningFlow commissioningFlow = CommissioningFlow::kStandard;
     123             :     // rendezvousInformation is Optional, because a payload parsed from a manual
     124             :     // numeric code would not have any rendezvousInformation available.  A
     125             :     // payload parsed from a QR code would always have a value for
     126             :     // rendezvousInformation.
     127             :     Optional<RendezvousInformationFlags> rendezvousInformation;
     128             :     SetupDiscriminator discriminator;
     129             :     uint32_t setUpPINCode = 0;
     130             : 
     131             :     bool isValidQRCodePayload() const;
     132             :     bool isValidManualCode() const;
     133             :     bool operator==(PayloadContents & input) const;
     134             : 
     135             :     static bool IsValidSetupPIN(uint32_t setupPIN);
     136             : 
     137             : private:
     138             :     bool CheckPayloadCommonConstraints() const;
     139             : };
     140             : 
     141             : enum optionalQRCodeInfoType
     142             : {
     143             :     optionalQRCodeInfoTypeUnknown,
     144             :     optionalQRCodeInfoTypeString,
     145             :     optionalQRCodeInfoTypeInt32,
     146             :     optionalQRCodeInfoTypeInt64,
     147             :     optionalQRCodeInfoTypeUInt32,
     148             :     optionalQRCodeInfoTypeUInt64
     149             : };
     150             : 
     151             : /**
     152             :  * A structure to hold optional QR Code info
     153             :  */
     154             : struct OptionalQRCodeInfo
     155             : {
     156          72 :     OptionalQRCodeInfo() { int32 = 0; }
     157             : 
     158             :     /*@{*/
     159             :     uint8_t tag;                      /**< the tag number of the optional info */
     160             :     enum optionalQRCodeInfoType type; /**< the type (String or Int) of the optional info */
     161             :     std::string data;                 /**< the string value if type is optionalQRCodeInfoTypeString, otherwise should not be set */
     162             :     int32_t int32;                    /**< the integer value if type is optionalQRCodeInfoTypeInt, otherwise should not be set */
     163             :     /*@}*/
     164             : };
     165             : 
     166             : struct OptionalQRCodeInfoExtension : OptionalQRCodeInfo
     167             : {
     168          29 :     OptionalQRCodeInfoExtension()
     169          29 :     {
     170          29 :         int32  = 0;
     171          29 :         int64  = 0;
     172          29 :         uint32 = 0;
     173          29 :         uint64 = 0;
     174          29 :     }
     175             : 
     176             :     int64_t int64;
     177             :     uint64_t uint32;
     178             :     uint64_t uint64;
     179             : };
     180             : 
     181             : class SetupPayload : public PayloadContents
     182             : {
     183             : 
     184             :     friend class QRCodeSetupPayloadGenerator;
     185             :     friend class QRCodeSetupPayloadParser;
     186             : 
     187             : public:
     188             :     /** @brief A function to add an optional vendor data
     189             :      * @param tag tag number in the [0x80-0xFF] range
     190             :      * @param data String representation of data to add
     191             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     192             :      **/
     193             :     CHIP_ERROR addOptionalVendorData(uint8_t tag, std::string data);
     194             : 
     195             :     /** @brief A function to add an optional vendor data
     196             :      * @param tag 7 bit [0-127] tag number
     197             :      * @param data Integer 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, int32_t data);
     201             : 
     202             :     /** @brief A function to remove an optional vendor data
     203             :      * @param tag 7 bit [0-127] tag number
     204             :      * @return Returns a CHIP_ERROR_KEY_NOT_FOUND on error, CHIP_NO_ERROR otherwise
     205             :      **/
     206             :     CHIP_ERROR removeOptionalVendorData(uint8_t tag);
     207             :     /**
     208             :      * @brief A function to retrieve the vector of OptionalQRCodeInfo infos
     209             :      * @return Returns a vector of optionalQRCodeInfos
     210             :      **/
     211             :     std::vector<OptionalQRCodeInfo> getAllOptionalVendorData() const;
     212             : 
     213             :     /** @brief A function to add a string serial number
     214             :      * @param serialNumber string serial number
     215             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     216             :      **/
     217             :     CHIP_ERROR addSerialNumber(std::string serialNumber);
     218             : 
     219             :     /** @brief A function to add a uint32_t serial number
     220             :      * @param serialNumber uint32_t serial number
     221             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     222             :      **/
     223             :     CHIP_ERROR addSerialNumber(uint32_t serialNumber);
     224             : 
     225             :     /** @brief A function to retrieve serial number as a string
     226             :      * @param outSerialNumber retrieved string serial number
     227             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     228             :      **/
     229             :     CHIP_ERROR getSerialNumber(std::string & outSerialNumber) const;
     230             : 
     231             :     /** @brief A function to remove the serial number from the payload
     232             :      * @return Returns a CHIP_ERROR_KEY_NOT_FOUND on error, CHIP_NO_ERROR otherwise
     233             :      **/
     234             :     CHIP_ERROR removeSerialNumber();
     235             : 
     236             :     bool operator==(SetupPayload & input);
     237             : 
     238             : private:
     239             :     std::map<uint8_t, OptionalQRCodeInfo> optionalVendorData;
     240             :     std::map<uint8_t, OptionalQRCodeInfoExtension> optionalExtensionData;
     241             : 
     242             :     /** @brief Checks if the tag is CHIP Common type
     243             :      * @param tag Tag to be checked
     244             :      * @return Returns True if the tag is of Common type
     245             :      **/
     246             :     static bool IsCommonTag(uint8_t tag);
     247             : 
     248             :     /** @brief Checks if the tag is vendor-specific
     249             :      * @param tag Tag to be checked
     250             :      * @return Returns True if the tag is Vendor-specific
     251             :      **/
     252             :     static bool IsVendorTag(uint8_t tag);
     253             : 
     254             :     /** @brief A function to add an optional QR Code info vendor object
     255             :      * @param info Optional QR code info object to add
     256             :      * @return Returns a CHIP_ERROR_INVALID_ARGUMENT on error, CHIP_NO_ERROR otherwise
     257             :      **/
     258             :     CHIP_ERROR addOptionalVendorData(const OptionalQRCodeInfo & info);
     259             : 
     260             :     /** @brief A function to add an optional QR Code info CHIP object
     261             :      * @param info Optional QR code info object to add
     262             :      * @return Returns a CHIP_ERROR_INVALID_ARGUMENT on error, CHIP_NO_ERROR otherwise
     263             :      **/
     264             :     CHIP_ERROR addOptionalExtensionData(const OptionalQRCodeInfoExtension & info);
     265             : 
     266             :     /**
     267             :      * @brief A function to retrieve the vector of CHIPQRCodeInfo infos
     268             :      * @return Returns a vector of CHIPQRCodeInfos
     269             :      **/
     270             :     std::vector<OptionalQRCodeInfoExtension> getAllOptionalExtensionData();
     271             : 
     272             :     /** @brief A function to retrieve an optional QR Code info vendor object
     273             :      * @param tag 7 bit [0-127] tag number
     274             :      * @param info retrieved OptionalQRCodeInfo object
     275             :      * @return Returns a CHIP_ERROR_KEY_NOT_FOUND on error, CHIP_NO_ERROR otherwise
     276             :      **/
     277             :     CHIP_ERROR getOptionalVendorData(uint8_t tag, OptionalQRCodeInfo & info);
     278             : 
     279             :     /** @brief A function to retrieve an optional QR Code info extended object
     280             :      * @param tag 8 bit [128-255] tag number
     281             :      * @param info retrieved OptionalQRCodeInfoExtension object
     282             :      * @return Returns a CHIP_ERROR_KEY_NOT_FOUND on error, CHIP_NO_ERROR otherwise
     283             :      **/
     284             :     CHIP_ERROR getOptionalExtensionData(uint8_t tag, OptionalQRCodeInfoExtension & info) const;
     285             : 
     286             :     /** @brief A function to retrieve the associated expected numeric value for a tag
     287             :      * @param tag 8 bit [0-255] tag number
     288             :      * @return Returns an optionalQRCodeInfoType value
     289             :      **/
     290             :     optionalQRCodeInfoType getNumericTypeFor(uint8_t tag);
     291             : };
     292             : 
     293             : } // namespace chip

Generated by: LCOV version 1.14