454 lines
14 KiB
C
454 lines
14 KiB
C
/*******************************************************************************
|
|
** 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 <android/log.h>
|
|
# 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 <syslog.h>
|
|
# 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 */
|
|
|
|
/******************************************************************************/
|
|
/******************************************************************************/
|
|
/******************************************************************************/
|
|
|