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