LCOV - code coverage report
Current view: top level - lib/support/logging - TextOnlyLogging.cpp (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 19 24 79.2 %
Date: 2024-02-15 08:20:41 Functions: 5 7 71.4 %

          Line data    Source code
       1             : /*
       2             :  *    Copyright (c) 2020-2023 Project CHIP Authors
       3             :  *    Copyright (c) 2013-2017 Nest Labs, Inc.
       4             :  *
       5             :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6             :  *    you may not use this file except in compliance with the License.
       7             :  *    You may obtain a copy of the License at
       8             :  *
       9             :  *        http://www.apache.org/licenses/LICENSE-2.0
      10             :  *
      11             :  *    Unless required by applicable law or agreed to in writing, software
      12             :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13             :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14             :  *    See the License for the specific language governing permissions and
      15             :  *    limitations under the License.
      16             :  */
      17             : 
      18             : /**
      19             :  *    @file
      20             :  *      This file implements macros, constants, and interfaces for a
      21             :  *      platform-independent logging interface for the chip SDK.
      22             :  *
      23             :  */
      24             : 
      25             : #include "TextOnlyLogging.h"
      26             : 
      27             : #include <lib/core/CHIPConfig.h>
      28             : #include <lib/support/CHIPMem.h>
      29             : 
      30             : #include <platform/logging/LogV.h>
      31             : 
      32             : #include <stdarg.h>
      33             : #include <stdio.h>
      34             : #include <string.h>
      35             : 
      36             : #include <atomic>
      37             : 
      38             : #if CHIP_PW_TOKENIZER_LOGGING
      39             : #include "pw_tokenizer/encode_args.h"
      40             : #endif
      41             : 
      42             : namespace chip {
      43             : namespace Logging {
      44             : 
      45             : #if _CHIP_USE_LOGGING
      46             : 
      47             : #if CHIP_PW_TOKENIZER_LOGGING
      48             : 
      49             : void HandleTokenizedLog(uint32_t levels, pw_tokenizer_Token token, pw_tokenizer_ArgTypes types, ...)
      50             : {
      51             :     uint8_t encoded_message[PW_TOKENIZER_CFG_ENCODING_BUFFER_SIZE_BYTES];
      52             : 
      53             :     memcpy(encoded_message, &token, sizeof(token));
      54             : 
      55             :     va_list args;
      56             :     va_start(args, types);
      57             :     // Use the C argument encoding API, since the C++ API requires C++17.
      58             :     const size_t encoded_size = sizeof(token) +
      59             :         pw_tokenizer_EncodeArgs(types, args, encoded_message + sizeof(token), sizeof(encoded_message) - sizeof(token));
      60             :     va_end(args);
      61             : 
      62             :     uint8_t log_category  = levels >> 8 & 0xFF;
      63             :     uint8_t log_module    = levels & 0xFF;
      64             :     char * logging_buffer = nullptr;
      65             : 
      66             :     // To reduce the number of alloc/free that is happening we will use a stack
      67             :     // buffer when buffer required to log is small.
      68             :     char stack_buffer[32];
      69             :     char * allocated_buffer     = nullptr;
      70             :     size_t required_buffer_size = 2 * encoded_size + 1;
      71             : 
      72             :     if (required_buffer_size > sizeof(stack_buffer))
      73             :     {
      74             :         allocated_buffer = (char *) chip::Platform::MemoryAlloc(required_buffer_size);
      75             :         if (allocated_buffer)
      76             :         {
      77             :             logging_buffer = allocated_buffer;
      78             :         }
      79             :     }
      80             :     else
      81             :     {
      82             :         logging_buffer = stack_buffer;
      83             :     }
      84             : 
      85             :     if (logging_buffer)
      86             :     {
      87             :         for (size_t i = 0; i < encoded_size; i++)
      88             :         {
      89             :             sprintf(logging_buffer + 2 * i, "%02x", encoded_message[i]);
      90             :         }
      91             :         logging_buffer[2 * encoded_size] = '\0';
      92             :         Log(log_module, log_category, "%s", logging_buffer);
      93             :     }
      94             :     if (allocated_buffer)
      95             :     {
      96             :         chip::Platform::MemoryFree(allocated_buffer);
      97             :     }
      98             : }
      99             : 
     100             : #endif
     101             : 
     102             : namespace {
     103             : 
     104             : std::atomic<LogRedirectCallback_t> sLogRedirectCallback{ nullptr };
     105             : 
     106             : /*
     107             :  * Array of strings containing the names for each of the chip log modules.
     108             :  *
     109             :  * NOTE: The names must be in the order defined in the LogModule enumeration.
     110             :  */
     111             : static const char ModuleNames[kLogModule_Max][kMaxModuleNameLen + 1] = {
     112             :     "-",   // None
     113             :     "IN",  // Inet
     114             :     "BLE", // BLE
     115             :     "ML",  // MessageLayer
     116             :     "SM",  // SecurityManager
     117             :     "EM",  // ExchangeManager
     118             :     "TLV", // TLV
     119             :     "ASN", // ASN1
     120             :     "CR",  // Crypto
     121             :     "CTL", // Controller
     122             :     "AL",  // Alarm
     123             :     "SC",  // SecureChannel
     124             :     "BDX", // BulkDataTransfer
     125             :     "DMG", // DataManagement
     126             :     "DC",  // DeviceControl
     127             :     "DD",  // DeviceDescription
     128             :     "ECH", // Echo
     129             :     "FP",  // FabricProvisioning
     130             :     "NP",  // NetworkProvisioning
     131             :     "SD",  // ServiceDirectory
     132             :     "SP",  // ServiceProvisioning
     133             :     "SWU", // SoftwareUpdate
     134             :     "FS",  // FailSafe
     135             :     "TS",  // TimeService
     136             :     "HB",  // Heartbeat
     137             :     "CSL", // chipSystemLayer
     138             :     "EVL", // Event Logging
     139             :     "SPT", // Support
     140             :     "TOO", // chipTool
     141             :     "ZCL", // Zcl
     142             :     "SH",  // Shell
     143             :     "DL",  // DeviceLayer
     144             :     "SPL", // SetupPayload
     145             :     "SVR", // AppServer
     146             :     "DIS", // Discovery
     147             :     "IM",  // InteractionModel
     148             :     "TST", // Test
     149             :     "OSS", // OperationalSessionSetup
     150             :     "ATM", // Automation
     151             :     "CSM", // CASESessionManager
     152             : };
     153             : 
     154             : } // namespace
     155             : 
     156     1080529 : const char * GetModuleName(LogModule module)
     157             : {
     158     1080529 :     return ModuleNames[(module < kLogModule_Max) ? module : kLogModule_NotSpecified];
     159             : }
     160             : 
     161          10 : void SetLogRedirectCallback(LogRedirectCallback_t callback)
     162             : {
     163          10 :     sLogRedirectCallback.store(callback);
     164          10 : }
     165             : 
     166             : /**
     167             :  * Log, to the platform-specified mechanism, the specified log
     168             :  * message, @a msg, for the specified module, @a module, in the
     169             :  * provided category, @a category.
     170             :  *
     171             :  * @param[in] module    A LogModule enumeration indicating the
     172             :  *                      source of the chip package module that
     173             :  *                      generated the log message. This must be
     174             :  *                      translated within the function to a module
     175             :  *                      name for inclusion in the log message.
     176             :  * @param[in] category  A LogCategory enumeration indicating the
     177             :  *                      category of the log message. The category
     178             :  *                      may be filtered in or out if
     179             :  *                      CHIP_LOG_FILTERING was asserted.
     180             :  * @param[in] msg       A pointer to a NULL-terminated C string with
     181             :  *                      C Standard Library-style format specifiers
     182             :  *                      containing the log message to be formatted and
     183             :  *                      logged.
     184             :  * @param[in] ...       A variadic argument list whose elements should
     185             :  *                      correspond to the format specifiers in @a msg.
     186             :  *
     187             :  */
     188     1080529 : void Log(uint8_t module, uint8_t category, const char * msg, ...)
     189             : {
     190             : 
     191             :     va_list v;
     192     1080529 :     va_start(v, msg);
     193     1080529 :     LogV(module, category, msg, v);
     194     1080529 :     va_end(v);
     195     1080529 : }
     196             : 
     197     1080529 : void LogV(uint8_t module, uint8_t category, const char * msg, va_list args)
     198             : {
     199     1080529 :     const char * moduleName        = GetModuleName(static_cast<LogModule>(module));
     200     1080529 :     LogRedirectCallback_t redirect = sLogRedirectCallback.load();
     201     1080529 :     if (redirect != nullptr)
     202             :     {
     203          11 :         redirect(moduleName, category, msg, args);
     204             :     }
     205             :     else
     206             :     {
     207     1080518 :         Platform::LogV(moduleName, category, msg, args);
     208             :     }
     209     1080529 : }
     210             : 
     211             : #if CHIP_LOG_FILTERING
     212             : uint8_t gLogFilter = kLogCategory_Max;
     213             : 
     214           0 : uint8_t GetLogFilter()
     215             : {
     216           0 :     return gLogFilter;
     217             : }
     218             : 
     219           0 : void SetLogFilter(uint8_t category)
     220             : {
     221           0 :     gLogFilter = category;
     222           0 : }
     223             : 
     224     1080526 : bool IsCategoryEnabled(uint8_t category)
     225             : {
     226     1080526 :     return (category <= gLogFilter);
     227             : }
     228             : #endif // CHIP_LOG_FILTERING
     229             : 
     230             : #endif // _CHIP_USE_LOGGING
     231             : 
     232             : } // namespace Logging
     233             : } // namespace chip

Generated by: LCOV version 1.14