Matter SDK Coverage Report
Current view: top level - protocols/user_directed_commissioning - UserDirectedCommissioningServer.cpp (source / functions) Coverage Total Hit
Test: SHA:6c8f029dd2432dc900f1c9245c324e69bd79e40a Lines: 52.1 % 288 150
Test Date: 2026-08-08 07:40:09 Functions: 36.4 % 11 4

            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
        

Generated by: LCOV version 2.0-1