一、VTP日志配置
ssmu_rv_cfg_log
RvInt32 iFilters = RVSIP_LOG_INFO_FILTER |
RVSIP_LOG_ERROR_FILTER |
RVSIP_LOG_EXCEP_FILTER |
RVSIP_LOG_WARN_FILTER;
//设置日志打印应用层回调函数
p_rv->stack_cfg.pfnPrintLogEntryEvHandler = ssmu_rv_log_handler;
//设置各模块的初始过滤等级
//当前VTP代码把defaultLogFilters给屏蔽了,后期调试可以放开
//p_rv->stack_cfg.defaultLogFilters = iFilters;
p_rv->stack_cfg.callLogFilters = iFilters;
p_rv->stack_cfg.callLogFilters = iFilters;
p_rv->stack_cfg.transactionLogFilters = iFilters;
p_rv->stack_cfg.msgLogFilters = iFilters;
p_rv->stack_cfg.transportLogFilters = iFilters;
p_rv->stack_cfg.parserLogFilters = iFilters;
p_rv->stack_cfg.stackLogFilters = iFilters;
p_rv->stack_cfg.msgBuilderLogFilters = iFilters;
p_rv->stack_cfg.authenticatorLogFilters = iFilters;
p_rv->stack_cfg.transmitterLogFilters = iFilters;
p_rv->stack_cfg.resolverLogFilters = iFilters;
p_rv->stack_cfg.regClientLogFilters = iFilters;
p_rv->stack_cfg.subscriptionLogFilters = iFilters;
p_rv->stack_cfg.compartmentLogFilters = iFilters;
p_rv->stack_cfg.authenticatorLogFilters = iFilters;
p_rv->stack_cfg.secAgreeLogFilters = iFilters;
p_rv->stack_cfg.securityLogFilters = iFilters;
p_rv->stack_cfg.adsFiltersCfg.adsRListLogFilters = 0x00;
p_rv->stack_cfg.adsFiltersCfg.adsRaLogFilters = 0x00;
p_rv->stack_cfg.adsFiltersCfg.adsRPoolLogFilters = 0x00;
p_rv->stack_cfg.adsFiltersCfg.adsHashLogFilters = 0x00;
p_rv->stack_cfg.adsFiltersCfg.adsPQueueLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.coreSemaphoreLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.coreMutexLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.coreLockLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.coreMemoryLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.coreThreadLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.coreQueueLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.coreTimerLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.coreTimestampLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.coreClockLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.coreTmLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.coreSocketLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.corePortRangeLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.coreSelectLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.coreHostLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.coreTlsLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.coreAresLogFilters = iFilters;
p_rv->stack_cfg.coreFiltersCfg.coreRcacheLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.coreEhdLogFilters = 0x00;
p_rv->stack_cfg.coreFiltersCfg.coreImsipsecLogFilters = 0x00;
二、RV协议栈日志管理对象初始化
RvSipStackConstruct
ConstructStackLog(pStackMgr,&internalCfgStruct);
pStackMgr->pLogMgr = NULL;
//日志管理对象构造
RvLogConstruct(&pStackMgr->logMgr);
logMgr->defaultMask = RV_LOGMASK;
//指示所有日志源对象是否打印日志根据每个日志源的过滤变量来处理
logMgr->level = RV_LOG_MASK;
//锁构造
RvLockConstruct(NULL, &logMgr->lock);
//调用所有日志模块构造日志源
for(i = 0; RvLogModules[i].srcConstruct != NULL; ++i)
RvLogModules[i].srcConstruct(logMgr);
----------------------------------------------------------------------------------------------------------
这里以RvSemaphoreSourceConstruct数组函数指针成员进行描述
RvLogSourceConstruct(logMgr, &logMgr->sema4Source, "SEMA4",
"Semaphores interface");
//分配一个可用的日志源索引
curSource = logMgr->source;
for (i = 0; i < logMgr->numSources; i++)
if ((vacantIndex < 0) && (curSource->timesConstructed == 0))
vacantIndex = i;
else if ((curSource->timesConstructed > 0)
&& (strcmp(curSource->name, name) == 0))
vacantIndex = i;
break;
curSource++;
//获取当前可用的日志源索引,并递加分配的日志源总数
if (vacantIndex < 0)
vacantIndex = logMgr->numSources;
logMgr->numSources++;
//初始化
curSource = &logMgr->source[vacantIndex];
if (curSource->timesConstructed == 0)
curSource->logMgr = logMgr;
curSource->name = name//” SEMA4”
curSource->messageTypes = logMgr->defaultMask;
curSource->timesConstructed++;
-------------------------------------------------------------------------------------------------------------
pStackMgr->pLogMgr = &pStackMgr->logMgr;
// logMgr->printThreadId = RV_TRUE;
RvLogPrintThreadId(pStackMgr->pLogMgr);
//注册日志监听器,该回调函数为 LogPrintCallbackFunction ,最终会调用应用层设置的
// ssmu_rv_log_handler
RvLogRegisterListener(pStackMgr->pLogMgr, LogPrintCallbackFunction, (void*)pStackMgr);
logMgr->listener[logMgr->numListeners] = listener;
logMgr->listenerUserData[logMgr->numListeners] = userData;
logMgr->numListeners++;
//不使用日志文件
pStackMgr->bLogFileListenerEnabled = RV_FALSE;
SetTemporaryCoreLogMasks(pStackMgr, pStackCfg);
//设置全局过滤掩码,当前pStackCfg->defaultLogFilters值为0
RvLogSetGlobalMask(pStackMgr->pLogMgr,
SipCommonConvertSipToCoreLogMask(pStackCfg->defaultLogFilters));
//设置默认过滤掩码
logMgr->defaultMask = messageMask;
//更新已经构造好的日志源的过滤掩码
for (i = 0; i < logMgr->numSources; i++)
if (logMgr->source[i].timesConstructed > 0)
logMgr->source[i].messageTypes = messageMask;
//如果配置了coreLogFilters,则使用该值进行配置覆盖
if(pStackCfg->coreLogFilters > 0)
RvLogSetGlobalMask(pStackMgr->pLogMgr,
SipCommonConvertSipToCoreLogMask(pStackCfg->defaultLogFilters))
firstModule = (RvInt32)RVSIP_CORE_SEMAPHORE;
lastModule = (RvInt32)RVSIP_CORE_IMSIPSEC;
//遍历核心模块
for(i = firstModule; i<= lastModule; i++)
//从用户配置中获取对象模块要设置的掩码,如RVSIP_CALL模块用户设置的
//掩码为 pStackCfg->callLogFilters = iFilters
moduleMask = GetModuleLogMaskFromCfg(pStackCfg,(RvSipStackModule)i);
//查找对应模块的日志源对象
RvLogGetSourceByName(pStackMgr->pLogMgr,
GetModuleName((RvSipStackModule)i), &tempLogSource);
//将用户配置的过滤掩码设置到对应的模块日志源中
RvLogSourceSetMask(&tempLogSource,
SipCommonConvertSipToCoreLogMask(moduleMask))
for(i=0; i<STACK_NUM_OF_LOG_SOURCE_MODULES; i++)
//将所有模块列表构造日志源对象
ConstructLogSource(pStackMgr,(RvSipStackModule)i);
//设置当前栈管理对日志源为RVSIP_STACK
pStackMgr->pLogSrc = pStackMgr->pLogSourceArrey[RVSIP_STACK];
//根据用户设置的defaultLogFilters,重新设置之前所有构造好的日志源过滤掩码
//当前VTP上层将该值设置为0,所以所有日志源都被屏蔽。
RvLogSetGlobalMask(pStackMgr->pLogMgr,
SipCommonConvertSipToCoreLogMask(pStackCfg->defaultLogFilters));
//如果用户设置了CORE相关日志过滤,则更改几个CORE相关的模块过滤设置
if(pStackCfg->coreLogFilters > 0)
RvSipStackSetNewLogFilters((RvSipStackHandle)pStackMgr,RVSIP_CORE,
pStackCfg->coreLogFilters);
//如果用户设置了ADS相关日志过滤,则更改几个ADS相关的模块过滤设置
if(pStackCfg->adsLogFilters > 0)
RvSipStackSetNewLogFilters((RvSipStackHandle)pStackMgr,RVSIP_ADS,
pStackCfg->adsLogFilters);
//针对其它模块,则根据上层用户设置的过滤值来更新
for(i=0; i<STACK_NUM_OF_LOG_SOURCE_MODULES; i++)
logMask = GetModuleLogMaskFromCfg(pStackCfg,(RvSipStackModule)i);
if(logMask > 0)
RvSipStackSetNewLogFilters((RvSipStackHandle)pStackMgr,(RvSipStackModule)i,
logMask);
三、模块日志源关联
这里以callleg模块为例,在上面通过RvSipStackSetNewLogFilters函数已经设置了callleg模块的日志源。
pStackMgr->pLogSourceArrey[RVSIP_CALL]. messageTypes = XXXXXX
StackConstructModules
//构造CALLLEG模块
StackConstructCallLegModule
//将日志管理对象句柄及CALLLEG日志源ID存入CALLLEG管理对象中
callLegMgrCfg.pLogMgr = pStackMgr->pLogMgr;
callLegMgrCfg.moduleLogId = pStackMgr->pLogSourceArrey[RVSIP_CALL];
//构造CALLLEG管理对象
SipCallLegMgrConstruct(&callLegMgrCfg, ……);
//这里就将日志源与对应的模块管理对象关联上
pMgr->pLogMgr = pCfg->pLogMgr;
pMgr->pLogSrc = pCfg->moduleLogId;
三、模块日志打印
以callleg模块中日志代码为例。
//打印INFO等级LOG,这里RvLogInfo是一个宏,该宏定义如下
RvLogInfo(pCallLeg->pMgr->pLogSrc,(pCallLeg->pMgr->pLogSrc,
"RvSipCallLegSetAddAuthInfoToMsgFlag - call-leg= %x bAddAuthInfoToMsg was set to %d",
pCallLeg, bAddAuthInfoToMsg));
----------------------------------------------------------------------------------------------------------------------------
//该宏定义为,如果callleg的日志源过滤值含有RV_LOGLEVEL_INFO允许位,则调用后面的
// RvLogTextInfo进行打印处理。
#define RvLogInfo(source, funcParams) \
{if ((source != NULL) && RvLogIsSelected(source, RV_LOGLEVEL_INFO)) (void)RvLogTextInfo funcParams;}
------------------------------------------------------------------------------------------------------------------------------
RvLogTextInfo
va_start(varArg, line);
RvLogTextAny(source, RV_LOGID_INFO, line, &varArg);
//如果这两个变量都为真,则表明这个函数出现递归调用,返回错误
if ((rvLogInsideTextAny==RV_TRUE)&&(RvThreadIdEqual(RvThreadCurrentId(),
rvLogCurId)))
return RvLogErrorCode(RV_LOG_ERROR_RECURSION);
//标记置位,防止重入
rvLogInsideTextAny = RV_TRUE;
rvLogCurId = RvThreadCurrentId();
//将用户要打印的字符放入ptr
ptr = rvLogTextStr + RV_LOG_RESERVED_BYTES;
i = RvVsnprintf((char *)ptr, RV_LOG_MESSAGE_SIZE, (char *)line, *varArg);
ptr[RV_LOG_MESSAGE_SIZE - 1] = '\0';
if (ptr[i-1] == '\n')
ptr[i-1] = '\0';
//保存线程ID
logRecord.printThreadId = logMgr->printThreadId;
//标记需要打印线程ID
logRecord.printThreadId = logMgr->printThreadId;
if (logRecord.printThreadId == RV_TRUE)
logRecord.threadName = (RvChar *)((RvUintPtr)rvLogCurId);
//分别保存日志源、当前日志打印标识(RV_LOGID_INFO)、及要打印的信息
logRecord.source = source;
logRecord.messageType = messageType;
logRecord.text = (const RvChar*)ptr;
//调用所有已注册的日志监听器回调,当前为LogPrintCallbackFunction
for (i = 0; i < logMgr->numListeners; i++)
logMgr->listener[i](&logRecord, logMgr->listenerUserData[i]);
//恢复防重入标记
rvLogInsideTextAny = RV_FALSE;
rvLogCurId = RV_THREAD_ILLEGAL_THREAD_ID;
va_end(varArg);
--------------------------------------------------------------------------------------------------------------------------------
LogPrintCallbackFunction
//在当前要打印的日志中添加信息头,当前大概为“INFO - CALL -”
SipCommonCoreFormatLogMessage(pLogRecord, &strFinalText);
//调用应用层设置的日志打印回调函数,当前该回调函数为
// ssmu_rv_log_handler
pStackMgr->pfnPrintLogEntryEvHandler(pStackMgr->logContext,
SipCommonConvertCoreToSipLogFilter(pLogRecord->messageType), strFinalText);
-----------------------------------------------------------------------------------------------------------------------------
ssmu_rv_log_handler
//将RV的日志等级转换为VTP格式的日志等级
switch(filter)
case RVSIP_LOG_DEBUG_FILTER:
spy_level = SPY_EVENT;
break;
//调用VTP的日志接口进行协议栈消息打印,注意这里的VTP日志接口是否打印消息
//是使用spy RVSIPST x来控制的。
Xspy(SPY_PORT_INVALID, ssmu_mcb.rv_spy_key, spy_level, "%s",formattedText);
RV日志流程分析
最新推荐文章于 2022-08-04 11:26:02 发布