Matter SDK Coverage Report
Current view: top level - protocols/user_directed_commissioning - UserDirectedCommissioningClient.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 61.1 % 126 77
Test Date: 2025-01-17 19:00:11 Functions: 60.0 % 5 3

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2021 Project CHIP Authors
       4              :  *    All rights reserved.
       5              :  *
       6              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       7              :  *    you may not use this file except in compliance with the License.
       8              :  *    You may obtain a copy of the License at
       9              :  *
      10              :  *        http://www.apache.org/licenses/LICENSE-2.0
      11              :  *
      12              :  *    Unless required by applicable law or agreed to in writing, software
      13              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      14              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15              :  *    See the License for the specific language governing permissions and
      16              :  *    limitations under the License.
      17              :  */
      18              : 
      19              : /**
      20              :  *    @file
      21              :  *      This file implements an object for a Matter User Directed Commissioning unsolicited
      22              :  *      initiator (client).
      23              :  *
      24              :  */
      25              : 
      26              : #include "UserDirectedCommissioning.h"
      27              : #include <transport/raw/Base.h>
      28              : 
      29              : #ifdef __ZEPHYR__
      30              : #include <zephyr/kernel.h>
      31              : #endif // __ZEPHYR__
      32              : 
      33              : #include <unistd.h>
      34              : 
      35              : namespace chip {
      36              : namespace Protocols {
      37              : namespace UserDirectedCommissioning {
      38              : 
      39            0 : CHIP_ERROR UserDirectedCommissioningClient::SendUDCMessage(TransportMgrBase * transportMgr, IdentificationDeclaration id,
      40              :                                                            chip::Transport::PeerAddress peerAddress)
      41              : {
      42              :     uint8_t idBuffer[IdentificationDeclaration::kUdcTLVDataMaxBytes];
      43            0 :     uint32_t length = id.WritePayload(idBuffer, sizeof(idBuffer));
      44            0 :     if (length == 0)
      45              :     {
      46            0 :         ChipLogError(AppServer, "UDC: error writing payload\n");
      47            0 :         return CHIP_ERROR_INTERNAL;
      48              :     }
      49              : 
      50            0 :     chip::System::PacketBufferHandle payload = chip::MessagePacketBuffer::NewWithData(idBuffer, length);
      51            0 :     if (payload.IsNull())
      52              :     {
      53            0 :         ChipLogError(AppServer, "Unable to allocate packet buffer\n");
      54            0 :         return CHIP_ERROR_NO_MEMORY;
      55              :     }
      56            0 :     ReturnErrorOnFailure(EncodeUDCMessage(payload));
      57              : 
      58            0 :     id.DebugLog();
      59            0 :     ChipLogProgress(Inet, "Sending UDC msg");
      60              : 
      61              :     // send UDC message 5 times per spec (no ACK on this message)
      62            0 :     for (unsigned int i = 0; i < 5; i++)
      63              :     {
      64            0 :         auto msgCopy = payload.CloneData();
      65            0 :         VerifyOrReturnError(!msgCopy.IsNull(), CHIP_ERROR_NO_MEMORY);
      66              : 
      67            0 :         auto err = transportMgr->SendMessage(peerAddress, std::move(msgCopy));
      68            0 :         if (err != CHIP_NO_ERROR)
      69              :         {
      70            0 :             ChipLogError(AppServer, "UDC SendMessage failed: %" CHIP_ERROR_FORMAT, err.Format());
      71            0 :             return err;
      72              :         }
      73              :         // Zephyr doesn't provide usleep implementation.
      74              : #ifdef __ZEPHYR__
      75              :         k_usleep(100 * 1000); // 100ms
      76              : #else
      77            0 :         usleep(100 * 1000); // 100ms
      78              : #endif // __ZEPHYR__
      79            0 :     }
      80              : 
      81            0 :     ChipLogProgress(Inet, "UDC msg sent");
      82            0 :     return CHIP_NO_ERROR;
      83            0 : }
      84              : 
      85            1 : CHIP_ERROR UserDirectedCommissioningClient::EncodeUDCMessage(const System::PacketBufferHandle & payload)
      86              : {
      87            1 :     PayloadHeader payloadHeader;
      88            1 :     PacketHeader packetHeader;
      89              : 
      90            1 :     payloadHeader.SetMessageType(MsgType::IdentificationDeclaration).SetInitiator(true).SetNeedsAck(false);
      91              : 
      92            1 :     VerifyOrReturnError(!payload.IsNull(), CHIP_ERROR_INVALID_ARGUMENT);
      93            1 :     VerifyOrReturnError(!payload->HasChainedBuffer(), CHIP_ERROR_INVALID_MESSAGE_LENGTH);
      94            1 :     VerifyOrReturnError(payload->TotalLength() <= kMaxAppMessageLen, CHIP_ERROR_MESSAGE_TOO_LONG);
      95              : 
      96            1 :     ReturnErrorOnFailure(payloadHeader.EncodeBeforeData(payload));
      97              : 
      98            1 :     ReturnErrorOnFailure(packetHeader.EncodeBeforeData(payload));
      99              : 
     100            1 :     return CHIP_NO_ERROR;
     101            1 : }
     102              : 
     103              : /**
     104              :  *  Reset the connection state to a completely uninitialized status.
     105              :  */
     106            1 : uint32_t IdentificationDeclaration::WritePayload(uint8_t * payloadBuffer, size_t payloadBufferSize)
     107              : {
     108              :     CHIP_ERROR err;
     109              : 
     110            1 :     chip::TLV::TLVWriter writer;
     111            1 :     chip::TLV::TLVType listContainerType = chip::TLV::kTLVType_List;
     112              : 
     113            1 :     memcpy(payloadBuffer, mInstanceName, sizeof(mInstanceName));
     114              : 
     115            1 :     writer.Init(payloadBuffer + sizeof(mInstanceName), payloadBufferSize - sizeof(mInstanceName));
     116              : 
     117            1 :     chip::TLV::TLVType outerContainerType = chip::TLV::kTLVType_Structure;
     118            1 :     VerifyOrExit(CHIP_NO_ERROR ==
     119              :                      (err = writer.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure, outerContainerType)),
     120              :                  LogErrorOnFailure(err));
     121              : 
     122            1 :     VerifyOrExit(CHIP_NO_ERROR == (err = writer.Put(chip::TLV::ContextTag(kVendorIdTag), GetVendorId())), LogErrorOnFailure(err));
     123            1 :     VerifyOrExit(CHIP_NO_ERROR == (err = writer.Put(chip::TLV::ContextTag(kProductIdTag), GetProductId())), LogErrorOnFailure(err));
     124            1 :     VerifyOrExit(CHIP_NO_ERROR == (err = writer.PutString(chip::TLV::ContextTag(kDeviceNameTag), mDeviceName)),
     125              :                  LogErrorOnFailure(err));
     126            1 :     VerifyOrExit(CHIP_NO_ERROR == (err = writer.PutString(chip::TLV::ContextTag(kPairingInstTag), mPairingInst)),
     127              :                  LogErrorOnFailure(err));
     128            1 :     VerifyOrExit(CHIP_NO_ERROR == (err = writer.Put(chip::TLV::ContextTag(kPairingHintTag), mPairingHint)), LogErrorOnFailure(err));
     129            1 :     VerifyOrExit(CHIP_NO_ERROR == (err = writer.Put(chip::TLV::ContextTag(kCdPortTag), GetCdPort())), LogErrorOnFailure(err));
     130              : 
     131            1 :     VerifyOrExit(
     132              :         CHIP_NO_ERROR ==
     133              :             (err = writer.PutBytes(chip::TLV::ContextTag(kRotatingIdTag), mRotatingId, static_cast<uint8_t>(mRotatingIdLen))),
     134              :         LogErrorOnFailure(err));
     135              : 
     136            1 :     if (mNumTargetAppInfos > 0)
     137              :     {
     138              :         // AppVendorIdList
     139            1 :         VerifyOrExit(CHIP_NO_ERROR ==
     140              :                          (err = writer.StartContainer(chip::TLV::ContextTag(kTargetAppListTag), chip::TLV::kTLVType_List,
     141              :                                                       listContainerType)),
     142              :                      LogErrorOnFailure(err));
     143            4 :         for (size_t i = 0; i < mNumTargetAppInfos; i++)
     144              :         {
     145              :             // start the TargetApp structure
     146            3 :             VerifyOrExit(CHIP_NO_ERROR ==
     147              :                              (err = writer.StartContainer(chip::TLV::ContextTag(kTargetAppTag), chip::TLV::kTLVType_Structure,
     148              :                                                           outerContainerType)),
     149              :                          LogErrorOnFailure(err));
     150              :             // add the vendor Id
     151            3 :             VerifyOrExit(CHIP_NO_ERROR == (err = writer.Put(chip::TLV::ContextTag(kAppVendorIdTag), mTargetAppInfos[i].vendorId)),
     152              :                          LogErrorOnFailure(err));
     153            3 :             VerifyOrExit(CHIP_NO_ERROR == (err = writer.Put(chip::TLV::ContextTag(kAppProductIdTag), mTargetAppInfos[i].productId)),
     154              :                          LogErrorOnFailure(err));
     155              :             // end the TargetApp structure
     156            3 :             VerifyOrExit(CHIP_NO_ERROR == (err = writer.EndContainer(outerContainerType)), LogErrorOnFailure(err));
     157              :         }
     158            1 :         VerifyOrExit(CHIP_NO_ERROR == (err = writer.EndContainer(listContainerType)), LogErrorOnFailure(err));
     159              :     }
     160              : 
     161            1 :     VerifyOrExit(CHIP_NO_ERROR == (err = writer.PutBoolean(chip::TLV::ContextTag(kNoPasscodeTag), mNoPasscode)),
     162              :                  LogErrorOnFailure(err));
     163            1 :     VerifyOrExit(CHIP_NO_ERROR == (err = writer.PutBoolean(chip::TLV::ContextTag(kCdUponPasscodeDialogTag), mCdUponPasscodeDialog)),
     164              :                  LogErrorOnFailure(err));
     165            1 :     VerifyOrExit(CHIP_NO_ERROR == (err = writer.PutBoolean(chip::TLV::ContextTag(kCommissionerPasscodeTag), mCommissionerPasscode)),
     166              :                  LogErrorOnFailure(err));
     167            1 :     VerifyOrExit(CHIP_NO_ERROR ==
     168              :                      (err = writer.PutBoolean(chip::TLV::ContextTag(kCommissionerPasscodeReadyTag), mCommissionerPasscodeReady)),
     169              :                  LogErrorOnFailure(err));
     170            1 :     VerifyOrExit(CHIP_NO_ERROR == (err = writer.PutBoolean(chip::TLV::ContextTag(kCancelPasscodeTag), mCancelPasscode)),
     171              :                  LogErrorOnFailure(err));
     172              : 
     173            1 :     VerifyOrExit(CHIP_NO_ERROR == (err = writer.EndContainer(outerContainerType)), LogErrorOnFailure(err));
     174            1 :     VerifyOrExit(CHIP_NO_ERROR == (err = writer.Finalize()), LogErrorOnFailure(err));
     175              : 
     176            1 :     return writer.GetLengthWritten() + static_cast<uint32_t>(sizeof(mInstanceName));
     177              : 
     178            0 : exit:
     179            0 :     ChipLogError(AppServer, "IdentificationDeclaration::WritePayload exiting early error %" CHIP_ERROR_FORMAT, err.Format());
     180            0 :     return 0;
     181              : }
     182              : 
     183            1 : CHIP_ERROR CommissionerDeclaration::ReadPayload(uint8_t * udcPayload, size_t payloadBufferSize)
     184              : {
     185              :     CHIP_ERROR err;
     186              : 
     187            1 :     TLV::TLVReader reader;
     188            1 :     reader.Init(udcPayload, payloadBufferSize);
     189              : 
     190              :     // read the envelope
     191            1 :     ReturnErrorOnFailure(reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()));
     192              : 
     193            1 :     chip::TLV::TLVType outerContainerType = chip::TLV::kTLVType_Structure;
     194            1 :     ReturnErrorOnFailure(reader.EnterContainer(outerContainerType));
     195              : 
     196            8 :     while ((err = reader.Next()) == CHIP_NO_ERROR)
     197              :     {
     198            7 :         chip::TLV::Tag containerTag = reader.GetTag();
     199            7 :         if (!TLV::IsContextTag(containerTag))
     200              :         {
     201            0 :             ChipLogError(AppServer, "Unexpected non-context TLV tag.");
     202            0 :             return CHIP_ERROR_INVALID_TLV_TAG;
     203              :         }
     204            7 :         uint8_t tagNum = static_cast<uint8_t>(chip::TLV::TagNumFromTag(containerTag));
     205              : 
     206            7 :         switch (tagNum)
     207              :         {
     208            1 :         case kErrorCodeTag:
     209            1 :             err = reader.Get(mErrorCode);
     210            1 :             break;
     211            1 :         case kNeedsPasscodeTag:
     212            1 :             err = reader.Get(mNeedsPasscode);
     213            1 :             break;
     214            1 :         case kNoAppsFoundTag:
     215            1 :             err = reader.Get(mNoAppsFound);
     216            1 :             break;
     217            1 :         case kPasscodeDialogDisplayedTag:
     218            1 :             err = reader.Get(mPasscodeDialogDisplayed);
     219            1 :             break;
     220            1 :         case kCommissionerPasscodeTag:
     221            1 :             err = reader.Get(mCommissionerPasscode);
     222            1 :             break;
     223            1 :         case kQRCodeDisplayedTag:
     224            1 :             err = reader.Get(mQRCodeDisplayed);
     225            1 :             break;
     226            1 :         case kCancelPasscodeTag:
     227            1 :             err = reader.Get(mCancelPasscode);
     228            1 :             break;
     229              :         }
     230              :     }
     231              : 
     232            1 :     if (err == CHIP_END_OF_TLV)
     233              :     {
     234              :         // Exiting container
     235            1 :         ReturnErrorOnFailure(reader.ExitContainer(outerContainerType));
     236              :     }
     237              : 
     238            1 :     ChipLogProgress(AppServer, "UDC TLV parse complete");
     239            1 :     return CHIP_NO_ERROR;
     240              : }
     241              : 
     242            0 : void UserDirectedCommissioningClient::OnMessageReceived(const Transport::PeerAddress & source, System::PacketBufferHandle && msg,
     243              :                                                         Transport::MessageTransportContext * ctxt)
     244              : {
     245              :     char addrBuffer[chip::Transport::PeerAddress::kMaxToStringSize];
     246            0 :     source.ToString(addrBuffer);
     247              : 
     248            0 :     ChipLogProgress(AppServer, "UserDirectedCommissioningClient::OnMessageReceived() from %s", addrBuffer);
     249              : 
     250            0 :     PacketHeader packetHeader;
     251              : 
     252            0 :     ReturnOnFailure(packetHeader.DecodeAndConsume(msg));
     253              : 
     254            0 :     if (packetHeader.IsEncrypted())
     255              :     {
     256            0 :         ChipLogError(AppServer, "UserDirectedCommissioningClient::OnMessageReceived() UDC encryption flag set - ignoring");
     257            0 :         return;
     258              :     }
     259              : 
     260            0 :     PayloadHeader payloadHeader;
     261            0 :     ReturnOnFailure(payloadHeader.DecodeAndConsume(msg));
     262              : 
     263            0 :     ChipLogProgress(AppServer,
     264              :                     "UserDirectedCommissioningClient::OnMessageReceived() CommissionerDeclaration DataLength() = %" PRIu32,
     265              :                     static_cast<uint32_t>(msg->DataLength()));
     266              : 
     267              :     uint8_t udcPayload[IdentificationDeclaration::kUdcTLVDataMaxBytes];
     268            0 :     size_t udcPayloadLength = std::min<size_t>(msg->DataLength(), sizeof(udcPayload));
     269            0 :     msg->Read(udcPayload, udcPayloadLength);
     270              : 
     271            0 :     CommissionerDeclaration cd;
     272            0 :     cd.ReadPayload(udcPayload, sizeof(udcPayload));
     273            0 :     cd.DebugLog();
     274              : 
     275              :     // Call the registered mCommissionerDeclarationHandler, if any.
     276            0 :     if (mCommissionerDeclarationHandler != nullptr)
     277              :     {
     278            0 :         mCommissionerDeclarationHandler->OnCommissionerDeclarationMessage(source, cd);
     279              :     }
     280              :     else
     281              :     {
     282            0 :         ChipLogProgress(AppServer, "UserDirectedCommissioningClient::OnMessageReceived() No registered handler for UDC messages");
     283              :     }
     284            0 : }
     285              : 
     286              : } // namespace UserDirectedCommissioning
     287              : } // namespace Protocols
     288              : } // namespace chip
        

Generated by: LCOV version 2.0-1