Line data Source code
1 : /*
2 : * Copyright (c) 2024 Project CHIP Authors
3 : * All rights reserved.
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 : #pragma once
19 :
20 : #include <lib/core/CHIPCallback.h>
21 : #include <lib/core/CHIPError.h>
22 : #include <lib/core/DataModelTypes.h>
23 : #include <lib/core/NodeId.h>
24 : #include <lib/core/Optional.h>
25 : #include <lib/support/Span.h>
26 : #include <setup_payload/SetupPayload.h>
27 : #include <system/SystemClock.h>
28 :
29 : namespace chip {
30 : namespace Controller {
31 :
32 : // Passing SetupPayload by value on purpose, in case a consumer decides to reuse
33 : // this object from inside the callback.
34 : typedef void (*OnOpenCommissioningWindow)(void * context, NodeId deviceId, CHIP_ERROR status, SetupPayload payload);
35 : typedef void (*OnOpenCommissioningWindowWithVerifier)(void * context, NodeId deviceId, CHIP_ERROR status);
36 : typedef void (*OnOpenBasicCommissioningWindow)(void * context, NodeId deviceId, CHIP_ERROR status);
37 :
38 : template <typename Derived>
39 : class CommissioningWindowCommonParams
40 : {
41 : public:
42 0 : CommissioningWindowCommonParams() = default;
43 :
44 12 : bool HasNodeId() const { return mNodeId != kUndefinedNodeId; }
45 4 : NodeId GetNodeId() const
46 : {
47 4 : VerifyOrDie(HasNodeId());
48 4 : return mNodeId;
49 : }
50 : // The node identifier of device
51 0 : Derived & SetNodeId(NodeId nodeId)
52 : {
53 0 : mNodeId = nodeId;
54 0 : return static_cast<Derived &>(*this);
55 : }
56 :
57 4 : EndpointId GetEndpointId() const { return mEndpointId; }
58 : Derived & SetEndpointId(EndpointId endpointId)
59 : {
60 : mEndpointId = endpointId;
61 : return static_cast<Derived &>(*this);
62 : }
63 :
64 4 : System::Clock::Seconds16 GetTimeout() const { return mTimeout; }
65 : // The duration for which the commissioning window should remain open.
66 0 : Derived & SetTimeout(System::Clock::Seconds16 timeout)
67 : {
68 0 : mTimeout = timeout;
69 0 : return static_cast<Derived &>(*this);
70 : }
71 : Derived & SetTimeout(uint16_t timeoutSeconds) { return SetTimeout(System::Clock::Seconds16(timeoutSeconds)); }
72 :
73 : // The PAKE iteration count associated with the PAKE Passcode ID and
74 : // ephemeral PAKE passcode verifier to be used for this commissioning.
75 18 : uint32_t GetIteration() const { return mIteration; }
76 0 : Derived & SetIteration(uint32_t iteration)
77 : {
78 0 : mIteration = iteration;
79 0 : return static_cast<Derived &>(*this);
80 : }
81 :
82 : // The long discriminator for the DNS-SD advertisement.
83 4 : uint16_t GetDiscriminator() const { return mDiscriminator.Value(); }
84 8 : bool HasDiscriminator() const { return mDiscriminator.HasValue(); }
85 0 : Derived & SetDiscriminator(uint16_t discriminator)
86 : {
87 0 : mDiscriminator = MakeOptional(discriminator);
88 0 : return static_cast<Derived &>(*this);
89 : }
90 :
91 : private:
92 : NodeId mNodeId = kUndefinedNodeId;
93 : EndpointId mEndpointId = kRootEndpointId; // Default endpoint for Administrator Commissioning Cluster
94 0 : System::Clock::Seconds16 mTimeout = System::Clock::Seconds16(300); // Defaulting
95 : uint32_t mIteration = 1000; // Defaulting
96 : Optional<uint16_t> mDiscriminator = NullOptional; // Using optional type to avoid picking a sentinnel in valid range
97 : };
98 :
99 : class CommissioningWindowPasscodeParams : public CommissioningWindowCommonParams<CommissioningWindowPasscodeParams>
100 : {
101 : public:
102 0 : CommissioningWindowPasscodeParams() = default;
103 :
104 6 : bool HasSetupPIN() const { return mSetupPIN.HasValue(); }
105 : // Get the value of setup PIN (Passcode) if present, crashes otherwise.
106 4 : uint32_t GetSetupPIN() const { return mSetupPIN.Value(); }
107 : // The setup PIN (Passcode) to use. A random one will be generated if not provided.
108 : CommissioningWindowPasscodeParams & SetSetupPIN(uint32_t setupPIN) { return SetSetupPIN(MakeOptional(setupPIN)); }
109 : // The setup PIN (Passcode) to use. A random one will be generated if NullOptional is used.
110 0 : CommissioningWindowPasscodeParams & SetSetupPIN(Optional<uint32_t> setupPIN)
111 : {
112 0 : mSetupPIN = setupPIN;
113 0 : return *this;
114 : }
115 :
116 6 : bool HasSalt() const { return mSalt.HasValue(); }
117 : // Get the value of salt if present.
118 : // Dies if absent! Make sure to check HasSalt()
119 10 : ByteSpan GetSalt() const { return mSalt.Value(); }
120 : // The salt to use. A random one will be generated if not provided.
121 : // If provided, must be at least kSpake2p_Min_PBKDF_Salt_Length bytes
122 : // and at most kSpake2p_Max_PBKDF_Salt_Length bytes in length.
123 : CommissioningWindowPasscodeParams & SetSalt(ByteSpan salt) { return SetSalt(MakeOptional(salt)); }
124 : // The salt to use. A random one will be generated if NullOptional is used.
125 : // If provided, must be at least kSpake2p_Min_PBKDF_Salt_Length bytes
126 : // and at most kSpake2p_Max_PBKDF_Salt_Length bytes in length.
127 : // Note that this an overloaded optional arg function to support existing APIs.
128 0 : CommissioningWindowPasscodeParams & SetSalt(Optional<ByteSpan> salt)
129 : {
130 0 : mSalt = salt;
131 0 : return *this;
132 : }
133 :
134 3 : bool GetReadVIDPIDAttributes() const { return mReadVIDPIDAttributes; }
135 : // Should the API internally read VID and PID from the device while opening the
136 : // commissioning window. If this argument is `true`, the API will read VID and PID
137 : // from the device and include them in the setup payload passed to the callback.
138 0 : CommissioningWindowPasscodeParams & SetReadVIDPIDAttributes(bool readVIDPIDAttributes)
139 : {
140 0 : mReadVIDPIDAttributes = readVIDPIDAttributes;
141 0 : return *this;
142 : }
143 :
144 3 : Callback::Callback<OnOpenCommissioningWindow> * GetCallback() const { return mCallback; }
145 : // The function to be called on success or failure of opening the commissioning window.
146 : // This will include the SetupPayload generated from provided parameters.
147 0 : CommissioningWindowPasscodeParams & SetCallback(Callback::Callback<OnOpenCommissioningWindow> * callback)
148 : {
149 0 : mCallback = callback;
150 0 : return *this;
151 : }
152 :
153 : private:
154 : Optional<uint32_t> mSetupPIN = NullOptional;
155 : Optional<ByteSpan> mSalt = NullOptional;
156 : bool mReadVIDPIDAttributes = false;
157 : Callback::Callback<OnOpenCommissioningWindow> * mCallback = nullptr;
158 : };
159 :
160 : class CommissioningWindowVerifierParams : public CommissioningWindowCommonParams<CommissioningWindowVerifierParams>
161 : {
162 : public:
163 : CommissioningWindowVerifierParams() = default;
164 :
165 2 : ByteSpan GetVerifier() const { return mVerifier.Value(); }
166 : // The PAKE passcode verifier generated with enclosed iterations, salt and not-enclosed passcode.
167 : CommissioningWindowVerifierParams & SetVerifier(ByteSpan verifier)
168 : {
169 : mVerifier = MakeOptional(verifier);
170 : return *this;
171 : }
172 :
173 11 : ByteSpan GetSalt() const { return mSalt.Value(); }
174 : // The salt that was used to generate the verifier.
175 : // It must be at least kSpake2p_Min_PBKDF_Salt_Length bytes.
176 : // Note: This is REQUIRED when verifier is used
177 : CommissioningWindowVerifierParams & SetSalt(ByteSpan salt)
178 : {
179 : mSalt = MakeOptional(salt);
180 : return *this;
181 : }
182 :
183 1 : Callback::Callback<OnOpenCommissioningWindowWithVerifier> * GetCallback() const { return mCallback; }
184 : // The function to be called on success or failure of opening the
185 : // commissioning window. This will NOT include the SetupPayload.
186 : CommissioningWindowVerifierParams & SetCallback(Callback::Callback<OnOpenCommissioningWindowWithVerifier> * callback)
187 : {
188 : mCallback = callback;
189 : return *this;
190 : }
191 :
192 : private:
193 : Optional<ByteSpan> mSalt;
194 : Optional<ByteSpan> mVerifier;
195 : Callback::Callback<OnOpenCommissioningWindowWithVerifier> * mCallback = nullptr;
196 : };
197 :
198 : } // namespace Controller
199 : } // namespace chip
|