Matter SDK Coverage Report
Current view: top level - app/MessageDef - MessageDefHelper.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 92.9 % 98 91
Test Date: 2025-01-17 19:00:11 Functions: 100.0 % 5 5

            Line data    Source code
       1              : /**
       2              :  *
       3              :  *    Copyright (c) 2020-2021 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 message helper functions in CHIP interaction model
      21              :  *
      22              :  */
      23              : 
      24              : #include "MessageDefHelper.h"
      25              : #include <algorithm>
      26              : #include <app/AppConfig.h>
      27              : #include <app/SpecificationDefinedRevisions.h>
      28              : #include <app/util/basic-types.h>
      29              : #include <inttypes.h>
      30              : #include <lib/support/logging/CHIPLogging.h>
      31              : #include <stdarg.h>
      32              : #include <stdio.h>
      33              : 
      34              : namespace chip {
      35              : namespace app {
      36              : #if CHIP_CONFIG_IM_PRETTY_PRINT && CHIP_DETAIL_LOGGING
      37              : // this is used to run in signle thread for IM message debug purpose
      38              : namespace {
      39              : uint32_t gPrettyPrintingDepthLevel = 0;
      40              : char gLineBuffer[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE];
      41              : size_t gCurLineBufferSize = 0;
      42              : } // namespace
      43              : 
      44       368060 : void PrettyPrintIMBlankLine()
      45              : {
      46       368060 :     if (gCurLineBufferSize)
      47              :     {
      48              :         // Don't need to explicitly NULL-terminate the string because
      49              :         // snprintf takes care of that.
      50       360177 :         ChipLogDetail(DataManagement, "%s", gLineBuffer);
      51       360177 :         gCurLineBufferSize = 0;
      52              :     }
      53              : 
      54      1382858 :     for (uint32_t i = 0; i < gPrettyPrintingDepthLevel; i++)
      55              :     {
      56      1014798 :         if (sizeof(gLineBuffer) > gCurLineBufferSize)
      57              :         {
      58      1014798 :             size_t sizeLeft = sizeof(gLineBuffer) - gCurLineBufferSize;
      59      1014798 :             size_t ret      = (size_t) (snprintf(gLineBuffer + gCurLineBufferSize, sizeLeft, "\t"));
      60      1014798 :             if (ret > 0)
      61              :             {
      62      1014798 :                 gCurLineBufferSize += std::min(ret, sizeLeft);
      63              :             }
      64              :         }
      65              :     }
      66       368060 : }
      67              : 
      68      1888965 : void PrettyPrintIM(bool aIsNewLine, const char * aFmt, ...)
      69              : {
      70              :     va_list args;
      71      1888965 :     va_start(args, aFmt);
      72              : 
      73      1888965 :     if (aIsNewLine)
      74              :     {
      75       329214 :         PrettyPrintIMBlankLine();
      76              :     }
      77              : 
      78      1888965 :     if (sizeof(gLineBuffer) > gCurLineBufferSize)
      79              :     {
      80       850175 :         size_t sizeLeft = sizeof(gLineBuffer) - gCurLineBufferSize;
      81       850175 :         size_t ret      = (size_t) (vsnprintf(gLineBuffer + gCurLineBufferSize, sizeLeft, aFmt, args));
      82       850175 :         if (ret > 0)
      83              :         {
      84       850175 :             gCurLineBufferSize += std::min(ret, sizeLeft);
      85              :         }
      86              :     }
      87              : 
      88      1888965 :     va_end(args);
      89      1888965 : }
      90        88339 : void IncreaseDepth()
      91              : {
      92        88339 :     gPrettyPrintingDepthLevel++;
      93        88339 : }
      94              : 
      95        88338 : void DecreaseDepth()
      96              : {
      97        88338 :     gPrettyPrintingDepthLevel--;
      98        88338 : }
      99              : #endif
     100              : 
     101              : #if CHIP_CONFIG_IM_PRETTY_PRINT
     102        42754 : CHIP_ERROR CheckIMPayload(TLV::TLVReader & aReader, int aDepth, const char * aLabel)
     103              : {
     104        42754 :     if (aDepth == 0)
     105              :     {
     106         8236 :         PRETTY_PRINT("%s = ", aLabel);
     107              :     }
     108              :     else
     109              :     {
     110        34518 :         if (TLV::IsContextTag(aReader.GetTag()))
     111              :         {
     112        28183 :             PRETTY_PRINT("0x%" PRIx32 " = ", TLV::TagNumFromTag(aReader.GetTag()));
     113              :         }
     114         6335 :         else if (TLV::IsProfileTag(aReader.GetTag()))
     115              :         {
     116            0 :             PRETTY_PRINT("0x%" PRIx32 "::0x%" PRIx32 " = ", TLV::ProfileIdFromTag(aReader.GetTag()),
     117              :                          TLV::TagNumFromTag(aReader.GetTag()));
     118              :         }
     119              :         else
     120              :         {
     121              :             // Anonymous tag, don't print anything
     122              :         }
     123              :     }
     124              : 
     125        42754 :     switch (aReader.GetType())
     126              :     {
     127         6005 :     case TLV::kTLVType_Structure:
     128         6005 :         PRETTY_PRINT("{");
     129         6005 :         break;
     130              : 
     131         5507 :     case TLV::kTLVType_Array:
     132         5507 :         PRETTY_PRINT_SAMELINE("[");
     133         5507 :         PRETTY_PRINT("\t\t");
     134         5507 :         break;
     135              : 
     136           90 :     case TLV::kTLVType_SignedInteger: {
     137              :         int64_t value_s64;
     138              : 
     139           90 :         ReturnErrorOnFailure(aReader.Get(value_s64));
     140              : 
     141              :         // TODO: Figure out how to not use PRId64 here, since it's not supported
     142              :         // on all libcs.
     143           90 :         PRETTY_PRINT_SAMELINE("%" PRId64 " (signed), ", value_s64);
     144           90 :         break;
     145              :     }
     146              : 
     147        15900 :     case TLV::kTLVType_UnsignedInteger: {
     148              :         uint64_t value_u64;
     149              : 
     150        15900 :         ReturnErrorOnFailure(aReader.Get(value_u64));
     151              : 
     152              :         // TODO: Figure out how to not use PRIu64 here, since it's not supported
     153              :         // on all libcs.
     154        15900 :         PRETTY_PRINT_SAMELINE("%" PRIu64 " (unsigned), ", value_u64);
     155        15900 :         break;
     156              :     }
     157              : 
     158         3254 :     case TLV::kTLVType_FloatingPointNumber: {
     159              :         double value_fp;
     160              : 
     161         3254 :         ReturnErrorOnFailure(aReader.Get(value_fp));
     162              : 
     163         3254 :         PRETTY_PRINT_SAMELINE("%f, ", value_fp);
     164         3254 :         break;
     165              :     }
     166         3343 :     case TLV::kTLVType_Boolean: {
     167              :         bool value_b;
     168              : 
     169         3343 :         ReturnErrorOnFailure(aReader.Get(value_b));
     170              : 
     171         3343 :         PRETTY_PRINT_SAMELINE("%s, ", value_b ? "true" : "false");
     172         3343 :         break;
     173              :     }
     174              : 
     175         1704 :     case TLV::kTLVType_UTF8String: {
     176              :         char value_s[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE];
     177              : 
     178              : #if CHIP_DETAIL_LOGGING
     179         1704 :         uint32_t readerLen = aReader.GetLength();
     180              : #endif // CHIP_DETAIL_LOGGING
     181         1704 :         CHIP_ERROR err = aReader.GetString(value_s, sizeof(value_s));
     182         1704 :         VerifyOrReturnError(err == CHIP_NO_ERROR || err == CHIP_ERROR_BUFFER_TOO_SMALL, err);
     183              : 
     184         1704 :         if (err == CHIP_ERROR_BUFFER_TOO_SMALL)
     185              :         {
     186            0 :             PRETTY_PRINT_SAMELINE("... (char string too long: %" PRIu32 " chars) ...", readerLen);
     187              :         }
     188              :         else
     189              :         {
     190         1704 :             PRETTY_PRINT_SAMELINE("\"%s\" (%" PRIu32 " chars), ", value_s, readerLen);
     191              :         }
     192         1704 :         break;
     193              :     }
     194              : 
     195         6869 :     case TLV::kTLVType_ByteString: {
     196              :         uint8_t value_b[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE];
     197              :         uint32_t len, readerLen;
     198              : 
     199         6869 :         readerLen = aReader.GetLength();
     200              : 
     201         6869 :         CHIP_ERROR err = aReader.GetBytes(value_b, sizeof(value_b));
     202         6869 :         VerifyOrReturnError(err == CHIP_NO_ERROR || err == CHIP_ERROR_BUFFER_TOO_SMALL, err);
     203              : 
     204         6869 :         PRETTY_PRINT_SAMELINE("[");
     205         6869 :         PRETTY_PRINT("\t\t");
     206              : 
     207         6869 :         if (readerLen < sizeof(value_b))
     208              :         {
     209         6869 :             len = readerLen;
     210              :         }
     211              :         else
     212              :         {
     213            0 :             len = sizeof(value_b);
     214              :         }
     215              : 
     216         6869 :         if (err == CHIP_ERROR_BUFFER_TOO_SMALL)
     217              :         {
     218            0 :             PRETTY_PRINT_SAMELINE("... (byte string too long) ...");
     219              :         }
     220              :         else
     221              :         {
     222      1529871 :             for (size_t i = 0; i < len; i++)
     223              :             {
     224      1523002 :                 PRETTY_PRINT_SAMELINE("0x%02x, ", value_b[i]);
     225              :             }
     226              :         }
     227              : 
     228         6869 :         PRETTY_PRINT("] (%" PRIu32 " bytes)", readerLen);
     229         6869 :         break;
     230              :     }
     231              : 
     232           82 :     case TLV::kTLVType_Null:
     233           82 :         PRETTY_PRINT_SAMELINE("NULL");
     234           82 :         break;
     235              : 
     236            0 :     default:
     237            0 :         PRETTY_PRINT_SAMELINE("--");
     238            0 :         break;
     239              :     }
     240              : 
     241        42754 :     if (aReader.GetType() == TLV::kTLVType_Structure || aReader.GetType() == TLV::kTLVType_Array)
     242              :     {
     243        11512 :         const char terminating_char = (aReader.GetType() == TLV::kTLVType_Structure) ? '}' : ']';
     244              :         TLV::TLVType type;
     245              : 
     246              :         IgnoreUnusedVariable(terminating_char);
     247              : 
     248        11512 :         ReturnErrorOnFailure(aReader.EnterContainer(type));
     249              : 
     250              :         CHIP_ERROR err;
     251        46030 :         while ((err = aReader.Next()) == CHIP_NO_ERROR)
     252              :         {
     253        34518 :             PRETTY_PRINT_INCDEPTH();
     254              : 
     255        34518 :             ReturnErrorOnFailure(CheckIMPayload(aReader, aDepth + 1, aLabel));
     256              : 
     257        34518 :             PRETTY_PRINT_DECDEPTH();
     258              :         }
     259              : 
     260        11512 :         PRETTY_PRINT("%c,", terminating_char);
     261              : 
     262        11512 :         ReturnErrorOnFailure(aReader.ExitContainer(type));
     263              :     }
     264              : 
     265        42754 :     return CHIP_NO_ERROR;
     266              : }
     267              : #endif // CHIP_CONFIG_IM_PRETTY_PRINT
     268              : 
     269              : }; // namespace app
     270              : }; // namespace chip
        

Generated by: LCOV version 2.0-1