Line data Source code
1 : /* 2 : * 3 : * Copyright (c) 2022 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 defines the SetupDiscriminator type, which is used by 21 : * low-level code (e.g. BLE) in addition to setup payload code. 22 : */ 23 : 24 : #pragma once 25 : 26 : #include <lib/support/CodeUtils.h> 27 : 28 : #include <cstdint> 29 : 30 : namespace chip { 31 : 32 : class SetupDiscriminator 33 : { 34 : public: 35 0 : constexpr SetupDiscriminator() : mDiscriminator(0), mIsShortDiscriminator(0) {} 36 : 37 : // See section 5.1.2. QR Code in the Matter specification 38 : static constexpr int kLongBits = 12; 39 : 40 : // See section 5.1.3. Manual Pairing Code in the Matter specification 41 : static constexpr int kShortBits = 4; 42 : 43 0 : void SetShortValue(uint8_t discriminator) 44 : { 45 0 : VerifyOrDie(discriminator == (discriminator & kShortMask)); 46 0 : mDiscriminator = (discriminator & kShortMask); 47 0 : mIsShortDiscriminator = true; 48 0 : } 49 : 50 0 : void SetLongValue(uint16_t discriminator) 51 : { 52 0 : VerifyOrDie(discriminator == (discriminator & kLongMask)); 53 0 : mDiscriminator = (discriminator & kLongMask); 54 0 : mIsShortDiscriminator = false; 55 0 : } 56 : 57 26 : bool IsShortDiscriminator() const { return mIsShortDiscriminator; } 58 : 59 0 : uint8_t GetShortValue() const 60 : { 61 0 : if (IsShortDiscriminator()) 62 : { 63 0 : return static_cast<uint8_t>(mDiscriminator); 64 : } 65 : 66 0 : return LongToShortValue(mDiscriminator); 67 : } 68 : 69 26 : uint16_t GetLongValue() const 70 : { 71 26 : VerifyOrDie(!IsShortDiscriminator()); 72 26 : return mDiscriminator; 73 : } 74 : 75 : bool MatchesLongDiscriminator(uint16_t discriminator) const 76 : { 77 : if (!IsShortDiscriminator()) 78 : { 79 : return mDiscriminator == discriminator; 80 : } 81 : 82 : return mDiscriminator == LongToShortValue(discriminator); 83 : } 84 : 85 20 : bool operator==(const SetupDiscriminator & other) const 86 : { 87 20 : return mIsShortDiscriminator == other.mIsShortDiscriminator && mDiscriminator == other.mDiscriminator; 88 : } 89 : 90 : private: 91 : static constexpr uint16_t kLongMask = (1 << kLongBits) - 1; 92 : static constexpr uint8_t kShortMask = (1 << kShortBits) - 1; 93 : 94 0 : static uint8_t LongToShortValue(uint16_t longValue) 95 : { 96 : // Short value consists of the high bits of the long value. 97 0 : constexpr int kLongToShortShift = kLongBits - kShortBits; 98 0 : return static_cast<uint8_t>(longValue >> kLongToShortShift); 99 : } 100 : 101 : // If long discriminator, all 12 bits are used. If short discriminator, 102 : // only the low kShortBits bits are used, to store the value of the short 103 : // discriminator (which contains only the high bits of the complete 12-bit 104 : // discriminator). 105 : static_assert(kLongBits == 12, "Unexpected field length"); 106 : static_assert(kShortBits <= kLongBits, "Unexpected field length"); 107 : uint16_t mDiscriminator : 12; 108 : uint16_t mIsShortDiscriminator : 1; 109 : }; 110 : 111 : } // namespace chip