LCOV - code coverage report
Current view: top level - app/MessageDef - StatusIB.cpp (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 82 87 94.3 %
Date: 2024-02-15 08:20:41 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /**
       2             :  *
       3             :  *    Copyright (c) 2020 Project CHIP Authors
       4             :  *    Copyright (c) 2018 Google LLC.
       5             :  *    Copyright (c) 2016-2017 Nest Labs, Inc.
       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             :  *    @file
      20             :  *      This file defines Status Information Block in Interaction Model
      21             :  *
      22             :  */
      23             : 
      24             : #include "StatusIB.h"
      25             : 
      26             : #include "MessageDefHelper.h"
      27             : 
      28             : #include <inttypes.h>
      29             : #include <stdarg.h>
      30             : #include <stdio.h>
      31             : 
      32             : #include <app/AppConfig.h>
      33             : #include <lib/core/CHIPCore.h>
      34             : 
      35             : using namespace chip;
      36             : using namespace chip::TLV;
      37             : using namespace chip::Protocols::InteractionModel;
      38             : 
      39             : namespace chip {
      40             : namespace app {
      41        2782 : CHIP_ERROR StatusIB::Parser::DecodeStatusIB(StatusIB & aStatusIB) const
      42             : {
      43             :     TLV::TLVReader reader;
      44        2782 :     reader.Init(mReader);
      45        5566 :     while (CHIP_NO_ERROR == reader.Next())
      46             :     {
      47        2784 :         if (!TLV::IsContextTag(reader.GetTag()))
      48             :         {
      49           0 :             continue;
      50             :         }
      51        2784 :         switch (TLV::TagNumFromTag(reader.GetTag()))
      52             :         {
      53        2782 :         case to_underlying(Tag::kStatus):
      54        2782 :             ReturnErrorOnFailure(reader.Get(aStatusIB.mStatus));
      55        2784 :             break;
      56           2 :         case to_underlying(Tag::kClusterStatus):
      57             :             ClusterStatus clusterStatus;
      58           2 :             ReturnErrorOnFailure(reader.Get(clusterStatus));
      59           2 :             aStatusIB.mClusterStatus.SetValue(clusterStatus);
      60           2 :             break;
      61             :         }
      62             :     }
      63        2782 :     return CHIP_NO_ERROR;
      64             : }
      65             : #if CHIP_CONFIG_IM_PRETTY_PRINT
      66        2788 : CHIP_ERROR StatusIB::Parser::PrettyPrint() const
      67             : {
      68        2788 :     CHIP_ERROR err = CHIP_NO_ERROR;
      69             :     TLV::TLVReader reader;
      70             : 
      71        2788 :     PRETTY_PRINT("StatusIB =");
      72        2788 :     PRETTY_PRINT("{");
      73             : 
      74             :     // make a copy of the reader
      75        2788 :     reader.Init(mReader);
      76        5578 :     while (CHIP_NO_ERROR == (err = reader.Next()))
      77             :     {
      78        2790 :         if (!TLV::IsContextTag(reader.GetTag()))
      79             :         {
      80           0 :             continue;
      81             :         }
      82        2790 :         uint32_t tagNum = TLV::TagNumFromTag(reader.GetTag());
      83        2790 :         switch (tagNum)
      84             :         {
      85        2788 :         case to_underlying(Tag::kStatus):
      86             : #if CHIP_DETAIL_LOGGING
      87             :         {
      88             :             uint8_t status;
      89        2788 :             ReturnErrorOnFailure(reader.Get(status));
      90        2788 :             PRETTY_PRINT("\tstatus = " ChipLogFormatIMStatus ",", ChipLogValueIMStatus(static_cast<Status>(status)));
      91             :         }
      92             : #endif // CHIP_DETAIL_LOGGING
      93        2788 :         break;
      94           2 :         case to_underlying(Tag::kClusterStatus):
      95             : #if CHIP_DETAIL_LOGGING
      96             :         {
      97             :             ClusterStatus clusterStatus;
      98           2 :             ReturnErrorOnFailure(reader.Get(clusterStatus));
      99           2 :             PRETTY_PRINT("\tcluster-status = 0x%x,", clusterStatus);
     100             :         }
     101             : #endif // CHIP_DETAIL_LOGGING
     102           2 :         break;
     103           0 :         default:
     104           0 :             PRETTY_PRINT("Unknown tag num %" PRIu32, tagNum);
     105           0 :             break;
     106             :         }
     107             :     }
     108             : 
     109        2788 :     PRETTY_PRINT("},");
     110        2788 :     PRETTY_PRINT_BLANK_LINE();
     111             :     // if we have exhausted this container
     112        2788 :     if (CHIP_END_OF_TLV == err)
     113             :     {
     114        2788 :         err = CHIP_NO_ERROR;
     115             :     }
     116        2788 :     ReturnErrorOnFailure(err);
     117        2788 :     return reader.ExitContainer(mOuterContainerType);
     118             : }
     119             : #endif // CHIP_CONFIG_IM_PRETTY_PRINT
     120             : 
     121        2815 : StatusIB::Builder & StatusIB::Builder::EncodeStatusIB(const StatusIB & aStatusIB)
     122             : {
     123        2815 :     mError = mpWriter->Put(TLV::ContextTag(Tag::kStatus), aStatusIB.mStatus);
     124        2815 :     SuccessOrExit(mError);
     125             : 
     126        2815 :     if (aStatusIB.mClusterStatus.HasValue())
     127             :     {
     128           2 :         mError = mpWriter->Put(TLV::ContextTag(Tag::kClusterStatus), aStatusIB.mClusterStatus.Value());
     129           2 :         SuccessOrExit(mError);
     130             :     }
     131             : 
     132        2815 :     EndOfContainer();
     133        2815 : exit:
     134        2815 :     return *this;
     135             : }
     136             : 
     137        1264 : CHIP_ERROR StatusIB::ToChipError() const
     138             : {
     139        1264 :     if (mStatus == Status::Success)
     140             :     {
     141        1146 :         return CHIP_NO_ERROR;
     142             :     }
     143             : 
     144         118 :     if (mClusterStatus.HasValue())
     145             :     {
     146           4 :         return ChipError(ChipError::SdkPart::kIMClusterStatus, mClusterStatus.Value());
     147             :     }
     148             : 
     149         114 :     return ChipError(ChipError::SdkPart::kIMGlobalStatus, to_underlying(mStatus));
     150             : }
     151             : 
     152          80 : void StatusIB::InitFromChipError(CHIP_ERROR aError)
     153             : {
     154          80 :     if (aError.IsPart(ChipError::SdkPart::kIMClusterStatus))
     155             :     {
     156           4 :         mStatus        = Status::Failure;
     157           4 :         mClusterStatus = MakeOptional(aError.GetSdkCode());
     158           4 :         return;
     159             :     }
     160             : 
     161          76 :     mClusterStatus = NullOptional;
     162          76 :     if (aError == CHIP_NO_ERROR)
     163             :     {
     164           1 :         mStatus = Status::Success;
     165           1 :         return;
     166             :     }
     167             : 
     168          75 :     if (aError.IsPart(ChipError::SdkPart::kIMGlobalStatus))
     169             :     {
     170          61 :         mStatus = static_cast<Status>(aError.GetSdkCode());
     171          61 :         return;
     172             :     }
     173             : 
     174          14 :     mStatus = Status::Failure;
     175             : }
     176             : 
     177             : namespace {
     178         436 : bool FormatStatusIBError(char * buf, uint16_t bufSize, CHIP_ERROR err)
     179             : {
     180         436 :     if (!err.IsIMStatus())
     181             :     {
     182         421 :         return false;
     183             :     }
     184             : 
     185          15 :     const char * desc = nullptr;
     186             : #if !CHIP_CONFIG_SHORT_ERROR_STR
     187             :     static constexpr char generalFormat[] = "General error: " ChipLogFormatIMStatus;
     188             :     static constexpr char clusterFormat[] = "Cluster-specific error: 0x%02x";
     189             : 
     190             :     // Formatting an 8-bit int will take at most 2 chars, and replace the '%02x'
     191             :     // so a buffer big enough to hold our format string will also hold our
     192             :     // formatted string, as long as we account for the possible string formats.
     193          15 :     constexpr size_t statusNameMaxLength =
     194             : #define CHIP_IM_STATUS_CODE(name, spec_name, value)                                                                                \
     195             :         max(sizeof(#spec_name),
     196             : #include <protocols/interaction_model/StatusCodeList.h>
     197             : #undef CHIP_IM_STATUS_CODE
     198             :         static_cast<size_t>(0)
     199             : #define CHIP_IM_STATUS_CODE(name, spec_name, value)                                                                                \
     200             :         )
     201             : #include <protocols/interaction_model/StatusCodeList.h>
     202             : #undef CHIP_IM_STATUS_CODE
     203             :         ;
     204          15 :     constexpr size_t formattedSize = max(sizeof(generalFormat) + statusNameMaxLength, sizeof(clusterFormat));
     205             :     char formattedString[formattedSize];
     206             : 
     207          15 :     StatusIB status;
     208          15 :     status.InitFromChipError(err);
     209          15 :     if (status.mClusterStatus.HasValue())
     210             :     {
     211           1 :         snprintf(formattedString, formattedSize, clusterFormat, status.mClusterStatus.Value());
     212             :     }
     213             :     else
     214             :     {
     215          14 :         snprintf(formattedString, formattedSize, generalFormat, ChipLogValueIMStatus(status.mStatus));
     216             :     }
     217          15 :     desc = formattedString;
     218             : #endif // !CHIP_CONFIG_SHORT_ERROR_STR
     219          15 :     FormatError(buf, bufSize, "IM", err, desc);
     220             : 
     221          15 :     return true;
     222          15 : }
     223             : } // anonymous namespace
     224             : 
     225         368 : void StatusIB::RegisterErrorFormatter()
     226             : {
     227             :     static ErrorFormatter sStatusIBErrorFormatter = { FormatStatusIBError, nullptr };
     228             : 
     229         368 :     ::RegisterErrorFormatter(&sStatusIBErrorFormatter);
     230         368 : }
     231             : 
     232             : }; // namespace app
     233             : }; // namespace chip

Generated by: LCOV version 1.14