Matter SDK Coverage Report
Current view: top level - protocols/user_directed_commissioning - UserDirectedCommissioningServer.cpp (source / functions) Coverage Total Hit
Test: SHA:209dc18e4021e7d0dff8120ccc585909391dd862 Lines: 52.6 % 291 153
Test Date: 2026-06-16 07:34:53 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 <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
        

Generated by: LCOV version 2.0-1