LCOV - code coverage report
Current view: top level - protocols/user_directed_commissioning - UserDirectedCommissioningClient.cpp (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 73 121 60.3 %
Date: 2024-02-15 08:20:41 Functions: 3 5 60.0 %

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

Generated by: LCOV version 1.14