Matter SDK Coverage Report
Current view: top level - lib/core - TLVDebug.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 84.0 % 156 131
Test Date: 2025-01-17 19:00:11 Functions: 83.3 % 6 5

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020-2021 Project CHIP Authors
       4              :  *    Copyright (c) 2015-2017 Nest Labs, Inc.
       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              : #include <lib/core/TLVDebug.h>
      19              : 
      20              : #include <inttypes.h>
      21              : 
      22              : #include <lib/core/CHIPError.h>
      23              : #include <lib/core/TLVReader.h>
      24              : #include <lib/core/TLVTags.h>
      25              : #include <lib/core/TLVTypes.h>
      26              : #include <lib/core/TLVUtilities.h>
      27              : #include <lib/support/CodeUtils.h>
      28              : 
      29              : namespace chip {
      30              : 
      31              : namespace TLV {
      32              : 
      33              : namespace Debug {
      34              : 
      35              : /**
      36              :  *  Dump the TLV element referenced by @a aReader in human-readable form using
      37              :  *  @a aWriter.
      38              :  *
      39              :  *  @param[in]     aWriter   The writer to log the TLV data.
      40              :  *  @param[in]     aIndent   The indentation for logging the current depth into
      41              :  *                           the TLV data.
      42              :  *  @param[in]     aReader   A read-only reference to the TLV reader containing
      43              :  *                           the TLV data to log.
      44              :  *  @param[in]     aDepth    The current depth into the TLV data.
      45              :  *
      46              :  */
      47         1409 : static void DumpHandler(DumpWriter aWriter, const char * aIndent, const TLVReader & aReader, size_t aDepth)
      48              : {
      49         1409 :     const TLVType type     = aReader.GetType();
      50         1409 :     const Tag tag          = aReader.GetTag();
      51         1409 :     const uint32_t len     = aReader.GetLength();
      52         1409 :     const uint8_t * strbuf = nullptr;
      53         1409 :     CHIP_ERROR err         = CHIP_NO_ERROR;
      54         1409 :     TLVReader temp;
      55              :     TLVTagControl tagControl;
      56              : 
      57         1409 :     temp.Init(aReader);
      58         1409 :     tagControl = static_cast<TLVTagControl>(temp.GetControlByte() & kTLVTagControlMask);
      59              : 
      60         1409 :     aWriter("0x%02X, ", temp.GetLengthRead());
      61              : 
      62         4391 :     for (size_t i = 0; i < aDepth; i++)
      63         2982 :         aWriter("%s", aIndent);
      64              : 
      65         1409 :     if (IsProfileTag(tag))
      66              :     {
      67           16 :         aWriter("tag[%s]: 0x%x::0x%x::0x%x, ", DecodeTagControl(tagControl), VendorIdFromTag(tag), ProfileNumFromTag(tag),
      68              :                 TagNumFromTag(tag));
      69              :     }
      70         1393 :     else if (IsContextTag(tag))
      71              :     {
      72         1231 :         aWriter("tag[%s]: 0x%x, ", DecodeTagControl(tagControl), TagNumFromTag(tag));
      73              :     }
      74          162 :     else if (IsSpecialTag(tag))
      75              :     {
      76              : 
      77          162 :         aWriter("tag[%s]: 0x%x, ", DecodeTagControl(tagControl), tag);
      78              :     }
      79              :     else
      80              :     {
      81            0 :         aWriter("tag[unknown]: 0x%x, ", tag);
      82              :     }
      83              : 
      84         1409 :     aWriter("type: %s (0x%02x), ", DecodeType(type), type);
      85              : 
      86         1409 :     if (TLVTypeIsContainer(type))
      87              :     {
      88          501 :         aWriter("container: ");
      89              :     }
      90              :     else
      91              :     {
      92          908 :         if (type == kTLVType_UTF8String || type == kTLVType_ByteString)
      93            3 :             aWriter("length: %" PRIu32 ", ", len);
      94              : 
      95          908 :         aWriter("value: ");
      96              : 
      97          908 :         switch (type)
      98              :         {
      99              : 
     100           93 :         case kTLVType_SignedInteger:
     101              :             int64_t sVal;
     102           93 :             err = temp.Get(sVal);
     103           93 :             VerifyOrExit(err == CHIP_NO_ERROR, aWriter("Error in kTLVType_SignedInteger"));
     104           93 :             aWriter("%" PRIi64, sVal);
     105          908 :             break;
     106              : 
     107          753 :         case kTLVType_UnsignedInteger:
     108              :             uint64_t uVal;
     109          753 :             err = temp.Get(uVal);
     110          753 :             VerifyOrExit(err == CHIP_NO_ERROR, aWriter("Error in kTLVType_UnsignedInteger"));
     111          753 :             aWriter("%" PRIu64, uVal);
     112          753 :             break;
     113              : 
     114           54 :         case kTLVType_Boolean:
     115              :             bool bVal;
     116           54 :             err = temp.Get(bVal);
     117           54 :             VerifyOrExit(err == CHIP_NO_ERROR, aWriter("Error in kTLVType_Boolean"));
     118           54 :             aWriter("%s", bVal ? "true" : "false");
     119           54 :             break;
     120              : 
     121            2 :         case kTLVType_FloatingPointNumber:
     122              :             double fpVal;
     123            2 :             err = temp.Get(fpVal);
     124            2 :             VerifyOrExit(err == CHIP_NO_ERROR, aWriter("Error in kTLVType_FloatingPointNumber"));
     125            2 :             aWriter("%lf", fpVal);
     126            2 :             break;
     127              : 
     128            2 :         case kTLVType_UTF8String:
     129            2 :             err = temp.GetDataPtr(strbuf);
     130            2 :             VerifyOrExit(err == CHIP_NO_ERROR, aWriter("Error in kTLVType_UTF8String"));
     131            2 :             aWriter("\"%-.*s\"", static_cast<int>(len), strbuf);
     132            2 :             break;
     133              : 
     134            1 :         case kTLVType_ByteString:
     135            1 :             err = temp.GetDataPtr(strbuf);
     136            1 :             VerifyOrExit(err == CHIP_NO_ERROR, aWriter("Error in kTLVType_ByteString"));
     137            1 :             aWriter("hex:");
     138            9 :             for (uint32_t i = 0; i < len; i++)
     139              :             {
     140            8 :                 aWriter("%02X", strbuf[i]);
     141              :             }
     142            1 :             break;
     143              : 
     144            3 :         case kTLVType_Null:
     145            3 :             aWriter("NULL");
     146            3 :             break;
     147              : 
     148            0 :         case kTLVType_NotSpecified:
     149            0 :             aWriter("Not Specified");
     150            0 :             break;
     151              : 
     152            0 :         default:
     153            0 :             aWriter("Error: Type is not primitive.");
     154            0 :             break;
     155              :         }
     156              :     }
     157              : 
     158         1409 : exit:
     159         1409 :     aWriter("\n");
     160         1409 : }
     161              : 
     162              : /**
     163              :  *  Decode a TLV tag control with a descriptive string.
     164              :  *
     165              :  *  @param[in]     aTagControl  The TLV tag control to decode and for which to return
     166              :  *                              a descriptive string.
     167              :  *
     168              :  *  @return  A pointer to a NULL-terminated string describing the specified
     169              :  *           tag control on success; otherwise, NULL.
     170              :  *
     171              :  */
     172         1409 : const char * DecodeTagControl(const TLVTagControl aTagControl)
     173              : {
     174              :     const char * retval;
     175              : 
     176         1409 :     switch (aTagControl)
     177              :     {
     178              : 
     179          162 :     case TLVTagControl::Anonymous:
     180          162 :         retval = "Anonymous";
     181          162 :         break;
     182              : 
     183         1231 :     case TLVTagControl::ContextSpecific:
     184         1231 :         retval = "Context Specific";
     185         1231 :         break;
     186              : 
     187            1 :     case TLVTagControl::CommonProfile_2Bytes:
     188            1 :         retval = "Common Profile (2 Bytes)";
     189            1 :         break;
     190              : 
     191            1 :     case TLVTagControl::CommonProfile_4Bytes:
     192            1 :         retval = "Common Profile (4 Bytes)";
     193            1 :         break;
     194              : 
     195            2 :     case TLVTagControl::ImplicitProfile_2Bytes:
     196            2 :         retval = "Implicit Profile (2 Bytes)";
     197            2 :         break;
     198              : 
     199            3 :     case TLVTagControl::ImplicitProfile_4Bytes:
     200            3 :         retval = "Implicit Profile (4 Bytes)";
     201            3 :         break;
     202              : 
     203            9 :     case TLVTagControl::FullyQualified_6Bytes:
     204            9 :         retval = "Fully Qualified (6 Bytes)";
     205            9 :         break;
     206              : 
     207            0 :     case TLVTagControl::FullyQualified_8Bytes:
     208            0 :         retval = "Fully Qualified (8 Bytes)";
     209            0 :         break;
     210              : 
     211            0 :     default:
     212            0 :         retval = nullptr;
     213            0 :         break;
     214              :     }
     215              : 
     216         1409 :     return retval;
     217              : }
     218              : 
     219              : /**
     220              :  *  Decode a TLV type with a descriptive string.
     221              :  *
     222              :  *  @param[in]     aType     The TLV type to decode and for which to return
     223              :  *                           a descriptive string.
     224              :  *
     225              :  *  @return  A pointer to a NULL-terminated string describing the specified
     226              :  *           type on success; otherwise, NULL.
     227              :  *
     228              :  */
     229         1409 : const char * DecodeType(const TLVType aType)
     230              : {
     231              :     const char * retval;
     232              : 
     233         1409 :     switch (aType)
     234              :     {
     235              : 
     236            0 :     case kTLVType_NotSpecified:
     237            0 :         retval = "Not Specified";
     238            0 :         break;
     239              : 
     240           93 :     case kTLVType_SignedInteger:
     241           93 :         retval = "Signed Fixed Point";
     242           93 :         break;
     243              : 
     244          753 :     case kTLVType_UnsignedInteger:
     245          753 :         retval = "Unsigned Fixed Point";
     246          753 :         break;
     247              : 
     248           54 :     case kTLVType_Boolean:
     249           54 :         retval = "Boolean";
     250           54 :         break;
     251              : 
     252            2 :     case kTLVType_FloatingPointNumber:
     253            2 :         retval = "Floating Point";
     254            2 :         break;
     255              : 
     256            2 :     case kTLVType_UTF8String:
     257            2 :         retval = "UTF-8 String";
     258            2 :         break;
     259              : 
     260            1 :     case kTLVType_ByteString:
     261            1 :         retval = "Octet String";
     262            1 :         break;
     263              : 
     264            3 :     case kTLVType_Null:
     265            3 :         retval = "Null";
     266            3 :         break;
     267              : 
     268          346 :     case kTLVType_Structure:
     269          346 :         retval = "Structure";
     270          346 :         break;
     271              : 
     272           28 :     case kTLVType_Array:
     273           28 :         retval = "Array";
     274           28 :         break;
     275              : 
     276          127 :     case kTLVType_List:
     277          127 :         retval = "List";
     278          127 :         break;
     279              : 
     280            0 :     default:
     281            0 :         retval = nullptr;
     282            0 :         break;
     283              :     }
     284              : 
     285         1409 :     return retval;
     286              : }
     287              : 
     288              : /**
     289              :  *  Log the TLV data within the specified reader in human-readable form to
     290              :  *  the specified writer.
     291              :  *
     292              :  *  @param[in]     aWriter   The writer to log the TLV data.
     293              :  *  @param[in]     aReader   A read-only reference to the TLV reader containing
     294              :  *                           the TLV data to log.
     295              :  *
     296              :  *  @retval  #CHIP_NO_ERROR  Unconditionally.
     297              :  *
     298              :  */
     299            0 : CHIP_ERROR DumpIterator(DumpWriter aWriter, const TLVReader & aReader)
     300              : {
     301            0 :     const char * tabs  = "";
     302            0 :     const size_t depth = 0;
     303            0 :     CHIP_ERROR retval  = CHIP_NO_ERROR;
     304              : 
     305            0 :     DumpHandler(aWriter, tabs, aReader, depth);
     306              : 
     307            0 :     return retval;
     308              : }
     309              : 
     310              : /**
     311              :  *  Log the TLV data within the specified reader in human-readable form.
     312              :  *
     313              :  *  @param[in]     aReader   A read-only reference to the TLV reader containing
     314              :  *                           the TLV data to log.
     315              :  *  @param[in]     aDepth    The current depth into the TLV data.
     316              :  *  @param[in,out] aContext  A pointer to the handler-specific context.
     317              :  *
     318              :  *  @retval  #CHIP_NO_ERROR                On success.
     319              :  *
     320              :  *  @retval  #CHIP_ERROR_INVALID_ARGUMENT  If aContext is NULL or if
     321              :  *                                          aContext->mWriter is NULL.
     322              :  *
     323              :  */
     324         1409 : CHIP_ERROR DumpHandler(const TLVReader & aReader, size_t aDepth, void * aContext)
     325              : {
     326              :     static const char indent[] = "    ";
     327              :     DumpContext * context;
     328              : 
     329         1409 :     VerifyOrReturnError(aContext != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
     330              : 
     331         1409 :     context = static_cast<DumpContext *>(aContext);
     332              : 
     333         1409 :     VerifyOrReturnError(context->mWriter != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
     334              : 
     335         1409 :     DumpHandler(context->mWriter, indent, aReader, aDepth);
     336              : 
     337         1409 :     return CHIP_NO_ERROR;
     338              : }
     339              : 
     340              : /**
     341              :  *  Dump the TLV data within the specified reader in human-readable form with
     342              :  *  the specified writer.
     343              :  *
     344              :  *  @param[in]     aReader          A read-only reference to the TLV reader containing
     345              :  *                                  the TLV data to log.
     346              :  *
     347              :  *  @param[in]     aWriter          A dump writer to log the TLV data of the TLV reader.
     348              :  *
     349              :  *  @retval  #CHIP_NO_ERROR        On success.
     350              :  *
     351              :  */
     352           75 : CHIP_ERROR Dump(const TLVReader & aReader, DumpWriter aWriter)
     353              : {
     354           75 :     void * context          = nullptr;
     355           75 :     DumpContext dumpContext = { aWriter, context };
     356              :     CHIP_ERROR retval;
     357              : 
     358           75 :     retval = Utilities::Iterate(aReader, DumpHandler, &dumpContext);
     359              : 
     360           75 :     return retval;
     361              : }
     362              : 
     363              : } // namespace Debug
     364              : 
     365              : } // namespace TLV
     366              : 
     367              : } // namespace chip
        

Generated by: LCOV version 2.0-1