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 <cstdint>
27 :
28 : #include <lib/support/CodeUtils.h>
29 :
30 : namespace chip {
31 :
32 : class SetupDiscriminator
33 : {
34 : public:
35 0 : constexpr SetupDiscriminator() : mDiscriminator(0), mIsShortDiscriminator(false) {}
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 4 : void SetLongValue(uint16_t discriminator)
51 : {
52 4 : VerifyOrDie(discriminator == (discriminator & kLongMask));
53 4 : mDiscriminator = (discriminator & kLongMask);
54 4 : mIsShortDiscriminator = false;
55 4 : }
56 :
57 114 : 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 32 : uint16_t GetLongValue() const
70 : {
71 32 : VerifyOrDie(!IsShortDiscriminator());
72 32 : 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 25 : bool operator==(const SetupDiscriminator & other) const
86 : {
87 25 : 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;
108 : bool mIsShortDiscriminator;
109 : };
110 :
111 : } // namespace chip
|