Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / lib / support / logging / CHIPLogging.cpp
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    Copyright (c) 2013-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
19 /**
20  *    @file
21  *      This file implements macros, constants, and interfaces for a
22  *      platform-independent logging interface for the chip SDK.
23  *
24  */
25
26 #include "CHIPLogging.h"
27
28 #include <core/CHIPCore.h>
29 #include <support/CodeUtils.h>
30 #include <support/DLLUtil.h>
31
32 #include <stdarg.h>
33 #include <stdio.h>
34 #include <string.h>
35
36 #include <atomic>
37
38 namespace chip {
39 namespace Logging {
40
41 #if _CHIP_USE_LOGGING
42
43 namespace {
44
45 std::atomic<LogRedirectCallback_t> sLogRedirectCallback{ nullptr };
46
47 }
48
49 /*
50  * Array of strings containing the names for each of the chip log
51  * modules.
52  *
53  * NOTE: The names must be in the order defined in the LogModule
54  *       enumeration. Each name must be a fixed number of characters
55  *       long (chip::Logging::kMaxModuleNameLen) padded with nulls as
56  *       necessary.
57  *
58  */
59 static const char ModuleNames[] = "-\0\0" // None
60                                   "IN\0"  // Inet
61                                   "BLE"   // BLE
62                                   "ML\0"  // MessageLayer
63                                   "SM\0"  // SecurityManager
64                                   "EM\0"  // ExchangeManager
65                                   "TLV"   // TLV
66                                   "ASN"   // ASN1
67                                   "CR\0"  // Crypto
68                                   "CTL"   // Controller
69                                   "AL\0"  // Alarm
70                                   "BDX"   // BulkDataTransfer
71                                   "DMG"   // DataManagement
72                                   "DC\0"  // DeviceControl
73                                   "DD\0"  // DeviceDescription
74                                   "ECH"   // Echo
75                                   "FP\0"  // FabricProvisioning
76                                   "NP\0"  // NetworkProvisioning
77                                   "SD\0"  // ServiceDirectory
78                                   "SP\0"  // ServiceProvisioning
79                                   "SWU"   // SoftwareUpdate
80                                   "TP\0"  // TokenPairing
81                                   "TS\0"  // TimeServices
82                                   "HB\0"  // Heartbeat
83                                   "CSL"   // chipSystemLayer
84                                   "EVL"   // Event Logging
85                                   "SPT"   // Support
86                                   "TOO"   // chipTool
87                                   "ZCL"   // Zcl
88                                   "SH\0"  // Shell
89                                   "DL\0"  // DeviceLayer
90                                   "SPL"   // SetupPayload
91                                   "SVR"   // AppServer
92                                   "DIS"   // Discovery
93     ;
94
95 #define ModuleNamesCount ((sizeof(ModuleNames) - 1) / chip::Logging::kMaxModuleNameLen)
96
97 void GetModuleName(char * buf, uint8_t bufSize, uint8_t module)
98 {
99     const char * moduleNamePtr = ModuleNames + ((module < ModuleNamesCount) ? module * chip::Logging::kMaxModuleNameLen : 0);
100
101     snprintf(buf, bufSize, "%s", moduleNamePtr);
102     buf[chip::Logging::kMaxModuleNameLen] = 0;
103 }
104
105 void SetLogRedirectCallback(LogRedirectCallback_t callback)
106 {
107     sLogRedirectCallback.store(callback);
108 }
109
110 /**
111  * Log, to the platform-specified mechanism, the specified log
112  * message, @a msg, for the specified module, @a module, in the
113  * provided category, @a category.
114  *
115  * @param[in] module    A LogModule enumeration indicating the
116  *                      source of the chip package module that
117  *                      generated the log message. This must be
118  *                      translated within the function to a module
119  *                      name for inclusion in the log message.
120  * @param[in] category  A LogCategory enumeration indicating the
121  *                      category of the log message. The category
122  *                      may be filtered in or out if
123  *                      CHIP_LOG_FILTERING was asserted.
124  * @param[in] msg       A pointer to a NULL-terminated C string with
125  *                      C Standard Library-style format specifiers
126  *                      containing the log message to be formatted and
127  *                      logged.
128  * @param[in] ...       A variadic argument list whose elements should
129  *                      correspond to the format specifiers in @a msg.
130  *
131  */
132 DLL_EXPORT void Log(uint8_t module, uint8_t category, const char * msg, ...)
133 {
134
135     va_list v;
136     va_start(v, msg);
137     LogV(module, category, msg, v);
138     va_end(v);
139 }
140
141 void LogV(uint8_t module, uint8_t category, const char * msg, va_list args)
142 {
143     if (!IsCategoryEnabled(category))
144     {
145         return;
146     }
147
148     char moduleName[chip::Logging::kMaxModuleNameLen + 1];
149     GetModuleName(moduleName, sizeof(moduleName), module);
150
151     LogRedirectCallback_t redirect = sLogRedirectCallback.load();
152
153     if (redirect != nullptr)
154     {
155         redirect(moduleName, category, msg, args);
156     }
157     else
158     {
159         Platform::LogV(moduleName, category, msg, args);
160     }
161 }
162
163 #if CHIP_LOG_FILTERING
164 uint8_t gLogFilter = kLogCategory_Max;
165 DLL_EXPORT bool IsCategoryEnabled(uint8_t category)
166 {
167     return (category <= gLogFilter);
168 }
169
170 DLL_EXPORT uint8_t GetLogFilter()
171 {
172     return gLogFilter;
173 }
174
175 DLL_EXPORT void SetLogFilter(uint8_t category)
176 {
177     gLogFilter = category;
178 }
179
180 #else  // CHIP_LOG_FILTERING
181
182 DLL_EXPORT bool IsCategoryEnabled(uint8_t category)
183 {
184     (void) category;
185     return true;
186 }
187
188 DLL_EXPORT uint8_t GetLogFilter()
189 {
190     return kLogCategory_Max;
191 }
192
193 DLL_EXPORT void SetLogFilter(uint8_t category)
194 {
195     (void) category;
196 }
197 #endif // CHIP_LOG_FILTERING
198
199 #endif /* _CHIP_USE_LOGGING */
200
201 } // namespace Logging
202 } // namespace chip