1/* 2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this list of 9 * conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 * of conditions and the following disclaimer in the documentation and/or other materials 13 * provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 16 * to endorse or promote products derived from this software without specific prior written 17 * permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include "shell_lk.h" 33#include "securec.h" 34#include "stdio.h" 35#include "stdlib.h" 36#include "unistd.h" 37#include "shcmd.h" 38#ifdef LOSCFG_SHELL_DMESG 39#include "dmesg_pri.h" 40#endif 41#include "los_init.h" 42#include "los_printf_pri.h" 43#include "los_process_pri.h" 44 45#ifdef LOSCFG_SHELL_LK 46 47typedef enum { 48 MODULE0 = 0, 49 MODULE1 = 1, 50 MODULE2 = 2, 51 MODULE3 = 3, 52 MODULE4 = 4, 53} MODULE_FLAG; 54 55typedef struct { 56 INT32 module_level; 57 INT32 trace_level; 58 FILE *fp; 59} Logger; 60 61STATIC INT32 g_tracelevel; 62STATIC INT32 g_modulelevel; 63 64STATIC Logger g_logger = { 0 }; 65 66VOID OsLkDefaultFunc(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, va_list ap); 67 68LK_FUNC g_osLkHook = (LK_FUNC)OsLkDefaultFunc; 69 70STATIC INLINE INT32 OsLkTraceLvGet(VOID) 71{ 72 return g_tracelevel; 73} 74 75const CHAR *OsLkCurLogLvGet(VOID) 76{ 77 return OsLogLvGet(g_tracelevel); 78} 79 80VOID OsLkTraceLvSet(INT32 level) 81{ 82 g_tracelevel = level; 83 g_logger.trace_level = level; 84 return; 85} 86 87VOID OsLkModuleLvSet(INT32 level) 88{ 89 g_modulelevel = level; 90 g_logger.module_level = level; 91 return; 92} 93 94INT32 OsLkModuleLvGet(VOID) 95{ 96 return g_modulelevel; 97} 98 99VOID OsLkLogFileSet(const CHAR *str) 100{ 101 FILE *fp = NULL; 102 FILE *oldfp = g_logger.fp; 103 104 if (str == NULL) { 105 return; 106 } 107 fp = fopen(str, "w+"); 108 if (fp == NULL) { 109 printf("Error can't open the %s file\n", str); 110 return; 111 } 112 113 g_logger.fp = fp; 114 if (oldfp != NULL) { 115 fclose(oldfp); 116 } 117} 118 119FILE *OsLogFpGet(VOID) 120{ 121 return g_logger.fp; 122} 123 124INT32 CmdLog(INT32 argc, const CHAR **argv) 125{ 126 size_t level; 127 size_t module; 128 CHAR *p = NULL; 129 130 if ((argc != 2) || (argv == NULL)) { /* 2:count of parameter */ 131 PRINTK("Usage: log level <num>\n"); 132 PRINTK("Usage: log module <num>\n"); 133 PRINTK("Usage: log path <PATH>\n"); 134 return -1; 135 } 136 137 if (!strncmp(argv[0], "level", strlen(argv[0]) + 1)) { 138 level = strtoul(argv[1], &p, 0); 139 if ((*p != 0) || (level > LOS_TRACE_LEVEL) || (level < LOS_EMG_LEVEL)) { 140 PRINTK("current log level %s\n", OsLkCurLogLvGet()); 141 PRINTK("log %s [num] can access as 0:EMG 1:COMMON 2:ERROR 3:WARN 4:INFO 5:DEBUG\n", argv[0]); 142 } else { 143 OsLkTraceLvSet(level); 144 PRINTK("Set current log level %s\n", OsLkCurLogLvGet()); 145 } 146 } else if (!strncmp(argv[0], "module", strlen(argv[0]) + 1)) { 147 module = strtoul(argv[1], &p, 0); 148 if ((*p != 0) || (module > MODULE4)) { 149 PRINTK("log %s can't access %s\n", argv[0], argv[1]); 150 PRINTK("not support yet\n"); 151 return -1; 152 } else { 153 OsLkModuleLvSet(module); 154 PRINTK("not support yet\n"); 155 } 156 } else if (!strncmp(argv[0], "path", strlen(argv[0]) + 1)) { 157 PRINTK("not support yet\n"); 158 } else { 159 PRINTK("Usage: log level <num>\n"); 160 PRINTK("Usage: log module <num>\n"); 161 PRINTK("Usage: log path <PATH>\n"); 162 return -1; 163 } 164 165 return 0; 166} 167 168#ifdef LOSCFG_SHELL_DMESG 169STATIC INLINE VOID OsLogCycleRecord(INT32 level) 170{ 171 UINT32 tmpLen; 172 if (level != LOS_COMMON_LEVEL && (level > LOS_EMG_LEVEL && level <= LOS_TRACE_LEVEL)) { 173 tmpLen = strlen(OsLogLvGet(level)); 174 const CHAR* tmpPtr = OsLogLvGet(level); 175 (VOID)OsLogRecordStr(tmpPtr, tmpLen); 176 } 177} 178#endif 179 180VOID OsLkDefaultFunc(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, va_list ap) 181{ 182 if (level > OsLkTraceLvGet()) { 183#ifdef LOSCFG_SHELL_DMESG 184 if ((UINT32)level <= OsDmesgLvGet()) { 185 OsLogCycleRecord(level); 186 DmesgPrintf(fmt, ap); 187 } 188#endif 189 return; 190 } 191 if ((level != LOS_COMMON_LEVEL) && ((level > LOS_EMG_LEVEL) && (level <= LOS_TRACE_LEVEL))) { 192 dprintf("[%s][%s:%s]", OsLogLvGet(level), 193 ((OsCurrProcessGet() == NULL) ? "NULL" : OsCurrProcessGet()->processName), 194 ((OsCurrTaskGet() == NULL) ? "NULL" : OsCurrTaskGet()->taskName)); 195 } 196 LkDprintf(fmt, ap); 197} 198 199VOID LOS_LkPrint(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, ...) 200{ 201 va_list ap; 202 if (g_osLkHook != NULL) { 203 va_start(ap, fmt); 204 g_osLkHook(level, func, line, fmt, ap); 205 va_end(ap); 206 } 207} 208 209VOID LOS_LkRegHook(LK_FUNC hook) 210{ 211 g_osLkHook = hook; 212} 213 214UINT32 OsLkLoggerInit(VOID) 215{ 216 (VOID)memset_s(&g_logger, sizeof(Logger), 0, sizeof(Logger)); 217 OsLkTraceLvSet(TRACE_DEFAULT); 218 LOS_LkRegHook(OsLkDefaultFunc); 219#ifdef LOSCFG_SHELL_DMESG 220 (VOID)LOS_DmesgLvSet(TRACE_DEFAULT); 221#endif 222 return LOS_OK; 223} 224 225#ifdef LOSCFG_SHELL_CMD_DEBUG 226SHELLCMD_ENTRY(log_shellcmd, CMD_TYPE_EX, "log", 1, (CmdCallBackFunc)CmdLog); 227#endif 228 229LOS_MODULE_INIT(OsLkLoggerInit, LOS_INIT_LEVEL_EARLIEST); 230 231#endif 232