/******************************************************************************* ** This file is provided under a dual BSD/GPLv2 license. When using or ** redistributing this file, you may do so under either license. ** ** GPL LICENSE SUMMARY ** ** Copyright (c) 2013 Intel Corporation All Rights Reserved ** ** This program is free software; you can redistribute it and/or modify it under ** the terms of version 2 of the GNU General Public License as published by the ** Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but WITHOUT ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ** details. ** ** You should have received a copy of the GNU General Public License along with ** this program; if not, write to the Free Software Foundation, Inc., ** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ** The full GNU General Public License is included in this distribution in the ** file called LICENSE.GPL. ** ** BSD LICENSE ** ** Copyright (c) 2013 Intel Corporation All Rights Reserved ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** ** * Redistributions of source code must retain the above copyright notice, this ** list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright notice, ** this list of conditions and the following disclaimer in the documentation ** and/or other materials provided with the distribution. ** * Neither the name of Intel Corporation nor the names of its contributors may ** be used to endorse or promote products derived from this software without ** specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ** POSSIBILITY OF SUCH DAMAGE. ** *******************************************************************************/ #include "esif.h" #include "esif_debug.h" #ifdef ESIF_ATTR_OS_WINDOWS /* * * The Windows banned-API check header must be included after all other headers, * or issues can be identified * against Windows SDK/DDK included headers which we have no control over. * */ #define _SDL_BANNED_RECOMMENDED #include "win\banned.h" #endif #ifdef ESIF_ATTR_KERNEL /* Debug Data */ u32 g_esif_trace_level = ESIF_TRACELEVEL_ERROR; u32 g_esif_module_mask = 0xFFFFFFFF; u32 g_esif_module_category_mask[ESIF_DEBUG_MOD_MAX]; /* Init Debug Modules */ void esif_debug_init_module_categories () { int i; for (i = 0; i < ESIF_DEBUG_MOD_MAX; i++) g_esif_module_category_mask[i] = ESIF_TRACE_CATEGORY_DEFAULT; } /* Set Debug Modules */ void esif_debug_set_modules (u32 module_mask) { ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ELF, ESIF_TRACE_CATEGORY_DEBUG, "%s: setting debug modules: 0x%08X\n", ESIF_FUNC, module_mask); g_esif_module_mask = module_mask; } /* Get Debug Modules */ void esif_debug_get_modules (u32 *module_mask_ptr) { *module_mask_ptr = g_esif_module_mask; } /* Set Module Level */ void esif_debug_set_module_category ( u32 module, u32 module_level_mask ) { ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ELF, ESIF_TRACE_CATEGORY_DEBUG, "%s: %s(%d) debug level: 0x%08X\n", ESIF_FUNC, esif_debug_mod_str((enum esif_debug_mod)module), module, module_level_mask); if (module < ESIF_DEBUG_MOD_MAX) g_esif_module_category_mask[module] = module_level_mask; else if (module == (u32)(-1) && module_level_mask <= ESIF_TRACELEVEL_DEBUG) g_esif_trace_level = module_level_mask; } /* Get Module Level */ void esif_debug_get_module_category ( u32 module, u32 *module_level_mask_ptr ) { if (module < ESIF_DEBUG_MOD_MAX) *module_level_mask_ptr = g_esif_module_category_mask[module]; } #else /* USER */ #include "esif_uf_log.h" #ifdef ESIF_ATTR_OS_WINDOWS #endif #ifdef ESIF_ATTR_OS_LINUX # ifdef ESIF_ATTR_OS_ANDROID # include # define IDENT "DPTF" # define ESIF_PRIORITY_FATAL ANDROID_LOG_FATAL # define ESIF_PRIORITY_ERROR ANDROID_LOG_ERROR # define ESIF_PRIORITY_WARNING ANDROID_LOG_WARN # define ESIF_PRIORITY_INFO ANDROID_LOG_INFO # define ESIF_PRIORITY_DEBUG ANDROID_LOG_DEBUG # else # include # define IDENT "DPTF" # define OPTION LOG_PID # define FACILITY LOG_DAEMON # define ESIF_PRIORITY_FATAL LOG_EMERG # define ESIF_PRIORITY_ERROR LOG_ERR # define ESIF_PRIORITY_WARNING LOG_WARNING # define ESIF_PRIORITY_INFO LOG_INFO # define ESIF_PRIORITY_DEBUG LOG_DEBUG # endif #endif #define TRACEON(module) ((esif_tracemask_t)1 << (module)) #define TRACEOFF(module) ((esif_tracemask_t)0) // Default Trace Module BitMask for DEBUG Messages // NOTE: Modules without a "#define ESIF_TRACE_ID" use DEFAULT option #define ESIF_TRACEMASK_DEBUG ( \ TRACEOFF(ESIF_TRACEMODULE_DEFAULT) | \ TRACEON (ESIF_TRACEMODULE_DPTF) | \ TRACEOFF(ESIF_TRACEMODULE_CCB) | \ TRACEON (ESIF_TRACEMODULE_SHELL) | \ TRACEOFF(ESIF_TRACEMODULE_UF) | \ TRACEON (ESIF_TRACEMODULE_ACTION) | \ TRACEON (ESIF_TRACEMODULE_APP) | \ TRACEON (ESIF_TRACEMODULE_CONJURE) | \ TRACEOFF(ESIF_TRACEMODULE_DSP) | \ TRACEOFF(ESIF_TRACEMODULE_EVENT) | \ TRACEOFF(ESIF_TRACEMODULE_IPC) | \ TRACEOFF(ESIF_TRACEMODULE_PARTICIPANT) | \ TRACEOFF(ESIF_TRACEMODULE_PRIMITIVE) | \ TRACEON (ESIF_TRACEMODULE_SERVICE) | \ TRACEON (ESIF_TRACEMODULE_TEST) | \ TRACEOFF(ESIF_TRACEMODULE_DATAVAULT) | \ TRACEOFF(ESIF_TRACEMODULE_EQL) | \ TRACEON (ESIF_TRACEMODULE_WEBSERVER) | \ /* windows specific */ \ TRACEOFF(ESIF_TRACEMODULE_WINDOWS) | \ TRACEON (ESIF_TRACEMODULE_ACTWIRELESS) | \ TRACEOFF(ESIF_TRACEMODULE_UMDF) | \ TRACEOFF(0) ) int g_traceLevel = ESIF_TRACELEVEL_DEFAULT; struct esif_tracelevel_s g_traceinfo[] = { {"FATAL", ESIF_TRACELEVEL_FATAL, ESIF_TRACEMASK_ALL, ESIF_TRACEROUTE_EVENTLOG}, {"ERROR", ESIF_TRACELEVEL_ERROR, ESIF_TRACEMASK_ALL, ESIF_TRACEROUTE_EVENTLOG}, {"WARNING", ESIF_TRACELEVEL_WARN, ESIF_TRACEMASK_ALL, ESIF_TRACEROUTE_EVENTLOG}, {"INFO", ESIF_TRACELEVEL_INFO, ESIF_TRACEMASK_ALL, ESIF_TRACEROUTE_EVENTLOG}, {"DEBUG", ESIF_TRACELEVEL_DEBUG, ESIF_TRACEMASK_ALL, ESIF_TRACEROUTE_DEBUGGER}, }; #define ESIF_TRACELEVEL_MAX ((sizeof(g_traceinfo) / sizeof(struct esif_tracelevel_s)) - 1) int g_traceLevel_max = ESIF_TRACELEVEL_MAX; #define DETAILED_TRACELEVEL ESIF_TRACELEVEL_FATAL /* All Trace Levels */ const struct EsifTraceModuleList_s { enum esif_tracemodule id; const char *str; } g_EsifTraceModuleList[] = { ENUM_TRACEMODULE(ENUMLIST) {(enum esif_tracemodule)0} }; const enum esif_tracemodule EsifTraceModule_FromString(const char *name) { int j; for (j=0; g_EsifTraceModuleList[j].str; j++) { if (esif_ccb_stricmp(name, g_EsifTraceModuleList[j].str)==0 || // ESIF_TRACEMODULE_XXXX esif_ccb_stricmp(name, g_EsifTraceModuleList[j].str+17)==0) // XXXX return g_EsifTraceModuleList[j].id; } return (enum esif_tracemodule)0; } #define ENUMSWITCHSTR(ENUM) case ENUM: str = #ENUM; break; #define ENUMSWITCHSTR_VAL(ENUM) ENUMSWITCHSTR(ENUM) const char *EsifTraceModule_ToString(enum esif_tracemodule val) { const char *str = NULL; switch (val) { ENUM_TRACEMODULE(ENUMSWITCHSTR) default: break; } if (str) str += 17; // Truncate "ESIF_TRACEMODULE_" return str; } int EsifTraceMessage( esif_tracemask_t module, int level, const char *func, const char *file, int line, const char *msg, ...) { int rc=0; char *appname = ""; char *fmtDetail= "%s%s:[%s@%s#%d]: "; char *fmtInfo = "%s%s: "; const char *sep=NULL; size_t fmtlen=esif_ccb_strlen(msg, 0x7FFFFFFF); int detailed_message = (level >= DETAILED_TRACELEVEL ? ESIF_TRUE : ESIF_FALSE); va_list args; UNREFERENCED_PARAMETER(module); level = esif_ccb_min(level, ESIF_TRACELEVEL_MAX); if ((sep = strrchr(file, *ESIF_PATH_SEP)) != NULL) file = sep+1; // Do not function/file/line number information for app interface messages logged from EsifSvcWriteLog if (esif_ccb_strcmp(func, "EsifSvcWriteLog") == 0) { detailed_message = ESIF_FALSE; } if (g_traceinfo[level].routes & ESIF_TRACEROUTE_CONSOLE) { if (detailed_message) rc = CMD_CONSOLE(fmtDetail, appname, g_traceinfo[level].label, func, file, line); else rc = CMD_CONSOLE(fmtInfo, appname, g_traceinfo[level].label); va_start(args, msg); rc += EsifConsole_WriteConsole(msg, args); va_end(args); if (fmtlen && msg[fmtlen-1]!='\n') CMD_CONSOLE("\n"); } if (g_traceinfo[level].routes & ESIF_TRACEROUTE_LOGFILE && EsifLogFile_IsOpen(ESIF_LOG_TRACE)) { time_t now=0; char timestamp[MAX_CTIME_LEN]={0}; time(&now); esif_ccb_ctime(timestamp, sizeof(timestamp), &now); timestamp[20] = 0; // truncate year if (detailed_message) rc = EsifLogFile_Write(ESIF_LOG_TRACE, fmtDetail, timestamp+4, g_traceinfo[level].label, func, file, line); else rc = EsifLogFile_Write(ESIF_LOG_TRACE, fmtInfo, timestamp+4, g_traceinfo[level].label); va_start(args, msg); rc += EsifLogFile_WriteArgs(ESIF_LOG_TRACE, msg, args); va_end(args); if (fmtlen && msg[fmtlen-1]!='\n') EsifLogFile_Write(ESIF_LOG_TRACE, "\n"); } #ifdef ESIF_ATTR_OS_WINDOWS if (g_traceinfo[level].routes & (ESIF_TRACEROUTE_DEBUGGER)) { size_t msglen=0; char *buffer=0; int offset=0; va_start(args, msg); msglen = esif_ccb_vscprintf(msg, args) + esif_ccb_strlen(g_traceinfo[level].label, MAX_PATH) + esif_ccb_strlen(appname, MAX_PATH) + esif_ccb_strlen(func, MAX_PATH) + esif_ccb_strlen(file, MAX_PATH) + 10; va_end(args); msglen += (detailed_message ? esif_ccb_strlen(fmtDetail, MAX_PATH) : esif_ccb_strlen(fmtInfo, MAX_PATH)); buffer = (char *)esif_ccb_malloc(msglen); if (NULL != buffer) { if (detailed_message) rc = esif_ccb_sprintf(msglen, buffer, fmtDetail, appname, g_traceinfo[level].label, func, file, line); else rc = esif_ccb_sprintf(msglen, buffer, fmtInfo, appname, g_traceinfo[level].label); offset = rc; va_start(args, msg); rc += esif_ccb_vsprintf(msglen-offset, buffer+offset, msg, args); va_end(args); if (rc && buffer[rc-1]!='\n') esif_ccb_strcat(buffer, "\n", msglen); OutputDebugStringA(buffer); esif_ccb_free(buffer); } } if (g_traceinfo[level].routes & (ESIF_TRACEROUTE_EVENTLOG)) { size_t msglen=0; char *buffer=0; int offset=0; int backset=0; WORD eventType; appname = ""; fmtInfo = "%sESIF(%s) TYPE: %s\n\n"; fmtDetail= "%sESIF(%s) TYPE: %s FUNC: %s FILE: %s LINE: %d\n\n"; backset = 0; va_start(args, msg); msglen = esif_ccb_vscprintf(msg,args) + esif_ccb_strlen(g_traceinfo[level].label, MAX_PATH) + esif_ccb_strlen(appname, MAX_PATH) + esif_ccb_strlen(func, MAX_PATH) + esif_ccb_strlen(file, MAX_PATH) + 20; va_end(args); msglen += (detailed_message ? esif_ccb_strlen(fmtDetail, MAX_PATH) : esif_ccb_strlen(fmtInfo, MAX_PATH)); buffer = (char *)esif_ccb_malloc(msglen); if (NULL != buffer) { if (detailed_message) rc = esif_ccb_sprintf(msglen, buffer, fmtDetail, appname, ESIF_UF_VERSION, g_traceinfo[level].label, func, file, line); else rc = esif_ccb_sprintf(msglen, buffer, fmtInfo, appname, ESIF_UF_VERSION, g_traceinfo[level].label); if (backset && backset < rc) buffer[rc-backset-1] = 0; offset = rc-backset; va_start(args, msg); rc += esif_ccb_vsprintf(msglen-(offset+backset), buffer+offset+backset, msg, args); va_end(args); if (rc && buffer[rc-1]=='\n') buffer[--rc] = 0; switch (g_traceinfo[level].level) { case ESIF_TRACELEVEL_FATAL: case ESIF_TRACELEVEL_ERROR: eventType = EVENTLOG_ERROR_TYPE; break; case ESIF_TRACELEVEL_WARN: eventType = EVENTLOG_WARNING_TYPE; break; case ESIF_TRACELEVEL_INFO: case ESIF_TRACELEVEL_DEBUG: default: eventType = EVENTLOG_INFORMATION_TYPE; break; } report_event_to_event_log(CATEGORY_GENERAL, eventType, buffer); esif_ccb_free(buffer); } } #endif #ifdef ESIF_ATTR_OS_LINUX if (g_traceinfo[level].routes & (ESIF_TRACEROUTE_EVENTLOG|ESIF_TRACEROUTE_DEBUGGER)) { size_t msglen=0; char *buffer=0; int offset=0; int priority; fmtDetail= "%s:[%s@%s#%d]: "; fmtInfo = "%s: "; va_start(args, msg); msglen = esif_ccb_vscprintf(msg,args) + esif_ccb_strlen(g_traceinfo[level].label, MAX_PATH) + esif_ccb_strlen(func, MAX_PATH) + esif_ccb_strlen(file, MAX_PATH) + 10; va_end(args); msglen += (detailed_message ? esif_ccb_strlen(fmtDetail, MAX_PATH) : esif_ccb_strlen(fmtInfo, MAX_PATH)); buffer = (char *)esif_ccb_malloc(msglen); if (NULL != buffer) { if (detailed_message) rc = esif_ccb_sprintf(msglen, buffer, fmtDetail, g_traceinfo[level].label, func, file, line); else rc = esif_ccb_sprintf(msglen, buffer, fmtInfo, g_traceinfo[level].label); offset = rc; va_start(args, msg); rc += esif_ccb_vsprintf(msglen-offset, buffer+offset, msg, args); va_end(args); if (rc && buffer[rc-1]=='\n') buffer[--rc] = 0; switch (g_traceinfo[level].level) { case ESIF_TRACELEVEL_FATAL: priority = ESIF_PRIORITY_FATAL; break; case ESIF_TRACELEVEL_ERROR: priority = ESIF_PRIORITY_ERROR; break; case ESIF_TRACELEVEL_WARN: priority = ESIF_PRIORITY_WARNING; break; case ESIF_TRACELEVEL_INFO: priority = ESIF_PRIORITY_INFO; break; case ESIF_TRACELEVEL_DEBUG: default: priority = ESIF_PRIORITY_DEBUG; break; } #ifdef ESIF_ATTR_OS_ANDROID __android_log_write(priority, IDENT, buffer); #else openlog(IDENT, OPTION, FACILITY); syslog(priority, "%s", buffer); closelog(); #endif esif_ccb_free(buffer); } } #endif return rc; } #endif /* NOT ESIF_ATTR_KERNEL */ /******************************************************************************/ /******************************************************************************/ /******************************************************************************/