Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2021-2022 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 implements an object for a Matter User Directed Commissioning unsolicited
22 : * recipient (server).
23 : *
24 : */
25 :
26 : #include "UserDirectedCommissioning.h"
27 : #include <lib/core/CHIPSafeCasts.h>
28 : #include <lib/support/CHIPMemString.h>
29 : #include <system/TLVPacketBufferBackingStore.h>
30 : #include <transport/raw/Base.h>
31 :
32 : #include <unistd.h>
33 :
34 : namespace chip {
35 : namespace Protocols {
36 : namespace UserDirectedCommissioning {
37 :
38 0 : void UserDirectedCommissioningServer::OnMessageReceived(const Transport::PeerAddress & source, System::PacketBufferHandle && msg,
39 : Transport::MessageTransportContext * ctxt)
40 : {
41 : char addrBuffer[chip::Transport::PeerAddress::kMaxToStringSize];
42 0 : source.ToString(addrBuffer);
43 0 : ChipLogProgress(AppServer, "UserDirectedCommissioningServer::OnMessageReceived from %s", addrBuffer);
44 :
45 0 : PacketHeader packetHeader;
46 :
47 0 : ReturnOnFailure(packetHeader.DecodeAndConsume(msg));
48 :
49 0 : if (packetHeader.IsEncrypted())
50 : {
51 0 : ChipLogError(AppServer, "UDC encryption flag set - ignoring");
52 0 : return;
53 : }
54 :
55 0 : PayloadHeader payloadHeader;
56 0 : ReturnOnFailure(payloadHeader.DecodeAndConsume(msg));
57 :
58 0 : ChipLogProgress(AppServer, "IdentityDeclaration DataLength()=%" PRIu32, static_cast<uint32_t>(msg->DataLength()));
59 :
60 0 : uint8_t udcPayload[IdentificationDeclaration::kUdcTLVDataMaxBytes] = {};
61 0 : size_t udcPayloadLength = std::min<size_t>(msg->DataLength(), sizeof(udcPayload));
62 0 : ReturnOnFailure(msg->Read(udcPayload, udcPayloadLength));
63 :
64 0 : IdentificationDeclaration id;
65 0 : ReturnOnFailure(id.ReadPayload(udcPayload, udcPayloadLength));
66 :
67 0 : if (id.GetCancelPasscode())
68 : {
69 0 : HandleUDCCancel(id);
70 0 : return;
71 : }
72 :
73 0 : if (id.GetCommissionerPasscodeReady())
74 : {
75 0 : HandleUDCCommissionerPasscodeReady(id);
76 0 : return;
77 : }
78 :
79 0 : HandleNewUDC(source, id);
80 : }
81 :
82 0 : void UserDirectedCommissioningServer::HandleNewUDC(const Transport::PeerAddress & source, IdentificationDeclaration & id)
83 : {
84 0 : char * instanceName = (char *) id.GetInstanceName();
85 0 : ChipLogProgress(AppServer, "HandleNewUDC instance=%s ", id.GetInstanceName());
86 :
87 0 : UDCClientState * client = mUdcClients.FindUDCClientState(instanceName);
88 0 : if (client == nullptr)
89 : {
90 0 : ChipLogProgress(AppServer, "UDC new instance state received");
91 :
92 0 : id.DebugLog();
93 :
94 : CHIP_ERROR err;
95 0 : err = mUdcClients.CreateNewUDCClientState(instanceName, &client);
96 0 : if (err != CHIP_NO_ERROR)
97 : {
98 0 : ChipLogError(AppServer, "UDC error creating new connection state");
99 0 : return;
100 : }
101 :
102 0 : if (id.HasDiscoveryInfo())
103 : {
104 : // if we received mDNS info, skip the commissionable lookup
105 0 : ChipLogDetail(AppServer, "UDC discovery info provided");
106 0 : mUdcClients.MarkUDCClientActive(client);
107 :
108 0 : client->SetUDCClientProcessingState(UDCClientProcessingState::kPromptingUser);
109 0 : client->SetPeerAddress(source);
110 :
111 0 : id.UpdateClientState(client);
112 :
113 : // Call the registered mUserConfirmationProvider, if any.
114 0 : if (mUserConfirmationProvider != nullptr)
115 : {
116 0 : mUserConfirmationProvider->OnUserDirectedCommissioningRequest(*client);
117 : }
118 0 : return;
119 : }
120 :
121 : // Call the registered InstanceNameResolver, if any.
122 0 : if (mInstanceNameResolver != nullptr)
123 : {
124 0 : mInstanceNameResolver->FindCommissionableNode(client->GetInstanceName());
125 : }
126 : else
127 : {
128 0 : ChipLogError(AppServer, "UserDirectedCommissioningServer::OnMessageReceived no mInstanceNameResolver registered");
129 : }
130 : }
131 0 : mUdcClients.MarkUDCClientActive(client);
132 : }
133 :
134 0 : void UserDirectedCommissioningServer::HandleUDCCancel(IdentificationDeclaration & id)
135 : {
136 0 : char * instanceName = (char *) id.GetInstanceName();
137 0 : ChipLogProgress(AppServer, "HandleUDCCancel instance=%s ", id.GetInstanceName());
138 :
139 0 : UDCClientState * client = mUdcClients.FindUDCClientState(instanceName);
140 0 : if (client == nullptr)
141 : {
142 0 : ChipLogProgress(AppServer, "UDC no matching instance found");
143 0 : return;
144 : }
145 0 : id.DebugLog();
146 0 : mUdcClients.MarkUDCClientActive(client);
147 :
148 : // Call the registered mUserConfirmationProvider, if any.
149 0 : if (mUserConfirmationProvider != nullptr)
150 : {
151 0 : mUserConfirmationProvider->OnCancel(*client);
152 : }
153 :
154 : // reset this entry so that the client can try again without waiting an hour
155 0 : client->Reset();
156 : }
157 :
158 0 : void UserDirectedCommissioningServer::HandleUDCCommissionerPasscodeReady(IdentificationDeclaration & id)
159 : {
160 0 : char * instanceName = (char *) id.GetInstanceName();
161 0 : ChipLogProgress(AppServer, "HandleUDCCommissionerPasscodeReady instance=%s ", id.GetInstanceName());
162 :
163 0 : UDCClientState * client = mUdcClients.FindUDCClientState(instanceName);
164 0 : if (client == nullptr)
165 : {
166 0 : ChipLogProgress(AppServer, "UDC no matching instance found");
167 0 : return;
168 : }
169 0 : if (client->GetUDCClientProcessingState() != UDCClientProcessingState::kWaitingForCommissionerPasscodeReady)
170 : {
171 0 : ChipLogProgress(AppServer, "UDC instance not in waiting for passcode ready state");
172 0 : return;
173 : }
174 0 : id.DebugLog();
175 0 : mUdcClients.MarkUDCClientActive(client);
176 0 : client->SetUDCClientProcessingState(UDCClientProcessingState::kObtainingOnboardingPayload);
177 :
178 : // Call the registered mUserConfirmationProvider, if any.
179 0 : if (mUserConfirmationProvider != nullptr)
180 : {
181 0 : mUserConfirmationProvider->OnCommissionerPasscodeReady(*client);
182 : }
183 : }
184 :
185 0 : CHIP_ERROR UserDirectedCommissioningServer::SendCDCMessage(CommissionerDeclaration cd, chip::Transport::PeerAddress peerAddress)
186 : {
187 0 : if (mTransportMgr == nullptr)
188 : {
189 0 : ChipLogError(AppServer, "CDC: No transport manager\n");
190 0 : return CHIP_ERROR_INCORRECT_STATE;
191 : }
192 : uint8_t idBuffer[IdentificationDeclaration::kUdcTLVDataMaxBytes];
193 0 : uint32_t length = cd.WritePayload(idBuffer, sizeof(idBuffer));
194 0 : if (length == 0)
195 : {
196 0 : ChipLogError(AppServer, "CDC: error writing payload\n");
197 0 : return CHIP_ERROR_INTERNAL;
198 : }
199 :
200 0 : chip::System::PacketBufferHandle payload = chip::MessagePacketBuffer::NewWithData(idBuffer, length);
201 0 : if (payload.IsNull())
202 : {
203 0 : ChipLogError(AppServer, "Unable to allocate packet buffer\n");
204 0 : return CHIP_ERROR_NO_MEMORY;
205 : }
206 0 : ReturnErrorOnFailure(EncodeUDCMessage(payload));
207 :
208 0 : cd.DebugLog();
209 0 : ChipLogProgress(Inet, "Sending CDC msg");
210 :
211 0 : auto err = mTransportMgr->SendMessage(peerAddress, std::move(payload));
212 0 : if (err != CHIP_NO_ERROR)
213 : {
214 0 : ChipLogError(AppServer, "CDC SendMessage failed: %" CHIP_ERROR_FORMAT, err.Format());
215 0 : return err;
216 : }
217 :
218 0 : ChipLogProgress(Inet, "CDC msg sent");
219 0 : return CHIP_NO_ERROR;
220 0 : }
221 :
222 0 : CHIP_ERROR UserDirectedCommissioningServer::EncodeUDCMessage(const System::PacketBufferHandle & payload)
223 : {
224 0 : PayloadHeader payloadHeader;
225 0 : PacketHeader packetHeader;
226 :
227 0 : payloadHeader.SetMessageType(MsgType::IdentificationDeclaration).SetInitiator(true).SetNeedsAck(false);
228 :
229 0 : VerifyOrReturnError(!payload.IsNull(), CHIP_ERROR_INVALID_ARGUMENT);
230 0 : VerifyOrReturnError(!payload->HasChainedBuffer(), CHIP_ERROR_INVALID_MESSAGE_LENGTH);
231 0 : VerifyOrReturnError(payload->TotalLength() <= kMaxAppMessageLen, CHIP_ERROR_MESSAGE_TOO_LONG);
232 :
233 0 : ReturnErrorOnFailure(payloadHeader.EncodeBeforeData(payload));
234 :
235 0 : ReturnErrorOnFailure(packetHeader.EncodeBeforeData(payload));
236 :
237 0 : return CHIP_NO_ERROR;
238 : }
239 :
240 6 : CHIP_ERROR IdentificationDeclaration::ReadPayload(uint8_t * udcPayload, size_t payloadBufferSize)
241 : {
242 6 : if (payloadBufferSize < sizeof(mInstanceName))
243 : {
244 1 : ChipLogError(AppServer, "UDC payload too short for instance name");
245 1 : return CHIP_ERROR_INVALID_MESSAGE_LENGTH;
246 : }
247 :
248 5 : size_t instanceNameLen = strnlen(reinterpret_cast<const char *>(udcPayload), sizeof(mInstanceName) - 1);
249 5 : Platform::CopyString(mInstanceName, ByteSpan(udcPayload, instanceNameLen));
250 :
251 5 : if (payloadBufferSize == sizeof(mInstanceName))
252 : {
253 2 : ChipLogProgress(AppServer, "UDC - No TLV information in Identification Declaration");
254 2 : return CHIP_NO_ERROR;
255 : }
256 : // advance i to the end of the fixed length block containing instance name
257 3 : size_t i = sizeof(mInstanceName);
258 :
259 : CHIP_ERROR err;
260 :
261 3 : TLV::TLVReader reader;
262 3 : reader.Init(udcPayload + i, payloadBufferSize - i);
263 :
264 : // read the envelope
265 3 : ReturnErrorOnFailure(reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()));
266 :
267 3 : chip::TLV::TLVType outerContainerType = chip::TLV::kTLVType_Structure;
268 3 : ReturnErrorOnFailure(reader.EnterContainer(outerContainerType));
269 :
270 42 : while ((err = reader.Next()) == CHIP_NO_ERROR)
271 : {
272 19 : chip::TLV::Tag containerTag = reader.GetTag();
273 19 : if (!TLV::IsContextTag(containerTag))
274 : {
275 0 : ChipLogError(AppServer, "Unexpected non-context TLV tag.");
276 0 : return CHIP_ERROR_INVALID_TLV_TAG;
277 : }
278 19 : uint8_t tagNum = static_cast<uint8_t>(chip::TLV::TagNumFromTag(containerTag));
279 :
280 19 : switch (tagNum)
281 : {
282 1 : case kVendorIdTag:
283 : // vendorId
284 1 : err = reader.Get(mVendorId);
285 1 : break;
286 1 : case kProductIdTag:
287 : // productId
288 1 : err = reader.Get(mProductId);
289 1 : break;
290 1 : case kCdPortTag:
291 : // port
292 1 : err = reader.Get(mCdPort);
293 1 : break;
294 1 : case kDeviceNameTag:
295 : // deviceName
296 1 : err = reader.GetString(mDeviceName, sizeof(mDeviceName));
297 1 : break;
298 1 : case kPairingInstTag:
299 : // pairingInst
300 1 : err = reader.GetString(mPairingInst, sizeof(mPairingInst));
301 1 : break;
302 1 : case kPairingHintTag:
303 : // pairingHint
304 1 : err = reader.Get(mPairingHint);
305 1 : break;
306 2 : case kRotatingIdTag:
307 : // rotatingId
308 2 : if (reader.GetLength() <= sizeof(mRotatingId))
309 : {
310 1 : mRotatingIdLen = reader.GetLength();
311 1 : err = reader.GetBytes(mRotatingId, sizeof(mRotatingId));
312 : }
313 : else
314 : {
315 1 : mRotatingIdLen = 0;
316 1 : err = CHIP_ERROR_BUFFER_TOO_SMALL;
317 : }
318 2 : break;
319 2 : case kTargetAppListTag:
320 : // app vendor list
321 : {
322 2 : ChipLogProgress(AppServer, "TLV found an applist");
323 2 : chip::TLV::TLVType listContainerType = chip::TLV::kTLVType_List;
324 2 : ReturnErrorOnFailure(reader.EnterContainer(listContainerType));
325 :
326 30 : while ((err = reader.Next()) == CHIP_NO_ERROR && mNumTargetAppInfos < kMaxTargetAppInfos)
327 : {
328 13 : containerTag = reader.GetTag();
329 13 : if (!TLV::IsContextTag(containerTag))
330 : {
331 0 : ChipLogError(AppServer, "Unexpected non-context TLV tag.");
332 0 : return CHIP_ERROR_INVALID_TLV_TAG;
333 : }
334 13 : tagNum = static_cast<uint8_t>(chip::TLV::TagNumFromTag(containerTag));
335 13 : if (tagNum == kTargetAppTag)
336 : {
337 13 : ReturnErrorOnFailure(reader.EnterContainer(outerContainerType));
338 13 : uint16_t appVendorId = 0;
339 13 : uint16_t appProductId = 0;
340 :
341 78 : while ((err = reader.Next()) == CHIP_NO_ERROR)
342 : {
343 26 : containerTag = reader.GetTag();
344 26 : if (!TLV::IsContextTag(containerTag))
345 : {
346 0 : ChipLogError(AppServer, "Unexpected non-context TLV tag.");
347 0 : return CHIP_ERROR_INVALID_TLV_TAG;
348 : }
349 26 : tagNum = static_cast<uint8_t>(chip::TLV::TagNumFromTag(containerTag));
350 26 : if (tagNum == kAppVendorIdTag)
351 : {
352 13 : err = reader.Get(appVendorId);
353 : }
354 13 : else if (tagNum == kAppProductIdTag)
355 : {
356 13 : err = reader.Get(appProductId);
357 : }
358 : }
359 26 : if (err == CHIP_END_OF_TLV)
360 : {
361 13 : ChipLogProgress(AppServer, "TLV end of struct TLV");
362 13 : ReturnErrorOnFailure(reader.ExitContainer(outerContainerType));
363 : }
364 13 : if (appVendorId != 0)
365 : {
366 13 : mTargetAppInfos[mNumTargetAppInfos].vendorId = appVendorId;
367 13 : mTargetAppInfos[mNumTargetAppInfos].productId = appProductId;
368 13 : mNumTargetAppInfos++;
369 : }
370 : }
371 : else
372 : {
373 0 : ChipLogError(AppServer, "unrecognized tag %d", tagNum);
374 : }
375 : }
376 4 : if (err == CHIP_END_OF_TLV)
377 : {
378 1 : ChipLogProgress(AppServer, "TLV end of array");
379 1 : ReturnErrorOnFailure(reader.ExitContainer(listContainerType));
380 1 : err = CHIP_NO_ERROR;
381 : }
382 : }
383 2 : break;
384 1 : case kNoPasscodeTag:
385 1 : err = reader.Get(mNoPasscode);
386 1 : break;
387 1 : case kCdUponPasscodeDialogTag:
388 1 : err = reader.Get(mCdUponPasscodeDialog);
389 1 : break;
390 1 : case kCommissionerPasscodeTag:
391 1 : err = reader.Get(mCommissionerPasscode);
392 1 : break;
393 1 : case kCommissionerPasscodeReadyTag:
394 1 : err = reader.Get(mCommissionerPasscodeReady);
395 1 : break;
396 1 : case kCancelPasscodeTag:
397 1 : err = reader.Get(mCancelPasscode);
398 1 : break;
399 1 : case kPasscodeLengthTag:
400 1 : err = reader.Get(mPasscodeLength);
401 1 : break;
402 : }
403 38 : if (err != CHIP_NO_ERROR)
404 : {
405 1 : ChipLogError(AppServer, "IdentificationDeclaration::ReadPayload read error %" CHIP_ERROR_FORMAT, err.Format());
406 1 : return err;
407 : }
408 : }
409 :
410 4 : if (err == CHIP_END_OF_TLV)
411 : {
412 : // Exiting container
413 2 : ReturnErrorOnFailure(reader.ExitContainer(outerContainerType));
414 : }
415 : else
416 : {
417 0 : ChipLogError(AppServer, "IdentificationDeclaration::ReadPayload exiting early error %" CHIP_ERROR_FORMAT, err.Format());
418 0 : return err;
419 : }
420 :
421 2 : ChipLogProgress(AppServer, "UDC TLV parse complete");
422 2 : return CHIP_NO_ERROR;
423 : }
424 :
425 : /**
426 : * Reset the connection state to a completely uninitialized status.
427 : */
428 1 : uint32_t CommissionerDeclaration::WritePayload(uint8_t * payloadBuffer, size_t payloadBufferSize)
429 : {
430 : CHIP_ERROR err;
431 :
432 1 : chip::TLV::TLVWriter writer;
433 :
434 1 : writer.Init(payloadBuffer, payloadBufferSize);
435 :
436 1 : chip::TLV::TLVType outerContainerType = chip::TLV::kTLVType_Structure;
437 2 : VerifyOrExit(CHIP_NO_ERROR ==
438 : (err = writer.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure, outerContainerType)),
439 : LogErrorOnFailure(err));
440 :
441 2 : VerifyOrExit(CHIP_NO_ERROR == (err = writer.Put(chip::TLV::ContextTag(kErrorCodeTag), GetErrorCode())), LogErrorOnFailure(err));
442 2 : VerifyOrExit(CHIP_NO_ERROR == (err = writer.PutBoolean(chip::TLV::ContextTag(kNeedsPasscodeTag), mNeedsPasscode)),
443 : LogErrorOnFailure(err));
444 2 : VerifyOrExit(CHIP_NO_ERROR == (err = writer.PutBoolean(chip::TLV::ContextTag(kNoAppsFoundTag), mNoAppsFound)),
445 : LogErrorOnFailure(err));
446 2 : VerifyOrExit(CHIP_NO_ERROR ==
447 : (err = writer.PutBoolean(chip::TLV::ContextTag(kPasscodeDialogDisplayedTag), mPasscodeDialogDisplayed)),
448 : LogErrorOnFailure(err));
449 2 : VerifyOrExit(CHIP_NO_ERROR == (err = writer.PutBoolean(chip::TLV::ContextTag(kCommissionerPasscodeTag), mCommissionerPasscode)),
450 : LogErrorOnFailure(err));
451 2 : VerifyOrExit(CHIP_NO_ERROR == (err = writer.PutBoolean(chip::TLV::ContextTag(kQRCodeDisplayedTag), mQRCodeDisplayed)),
452 : LogErrorOnFailure(err));
453 2 : VerifyOrExit(CHIP_NO_ERROR == (err = writer.PutBoolean(chip::TLV::ContextTag(kCancelPasscodeTag), mCancelPasscode)),
454 : LogErrorOnFailure(err));
455 2 : VerifyOrExit(CHIP_NO_ERROR == (err = writer.Put(chip::TLV::ContextTag(kPasscodeLengthTag), GetPasscodeLength())),
456 : LogErrorOnFailure(err));
457 :
458 2 : VerifyOrExit(CHIP_NO_ERROR == (err = writer.EndContainer(outerContainerType)), LogErrorOnFailure(err));
459 2 : VerifyOrExit(CHIP_NO_ERROR == (err = writer.Finalize()), LogErrorOnFailure(err));
460 :
461 1 : ChipLogProgress(AppServer, "TLV write done");
462 :
463 1 : return writer.GetLengthWritten();
464 :
465 0 : exit:
466 0 : return 0;
467 : }
468 :
469 6 : void UserDirectedCommissioningServer::SetUDCClientProcessingState(char * instanceName, UDCClientProcessingState state)
470 : {
471 6 : UDCClientState * client = mUdcClients.FindUDCClientState(instanceName);
472 6 : if (client == nullptr)
473 : {
474 : CHIP_ERROR err;
475 3 : err = mUdcClients.CreateNewUDCClientState(instanceName, &client);
476 6 : if (err != CHIP_NO_ERROR)
477 : {
478 0 : ChipLogError(AppServer,
479 : "UserDirectedCommissioningServer::SetUDCClientProcessingState error creating new connection state");
480 0 : return;
481 : }
482 : }
483 :
484 6 : ChipLogDetail(AppServer, "SetUDCClientProcessingState instance=%s new state=%d", StringOrNullMarker(instanceName), (int) state);
485 :
486 6 : client->SetUDCClientProcessingState(state);
487 :
488 6 : mUdcClients.MarkUDCClientActive(client);
489 : }
490 :
491 6 : void UserDirectedCommissioningServer::OnCommissionableNodeFound(const Dnssd::DiscoveredNodeData & discNodeData)
492 : {
493 6 : if (!discNodeData.Is<Dnssd::CommissionNodeData>())
494 : {
495 0 : return;
496 : }
497 :
498 6 : const Dnssd::CommissionNodeData & nodeData = discNodeData.Get<Dnssd::CommissionNodeData>();
499 6 : if (nodeData.numIPs == 0)
500 : {
501 0 : ChipLogError(AppServer, "OnCommissionableNodeFound no IP addresses returned for instance name=%s", nodeData.instanceName);
502 0 : return;
503 : }
504 6 : if (nodeData.port == 0)
505 : {
506 0 : ChipLogError(AppServer, "OnCommissionableNodeFound no port returned for instance name=%s", nodeData.instanceName);
507 0 : return;
508 : }
509 :
510 6 : UDCClientState * client = mUdcClients.FindUDCClientState(nodeData.instanceName);
511 6 : if (client != nullptr && client->GetUDCClientProcessingState() == UDCClientProcessingState::kDiscoveringNode)
512 : {
513 2 : ChipLogDetail(AppServer, "OnCommissionableNodeFound instance: name=%s old_state=%d new_state=%d", client->GetInstanceName(),
514 : (int) client->GetUDCClientProcessingState(), (int) UDCClientProcessingState::kPromptingUser);
515 2 : client->SetUDCClientProcessingState(UDCClientProcessingState::kPromptingUser);
516 :
517 : #if INET_CONFIG_ENABLE_IPV4
518 : // prefer IPv4 if its an option
519 2 : bool foundV4 = false;
520 2 : for (unsigned i = 0; i < nodeData.numIPs; ++i)
521 : {
522 2 : if (nodeData.ipAddress[i].IsIPv4())
523 : {
524 2 : foundV4 = true;
525 2 : client->SetPeerAddress(chip::Transport::PeerAddress::UDP(nodeData.ipAddress[i], nodeData.port));
526 2 : break;
527 : }
528 : }
529 : // use IPv6 as last resort
530 2 : if (!foundV4)
531 : {
532 0 : client->SetPeerAddress(chip::Transport::PeerAddress::UDP(nodeData.ipAddress[0], nodeData.port));
533 : }
534 : #else // INET_CONFIG_ENABLE_IPV4
535 : // if we only support V6, then try to find a v6 address
536 : bool foundV6 = false;
537 : for (unsigned i = 0; i < nodeData.numIPs; ++i)
538 : {
539 : if (nodeData.ipAddress[i].IsIPv6())
540 : {
541 : foundV6 = true;
542 : client->SetPeerAddress(chip::Transport::PeerAddress::UDP(nodeData.ipAddress[i], nodeData.port));
543 : break;
544 : }
545 : }
546 : // last resort, try with what we have
547 : if (!foundV6)
548 : {
549 : ChipLogError(AppServer, "OnCommissionableNodeFound no v6 returned for instance name=%s", nodeData.instanceName);
550 : client->SetPeerAddress(chip::Transport::PeerAddress::UDP(nodeData.ipAddress[0], nodeData.port));
551 : }
552 : #endif // INET_CONFIG_ENABLE_IPV4
553 :
554 2 : client->SetDeviceName(nodeData.deviceName);
555 2 : client->SetLongDiscriminator(nodeData.longDiscriminator);
556 2 : client->SetVendorId(nodeData.vendorId);
557 2 : client->SetProductId(nodeData.productId);
558 2 : client->SetRotatingId(nodeData.rotatingId, nodeData.rotatingIdLen);
559 :
560 : // Call the registered mUserConfirmationProvider, if any.
561 2 : if (mUserConfirmationProvider != nullptr)
562 : {
563 1 : mUserConfirmationProvider->OnUserDirectedCommissioningRequest(*client);
564 : }
565 : }
566 : }
567 :
568 0 : void UserDirectedCommissioningServer::PrintUDCClients()
569 : {
570 : #if CHIP_PROGRESS_LOGGING
571 0 : for (uint8_t i = 0; i < kMaxUDCClients; i++)
572 : {
573 0 : UDCClientState * state = GetUDCClients().GetUDCClientState(i);
574 0 : if (state == nullptr)
575 : {
576 0 : ChipLogProgress(AppServer, "UDC Client[%d] null", i);
577 : }
578 : else
579 : {
580 : char addrBuffer[chip::Transport::PeerAddress::kMaxToStringSize];
581 0 : state->GetPeerAddress().ToString(addrBuffer);
582 :
583 0 : char rotatingIdString[chip::Dnssd::kMaxRotatingIdLen * 2 + 1] = "";
584 0 : const char * rotatingIdStringPtr = rotatingIdString;
585 0 : if (Encoding::BytesToUppercaseHexString(state->GetRotatingId(), chip::Dnssd::kMaxRotatingIdLen, rotatingIdString,
586 0 : sizeof(rotatingIdString)) != CHIP_NO_ERROR)
587 : {
588 0 : rotatingIdStringPtr = "<invalid id>";
589 : }
590 :
591 0 : ChipLogProgress(AppServer,
592 : "PrintUDCClients() UDC Client[%d] instance=%s deviceName=%s address=%s, vid/pid=%d/%d disc=%d rid=%s",
593 : i, state->GetInstanceName(), state->GetDeviceName(), addrBuffer, state->GetVendorId(),
594 : state->GetProductId(), state->GetLongDiscriminator(), rotatingIdStringPtr);
595 : }
596 : }
597 : #endif
598 0 : }
599 :
600 : } // namespace UserDirectedCommissioning
601 : } // namespace Protocols
602 : } // namespace chip
|