Fix generation and parsing of Manual Setup Codes to match specification (#5383)

* Fix generation and parsing of Manual Setup Codes to match specification

See #5328

* Fixed naming conventions on constexpr's
Removed unused constants
Simplified shift calculation in ManualSetupPayloadGenerator
diff --git a/src/setup_payload/ManualSetupPayloadGenerator.cpp b/src/setup_payload/ManualSetupPayloadGenerator.cpp
index 004893f..0961a13 100644
--- a/src/setup_payload/ManualSetupPayloadGenerator.cpp
+++ b/src/setup_payload/ManualSetupPayloadGenerator.cpp
@@ -31,17 +31,59 @@
 
 namespace chip {
 
-static uint32_t shortPayloadRepresentation(const SetupPayload & payload)
+static uint32_t chunk1PayloadRepresentation(const SetupPayload & payload)
 {
-    constexpr int discriminatorOffset = kCustomFlowRequiredFieldLengthInBits;
-    constexpr int pinCodeOffset       = discriminatorOffset + kManualSetupDiscriminatorFieldLengthInBits;
-    uint32_t result                   = payload.requiresCustomFlow ? 1 : 0;
+    /* <1 digit> Represents:
+     *     - <bits 1..0> Discriminator <bits 11.10>
+     *     - <bit 2> VID/PID present flag
+     */
 
-    static_assert(kManualSetupDiscriminatorFieldBitMask <= UINT32_MAX >> discriminatorOffset, "Discriminator won't fit");
-    result |= static_cast<uint32_t>((payload.discriminator & kManualSetupDiscriminatorFieldBitMask) << discriminatorOffset);
+    constexpr int kDiscriminatorShift     = (kPayloadDiscriminatorFieldLengthInBits - kManualSetupChunk1DiscriminatorMsbitsLength);
+    constexpr uint32_t kDiscriminatorMask = (1 << kManualSetupChunk1DiscriminatorMsbitsLength) - 1;
 
-    static_assert(pinCodeOffset + kSetupPINCodeFieldLengthInBits <= std::numeric_limits<uint32_t>::digits, "PIN code won't fit");
-    result |= static_cast<uint32_t>(payload.setUpPINCode << pinCodeOffset);
+    static_assert(kManualSetupChunk1VidPidPresentBitPos >=
+                      kManualSetupChunk1DiscriminatorMsbitsPos + kManualSetupChunk1DiscriminatorMsbitsLength,
+                  "Discriminator won't fit");
+
+    uint32_t discriminatorChunk = (payload.discriminator >> kDiscriminatorShift) & kDiscriminatorMask;
+    uint32_t vidPidPresentFlag  = payload.requiresCustomFlow ? 1 : 0;
+
+    uint32_t result = (discriminatorChunk << kManualSetupChunk1DiscriminatorMsbitsPos) |
+        (vidPidPresentFlag << kManualSetupChunk1VidPidPresentBitPos);
+
+    return result;
+}
+
+static uint32_t chunk2PayloadRepresentation(const SetupPayload & payload)
+{
+    /* <5 digits> Represents:
+     *     - <bits 13..0> PIN Code <bits 13..0>
+     *     - <bits 15..14> Discriminator <bits 9..8>
+     */
+
+    constexpr int kDiscriminatorShift     = (kPayloadDiscriminatorFieldLengthInBits - kManualSetupDiscriminatorFieldLengthInBits);
+    constexpr uint32_t kDiscriminatorMask = (1 << kManualSetupChunk2DiscriminatorLsbitsLength) - 1;
+    constexpr uint32_t kPincodeMask       = (1 << kManualSetupChunk2PINCodeLsbitsLength) - 1;
+
+    uint32_t discriminatorChunk = (payload.discriminator >> kDiscriminatorShift) & kDiscriminatorMask;
+
+    uint32_t result = ((payload.setUpPINCode & kPincodeMask) << kManualSetupChunk2PINCodeLsbitsPos) |
+        (discriminatorChunk << kManualSetupChunk2DiscriminatorLsbitsPos);
+
+    return result;
+}
+
+static uint32_t chunk3PayloadRepresentation(const SetupPayload & payload)
+{
+    /* <4 digits> Represents:
+     *     - <bits 12..0> PIN Code <bits 26..14>
+     */
+
+    constexpr int kPincodeShift     = (kSetupPINCodeFieldLengthInBits - kManualSetupChunk3PINCodeMsbitsLength);
+    constexpr uint32_t kPincodeMask = (1 << kManualSetupChunk3PINCodeMsbitsLength) - 1;
+
+    uint32_t result = ((payload.setUpPINCode >> kPincodeShift) & kPincodeMask) << kManualSetupChunk3PINCodeMsbitsPos;
+
     return result;
 }
 
@@ -70,8 +112,22 @@
         return CHIP_ERROR_INVALID_ARGUMENT;
     }
 
-    uint32_t shortDecimal     = shortPayloadRepresentation(mSetupPayload);
-    std::string decimalString = decimalStringWithPadding(shortDecimal, kManualSetupShortCodeCharLength);
+    static_assert(kManualSetupCodeChunk1CharLength + kManualSetupCodeChunk2CharLength + kManualSetupCodeChunk3CharLength ==
+                      kManualSetupShortCodeCharLength,
+                  "Manual code length mismatch");
+    static_assert(kManualSetupChunk1DiscriminatorMsbitsLength + kManualSetupChunk2DiscriminatorLsbitsLength ==
+                      kManualSetupDiscriminatorFieldLengthInBits,
+                  "Discriminator won't fit");
+    static_assert(kManualSetupChunk2PINCodeLsbitsLength + kManualSetupChunk3PINCodeMsbitsLength == kSetupPINCodeFieldLengthInBits,
+                  "PIN code won't fit");
+
+    uint32_t chunk1 = chunk1PayloadRepresentation(mSetupPayload);
+    uint32_t chunk2 = chunk2PayloadRepresentation(mSetupPayload);
+    uint32_t chunk3 = chunk3PayloadRepresentation(mSetupPayload);
+
+    std::string decimalString = decimalStringWithPadding(chunk1, kManualSetupCodeChunk1CharLength);
+    decimalString += decimalStringWithPadding(chunk2, kManualSetupCodeChunk2CharLength);
+    decimalString += decimalStringWithPadding(chunk3, kManualSetupCodeChunk3CharLength);
 
     if (mSetupPayload.requiresCustomFlow)
     {
diff --git a/src/setup_payload/ManualSetupPayloadGenerator.h b/src/setup_payload/ManualSetupPayloadGenerator.h
index 362788a..7a7268c 100644
--- a/src/setup_payload/ManualSetupPayloadGenerator.h
+++ b/src/setup_payload/ManualSetupPayloadGenerator.h
@@ -21,13 +21,17 @@
  *      CHIP specification.
  *
  *      The encoding of the binary data to a decimal string is split
- *      into 3 chunks <32 bit><16 bit><16 bit>:
- *      - <32 bit> Represents:
- *          - <1 bit> 1 if vid+pid present, 0 otherwise
- *          - <27 bit> setup pin code
- *          - <4 bit> discriminator
- *      - <16 bit> Vendor ID
- *      - <16 bit> Product ID
+ *      into 5 chunks <1-digit/3-bits><5 digits/16-bits><4-digits/13-bits><5-digits/16-bits><5-digits/16-bits>:
+ *      - <1 digit> Represents:
+ *          - <bits 1..0> Discriminator <bits 11.10>
+ *          - <bit 2> VID/PID present flag
+ *      - <5 digits> Represents:
+ *          - <bits 13..0> PIN Code <bits 13..0>
+ *          - <bits 15..14> Discriminator <bits 9..8>
+ *      - <4 digits> Represents:
+ *          - <bits 12..0> PIN Code <bits 26..14>
+ *      - <5 digits> Vendor ID
+ *      - <5 digits> Product ID
  *
  */
 
diff --git a/src/setup_payload/ManualSetupPayloadParser.cpp b/src/setup_payload/ManualSetupPayloadParser.cpp
index eaab94d..e804134 100644
--- a/src/setup_payload/ManualSetupPayloadParser.cpp
+++ b/src/setup_payload/ManualSetupPayloadParser.cpp
@@ -63,21 +63,9 @@
     return CHIP_NO_ERROR;
 }
 
-// Extract n bits starting at index i and store it in dest
-static CHIP_ERROR extractBits(uint32_t number, uint64_t & dest, size_t index, size_t numberBits, size_t maxBits)
+static CHIP_ERROR toNumber(const std::string & decimalString, uint32_t & dest)
 {
-    if ((index + numberBits) > maxBits)
-    {
-        ChipLogError(SetupPayload, "Number %lu maxBits %zu index %zu n %zu", number, maxBits, index, numberBits);
-        return CHIP_ERROR_INVALID_STRING_LENGTH;
-    }
-    dest = (((1 << numberBits) - 1) & (number >> index));
-    return CHIP_NO_ERROR;
-}
-
-static CHIP_ERROR toNumber(const std::string & decimalString, uint64_t & dest)
-{
-    uint64_t number = 0;
+    uint32_t number = 0;
     for (char c : decimalString)
     {
         if (!isdigit(c))
@@ -86,14 +74,14 @@
             return CHIP_ERROR_INVALID_INTEGER_VALUE;
         }
         number *= 10;
-        number += static_cast<uint64_t>(c - '0');
+        number += static_cast<uint32_t>(c - '0');
     }
     dest = number;
     return CHIP_NO_ERROR;
 }
 
 // Populate numberOfChars into dest from decimalString starting at startIndex (least significant digit = left-most digit)
-static CHIP_ERROR readDigitsFromDecimalString(const std::string & decimalString, size_t & index, uint64_t & dest,
+static CHIP_ERROR readDigitsFromDecimalString(const std::string & decimalString, size_t & index, uint32_t & dest,
                                               size_t numberOfCharsToRead)
 {
     if (decimalString.length() < numberOfCharsToRead || (numberOfCharsToRead + index > decimalString.length()))
@@ -107,21 +95,6 @@
     return toNumber(decimalSubstring, dest);
 }
 
-// Populate numberOfBits into dest from number starting at startIndex (LSB = right-most bit)
-static CHIP_ERROR readBitsFromNumber(uint32_t number, size_t & index, uint64_t & dest, size_t numberOfBitsToRead, size_t maxBits)
-{
-    uint64_t bits     = 0;
-    CHIP_ERROR result = extractBits(number, bits, index, numberOfBitsToRead, maxBits);
-    if (result != CHIP_NO_ERROR)
-    {
-        return result;
-    }
-
-    index += numberOfBitsToRead;
-    dest = bits;
-    return CHIP_NO_ERROR;
-}
-
 CHIP_ERROR ManualSetupPayloadParser::populatePayload(SetupPayload & outPayload)
 {
     CHIP_ERROR result = CHIP_NO_ERROR;
@@ -135,44 +108,50 @@
     }
 
     size_t stringOffset = 0;
-    uint64_t shortCode;
-    result = readDigitsFromDecimalString(representationWithoutCheckDigit, stringOffset, shortCode, kManualSetupShortCodeCharLength);
+    uint32_t chunk1, chunk2, chunk3;
+
+    result = readDigitsFromDecimalString(representationWithoutCheckDigit, stringOffset, chunk1, kManualSetupCodeChunk1CharLength);
     if (result != CHIP_NO_ERROR)
     {
         return result;
     }
 
-    if (!CanCastTo<uint32_t>(shortCode))
+    result = readDigitsFromDecimalString(representationWithoutCheckDigit, stringOffset, chunk2, kManualSetupCodeChunk2CharLength);
+    if (result != CHIP_NO_ERROR)
     {
-        // Our attempts to extract discriminators and whatnot won't work right.
-        return CHIP_ERROR_INVALID_INTEGER_VALUE;
+        return result;
     }
 
-    bool isLongCode = (shortCode & 1) == 1;
+    result = readDigitsFromDecimalString(representationWithoutCheckDigit, stringOffset, chunk3, kManualSetupCodeChunk3CharLength);
+    if (result != CHIP_NO_ERROR)
+    {
+        return result;
+    }
+
+    bool isLongCode = ((chunk1 >> kManualSetupChunk1VidPidPresentBitPos) & 1) == 1;
     result          = checkCodeLengthValidity(representationWithoutCheckDigit, isLongCode);
     if (result != CHIP_NO_ERROR)
     {
         return result;
     }
 
-    size_t numberOffset = 1;
-    uint64_t setUpPINCode;
-    size_t maxShortCodeBitsLength = 1 + kSetupPINCodeFieldLengthInBits + kManualSetupDiscriminatorFieldLengthInBits;
+    constexpr uint32_t kDiscriminatorMsbitsMask = (1 << kManualSetupChunk1DiscriminatorMsbitsLength) - 1;
+    constexpr uint32_t kDiscriminatorLsbitsMask = (1 << kManualSetupChunk2DiscriminatorLsbitsLength) - 1;
 
-    uint64_t discriminator;
-    result = readBitsFromNumber(static_cast<uint32_t>(shortCode), numberOffset, discriminator,
-                                kManualSetupDiscriminatorFieldLengthInBits, maxShortCodeBitsLength);
-    if (result != CHIP_NO_ERROR)
-    {
-        return result;
-    }
+    uint32_t discriminator = ((chunk2 >> kManualSetupChunk2DiscriminatorLsbitsPos) & kDiscriminatorLsbitsMask);
+    discriminator |= ((chunk1 >> kManualSetupChunk1DiscriminatorMsbitsPos) & kDiscriminatorMsbitsMask)
+        << kManualSetupChunk2DiscriminatorLsbitsLength;
 
-    result = readBitsFromNumber(static_cast<uint32_t>(shortCode), numberOffset, setUpPINCode, kSetupPINCodeFieldLengthInBits,
-                                maxShortCodeBitsLength);
-    if (result != CHIP_NO_ERROR)
-    {
-        return result;
-    }
+    // Since manual code only contains upper msbits of discriminator, re-align
+    constexpr int kDiscriminatorShift = (kPayloadDiscriminatorFieldLengthInBits - kManualSetupDiscriminatorFieldLengthInBits);
+    discriminator <<= kDiscriminatorShift;
+
+    constexpr uint32_t kPincodeMsbitsMask = (1 << kManualSetupChunk3PINCodeMsbitsLength) - 1;
+    constexpr uint32_t kPincodeLsbitsMask = (1 << kManualSetupChunk2PINCodeLsbitsLength) - 1;
+
+    uint32_t setUpPINCode = ((chunk2 >> kManualSetupChunk2PINCodeLsbitsPos) & kPincodeLsbitsMask);
+    setUpPINCode |= ((chunk3 >> kManualSetupChunk3PINCodeMsbitsPos) & kPincodeMsbitsMask) << kManualSetupChunk2PINCodeLsbitsLength;
+
     if (setUpPINCode == 0)
     {
         ChipLogError(SetupPayload, "Failed decoding base10. SetUpPINCode was 0.");
@@ -181,7 +160,7 @@
 
     if (isLongCode)
     {
-        uint64_t vendorID;
+        uint32_t vendorID;
         result =
             readDigitsFromDecimalString(representationWithoutCheckDigit, stringOffset, vendorID, kManualSetupVendorIdCharLength);
         if (result != CHIP_NO_ERROR)
@@ -189,7 +168,7 @@
             return result;
         }
 
-        uint64_t productID;
+        uint32_t productID;
         result =
             readDigitsFromDecimalString(representationWithoutCheckDigit, stringOffset, productID, kManualSetupProductIdCharLength);
         if (result != CHIP_NO_ERROR)
diff --git a/src/setup_payload/SetupPayload.cpp b/src/setup_payload/SetupPayload.cpp
index 5dcd2ae..2888a39 100644
--- a/src/setup_payload/SetupPayload.cpp
+++ b/src/setup_payload/SetupPayload.cpp
@@ -79,10 +79,10 @@
 
 bool SetupPayload::isValidManualCode()
 {
-    // The discriminator for manual setup code is 4 least significant bits
+    // The discriminator for manual setup code is 4 most significant bits
     // in a regular 12 bit discriminator. Let's make sure that the provided
     // discriminator fits within 12 bits (kPayloadDiscriminatorFieldLengthInBits).
-    // The manual setup code generator will only use 4 least significant bits from
+    // The manual setup code generator will only use 4 most significant bits from
     // it.
     if (discriminator >= 1 << kPayloadDiscriminatorFieldLengthInBits)
     {
diff --git a/src/setup_payload/SetupPayload.h b/src/setup_payload/SetupPayload.h
index ebc5133..0a02137 100644
--- a/src/setup_payload/SetupPayload.h
+++ b/src/setup_payload/SetupPayload.h
@@ -33,23 +33,35 @@
 namespace chip {
 
 // TODO this should point to the spec
-const int kVersionFieldLengthInBits                  = 3;
-const int kVendorIDFieldLengthInBits                 = 16;
-const int kProductIDFieldLengthInBits                = 16;
-const int kCustomFlowRequiredFieldLengthInBits       = 1;
-const int kRendezvousInfoFieldLengthInBits           = 8;
-const int kPayloadDiscriminatorFieldLengthInBits     = 12;
-const int kManualSetupDiscriminatorFieldLengthInBits = 4;
-const int kManualSetupDiscriminatorFieldBitMask      = (1 << kManualSetupDiscriminatorFieldLengthInBits) - 1;
-const int kSetupPINCodeFieldLengthInBits             = 27;
-const int kPaddingFieldLengthInBits                  = 5;
+const int kVersionFieldLengthInBits                   = 3;
+const int kVendorIDFieldLengthInBits                  = 16;
+const int kProductIDFieldLengthInBits                 = 16;
+const int kCustomFlowRequiredFieldLengthInBits        = 1;
+const int kRendezvousInfoFieldLengthInBits            = 8;
+const int kPayloadDiscriminatorFieldLengthInBits      = 12;
+const int kManualSetupDiscriminatorFieldLengthInBits  = 4;
+const int kManualSetupChunk1DiscriminatorMsbitsPos    = 0;
+const int kManualSetupChunk1DiscriminatorMsbitsLength = 2;
+const int kManualSetupChunk1VidPidPresentBitPos =
+    (kManualSetupChunk1DiscriminatorMsbitsPos + kManualSetupChunk1DiscriminatorMsbitsLength);
+const int kManualSetupChunk2PINCodeLsbitsPos       = 0;
+const int kManualSetupChunk2PINCodeLsbitsLength    = 14;
+const int kManualSetupChunk2DiscriminatorLsbitsPos = (kManualSetupChunk2PINCodeLsbitsPos + kManualSetupChunk2PINCodeLsbitsLength);
+const int kManualSetupChunk2DiscriminatorLsbitsLength = 2;
+const int kManualSetupChunk3PINCodeMsbitsPos          = 0;
+const int kManualSetupChunk3PINCodeMsbitsLength       = 13;
+const int kSetupPINCodeFieldLengthInBits              = 27;
+const int kPaddingFieldLengthInBits                   = 5;
 
 const int kRawVendorTagLengthInBits = 7;
 
-const int kManualSetupShortCodeCharLength = 10;
-const int kManualSetupLongCodeCharLength  = 20;
-const int kManualSetupVendorIdCharLength  = 5;
-const int kManualSetupProductIdCharLength = 5;
+const int kManualSetupShortCodeCharLength  = 10;
+const int kManualSetupLongCodeCharLength   = 20;
+const int kManualSetupCodeChunk1CharLength = 1;
+const int kManualSetupCodeChunk2CharLength = 5;
+const int kManualSetupCodeChunk3CharLength = 4;
+const int kManualSetupVendorIdCharLength   = 5;
+const int kManualSetupProductIdCharLength  = 5;
 
 const uint8_t kSerialNumberTag = 128;
 
diff --git a/src/setup_payload/tests/TestManualCode.cpp b/src/setup_payload/tests/TestManualCode.cpp
index 417b6ad..b1a4a17 100644
--- a/src/setup_payload/tests/TestManualCode.cpp
+++ b/src/setup_payload/tests/TestManualCode.cpp
@@ -61,8 +61,8 @@
 SetupPayload GetDefaultPayload()
 {
     SetupPayload payload;
-    payload.setUpPINCode  = 1234;
-    payload.discriminator = 1;
+    payload.setUpPINCode  = 123456780;
+    payload.discriminator = 2560;
 
     return payload;
 }
@@ -71,7 +71,7 @@
 {
     SetupPayload payload = GetDefaultPayload();
 
-    std::string expectedResult = "0000039490";
+    std::string expectedResult = "2361087535";
 
     NL_TEST_ASSERT(inSuite, CheckGenerator(payload, expectedResult));
 }
@@ -81,7 +81,7 @@
     SetupPayload payload       = GetDefaultPayload();
     payload.requiresCustomFlow = true;
 
-    std::string expectedResult = "00000394910000000000";
+    std::string expectedResult = "63610875350000000000";
 
     NL_TEST_ASSERT(inSuite, CheckGenerator(payload, expectedResult));
 }
@@ -93,7 +93,7 @@
     payload.vendorID           = 1;
     payload.productID          = 1;
 
-    std::string expectedResult = "00000394910000100001";
+    std::string expectedResult = "63610875350000100001";
 
     NL_TEST_ASSERT(inSuite, CheckGenerator(payload, expectedResult));
 }
@@ -105,7 +105,7 @@
     payload.vendorID           = 45367;
     payload.productID          = 14526;
 
-    std::string expectedResult = "00000394914536714526";
+    std::string expectedResult = "63610875354536714526";
 
     NL_TEST_ASSERT(inSuite, CheckGenerator(payload, expectedResult));
 }
@@ -116,7 +116,7 @@
     payload.vendorID     = 45367;
     payload.productID    = 14526;
 
-    std::string expectedResult = "0000039490";
+    std::string expectedResult = "2361087535";
 
     NL_TEST_ASSERT(inSuite, CheckGenerator(payload, expectedResult));
 }
@@ -132,6 +132,20 @@
     NL_TEST_ASSERT(inSuite, CheckGenerator(payload, expectedResult));
 }
 
+void TestDecimalRepresentation_AllOnes(nlTestSuite * inSuite, void * inContext)
+{
+    SetupPayload payload;
+    payload.setUpPINCode       = 0x7FFFFFF;
+    payload.discriminator      = 0xFFF;
+    payload.requiresCustomFlow = true;
+    payload.vendorID           = 65535;
+    payload.productID          = 65535;
+
+    std::string expectedResult = "76553581916553565535";
+
+    NL_TEST_ASSERT(inSuite, CheckGenerator(payload, expectedResult));
+}
+
 void TestDecimalRepresentation_InvalidPayload(nlTestSuite * inSuite, void * inContext)
 {
     SetupPayload payload  = GetDefaultPayload();
@@ -156,7 +170,7 @@
 {
     SetupPayload payload       = GetDefaultPayload();
     payload.requiresCustomFlow = false;
-    payload.discriminator      = 0xf1a;
+    payload.discriminator      = 0xa1f;
 
     {
         // Test short 11 digit code
@@ -166,14 +180,14 @@
 
         SetupPayload outPayload;
         CHIP_ERROR err = ManualSetupPayloadParser(result).populatePayload(outPayload);
-        assertPayloadValues(inSuite, err, CHIP_NO_ERROR, outPayload, payload.setUpPINCode, 0xa, payload.vendorID,
+        assertPayloadValues(inSuite, err, CHIP_NO_ERROR, outPayload, payload.setUpPINCode, 0xa00, payload.vendorID,
                             payload.productID);
     }
 
     payload.vendorID           = 1;
     payload.productID          = 1;
     payload.requiresCustomFlow = true;
-    payload.discriminator      = 0xf1b;
+    payload.discriminator      = 0xb1f;
 
     {
         // Test long 21 digit code
@@ -183,7 +197,7 @@
 
         SetupPayload outPayload;
         CHIP_ERROR err = ManualSetupPayloadParser(result).populatePayload(outPayload);
-        assertPayloadValues(inSuite, err, CHIP_NO_ERROR, outPayload, payload.setUpPINCode, 0xb, payload.vendorID,
+        assertPayloadValues(inSuite, err, CHIP_NO_ERROR, outPayload, payload.setUpPINCode, 0xb00, payload.vendorID,
                             payload.productID);
     }
 }
@@ -201,20 +215,20 @@
     SetupPayload payload;
     std::string decimalString;
 
-    decimalString = "00000394914536714526";
+    decimalString = "63610875354536714526";
     decimalString += Verhoeff10::ComputeCheckChar(decimalString.c_str());
     CHIP_ERROR err = ManualSetupPayloadParser(decimalString).populatePayload(payload);
-    assertPayloadValues(inSuite, err, CHIP_NO_ERROR, payload, 1234, 1, 45367, 14526);
+    assertPayloadValues(inSuite, err, CHIP_NO_ERROR, payload, 123456780, 2560, 45367, 14526);
 
-    decimalString = "12393051190456200032";
+    decimalString = "52927623630456200032";
     decimalString += Verhoeff10::ComputeCheckChar(decimalString.c_str());
     err = ManualSetupPayloadParser(decimalString).populatePayload(payload);
-    assertPayloadValues(inSuite, err, CHIP_NO_ERROR, payload, 38728284, 15, 4562, 32);
+    assertPayloadValues(inSuite, err, CHIP_NO_ERROR, payload, 38728284, 1280, 4562, 32);
 
-    decimalString = "00000000350000100001";
+    decimalString = "40000100000000100001";
     decimalString += Verhoeff10::ComputeCheckChar(decimalString.c_str());
     err = ManualSetupPayloadParser(decimalString).populatePayload(payload);
-    assertPayloadValues(inSuite, err, CHIP_NO_ERROR, payload, 1, 1, 1, 1);
+    assertPayloadValues(inSuite, err, CHIP_NO_ERROR, payload, 1, 0, 1, 1);
 }
 
 void TestGenerateAndParser_FullPayload(nlTestSuite * inSuite, void * inContext)
@@ -254,40 +268,40 @@
     SetupPayload payload;
     std::string decimalString;
 
-    decimalString = "0000039490";
+    decimalString = "2361087535";
     decimalString += Verhoeff10::ComputeCheckChar(decimalString.c_str());
     NL_TEST_ASSERT(inSuite, decimalString.length() == 11);
     err = ManualSetupPayloadParser(decimalString).populatePayload(payload);
-    assertPayloadValues(inSuite, err, CHIP_NO_ERROR, payload, 1234, 1, 0, 0);
+    assertPayloadValues(inSuite, err, CHIP_NO_ERROR, payload, 123456780, 2560, 0, 0);
 
-    decimalString = "0000000034";
+    decimalString = "0000010000";
     decimalString += Verhoeff10::ComputeCheckChar(decimalString.c_str());
     NL_TEST_ASSERT(inSuite, decimalString.length() == 11);
     err = ManualSetupPayloadParser(decimalString).populatePayload(payload);
-    assertPayloadValues(inSuite, err, CHIP_NO_ERROR, payload, 1, 1, 0, 0);
-
-    decimalString = "00000000330000000000";
-    decimalString += Verhoeff10::ComputeCheckChar(decimalString.c_str());
-    NL_TEST_ASSERT(inSuite, decimalString.length() == 21);
-    err = ManualSetupPayloadParser(decimalString).populatePayload(payload);
     assertPayloadValues(inSuite, err, CHIP_NO_ERROR, payload, 1, 0, 0, 0);
 
+    decimalString = "63610875350000000000";
+    decimalString += Verhoeff10::ComputeCheckChar(decimalString.c_str());
+    NL_TEST_ASSERT(inSuite, decimalString.length() == 21);
+    err = ManualSetupPayloadParser(decimalString).populatePayload(payload);
+    assertPayloadValues(inSuite, err, CHIP_NO_ERROR, payload, 123456780, 2560, 0, 0);
+
     // no discriminator (= 0)
-    decimalString = "0000000032";
+    decimalString = "0033407535";
     decimalString += Verhoeff10::ComputeCheckChar(decimalString.c_str());
     NL_TEST_ASSERT(inSuite, decimalString.length() == 11);
     err = ManualSetupPayloadParser(decimalString).populatePayload(payload);
     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
 
     // no vid (= 0)
-    decimalString = "00000000330000014536";
+    decimalString = "63610875350000014526";
     decimalString += Verhoeff10::ComputeCheckChar(decimalString.c_str());
     NL_TEST_ASSERT(inSuite, decimalString.length() == 21);
     err = ManualSetupPayloadParser(decimalString).populatePayload(payload);
     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
 
     // no pid (= 0)
-    decimalString = "00000000332645300000";
+    decimalString = "63610875354536700000";
     decimalString += Verhoeff10::ComputeCheckChar(decimalString.c_str());
     NL_TEST_ASSERT(inSuite, decimalString.length() == 21);
     err = ManualSetupPayloadParser(decimalString).populatePayload(payload);
@@ -323,23 +337,6 @@
     NL_TEST_ASSERT(inSuite, inPayload == outPayload);
 }
 
-void TestExtractBits(nlTestSuite * inSuite, void * inContext)
-{
-    uint64_t dest;
-    CHIP_ERROR result = extractBits(5, dest, 2, 1, 3);
-    NL_TEST_ASSERT(inSuite, result == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, dest == 1);
-
-    result = extractBits(4567, dest, 4, 8, 13);
-    NL_TEST_ASSERT(inSuite, result == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, dest == 29);
-
-    NL_TEST_ASSERT(inSuite, extractBits(4567, dest, 4, 18, 13) == CHIP_ERROR_INVALID_STRING_LENGTH);
-    NL_TEST_ASSERT(inSuite, extractBits(4567, dest, 14, 2, 13) == CHIP_ERROR_INVALID_STRING_LENGTH);
-    NL_TEST_ASSERT(inSuite, extractBits(5, dest, 3, 1, 3) == CHIP_ERROR_INVALID_STRING_LENGTH);
-    NL_TEST_ASSERT(inSuite, extractBits(5, dest, 2, 2, 3) == CHIP_ERROR_INVALID_STRING_LENGTH);
-}
-
 void TestPayloadParser_InvalidEntry(nlTestSuite * inSuite, void * inContext)
 {
     SetupPayload payload;
@@ -381,7 +378,7 @@
     assertEmptyPayloadWithError(inSuite, ManualSetupPayloadParser(decimalString).populatePayload(payload),
                                 CHIP_ERROR_INVALID_STRING_LENGTH, payload);
     // no pin code (= 0)
-    decimalString = "0000000016";
+    decimalString = "2327680000";
     decimalString += Verhoeff10::ComputeCheckChar(decimalString.c_str());
     assertEmptyPayloadWithError(inSuite, ManualSetupPayloadParser(decimalString).populatePayload(payload),
                                 CHIP_ERROR_INVALID_ARGUMENT, payload);
@@ -432,12 +429,12 @@
 
 void TestDecimalStringToNumber(nlTestSuite * inSuite, void * inContext)
 {
-    uint64_t number;
+    uint32_t number;
     NL_TEST_ASSERT(inSuite, toNumber("12345", number) == CHIP_NO_ERROR);
     NL_TEST_ASSERT(inSuite, number == 12345);
 
-    NL_TEST_ASSERT(inSuite, toNumber("01234567890123456789", number) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, number == 1234567890123456789);
+    NL_TEST_ASSERT(inSuite, toNumber("01234567890", number) == CHIP_NO_ERROR);
+    NL_TEST_ASSERT(inSuite, number == 1234567890);
 
     NL_TEST_ASSERT(inSuite, toNumber("00000001", number) == CHIP_NO_ERROR);
     NL_TEST_ASSERT(inSuite, number == 1);
@@ -451,7 +448,7 @@
 
 void TestReadCharsFromDecimalString(nlTestSuite * inSuite, void * inContext)
 {
-    uint64_t number;
+    uint32_t number;
     size_t index = 3;
     NL_TEST_ASSERT(inSuite, readDigitsFromDecimalString("12345", index, number, 2) == CHIP_NO_ERROR);
     NL_TEST_ASSERT(inSuite, number == 45);
@@ -483,36 +480,6 @@
     NL_TEST_ASSERT(inSuite, readDigitsFromDecimalString("6256276377282", index, number, 1) == CHIP_ERROR_INVALID_STRING_LENGTH);
 }
 
-void TestReadBitsFromNumber(nlTestSuite * inSuite, void * inContext)
-{
-    uint64_t number;
-    size_t index = 3;
-    NL_TEST_ASSERT(inSuite, readBitsFromNumber(12345, index, number, 6, 14) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, number == 7);
-
-    index = 0;
-    NL_TEST_ASSERT(inSuite, readBitsFromNumber(12345, index, number, 14, 14) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, number == 12345);
-
-    index = 0;
-    NL_TEST_ASSERT(inSuite, readBitsFromNumber(1, index, number, 1, 14) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, number == 1);
-
-    index = 0;
-    NL_TEST_ASSERT(inSuite, readBitsFromNumber(12345, index, number, 20, 22) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, number == 12345);
-
-    index = 1;
-    NL_TEST_ASSERT(inSuite, readBitsFromNumber(1, index, number, 1, 14) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, number == 0);
-
-    index = 0;
-    NL_TEST_ASSERT(inSuite, readBitsFromNumber(12345, index, number, 15, 14) == CHIP_ERROR_INVALID_STRING_LENGTH);
-
-    index = 14;
-    NL_TEST_ASSERT(inSuite, readBitsFromNumber(12345, index, number, 1, 14) == CHIP_ERROR_INVALID_STRING_LENGTH);
-}
-
 void TestShortCodeCharLengths(nlTestSuite * inSuite, void * inContext)
 {
     size_t numBits                        = 1 + kSetupPINCodeFieldLengthInBits + kManualSetupDiscriminatorFieldLengthInBits;
@@ -544,16 +511,15 @@
     NL_TEST_DEF("Test Decimal Representation - Invalid Payload",                        TestDecimalRepresentation_InvalidPayload),
     NL_TEST_DEF("Test 12 bit discriminator for manual setup code",                      TestGenerateAndParser_ManualSetupCodeWithLongDiscriminator),
     NL_TEST_DEF("Test Decimal Representation - All Zeros",                              TestDecimalRepresentation_AllZeros),
+    NL_TEST_DEF("Test Decimal Representation - All Ones",                               TestDecimalRepresentation_AllOnes),
     NL_TEST_DEF("Parse from Partial Payload",                                           TestPayloadParser_PartialPayload),
     NL_TEST_DEF("Parse from Full Payload",                                              TestPayloadParser_FullPayload),
     NL_TEST_DEF("Test Invalid Entry To QR Code Parser",                                 TestPayloadParser_InvalidEntry),
     NL_TEST_DEF("Test Short Read Write",                                                TestShortCodeReadWrite),
     NL_TEST_DEF("Test Long Read Write",                                                 TestLongCodeReadWrite),
-    NL_TEST_DEF("Test Extract Bits",                                                    TestExtractBits),
     NL_TEST_DEF("Check Decimal String Validity",                                        TestCheckDecimalStringValidity),
     NL_TEST_DEF("Check QR Code Length Validity",                                        TestCheckCodeLengthValidity),
     NL_TEST_DEF("Test Decimal String to Number",                                        TestDecimalStringToNumber),
-    NL_TEST_DEF("Read Bits from Number",                                                TestReadBitsFromNumber),
     NL_TEST_DEF("Test Short Code Character Lengths",                                    TestShortCodeCharLengths),
     NL_TEST_DEF("Test Read Characters from Decimal String",                             TestReadCharsFromDecimalString),
     NL_TEST_DEF("Generate Full Payload and Parse it",                                   TestGenerateAndParser_FullPayload),