Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2021 Project CHIP Authors
4 : * All rights reserved.
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 :
19 : /**
20 : * @file
21 : * This file defines objects for a User-Directed Commissioning unsolicited
22 : * initiator (client) and recipient (server).
23 : *
24 : */
25 :
26 : #pragma once
27 :
28 : #include "UDCClients.h"
29 : #include <lib/core/CHIPCore.h>
30 : #include <lib/dnssd/Resolver.h>
31 : #include <lib/support/CodeUtils.h>
32 : #include <lib/support/DLLUtil.h>
33 : #include <lib/support/logging/CHIPLogging.h>
34 : #include <messaging/ExchangeContext.h>
35 : #include <messaging/ExchangeMgr.h>
36 : #include <messaging/Flags.h>
37 : #include <protocols/Protocols.h>
38 : #include <transport/TransportMgr.h>
39 :
40 : namespace chip {
41 : namespace Protocols {
42 : namespace UserDirectedCommissioning {
43 :
44 : inline constexpr char kProtocolName[] = "UserDirectedCommissioning";
45 :
46 : // Cache contains 16 clients. This may need to be tweaked.
47 : inline constexpr uint8_t kMaxUDCClients = 16;
48 :
49 : /**
50 : * User Directed Commissioning Protocol Message Types
51 : */
52 : enum class MsgType : uint8_t
53 : {
54 : IdentificationDeclaration = 0x00,
55 : };
56 :
57 : /**
58 : * Represents the Identification Delaration message
59 : * sent by a UDC client to a UDC server.
60 : *
61 : * ### IdentificationDeclaration format
62 : *
63 : * <pre>
64 : * ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓
65 : * ┃ instance name '\n' ┃ ignore ┃ additional data TLV ┃
66 : * ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━┛
67 : * │← · · kInstanceNameMaxLength + 1 · · →│← TLV DataLength() →│
68 : *
69 : * Commissioning kInstanceNameMaxLength is 16
70 : * </pre>
71 : *
72 : */
73 : class DLL_EXPORT IdentificationDeclaration
74 : {
75 : public:
76 : constexpr static size_t kUdcTLVDataMaxBytes = 500;
77 :
78 0 : const char * GetInstanceName() const { return mInstanceName; }
79 : void SetInstanceName(const char * instanceName) { Platform::CopyString(mInstanceName, instanceName); }
80 :
81 0 : bool HasDiscoveryInfo() { return mVendorId != 0 && mProductId != 0 && mCdPort != 0 && strlen(mDeviceName) > 0; }
82 :
83 0 : const char * GetDeviceName() const { return mDeviceName; }
84 : void SetDeviceName(const char * deviceName) { Platform::CopyString(mDeviceName, deviceName); }
85 :
86 0 : uint16_t GetCdPort() const { return mCdPort; }
87 : void SetCdPort(uint16_t port) { mCdPort = port; }
88 :
89 0 : uint16_t GetVendorId() const { return mVendorId; }
90 : void SetVendorId(uint16_t vendorId) { mVendorId = vendorId; }
91 :
92 0 : uint16_t GetProductId() const { return mProductId; }
93 : void SetProductId(uint16_t productId) { mProductId = productId; }
94 :
95 0 : const uint8_t * GetRotatingId() const { return mRotatingId; }
96 0 : size_t GetRotatingIdLength() const { return mRotatingIdLen; }
97 : void SetRotatingId(const uint8_t * rotatingId, size_t rotatingIdLen)
98 : {
99 : size_t maxSize = ArraySize(mRotatingId);
100 : mRotatingIdLen = (maxSize < rotatingIdLen) ? maxSize : rotatingIdLen;
101 : memcpy(mRotatingId, rotatingId, mRotatingIdLen);
102 : }
103 :
104 0 : bool GetTargetAppInfo(uint8_t index, TargetAppInfo & info) const
105 : {
106 0 : if (index < mNumTargetAppInfos)
107 : {
108 0 : info.vendorId = mTargetAppInfos[index].vendorId;
109 0 : info.productId = mTargetAppInfos[index].productId;
110 0 : return true;
111 : }
112 0 : return false;
113 : }
114 0 : uint8_t GetNumTargetAppInfos() const { return mNumTargetAppInfos; }
115 :
116 : bool AddTargetAppInfo(TargetAppInfo vid)
117 : {
118 : if (mNumTargetAppInfos >= sizeof(mTargetAppInfos))
119 : {
120 : // already at max
121 : return false;
122 : }
123 : mTargetAppInfos[mNumTargetAppInfos].vendorId = vid.vendorId;
124 : mTargetAppInfos[mNumTargetAppInfos].productId = vid.productId;
125 : mNumTargetAppInfos++;
126 : return true;
127 : }
128 :
129 0 : const char * GetPairingInst() const { return mPairingInst; }
130 : void SetPairingInst(const char * pairingInst) { Platform::CopyString(mPairingInst, pairingInst); }
131 :
132 0 : uint16_t GetPairingHint() const { return mPairingHint; }
133 : void SetPairingHint(uint16_t pairingHint) { mPairingHint = pairingHint; }
134 :
135 : void SetNoPasscode(bool newValue) { mNoPasscode = newValue; };
136 0 : bool GetNoPasscode() const { return mNoPasscode; };
137 :
138 : void SetCdUponPasscodeDialog(bool newValue) { mCdUponPasscodeDialog = newValue; };
139 0 : bool GetCdUponPasscodeDialog() const { return mCdUponPasscodeDialog; };
140 :
141 : void SetCommissionerPasscode(bool newValue) { mCommissionerPasscode = newValue; };
142 0 : bool GetCommissionerPasscode() const { return mCommissionerPasscode; };
143 :
144 : void SetCommissionerPasscodeReady(bool newValue) { mCommissionerPasscodeReady = newValue; };
145 0 : bool GetCommissionerPasscodeReady() const { return mCommissionerPasscodeReady; };
146 :
147 : void SetCancelPasscode(bool newValue) { mCancelPasscode = newValue; };
148 0 : bool GetCancelPasscode() const { return mCancelPasscode; };
149 :
150 : /**
151 : * Writes the IdentificationDeclaration message to the given buffer.
152 : *
153 : * @return Total number of bytes written or 0 if an error occurred.
154 : */
155 : uint32_t WritePayload(uint8_t * payloadBuffer, size_t payloadBufferSize);
156 :
157 : /**
158 : * Reads the IdentificationDeclaration message from the given buffer.
159 : */
160 : CHIP_ERROR ReadPayload(uint8_t * payloadBuffer, size_t payloadBufferSize);
161 :
162 : /**
163 : * Assigns fields from this Identification Declaration to the given UDC client state.
164 : */
165 0 : void UpdateClientState(UDCClientState * client)
166 : {
167 0 : client->SetDeviceName(GetDeviceName());
168 0 : client->SetVendorId(GetVendorId());
169 0 : client->SetProductId(GetProductId());
170 0 : client->SetRotatingId(GetRotatingId(), GetRotatingIdLength());
171 0 : client->SetPairingInst(GetPairingInst());
172 0 : client->SetPairingHint(GetPairingHint());
173 0 : for (uint8_t i = 0; i < GetNumTargetAppInfos(); i++)
174 : {
175 0 : TargetAppInfo info;
176 0 : if (GetTargetAppInfo(i, info))
177 : {
178 0 : client->AddTargetAppInfo(info);
179 : }
180 : }
181 :
182 0 : client->SetCdPort(GetCdPort());
183 0 : client->SetNoPasscode(GetNoPasscode());
184 0 : client->SetCdUponPasscodeDialog(GetCdUponPasscodeDialog());
185 0 : client->SetCommissionerPasscode(GetCommissionerPasscode());
186 0 : client->SetCommissionerPasscodeReady(GetCommissionerPasscodeReady());
187 0 : client->SetCancelPasscode(GetCancelPasscode());
188 0 : }
189 :
190 0 : void DebugLog()
191 : {
192 0 : ChipLogDetail(AppServer, "---- Identification Declaration Start ----");
193 :
194 0 : ChipLogDetail(AppServer, "\tinstance: %s", mInstanceName);
195 0 : if (strlen(mDeviceName) != 0)
196 : {
197 0 : ChipLogDetail(AppServer, "\tdevice Name: %s", mDeviceName);
198 : }
199 0 : if (mVendorId != 0)
200 : {
201 0 : ChipLogDetail(AppServer, "\tvendor id: %d", mVendorId);
202 : }
203 0 : if (mProductId != 0)
204 : {
205 0 : ChipLogDetail(AppServer, "\tproduct id: %d", mProductId);
206 : }
207 0 : if (mCdPort != 0)
208 : {
209 0 : ChipLogDetail(AppServer, "\tcd port: %d", mCdPort);
210 : }
211 0 : if (mRotatingIdLen > 0)
212 : {
213 0 : char rotatingIdString[chip::Dnssd::kMaxRotatingIdLen * 2 + 1] = "";
214 0 : Encoding::BytesToUppercaseHexString(mRotatingId, mRotatingIdLen, rotatingIdString, sizeof(rotatingIdString));
215 0 : ChipLogDetail(AppServer, "\trotating id: %s", rotatingIdString);
216 : }
217 0 : for (uint8_t i = 0; i < mNumTargetAppInfos; i++)
218 : {
219 0 : ChipLogDetail(AppServer, "\tapp vendor id / product id [%d]: %u/%u", i, mTargetAppInfos[i].vendorId,
220 : mTargetAppInfos[i].productId);
221 : }
222 0 : if (strlen(mPairingInst) != 0)
223 : {
224 0 : ChipLogDetail(AppServer, "\tpairing instruction: %s", mPairingInst);
225 : }
226 0 : if (mPairingHint != 0)
227 : {
228 0 : ChipLogDetail(AppServer, "\tpairing hint: %d", mPairingHint);
229 : }
230 0 : if (mNoPasscode)
231 : {
232 0 : ChipLogDetail(AppServer, "\tno passcode: true");
233 : }
234 0 : if (mCdUponPasscodeDialog)
235 : {
236 0 : ChipLogDetail(AppServer, "\tcd upon passcode dialog: true");
237 : }
238 0 : if (mCommissionerPasscode)
239 : {
240 0 : ChipLogDetail(AppServer, "\tcommissioner passcode: true");
241 : }
242 0 : if (mCommissionerPasscodeReady)
243 : {
244 0 : ChipLogDetail(AppServer, "\tcommissioner passcode ready: true");
245 : }
246 0 : if (mCancelPasscode)
247 : {
248 0 : ChipLogDetail(AppServer, "\tcancel passcode: true");
249 : }
250 0 : ChipLogDetail(AppServer, "---- Identification Declaration End ----");
251 0 : }
252 :
253 : private:
254 : // TODO: update spec per the latest tags
255 : enum IdentificationDeclarationTLVTag
256 : {
257 : kVendorIdTag = 1,
258 : kProductIdTag,
259 : kDeviceNameTag,
260 : kDeviceTypeTag,
261 : kPairingInstTag,
262 : kPairingHintTag,
263 : kRotatingIdTag,
264 : kCdPortTag,
265 : kTargetAppListTag,
266 : kTargetAppTag,
267 : kAppVendorIdTag,
268 : kAppProductIdTag,
269 : kNoPasscodeTag,
270 : kCdUponPasscodeDialogTag,
271 : kCommissionerPasscodeTag,
272 : kCommissionerPasscodeReadyTag,
273 : kCancelPasscodeTag,
274 :
275 : kMaxNum = UINT8_MAX
276 : };
277 :
278 : char mInstanceName[Dnssd::Commission::kInstanceNameMaxLength + 1] = {};
279 : char mDeviceName[Dnssd::kMaxDeviceNameLen + 1] = {};
280 : uint16_t mCdPort = 0;
281 :
282 : uint16_t mVendorId = 0;
283 : uint16_t mProductId = 0;
284 : uint8_t mRotatingId[chip::Dnssd::kMaxRotatingIdLen];
285 : size_t mRotatingIdLen = 0;
286 :
287 : constexpr static size_t kMaxTargetAppInfos = 10;
288 : uint8_t mNumTargetAppInfos = 0; // number of vendor Ids
289 : TargetAppInfo mTargetAppInfos[kMaxTargetAppInfos];
290 :
291 : char mPairingInst[chip::Dnssd::kMaxPairingInstructionLen + 1] = {};
292 : uint16_t mPairingHint = 0;
293 :
294 : bool mNoPasscode = false;
295 : bool mCdUponPasscodeDialog = false;
296 : bool mCommissionerPasscode = false;
297 : bool mCommissionerPasscodeReady = false;
298 : bool mCancelPasscode = false;
299 : };
300 :
301 : /**
302 : * Represents the Commissioner Delaration message
303 : * sent by a UDC server to a UDC client.
304 : */
305 : class DLL_EXPORT CommissionerDeclaration
306 : {
307 : public:
308 : enum class CdError : uint16_t
309 : {
310 : kNoError = 0,
311 : kCommissionableDiscoveryFailed = 1,
312 : kPaseConnectionFailed = 2,
313 : kPaseAuthFailed = 3,
314 : kDacValidationFailed = 4,
315 : kAlreadyOnFabric = 5,
316 : kOperationalDiscoveryFailed = 6,
317 : kCaseConnectionFailed = 7,
318 : kCaseAuthFailed = 8,
319 : kConfigurationFailed = 9,
320 : kBindingConfigurationFailed = 10,
321 : kCommissionerPasscodeNotSupported = 11,
322 : kInvalidIdentificationDeclarationParams = 12,
323 : kAppInstallConsentPending = 13,
324 : kAppInstalling = 14,
325 : kAppInstallFailed = 15,
326 : kAppInstalledRetryNeeded = 16,
327 : kCommissionerPasscodeDisabled = 17,
328 : kUnexpectedCommissionerPasscodeReady = 18
329 : };
330 :
331 : constexpr static size_t kUdcTLVDataMaxBytes = 500;
332 :
333 : void SetErrorCode(CdError newValue) { mErrorCode = newValue; };
334 0 : CdError GetErrorCode() const { return mErrorCode; };
335 :
336 : void SetNeedsPasscode(bool newValue) { mNeedsPasscode = newValue; };
337 : bool GetNeedsPasscode() const { return mNeedsPasscode; };
338 :
339 : void SetNoAppsFound(bool newValue) { mNoAppsFound = newValue; };
340 : bool GetNoAppsFound() const { return mNoAppsFound; };
341 :
342 : void SetPasscodeDialogDisplayed(bool newValue) { mPasscodeDialogDisplayed = newValue; };
343 : bool GetPasscodeDialogDisplayed() const { return mPasscodeDialogDisplayed; };
344 :
345 : void SetCommissionerPasscode(bool newValue) { mCommissionerPasscode = newValue; };
346 : bool GetCommissionerPasscode() const { return mCommissionerPasscode; };
347 :
348 : void SetQRCodeDisplayed(bool newValue) { mQRCodeDisplayed = newValue; };
349 : bool GetQRCodeDisplayed() const { return mQRCodeDisplayed; };
350 :
351 : void SetCancelPasscode(bool newValue) { mCancelPasscode = newValue; };
352 : bool GetCancelPasscode() const { return mCancelPasscode; };
353 :
354 : /**
355 : * Writes the CommissionerDeclaration message to the given buffer.
356 : *
357 : * @return Total number of bytes written or 0 if an error occurred.
358 : */
359 : uint32_t WritePayload(uint8_t * payloadBuffer, size_t payloadBufferSize);
360 :
361 : /**
362 : * Reads the CommissionerDeclaration message from the given buffer.
363 : */
364 : CHIP_ERROR ReadPayload(uint8_t * payloadBuffer, size_t payloadBufferSize);
365 :
366 0 : void DebugLog()
367 : {
368 0 : ChipLogDetail(AppServer, "---- Commissioner Declaration Start ----");
369 :
370 0 : if (mErrorCode != CdError::kNoError)
371 : {
372 0 : ChipLogDetail(AppServer, "\terror code: %d", static_cast<uint16_t>(mErrorCode));
373 : }
374 :
375 0 : if (mNeedsPasscode)
376 : {
377 0 : ChipLogDetail(AppServer, "\tneeds passcode: true");
378 : }
379 0 : if (mNoAppsFound)
380 : {
381 0 : ChipLogDetail(AppServer, "\tno apps found: true");
382 : }
383 0 : if (mPasscodeDialogDisplayed)
384 : {
385 0 : ChipLogDetail(AppServer, "\tpasscode dialog displayed: true");
386 : }
387 0 : if (mCommissionerPasscode)
388 : {
389 0 : ChipLogDetail(AppServer, "\tcommissioner passcode: true");
390 : }
391 0 : if (mQRCodeDisplayed)
392 : {
393 0 : ChipLogDetail(AppServer, "\tQR code displayed: true");
394 : }
395 0 : if (mCancelPasscode)
396 : {
397 0 : ChipLogDetail(AppServer, "\tPasscode cancelled: true");
398 : }
399 0 : ChipLogDetail(AppServer, "---- Commissioner Declaration End ----");
400 0 : }
401 :
402 : private:
403 : // TODO: update spec per the latest tags
404 : enum CommissionerDeclarationTLVTag
405 : {
406 : kErrorCodeTag = 1,
407 : kNeedsPasscodeTag,
408 : kNoAppsFoundTag,
409 : kPasscodeDialogDisplayedTag,
410 : kCommissionerPasscodeTag,
411 : kQRCodeDisplayedTag,
412 : kCancelPasscodeTag,
413 :
414 : kMaxNum = UINT8_MAX
415 : };
416 :
417 : CdError mErrorCode = CdError::kNoError;
418 : bool mNeedsPasscode = false;
419 : bool mNoAppsFound = false;
420 : bool mPasscodeDialogDisplayed = false;
421 : bool mCommissionerPasscode = false;
422 : bool mQRCodeDisplayed = false;
423 : bool mCancelPasscode = false;
424 : };
425 :
426 : class DLL_EXPORT InstanceNameResolver
427 : {
428 : public:
429 : /**
430 : * @brief
431 : * Called when a UDC message is received specifying the given instanceName
432 : * This method indicates that UDC Server needs the Commissionable Node corresponding to
433 : * the given instance name to be found. UDC Server will wait for OnCommissionableNodeFound.
434 : *
435 : * @param instanceName DNS-SD instance name for the client requesting commissioning
436 : *
437 : */
438 : virtual void FindCommissionableNode(char * instanceName) = 0;
439 :
440 : virtual ~InstanceNameResolver() = default;
441 : };
442 :
443 : class DLL_EXPORT UserConfirmationProvider
444 : {
445 : public:
446 : /**
447 : * @brief
448 : * Called when an Identification Declaration UDC message has been received
449 : * and corresponding nodeData has been found.
450 : * It is expected that the implementer will prompt the user to confirm their intention to
451 : * commission the given node, and obtain the setup code to allow commissioning to proceed,
452 : * and then invoke commissioning on the given Node (using CHIP Device Controller, for example)
453 : *
454 : * @param[in] state The state for the UDC Client.
455 : *
456 : */
457 : virtual void OnUserDirectedCommissioningRequest(UDCClientState state) = 0;
458 :
459 : /**
460 : * @brief
461 : * Called when an Identification Declaration UDC message has been received
462 : * with the cancel flag set.
463 : * It is expected that the implementer will tear down any dialog prompts for the
464 : * commissionee instance (identified in the UDC client state argument).
465 : *
466 : * @param[in] state The state for the UDC Client.
467 : *
468 : */
469 : virtual void OnCancel(UDCClientState state) = 0;
470 :
471 : /**
472 : * @brief
473 : * Called when an Identification Declaration UDC message has been received
474 : * with the commissioner passcode ready flag set.
475 : * It is expected that the implementer will invoke commissioning on the
476 : * commissionee instance (identified in the UDC client state argument).
477 : *
478 : * @param[in] state The state for the UDC Client.
479 : *
480 : */
481 : virtual void OnCommissionerPasscodeReady(UDCClientState state) = 0;
482 :
483 : virtual ~UserConfirmationProvider() = default;
484 : };
485 :
486 : class DLL_EXPORT CommissionerDeclarationHandler
487 : {
488 : public:
489 : /**
490 : * @brief
491 : * Called when a Commissioner Declaration UDC message has been received.
492 : * It is expected that the implementer will de-dup messages received from the
493 : * same source within a short (1 second) time window.
494 : *
495 : * @param[in] source The source of the Commissioner Declaration Message.
496 : * @param[in] cd The Commissioner Declaration Message.
497 : *
498 : */
499 : virtual void OnCommissionerDeclarationMessage(const chip::Transport::PeerAddress & source, CommissionerDeclaration cd) = 0;
500 :
501 : virtual ~CommissionerDeclarationHandler() = default;
502 : };
503 :
504 : /**
505 : * TODO:
506 : * - add processing of Commissioner Declaration flags
507 : */
508 : class DLL_EXPORT UserDirectedCommissioningClient : public TransportMgrDelegate
509 : {
510 : public:
511 : /**
512 : * Send a User Directed Commissioning message to a CHIP node.
513 : *
514 : * @param transportMgr A transport to use for sending the message.
515 : * @param idMessage The Identification Declaration message.
516 : * @param peerAddress Address of destination.
517 : *
518 : * @return CHIP_ERROR_NO_MEMORY if allocation fails.
519 : * Other CHIP_ERROR codes as returned by the lower layers.
520 : *
521 : */
522 :
523 : CHIP_ERROR SendUDCMessage(TransportMgrBase * transportMgr, IdentificationDeclaration idMessage,
524 : chip::Transport::PeerAddress peerAddress);
525 :
526 : /**
527 : * Encode a User Directed Commissioning message.
528 : *
529 : * @param payload A PacketBufferHandle with the payload.
530 : *
531 : * @return CHIP_ERROR_NO_MEMORY if allocation fails.
532 : * Other CHIP_ERROR codes as returned by the lower layers.
533 : *
534 : */
535 :
536 : CHIP_ERROR EncodeUDCMessage(const System::PacketBufferHandle & payload);
537 :
538 : /**
539 : * Set the listener to be called when a Commissioner Declaration UDC request is received.
540 : *
541 : * @param[in] commissionerDeclarationHandler The callback function to handle the message.
542 : *
543 : */
544 : void SetCommissionerDeclarationHandler(CommissionerDeclarationHandler * commissionerDeclarationHandler)
545 : {
546 : ChipLogProgress(AppServer, "UserDirectedCommissioningClient::SetCommissionerDeclarationHandler()");
547 : mCommissionerDeclarationHandler = commissionerDeclarationHandler;
548 : }
549 :
550 : private:
551 : void OnMessageReceived(const Transport::PeerAddress & source, System::PacketBufferHandle && msgBuf,
552 : Transport::MessageTransportContext * ctxt = nullptr) override;
553 :
554 : CommissionerDeclarationHandler * mCommissionerDeclarationHandler = nullptr;
555 : };
556 :
557 : /**
558 : * TODO:
559 : * - add processing of Identification Declaration flags
560 : */
561 : class DLL_EXPORT UserDirectedCommissioningServer : public TransportMgrDelegate
562 : {
563 : public:
564 : /**
565 : * Set the listener to be called when a UDC request is received
566 : * and the Instance Name provided needs to be resolved.
567 : *
568 : * The resolver should call OnCommissionableNodeFound when the instance is found
569 : *
570 : * @param[in] instanceNameResolver The callback function to receive UDC request instance name.
571 : *
572 : */
573 : void SetInstanceNameResolver(InstanceNameResolver * instanceNameResolver) { mInstanceNameResolver = instanceNameResolver; }
574 :
575 : /**
576 : * Set the listener to be called when a UDC request is received
577 : * and the Instance Name has been resolved.
578 : *
579 : * The provider should prompt the user to allow commissioning of the node and provide the setup code.
580 : *
581 : * @param[in] userConfirmationProvider The callback function to obtain user confirmation.
582 : *
583 : */
584 : void SetUserConfirmationProvider(UserConfirmationProvider * userConfirmationProvider)
585 : {
586 : mUserConfirmationProvider = userConfirmationProvider;
587 : }
588 :
589 : /**
590 : * Update the processing state for a UDC Client based upon instance name.
591 : *
592 : * This can be used by the UX to set the state to one of the following values:
593 : * - kUserDeclined
594 : * - kObtainingOnboardingPayload
595 : * - kCommissioningNode
596 : * - kCommissioningFailed
597 : *
598 : * @param[in] instanceName The instance name for the UDC Client.
599 : * @param[in] state The state for the UDC Client.
600 : *
601 : */
602 : void SetUDCClientProcessingState(char * instanceName, UDCClientProcessingState state);
603 :
604 : /**
605 : * Reset the processing states for all UDC Clients
606 : *
607 : */
608 : void ResetUDCClientProcessingStates() { mUdcClients.ResetUDCClientStates(); }
609 :
610 : /**
611 : * Called when a CHIP Node in commissioning mode is found.
612 : *
613 : * Lookup instanceName from nodeData in the active UDC Client states
614 : * and if current state is kDiscoveringNode then change to kPromptingUser and
615 : * call UX Prompt callback
616 : *
617 : * @param[in] nodeData DNS-SD response data.
618 : *
619 : */
620 : void OnCommissionableNodeFound(const Dnssd::DiscoveredNodeData & nodeData);
621 :
622 : /**
623 : * Get the cache of UDC Clients
624 : *
625 : */
626 0 : UDCClients<kMaxUDCClients> & GetUDCClients() { return mUdcClients; }
627 :
628 : /**
629 : * Print the cache of UDC Clients
630 : *
631 : */
632 : void PrintUDCClients();
633 :
634 : /**
635 : * Send a Commissioner Declaration message to the given peer address
636 : *
637 : * Only one message will be sent.
638 : * Clients should follow spec and send up to 5 times with 100ms sleep between each call.
639 : */
640 : CHIP_ERROR SendCDCMessage(CommissionerDeclaration cdMessage, chip::Transport::PeerAddress peerAddress);
641 :
642 : /**
643 : * Encode a User Directed Commissioning message.
644 : *
645 : * @param payload A PacketBufferHandle with the payload.
646 : *
647 : * @return CHIP_ERROR_NO_MEMORY if allocation fails.
648 : * Other CHIP_ERROR codes as returned by the lower layers.
649 : *
650 : */
651 : CHIP_ERROR EncodeUDCMessage(const System::PacketBufferHandle & payload);
652 :
653 : /**
654 : * Assign the transport manager to use for Commissioner Declaration messages
655 : */
656 : void SetTransportManager(TransportMgrBase * transportMgr) { mTransportMgr = transportMgr; }
657 :
658 : private:
659 : InstanceNameResolver * mInstanceNameResolver = nullptr;
660 : UserConfirmationProvider * mUserConfirmationProvider = nullptr;
661 :
662 : void HandleNewUDC(const Transport::PeerAddress & source, IdentificationDeclaration & id);
663 : void HandleUDCCancel(IdentificationDeclaration & id);
664 : void HandleUDCCommissionerPasscodeReady(IdentificationDeclaration & id);
665 : void OnMessageReceived(const Transport::PeerAddress & source, System::PacketBufferHandle && msgBuf,
666 : Transport::MessageTransportContext * ctxt = nullptr) override;
667 :
668 : UDCClients<kMaxUDCClients> mUdcClients; // < Active UDC clients
669 :
670 : TransportMgrBase * mTransportMgr = nullptr;
671 : };
672 :
673 : } // namespace UserDirectedCommissioning
674 :
675 : template <>
676 : struct MessageTypeTraits<UserDirectedCommissioning::MsgType>
677 : {
678 1 : static constexpr const Protocols::Id & ProtocolId() { return UserDirectedCommissioning::Id; }
679 :
680 0 : static auto GetTypeToNameTable()
681 : {
682 : static const std::array<MessageTypeNameLookup, 1> typeToNameTable = {
683 : {
684 : { UserDirectedCommissioning::MsgType::IdentificationDeclaration, "IdentificationDeclaration" },
685 : },
686 : };
687 :
688 0 : return &typeToNameTable;
689 : }
690 : };
691 :
692 : } // namespace Protocols
693 : } // namespace chip
|