//MTF基础模块初始化
rvIppSipSystemInit()
//RV基础支撑模块初始化(如时间戳、信号量、内存管理等系统抽象层对象的初始化)
RvCBaseInit();
//获取内存对象信息,默认的内存对象构造详见RvCBaseInit中的RvMemoryInit
RvMemoryGetInfo(NULL, NULL, &memInfo);
initialAlloc = memInfo.bytes_requested_byuser;
//设置内存分配对象为上面构造的默认内存分配管理对象。
prvDefaultAlloc = rvAllocGetDefaultAllocator();
memset(&sipExtClbksDeprecated, 0, sizeof(RvIppSipExtClbks));
//MTF对象构造
SipStack_MtfConstruct(&gstSipUserConfig, (char *)&gstSipUserConfig)
//将用户设置的MTF调试配置映射到MTF所需的对应值,保存到gstLogFilterTable
SipStack_LogLevelPrintParse(…);
//设置RV日志配置,其中MTF_LOG_PATH为"/var/temp/mtflog.log"
SipStack_AppLogInitial( gstLogFilterTable, MTF_LOG_PATH );
IppLogInit( ippFilters, szLogFileName )
//分配日志管理对象资源
RvMemoryAlloc(NULL, sizeof(*g_logMgr)…
//构造日志管理对象,为每个RV基础模块构造日志源对象
RvLogConstruct(g_logMgr)
//构造线程对象,并不构造新的对象,而是直接使用用户当前线程。
RvThreadConstructFromUserThread(g_logMgr, &g_th);
//设置线程对象名字
RvThreadSetName(&g_th,"MTF_LOG");
//为MTF所有模块构造日志源对象
for (i = 0; (i < (int)LOGSRC_NUMBER)&& (status == RV_OK); i++)
RvLogSourceConstruct(g_logMgr, logSrcTable[i].logSrc,
logSrcTable[i].logSrcName, logSrcTable[i].logSrcName)
//构建输出终端串口的日志监听对象,最终向串口的日志输出调用了
// logPrintTerminal函数
RvLogListenerConstructTerminal(&g_logListener, g_logMgr, RV_TRUE);
//构建向文件输出的日志监听对象
RvLogListenerConstructLogfile(&g_logListener, g_logMgr, szLogFileName, 1, 0,
RV_TRUE);
//先将所有的日志源对象过滤掩码设置为默认
RvLogSetGlobalMask(g_logMgr, 0);
//在根据用户设置进行日志源对象控制
logSetFilters(ippFilters);
//初始化MTF默认配置参数
rvIppSipInitConfig(&sipCfg);
//更新为用户的配置参数
SipStack_LoadSipConfigMTFParams(pUserConfig, &sipCfg);
//注册状态改变的回调,目前这里面仅仅是处理状态显示,感觉这里不太合理,这个回
//调是SIP Stack的回调,比较底层,这里做一些SIP Stack相关处理更好,状态显示合理 //的地方应该在termRegistrationStateChangedCB回调中处理
sipExtClbks.regClientStateChangedCB = SipStack_MtfSipRegClientStateChanged;
//注册SIP协议栈扩展支持的回调
rvMtfRegisterSipExtCallbacks(&sipExtClbks);
//数图对象构造,初始化默认值
rvMdmDigitMapConstruct(&digitMap);
//使用用户配置构造数图
rvMtfUtilBuildDigitMap(&digitMap, pUserConfig->digitMapPatterns);
//设置数图对象启始定时器、位间短定时器、位间长定时器
rvMdmDigitMapSetStartTimeout( digitMap, 100 );
rvMdmDigitMapSetShortTimeout( digitMap, 5 );
rvMdmDigitMapSetLongTimeout( digitMap, 10 );
//根据用户配置构造数图组到digitMap对象中。
//数图对象构成如下:
// RvMdmDigitMap. Patterns[n]表示一条数图规则
//RvMdmDigitMap.Patterns[n]. elements[n]表示一条数图规则中的子元素对象,
//例如123即3个子元素对象。
//这里的S、L指示符好像有问题。
sipCfg.digitMapPtr = &digitMap;
//MTF对象构造
rvMtfSipConstruct(&pUserConfig->mtfHandle, &sipCfg);
g_mtfMgr = mtfMgr;
mtfMgr->userData = NULL;
//从用户配置中获取生成端口范围参数,设置到g_mtfMgr->portRange
rvMtfMgrPortRangeConstruct(g_mtfMgr->portRange,config);
//注册SIP栈的日志打印回调
// sipExtClbksDeprecated.stackConfigF.pfnPrintLogEntryEvHandler
deprecatedSipExtClbks.stackConfigF = userSipStackConfig;
rvIppSipRegisterExtClbks(&deprecatedSipExtClbks);
//SIP栈初始化,这里启动了MTF及SIP栈处理的核心线程任务
rvIppSipStackInitialize(&(mtfMgr->sipStackHandle), config);
//构造并初始化g_basePhone对象
rvCCBasePhoneConstruct(rvCCBasePhoneGetBasePhone());
//初始化SIP栈配置
RvSipStackInitCfg(sizeof(stackCfg), &stackCfg);
//将用户配置的本地地址设置到SIP栈的本地TCP地址/UCP地址
//配置参数中。
strncpy(stackCfg.localTcpAddress, cfg->localAddress…
strncpy(stackCfg.localUdpAddress, cfg->localAddress,…
//如果配置了outband地址,则设置到SIP栈配置中,地址格式则设置到
//outboundProxyIpAddress,域名格式则设置到outboundProxyHostName
if (!rvSipControlIsAddressEmpty(cfg->outboundProxyAddress))
if (IppUtilIsIpAddress(cfg->outboundProxyAddress))
strncpy(stackCfg.outboundProxyIpAddress, cfg->outboundProxyAddress.
else
stackCfg.outboundProxyHostName = cfg->outboundProxyAddress;
//其它一些SIP栈配置
stackCfg.outboundProxyPort = cfg->outboundProxyPort;
……
//使用用户设置配置SIP栈中所有日志源对象过滤掩码
rvSipControlSetCfgLogFilters(&stackCfg, cfg->logOptions);
//设置SIP支持字段的扩展支持字符串
strcpy(tempList, "replaces,100rel,path,sec-agree");
stackCfg.supportedExtensionList = tempList;
// sipExtClbksDeprecated.stackConfigF和
// sipExtClbks.stackConfigCB两个回调的触发,目的为了在SIP栈配置阶段
//看一下上层用户是否有其它处理需求。
rvIppSipExtStackConfigCB(&stackCfg);
//如果用户设置了会话定时器配置,则在扩展列表中增加会话刷新的需求字符
if (cfg->sessionTimerSessionExpires > 0)
strcpy(&tempList[0], stackCfg.supportedExtensionList);
strcat(tempList, ",timer");
stackCfg.supportedExtensionList = tempList;
//协议栈核心线程构造,这里的回调sipStackProcessInit是SIP Stack的核心
//调用,调用RvSipStackConstruct进行SIP Stack各核心组件模块执行。
ProtocolThreadConstruct(cfg->priority, sipStackProcessInit, sipStackProcessEnd,
cfg, PROTOCOL);
//构造协议栈处理线程对象并启动,该线程的执行函数为
// protocolThread,该函数负责整个SIP Stack及MTF的消息处理。
//该函数在下面单独分析。
RvThreadConstruct(protocolThread, NULL, IppLogMgr(), &thread);
RvThreadSetPriority(&thread, priority);
RvThreadSetStack(&thread, NULL, RV_PROTOCOLTHREAD_STACKSIZE);
RvThreadSetName(&thread,"MTF_PRT");
RvThreadCreate(&thread);
initiated++;
RvThreadStart(&thread);
//等待协议栈线程函数执行,该信号量触发代码在protocolThread函数中
RvSemaphoreWait(&threadConstructed, IppLogMgr());
//保存当前协议版本的构造函数和销毁函数,同时向“MTF_PRT”线程
//发送消息,消息的内容为“0”,该SOCKET处理函数在protocolThread
//中,该线程函数收到内容为“0”的消息时,会执行sipStackProcessInit
//进行协议栈核心代码调用。
protocolConstructF[protocol]=pcf; //sipStackProcessInit
protocolDestructF[protocol]=pdf; //sipStackProcessEnd
protocolParam[protocol]=param; //cfg
sendEventToMsgSocket((void*)protocol); //protocol =“0”
//暂时等待,当SIP栈核心线程启动成功之后,就会触发该信号量,使该
//流程继续向后执行。semStackConstructed信号量触发的代码在
//sipStackProcessInit函数中,该函数在上面做为SIP栈核心线程的主程序执行
RvSemaphoreWait(&g_threadData.semStackConstructed, IppLogMgr());
//IP Phone对象构造及相关回调设置
rvIPPhoneConstruct(&mtfMgr->termMgr, config);
//构造终端管理对象
rvMdmTermMgrConstruct_(mgr, prvDefaultAlloc);
//注册所有终端处理包
rvMdmRegisterPackages(mgr);
//创建模拟线路处理包对象,该对象是HASH类型对象
//其中索引key为“al”字符,配对的为RvMdmPackagePtr对象
//该对象中存储signals和events列表,也就是说通过字符串“al”
//可以得到RvMdmPackagePtr对象,在该对象中可以得到信号列表
//和事件列表。
pkg = rvMdmTermMgrCreatePackage(mgr,"al");
//向“al”包中注册摘机事件
rvMdmPackageRegisterEvent(pkg,"of");
//向“al”包中注册挂机事件
rvMdmPackageRegisterEvent(pkg,"on");
//注册其它事件、信号及包对象
//资源分配
rvMtfAllocatorAlloc(sizeof(RvCCIPPhone), (void**)&ipPhone);
//ipPhone对象构造
rvCCIPPhoneConstruct(ipPhone, mgr, cfg);
//SDP管理对象构造
RvSdpMgrConstructWithConfig(&cfg->sdpStackCfg, sizeof(RvSdpStackCfg));
//从线程私有变量中获取SDP全局索引值
__globals__ =
(RvSdpGlobals *)RvGetGlobalDataPtr(RV_SDP_GLOBALS_INDEX);
//创建SDP全局数据
RvCreateGlobalData(RV_SDP_GLOBALS_INDEX,RvSdpInitializeGlobals,
NULL,RvSdpDestroyGlobals)
//调用RvSdpInitializeGlobals进行全局数据初始化
gsGlobalsDataArray[index].iGlobalData = (*crtF)(index,usrData);
gsGlobalsDataArray[index].iDestroyFunc = dstrF;
gsGlobalsDataArray[index].iRefCount = 1;
gsGlobalsDataArray[index].iIndex = index;
__globals__->_sdpRefCount ++; //引用递增
//设置默认内存分配对象
rvSdpSetDefaultAllocator(rvAllocGetDefaultAllocator());
//注册属性处理参数
rvSdpRegisterAttributes();
//指示该属性可以出现多次
attrD.bIsSingle = RV_FALSE;
//指示该属性只能出现在媒体描述符中
attrD.bMediaScopeOnly = RV_TRUE;
//设置该参数的解析、编码、释放等回调处理函数
attrD.parseFunc = rvSdpRtpMapParsing;
attrD.encodeFunc = rvSdpRtpMapGetValue;
attrD.destroyFunc = rvSdpRtpMapSpecAttrDestruct;
attrD.copyFunc = rvSdpRtpMapSpecAttrCopy;
//将rtpmap属性处理加入到全局SDP数据中
rvSdpSpecAttrInternalRegister("rtpmap",SDP_FIELDTYPE_RTP_MAP,
&attrD,NULL,NULL,&d)
RvSdpInternalSpecAttrData *d;
//获取空闲的属性设置对象
d = gSpecAttrs + gSpecAttrsCnt;
//将上面设置的指定参数配置存入属性对象中
d->iName = “rtpmap”
d->iAttrFieldType =SDP_FIELDTYPE_RTP_MAP,
d->parseFunc = pSpecAttrData->parseFunc;
d->copyFunc = pSpecAttrData->copyFunc;
d->destroyFunc = pSpecAttrData->destroyFunc;
……
gSpecAttrsCnt ++; //属性个数递增
d->iReshuffleFunc = (rvAttrReshuffleCB)rvSdpRtpMapReshuffle;
……
//SDP编码集构造
rvSdpCodecInitialize();
gsParsersTableLen = 0;
//TELE EVENT编码解析对象构造
RvSdpCodec_DTMF_Init(rvSdpGetDefaultAllocator());
//将编码对应的fmtp及a参数属性解析到
// cp->iFmtpParamData和cp->iAttrParamData中,如果出现
//多个参数属性及形成链表。
cp = RvSdpCodecParserInternalConstruct(
gs_DTMF_FmtpParserData, gs_DTMF_AttrsParserData,a);
//设置编码名称,及处理fmtp属性时的参数列表串的分隔
//符,这里编码名称是数据形式主要考虑可能有多个别名存
//在。
cp->iCodecNames[0] = "PCMU";
cp->iSeparator = ';';
//将上面设置好的编码解析对象注册到编码解析表中
RvSdpCodecRegister(cp)
//设置iParsingErrorCB、iFmtpUnknownNameCB、
// iFmtpTreatParamCB回调
RvSdpCodecSetCallbacks(cp);
//加入编码解析表
gsParsersTable[gsParsersTableLen++] = cp;
……
//g_basePhone.pmdmProvider,mdm provider对象
mdmProvider = rvCCBasePhoneGetMdmProvider();
//创建Provider MDM对象
rvCCProviderMdmConstruct(mdmProvider, rvCCBasePhoneGetCallMgr(),
termMgr, cfg, termMgr->a);
//这里p是mdmProvider对象
p->funcs->createConnectionF = rvCCProviderMdmCreateConnection;
//将MTF一些配置参数存储在mdmProvider.provider中
provider = p->provider;
provider->a = a;
provider->callMgr = callMgr;
provider->autoAnswer = cfg->autoAnswer;
provider->semiTransferWithNoCancel = cfg->semiTransferWithNoCancel;
provider->blindTransferByeAfterRefer = cfg->blindTransferByeAfterRefer;
……
//给mdmProvider.provider.funcs设置终端处理函数,包括
//ringbackF = rvCCConnMdmRingback;
//disconnectF = rvCCConnMdmDisconnecting;
//getMediaF = rvCCConnMdmGetMedia;
//getMediaCapsF = rvCCConnMdmGetMediaCaps;
//makeCallF = rvCCConnMdmMakeCall;
//rejectF = rvCCConnMdmReject;
//callAnsweredF = rvCCConnMdmCallAnswered;
//createMediaF = rvCCConnMdmCreateMedia;
//setRemoteMediaF = rvCCConnMdmSetRemoteMedia;
//setLocalMediaF = rvCCConnMdmSetLocalMedia;
//restartMediaF = rvCCConnMdmRestartMedia;
//addressAnalyzeF = rvCCConnMdmAddressAnalyze;
//releaseF = rvCCConnMdmRelease;
//processTermEventF = rvCCConnMdmProcessEvent;
//joinConferenceF = rvCCConnMdmJoinConference;
//leaveConferenceF = rvCCConnMdmLeaveConference;
//transferOfferedF = rvCCConnMdmTransferOffered;
//transferConnectedF = rvCCConnMdmTransferConnected;
//isTransferedConnF = rvCCConnMdmIsTransferedConn;
//getCallerNumberF = rvCCConnMdmGetCallerNumber;
//terminateF = rvCCConnMdmTerminate;
//modifyMediaF = rvCCConnMdmModifyMedia;
//modifyMediaDoneF = rvCCConnMdmModifyMediaDone;
//holdF = rvCCConnTermMdmHold;
//unholdF = rvCCConnTermMdmUnhold;
//disconnectMediaF = rvCCConnMdmDisconnectMedia;
//connectMediaF = (RvCCConnectionTermConnectMediaF)rvCCConnMdmConnectMedia;
//remoteHoldF = rvCCConnTermMdmRemoteHold;
//remoteUnholdF = rvCCConnTermMdmRemoteUnhold;
//setHoldIndicatorF = rvCCConnTermMdmSetHoldIndicator;
//playDtmfF = rvCCConnTermMdmPlayDtmf;
//setMuteIndicatorF = rvCCConnTermMdmSetMuteIndicator;
//muteF = rvCCConnTermMdmMute;
rvInitConnFuncs(provider);
//给mdmProvider.provider.clbks设置终端信号回调,包括
//initiatedCB = rvCCConnMdmInitiatedCB;
//newDigitCB = rvCCConnMdmNewDigitCB;
//callAnsweredCB = rvCCConnMdmCallAnsweredCB;
//callDeliveredCB = rvCCConnMdmCallDeliveredCB;
//offeredCB = rvCCConnMdmOfferedCB;
//transferInProcessCB = rvCCCallTransferInProcessCB;
//conferenceJoinedCB = rvCCCallConferenceJoinedCB;
//transferOfferedCB = rvCCConnMdmTransferOfferedCB;
//sendUserEventCB = rvCCCallSendUserEventCB;
//mediaModifiedCB = rvCCCallModifyMediaCB;
//mediaModifiedDoneCB = rvCCCallModifyMediaDoneCB;
rvInitConnCallbacks(provider);
provider->mdmTermMgr = termMgr;
provider->mdmTermMgr->xTermMgr = p; //这里p为mdmProvider
//设置provider->mdmTermMgr->xTermMgrClbks终端管理回调集合
//包括
//RvMdmXTermMgrRegisterPhysTermCB
//RvMdmXTermMgrRegisterPhysTermAsyncCB
//RvMdmXTermMgrRegisterEphTermCB
//RvMdmXTermMgrUnregisterTermCB
//RvMdmXTermMgrUnregisterTermAsyncCB
//RvMdmXTermMgrFindTermCB
//RvMdmXTermMgrFindTermCB
//RvMdmXTermMgrStartCB
//RvMdmXTermMgrStopCB
//RvMdmXTermMgrDestructCB
//RvMdmXTermMgrForEachPhysTermCB
//RvMdmXTermMgrMediaCapsUpdatedCB
//RvMdmXTermMgrRegisterAllTermsToNetworkCB
//RvMdmXTermMgrRegisterTermToNetworkCB
//RvMdmXTermMgrUnregisterTermFromNetworkCB
rvMdmTermMgrRegisterXTermMgrClbks_(provider->mdmTermMgr,
&rvMdmTermMgrClbks);
//获取按键检测包对象
pkg = rvMdmTermMgrGetPackage(provider->mdmTermMgr, "dd");
//构造数图数据对象,设置了两个关键函数
//evCompleteF =rvMdmDigitMapBuildDDEvComplete
//translateF =rvMdmDigitMapTranslateDDEvent
rvMdmDigitMapDataConstruct(&dmData,"ce",
rvMdmDigitMapBuildDDEvComplete,
rvMdmDigitMapTranslateDDEvent,
provider->mdmTermMgr->a);
//将数图数据对象存储到终端管理对象中,mgr->digitMapData
rvMdmPackageRegisterDigitMapData(pkg,&dmData);
//将上面在rvMtfUtilBuildDigitMap中构造的数图对象存储到
//provider->digitMap中,如果用户没有配置数图,则使用
// rvCCTerminalMdmCreateDefaultDigitMap构造一个默认数图
//,该默认数图为XXXX | XXX*XXX*XXX*XXX
rvMdmDigitMapCopy(&provider->digitMap, cfg->digitMapPtr);
rvMdmControlStarted = 1; //标记MDM CONTROL已经启动
//显示字符
//mdmProvider.provider.displayData = rvCCIpPhoneDisplayLogo
rvCCProviderMdmSetDisplayData(mdmProvider,rvCCIpPhoneDisplayLogo);
//mdmProvider.provider. connClbks.addressAnalyzeCB = addressAnalyzeCB
rvCCProviderMdmRegisterAddressAnalyzeCB(mdmProvider,
addressAnalyzeCB);
//mdmProvider.provider.connClbks.inProcessCB = inProcessCB
rvCCProviderMdmRegisterInProcessCB(mdmProvider, inProcessCB);
// g_basePhone.pmdmProvider.provider.mdmTermMgr = termMgr
setMdmTermMgr(termMgr);
// termMgr.mapAddressToTermF =mapAddressToTermination
rvMdmTermMgrRegisterMapAddressToTermCB(termMgr,
mapAddressToTermination);
//存储ipPhone对象到终端管理中
mgr->xApp = ipPhone;
//设置sip phone终端管理回调
//xTermMgrClbks[0].registerPhysTermF = sipPhoneRegisterPhysTerm;
//….registerPhysTermAsyncF=sipPhoneRegisterPhysTermAsync
//….unregisterTermF=sipPhoneUnregisterPhysTerm
//….mediaCapsUpdatedF=sipPhoneSetMediaCaps
//….registerAllTermsToNetworkF=registerAllTermsToNetwork
//….registerTermToNetworkF=registerTermToNetwork
//…. unregisterTermFromNetworkF = unregisterTermFromNetwork
//…. startF = NULL
//….stopF = sipPhoneStop
//….destructF = sipPhoneMgrDestruct
rvCCSipPhoneGetCallback(&xTermMgrClbks[0]);
//设置终端管理对象的终端管理回调,最终是调用的上面的xTermMgrClbks
mgr->xTermMgrClbks->registerPhysTermF = ipPhoneRegisterPhysTerm;
mgr->xTermMgrClbks->registerPhysTermAsyncF = ipPhoneRegisterPhysTermAsync;
mgr->xTermMgrClbks->unregisterTermF = ipPhoneUnregisterPhysTerm;
mgr->xTermMgrClbks->mediaCapsUpdatedF = ipPhoneSetMediaCaps;
mgr->xTermMgrClbks->registerAllTermsToNetworkF =
ipPhoneRegisterAllTermsToNetwork;
mgr->xTermMgrClbks->registerTermToNetworkF =
ipPhoneRegisterTermToNetwork;
mgr->xTermMgrClbks->unregisterTermFromNetworkF =
ipPhoneUnregisterTermFromNetwork;
mgr->xTermMgrClbks->startF = ipPhoneStart;
mgr->xTermMgrClbks->stopF = ipPhoneStop;
mgr->xTermMgrClbks->destructF = ipPhoneMgrDestruct;
//终端管理的使用者是MTF管理对象
//termMgr.userData = mtfMgr
rvMdmTermMgrSetUserData(&mtfMgr->termMgr, mtfMgr);
//注册终端管理对象相关回调
// termMgr.connect = NULL
// termMgr.disconnect = NULL
// termMgr.select = NULL
// termMgr.deleteEphF = NULL
// termMgr.mapAddressToTermF = NULL
// termMgr.mapAddressToTermNewF = rvMapAddressToTerminationCB
registerMdmInternalCallbacks(mtfMgr);
//清除MDM扩展处理回调,不使用,包含如下:
//mdmExtClbksDeprecated.connectionCreated
//mdmExtClbksDeprecated.connectionDestructed
//mdmExtClbksDeprecated.display
//mdmExtClbksDeprecated.displayData
//mdmExtClbksDeprecated.mapUserEvent
//mdmExtClbksDeprecated.postProcessEvent
//mdmExtClbksDeprecated.preProcessEvent
rvIppMdmRegisterExtClbks(&deprecatedMdmExtClbks);
//创建终端类对象
mtfMgr->rtpClass = rvMdmTermMgrCreateTermClass(&mtfMgr->termMgr);
rvMdmTermClassConstructA_(termClass,mgr->a);
//设置当前终端类对象支持通用包能力,存储在termClass.pkgsCaps.packages
rvMdmTermClassAddSupportedPkg(termClass,"g",1);
//初始化RTP终端类对象
//mtfMgr->rtpClass.createMediaF = NULL
//mtfMgr->rtpClass.modifyMediaF= NULL
//mtfMgr->rtpClass.destroyMediaF= NULL
//mtfMgr->rtpClass.modifyMediaCompletedF= NULL
rvInitRtpTermClass(mtfMgr->rtpClass);
//初始化各终端类对象
rvInitIppClasses(mtfMgr);
//创建音频传送终端类
mtfMgr->atClass = rvMdmTermMgrCreateTermClass(&mtfMgr->termMgr);
//初始化终端类回调,包括
//startSignalF =rvStartSignalIntCB
//stopSignalF =rvStopSignalIntCB
//playSignalF = rvPlaySignalIntCB
//createMediaF =rvPhysCreateMediaIntCB
//destroyMediaF =rvPhysDestroyMediaIntCB
//mapDialStringToAddressF = rvMapDialStringToAddressCB
//matchDialStringF = rvMatchDialStringToPatternCB
//registerPhysTermCompletedF = rvRegisterTermCompletedCB
//unregisterTermCompletedF = rvUnregisterTermCompletedCB
//unregisterTermFromNetworkCompletedF=
rvUnregisterTermFromNetworkCompletedCB
initClassCallbacks(mtfMgr->atClass);
//创建用户接口终端类,并初始化回调
mtfMgr->uiClass = rvMdmTermMgrCreateTermClass(&mtfMgr->termMgr);
initClassCallbacks(mtfMgr->uiClass);
//注册模拟线路终端类,并初始化回调
mtfMgr->phoneClass = rvMdmTermMgrCreateTermClass(&mtfMgr->termMgr);
initClassCallbacks(mtfMgr->phoneClass);
//创建Ip phone用户接口相关的包对象,包括
// dis、key、kp、ce、labelkey、kf、ind、ks、rvcc包对象
rvMdmTermMgrRegisterIPPhoneUiPackages(&mtfMgr->termMgr);
//设置用户接口终端类支持dis、key、kp、labelkey、kf、ind、ks、rvcc包能力
rvMdmTermClassSetIPPhoneUIPackages(mtfMgr->uiClass)
//设置音频传输终端类支持dg、cg、rtp、tdmc包能力
rvMdmTermClassSetAudioTransducerPackages(mtfMgr->atClass);
//设置模拟线路终端类支持al、dd、dd-end、cg、dg、andisp、rvcc、rtp、tdmc
//包能力
rvMdmTermClassSetAnalogLinePackages(mtfMgr->phoneClass);
//设置模拟线路终端类支持dis、key、kp、labelkey、kf、ind、ks、rvcc包能力
rvMdmTermClassSetIPPhoneUIPackages(mtfMgr->phoneClass);
//设置模拟线路终端类支持dg、cg、rtp、tdmc包能力
rvMdmTermClassSetAudioTransducerPackages(mtfMgr->phoneClass);
//为IP Phone对象添加SIP管理对象
rvCCIPPhoneAddSIP(&mtfMgr->termMgr,config, mtfMgr->sipStackHandle);
// g_basePhone.usedProvider[0]=RV_TRUE;
rvCCBasePhoneUse();
//Provdier SIP对象构造
rvCCProviderSipConstruct(rvCCBasePhoneGetNetProvider(), rvCCBasePhoneGetCallMgr(), stackHandle, cfg,
((RvCCIPPhone*)termMgr->xApp)->a);
p->funcs->createConnectionF = rvCCProviderSipCreateConnection;
provider = p->provider;
//将相关参数存储到Provider SIP对象的provider中
provider->autoRegister = cfg->autoRegister;
provider->callWaitingReply = cfg->callWaitingReply;
provider->watchdogTimeout = cfg->watchdogTimeout;
….
//设置SIP连接相关函数,包括
//acceptF = rvCCConnSipAccept;
//rejectF = rvCCConnSipReject;
//ringbackF = rvCCConnSipRingback;
//disconnectF = rvCCConnSipDisconnecting;
//getMediaF = rvCCConnSipGetMedia;
//getMediaCapsF = rvCCConnSipGetMediaCaps;
//makeCallF = rvCCConnSipMakeCall;
//callAnsweredF = rvCCConnSipCallAnswered;
//createMediaF = rvCCConnSipCreateMedia;
//setRemoteMediaF = rvCCConnSipSetRemoteMedia;
//remoteHoldF = rvCCConnSipRemoteHold;
//remoteUnholdF = rvCCConnSipRemoteUnhold;
//holdF = rvCCConnSipHold;
//unholdF = rvCCConnSipUnhold;
//getCallerIdF = rvCCConnSipGetCallerId;
//getCallerNameF = rvCCConnSipGetCallerName;
//getCallerAddressF = rvCCConnSipGetCallerAddress;
//getCallerNumberF = rvCCConnSipGetCallerNumber;
//transferInitF = rvCCConnSipTransferInit;
//transferInProgressF = rvCCConnSipTransferInProgress;
//playDtmfF = rvCCConnSipPlayDtmf;
//terminateF = rvCCConnSipTerminate;
//releaseF = rvCCConnSipRelease;
//modifyMediaF = rvCCConnSipModifyMedia;
//modifyMediaDoneF = rvCCConnSipModifyMediaDone;
//processTermEventF = rvCCConnSipProcessEvent;
//forwardCallF = rvCCConnSipForwardCall;
//getProtocolIdF = rvCCConnSipGetProtocolId;
//getRemoteDisplayNameF = rvCCConnSipGetRemoteDisplayName;
//getRemotePhoneNumberF = rvCCConnSipGetRemotePhoneNumber;
//getRemoteUriF = rvCCConnSipGetRemoteUri;
rvInitConnFuncs(provider);
//设置SIP连接相关回调
//initiatedCB = rvCCConnSipInitiatedCB;
//callDeliveredCB = rvCCConnSipCallDeliveredCB;
//offeredCB = rvCCConnSipOfferedCB;
//transferInitCB = rvCCConnSipTransferInitCB;
//transferOfferedCB = rvCCConnSipTransferOfferedCB;
//mediaCreatedCB = rvCCConnSipMediaCreatedCB;
//mediaUpdatedCB = rvCCCallMediaUpdatedCB;
//mediaModifiedCB = rvCCCallModifyMediaCB;
//mediaModifiedDoneCB = rvCCCallModifyMediaDoneCB;
rvInitConnCallbacks(provider);
//构造SIP管理对象
rvSipControlConstruct(&provider->sipMgr, stackHandle, cfg);
g_sipControl = x; //x为provider->sipMgr
//SIP管理对象存储配置
x->stackHndl = stackHandle;
x->stackTcpPort = cfg->stackTcpPort;
x->stackUdpPort = cfg->stackUdpPort;
……
//给Sip Stack组件注册所有回调
setCallBackFunctions( rvSipControlGetStackHandle(x),
&x->stackCallbacks);
//获取Sip Stack组件各管理模块句柄
RvSipStackGetCallLegMgrHandle(stackHndl,
&hCallLegMgr);
RvSipStackGetTransportMgrHandle(stackHndl, &hTransportMgr);
RvSipStackGetTransactionMgrHandle(stackHndl,
&hTranscMgr);
RvSipStackGetRegClientMgrHandle(stackHndl, &hRegClientMgr);
RvSipStackGetAuthenticatorHandle(stackHndl, &hAuth);
RvSipStackGetTransmitterMgrHandle(stackHndl,
&hTransmitterMgr);
RvSipStackGetSubsMgrHandle(stackHndl, &hSubsMgr);
RvSipStackGetSecAgreeMgrHandle(stackHndl, &hSecAgreeMgr);
//Sip管理对象向Sip Stack组件的对话框模块注册回调
stackCallbacks->sipCallLegEvHandlers.pfnCallLegCreatedEvHandler
= AppCallLegCreatedEvHandler;
……
RvSipCallLegMgrSetEvHandlers( hCallLegMgr,
&stackCallbacks->sipCallLegEvHandlers,
sizeof(RvSipCallLegEvHandlers));
//Sip管理对象向Sip Stack组件的事务层模块注册回调
stackCallbacks->sipTransEvHandlers.pfnEvTransactionCreated =
AppTranscCreatedEvHandler;
……
RvSipTransactionMgrSetEvHandlers( hTranscMgr, NULL,
&stackCallbacks->sipTransEvHandlers,
sizeof(RvSipTransactionEvHandlers));
//Sip管理对象向Sip Stack组件的传输层模块注册回调
stackCallbacks->sipTransactionMgrEvHandlers.
pfnEvNewRequestRcvd =AppTransactionManagerNewRequestRcvd;
RvSipTransactionMgrSetMgrEvHandlers(…)
//Sip管理对象向Sip Stack组件的注册客户端模块注册回调
stackCallbacks->sipRegClientEvHandlers.pfnStateChangedEvHandler
= AppRegClientStateChangedEvHandler;
……
RvSipRegClientMgrSetEvHandlers(…)
//Sip管理对象向Sip Stack组件的鉴权模块注册回调
stackCallbacks->sipAuthEvHandlers.pfnMD5AuthenticationHandler
= AppAuthenticationMD5Ev;
……
RvSipAuthenticatorSetEvHandlers(…… )
//Sip管理对象向Sip Stack组件的传送模块注册回调
stackCallbacks->sipTransmitterEvHandlers.
pfnRegExpResolutionNeededEvHandler =
AppRegExpResolutionNeededEvHandler;
RvSipTransmitterMgrSetEvHandlers(…)
//Sip管理对象向Sip Stack组件的订阅模块注册回调
stackCallbacks->sipSubsEvHandlers.pfnSubsCreatedEvHandler
= AppSipSubsCreatedEvHandler;
RvSipSubsMgrSetEvHandlers(…);
//Sip管理对象向Sip Stack组件的安全联盟模块注册回调
stackCallbacks->sipSecAgreeEvHandlers.
pfnSecAgreeStatusEvHandler = rvSecAgreeStatusEvHandler;
RvSipSecAgreeMgrSetSecAgreeEvHandlers(…)
//使用sipExtClbksDeprecated.registerStackEventsF或
// sipExtClbks.registerStackEventsCB上层回调,来通知用户是否需要 //在Sip管理对象向Sip Stack注册关键回调过程中进行其它处理。
rvIppSipExtRegisterStackEventsCB(x, stackHandle);
//其它sip配置参数的保存
//用于SIP资源使用的周期性检测
if(provider->watchdogTimeout > 0)
rvSipControlWatchDogTimerConstruct((RvCCProvider*)provider);
provider->callMgr = callMgr;
//设置Sip管理对象的回调
// sipProvider.provider.connClbks.addressAnalyzeCB =addressSipAnalyzeCB
//sipProvider.provider.connClbks. inProcessCB =inProcessCB
rvCCProviderSipRegisterAddressAnalyzeCB(rvCCBasePhoneGetNetProvider(),
addressAnalyzeCB);
rvCCProviderSipRegisterInProcessCB(rvCCBasePhoneGetNetProvider(),
inProcessCB);
//设置mtf对象句柄为Sip Stack对象的使用者
// pStackMgr->hAppStack = hMtf;
RvSipStackSetAppHandle(mtfMgr->sipStackHandle, (RvSipAppStackHandle)*hMtf);
//随机数生成器构造
RvRandomGeneratorConstruct(&mtfMgr->randomGenerator,
(RvUint32)RvClockGet(NULL,NULL));
rvMdmDigitMapDestruct(&digitMap);
//将sip stack句柄存储到pUserConfig->sipStackHandle中
rvMtfGetSipStackHandle(pUserConfig->mtfHandle, &pUserConfig->sipStackHandle);
//构造本地媒体能力集
SipStack_ConstructLocalSdpMsg();
//遍历所有线路
for(i=0; i<RVSIP_LINE_NUM; i++)
//构造SDP消息
sdpMsg= rvSdpMsgConstruct(sdpMsg);
gstSipUserConfig.sdpOfFullCaps[i] = sdpMsg;
//设置ver及origin字段信息
rvSdpMsgSetVersion2(sdpMsg,"0");
rvSdpMsgSetOrigin(sdpMsg, gstSipUserConfig.localAddress, "12345",
"12345", RV_SDPNETTYPE_IN,
RV_SDPADDRTYPE_IP4, gstSipUserConfig.localAddress );
//向SDP消息中增加一个音频描述符对象
rvSdpMsgAddMediaDescr(sdpMsg, RV_SDPMEDIATYPE_AUDIO,
gstSipUserConfig.localRtpPort, RV_SDPPROTOCOL_RTP);
//设置音频描述符对象的地址字段
rvSdpMediaDescrAddConnection(pMediaDescr, RV_SDPNETTYPE_IN,
RV_SDPADDRTYPE_IP4, gstSipUserConfig.localAddress);
//遍历所有编码
for(j=0; j<VICL_NUM; j++)
//添置payload列表及rtpmap属性
rvSdpMediaDescrAddPayloadNumber(pMediaDescr,
gstSipStackencodingMap[k].pt);
rvSdpMediaDescrAddRtpMap(pMediaDescr, gstSipStackencodingMap[k].pt,
gstSipStackencodingMap[k].encodingName,
gstSipStackencodingMap[k].clockRate);
//添加fmtp字段(主要G723和G729编码的静音属性)
rvSdpMediaDescrAddFmtp(pMediaDescr, "18 annexb=no");
rvSdpMediaDescrAddFmtp(pMediaDescr, "4 bitrate=6.3;annexa=no");
//如果用户配置了RFC2833按键方式,则添加tele event编码
if(gstSipUserConfig.dtmfRelay == RV_IPP_DTMF_RELAY_OOB )
rvSdpMediaDescrAddPayloadNumber(pMediaDescr, 101);
rvSdpMediaDescrAddRtpMap(pMediaDescr, 101, "telephone-event",
8000);
//添加ptime
rvSdpMediaDescrAddSpecialAttributeByType(pMediaDescr,
SDP_FIELDTYPE_ATTR_PTIME, pTime);
//设置连接模式
rvSdpMsgSetConnectionMode(sdpMsg, RV_SDPCONNECTMODE_SENDRECV);
//将本地集力级加载到Mtf组件中
rvMtfLoadMediaCapabilities(gstSipUserConfig.mtfHandle, sdpMsg);
//将sdp消息对象加载到sdpList消息列表中
sdpMsg = rvSdpMsgListAddMsg( &sdpList);
rvSdpMsgCopy( sdpMsg, mediaCaps);
//将本地和远端媒体能力集存储到rtp终端类的mediaCaps中,此
//本地和远端都为本地的能力值。
rvMdmTermClassAddMediaCapabilities( mtfMgr->rtpClass, &sdpList,
&sdpList, ¶ms);
//使用mgr->xTermMgrClbks->mediaCapsUpdatedF回调通过MTF
//上层用户,编码能力集有更新。
rvMdmTermMgrMediaCapabilitiesUpdated(&mtfMgr->termMgr,
mtfMgr->rtpClass);
//将本地和远端媒体能力集存储到at终端类中
rvMdmTermClassAddMediaCapabilities(mtfMgr->atClass, &sdpList,
&sdpList, ¶ms);
//将本地和远端媒体能力集存储到phone终端类中
rvMdmTermClassAddMediaCapabilities(mtfMgr->phoneClass, &sdpList,
&sdpList, ¶ms);
//注册MTF终端处理的回调
mdmClbks.startSignalCB = SipStack_MtfStartSignalCB;
mdmClbks.stopSignalCB = SipStack_MtfStopSignalCB;
mdmClbks.mapDialStringToAddressCB = SipStack_MtfMapDialStringToAddressCB;
mdmClbks.unregisterTermFromServerCompletedCB =
SipStack_MtfUnregisterTermFromServerCompletedCB;
rvMtfRegisterMdmCallbacks(pUserConfig->mtfHandle, &mdmClbks);
//注册MTF媒体处理回调
mediaClbks.destroyMediaStreamCB = SipStack_MtfDestroyMediaCB;
mediaClbks.connectMediaCB = SipStack_MtfConnectMediaCB;
mediaClbks.modifyMediaCompletedCB = SipStack_MtfModifyMediaCompletedCB;
rvMtfRegisterMediaCallbacks(pUserConfig->mtfHandle, &mediaClbks);
//注册MTF连接相关的媒体回调
connMediaClbks.connCreateMediaStreamCB = SipStack_MtfCreateMediaCB;
connMediaClbks.connModifyMediaStreamCB = SipStack_MtfModifyMediaCB;
rvMtfRegisterConnMediaCallbacks(pUserConfig->mtfHandle, &connMediaClbks);
//注册MTF扩展回调处理
mdmExtClbks.connStateChangedCB = SipStack_MtfConnStateChangedCB;
mdmExtClbks.termRegistrationStateChangedCB =
SipStack_MtfTermRegistrationStateChangedCB;
mdmExtClbks.termTransferCompletedCB = SipStack_MtfTermTransferCompletedCB;
mdmExtClbks.postProcessEventCB = SipStack_MtfPostProcessEventCB;
rvMtfRegisterMdmExtCallbacks(&mdmExtClbks);
//注册MTF处理IMS相关回调
imsClbks.secAgreeNegCompletedEv = RvMtfHandleSecAgreeNegCompletedEv;
rvMtfRegisterImsCallbacks(pUserConfig->mtfHandle, &imsClbks);
//构建rtp对象
RvRtpInit();
//RV基础支撑模块初始化,已经在前面初始化过了。
RvCBaseInit();
//获取本地地址
RvHostLocalGetAddress(logMgr, &numAddrs, rvRtpInstance.hostIPs);
rvRtpInstance.addressesNum = numAddrs;
//构造随机数生成器对象
RvRandomGeneratorConstruct(&rvRtpInstance.randomGenerator,
(RvRandom)(RvTimestampGet(logMgr)>>8));
//构造目标地址内存池
RvRtpDestinationAddressPoolConstruct();
//第一个本地地址存储到rvRtpInstance.rvLocalAddress中
RvAddressCopy(&rvRtpInstance.hostIPs[0], &rvRtpInstance.rvLocalAddress);
//构造select引擎对象,之前已经构造了,这里仅仅是引用递增
rtpMaxSessions = RVRTP_MAXSESSIONS;
RvSelectConstruct(rtpMaxSessions, 0, logMgr, &rvRtpInstance.selectEngine);
//注册模拟线路终端对象
SipStack_RegisterAnalog()
for(i = 0;i < RVSIP_LINE_NUM;i++)
//初始化默认终端配置
rvMtfTerminationInitConfig(&termConfig[i]);
//使用用户配置更新终端配置
SipStack_ConfigTermParam(i,&termConfig[i]);
gstSipTermDC[i].pstTermConfig=&termConfig[i];
//向MTF注册模拟线路终端
rvMtfRegisterAnalogTermination (gstSipUserConfig.mtfHandle,
gstSipUserConfig.mtfHandle, termConfig[i].username, &termConfig[i],
(RvMtfTerminalAppHandle)&gstSipTermDC[i],&gstIppTerm[i]);
//设置终端默认配置,并使用用户配置进行更新
rvMdmTermDefaultPropertiesConstruct(&termProperties);
setTermProperties(&termProperties, termConfig);
//注册模拟线路类型终端
rvMdmTermMgrRegisterPhysicalTerminationAsync(termMgr,
mtfMgr->phoneClass, termId, &termProperties, (void*)hAppTerm);
//该回调函数为ipPhoneRegisterPhysTermAsync,在下面单独
//分析
mgr->xTermMgrClbks->registerPhysTermAsyncF(mgr->xTermMgr, c,
id, termProperties, userData);
//空函数
rvMtfStart(gstSipUserConfig.mtfHandle)
//MTF主线程处理函数
protocolThread
//构造select引擎对象,并获取该引擎对象中的定时器队列做为MTF定时器机制处理。
IppTimerInit();
//将select引擎对象存储到engine变量中
RvSelectGetThreadEngine(IppLogMgr(), &engine);
//创建MTF消息处理,该消息处理基于SOCKET方式,并将该SOCKET对象加载到select
//引擎对象中。其中消息处理回调函数为msgSocketCB,该函数的简单描述在下文。
createMsgSockets();
//触发信号量,让上文ProtocolThreadConstruct函数继续同步执行
RvSemaphorePost(&threadConstructed, IppLogMgr());
//进入MTF线程主处理循环中,这里主要处理MTF事件,及调度SIP Stack的消息处理,
//也就是说Sip Stack对网络侧收到的数据报文,MTF从用户侧收到的事件,及定时器
//事件的执行都是靠这里的主select引擎来调度。
while (initiated)
RvSelectWaitAndBlock(engine, timeout)
//当将MTF释放时,这里执行协议栈的销毁回调处理,该函数在ProtocolThreadConstruct
//函数中设置为sipStackProcessEnd
for (protocol=0;protocol<RV_MTF_PROTOCOL_NUM;protocol++)
protocolDestructF[protocol](protocolParam[protocol]);
//select引擎销毁
IppTimerEnd();
-------------------------------------------------------------------------------------------------------------------------------
//用户层向MTF发送的事件处理
msgSocketCB
//从MTF事件socket中获取用户传入的消息信息
RvSocketReceiveBuffer(&recvsock, (RvUint8*)&data,sizeof(data),IppLogMgr (),&bytesRcvd,
&fromAddr);
if ((RvSize_t)data<RV_MTF_PROTOCOL_NUM)
//当用户层发来的消息内容仅仅为小的数值时,做特殊处理,这里仅仅在
//ProtocolThreadConstruct函数进行MTF核心线程初始化时,让MTF调用设置
//的函数sipStackProcessInit进行Sip Stack的初始化。
protocolConstructF[(RvSize_t)data](protocolParam[(RvSize_t)data]);
else
//对于其它内容的消息,则都归为向MTF发启的终端事件,这个处理函数中
//MTF主要的业务处理函数,暂时不进行全面分析,待后面根据特定业务处理流程
//中再进行分析。
rvCCProviderMdmProcessTerminationEvent(data);
//注册物理终端
ipPhoneRegisterPhysTermAsync
//注册物理终端
mdmTerm = rvMdmProviderRegisterPhysTermAsync(x,c,id,termProperties, userData);
//获取终端类型,这里返回RV_CCTERMINALTYPE_ANALOG
type = rvCCProviderMdmFindTerminalType(c, id);
//创建终端对象
t = rvCCProviderMdmCreateTerminal(p, type, id, 0, termProperties);
//终端创建
rvCCTerminalMdmConstruct(t, x, id, type, clbks, termProperties, provider->a);
term->provider = p;
term->alloc = a;
//构造动态关键字段,这里设置了一个很重要的标记
//x->blockedEventTypeMask = RV_BLOCKEDEVENT_NOTIFY,用于后继终端 //事件上报给MTF,MTF是否进行该终端事件处理的判断条件。
constructDynamicFields(term);
term->termType = type; //RV_CCTERMINALTYPE_ANALOG
term->terminalId = id //用户号码
term->type = RV_MDMTERMTYPE_UNKNOWN;
term->inactive = RV_TRUE;
term->numberOfLines = 2;
……
//设置终端配置属性
rvMdmTermDefaultPropertiesConstructA(&term->defaultState, a);
//x->terminal = term;
//x->audioTermState = RV_CCAUDIOTERM_PASSIVE;
//x->clbks = clbks; //NULL
rvCCTerminalInit(x, term, clbks);
//一个终端拥有3个连接资源
maxConnections = rvCCTerminalGetNumberOfLines(x);
//一个终端可以建立2个呼叫
term->numberOfLines = 2;
//为终端分配连接资源
for (i=0;i<maxConnections;i++)
x->connections[i] = rvAllocConnection(x, p);
//x->lineId = i + 1;
rvCCConnectionSetLineId(x->connections[i],i+1);
term->compEventPkg = "dd";
//为终端设置了两个数图处理定时器
//digitMapTimer[0]和digitMapTimer[1]
//分别对应的回调函数为digitMapTimerProcess0、digitMapTimerProcess1
rvMdmTermDigitMapTimerConstruct(term);
//当前没有为线路配置数图,所以使用的是从mdmProvider中取的全局 //性数图参数。
if (*rvMdmDigitMapDescriptorGetName(&defaultProperties->digitMap))
//no thing
else
//设置终端的数图,当前数图名为“dialplan0”
setTermDigitMap(term, p);
//如果配置了放播号音的时间,则初始化播号音定时器,并设置定时器的
//超时处理回调为rvCCTerminalMdmDialToneTimerExpired
if (rvCCProviderMdmGetDialToneDuration(…) > 0)
IppTimerConstruct(&term->dialToneTimer,
rvCCProviderMdmGetDialToneDuration(p),
rvCCTerminalMdmDialToneTimerExpired, x);
//如果配置了注册完成超时时间值,则初始化注册完成定时器,当注册包 //发出后,在指定超时时间没有完成,则执行定时器回调函数
//rvCCTerminalMdmRegisterCompleteTimerExpired
if (provider->registerCompleteTimeout > 0)
IppTimerConstruct(&term->registerCompleteTimer,
provider->registerCompleteTimeout * 1000,
rvCCTerminalMdmRegisterCompleteTimerExpired, x);
term->outOfBandDtmfRelayEnabled =
rvCCProviderMdmGetoutOfBandDtmf(…);
term->playDtmfEnabled = RV_FALSE;
//显示信息初始化
//x->presentationName[0] = '\0';
//x->callerIdPermission = RV_MDM_PRSENTATION_RESTRICTED;
//x->calleeIdPermission = RV_MDM_PRSENTATION_RESTRICTED;
rvMdmTermPresentationInfoConstruct(&(term->presentationInfo));
//设置呼叫转移业务参数为关闭
// cfwData->cfwTypes[0].cfwState = RV_IPP_CFW_STATE_DEACTIVATED;
// cfwData->cfwTypes[0].cfwState = RV_IPP_CFW_STATE_DEACTIVATED;
// cfwData->cfwTypes[0].cfwState = RV_IPP_CFW_STATE_DEACTIVATED;
rvCCCfwDataInitToDefaultValues(&(term->cfwData));
//设置终端状态x->state = RV_CCTERMINAL_IDLE_STATE;
rvCCTerminalSetState(x, RV_CCTERMINAL_IDLE_STATE);
//将创建好的终端对象加入provider的终端列表中
rvCCProviderMdmAddTerminal(provider, t);
term = rvCCTerminalMdmGetImpl(t);
//mdmTerm构造
//term->termClass = termClass; //mtfMgr->phoneClass
//term->xTerm = xTerm; //上面使用rvCCProviderMdmCreateTerminal创建好的终端
//term->userData = NULL;
//term-> type = RV_MDMTERMTYPE_PHYSICAL
rvMdmTermConstruct_(&term->mdmTerm, c, t);
rvCCTerminalMdmSetType(term, RV_MDMTERMTYPE_PHYSICAL);
//存储本地和远端媒体能力集
term->mediaCaps = rvMdmTermClassGetMediaCapabilites_(c);
term->inactive = RV_FALSE;
//使用用户配置中更新当前终端相关配置
loadTerminalProperties(t, termProperties);
rvMdmTermPhoneNumbersCopy(&(term->phoneNumbers),
&(termProperties->phoneNumbers));
rvCCTerminalMdmLoadPresentationInfo(term, termProperties);
//term->mdmTerm.userData =gstIppTerm[i];
rvMdmTermSetUserData(&term->mdmTerm, userData);
//给MTF主线程任务发送终端注册的事件,MTF处理事件的回调函数为
// rvMdmTermProcessBlockedEvent,该函数里如果判断出是收到的终端注册
//事件,则执行processBlockedEventRegisterTerm。
//processBlockedEventRegisterTerm函数在下面单独分析。
rvMdmTermQueueRegisterTermEvent(&term->mdmTerm);
//向MTF发送消息
rvMdmTermPostEvent(t);
//标记当明终端阻塞在注册处理
//term.blockedEventTypeMask |= RV_BLOCKEDEVENT_REGISTER
rvCCTerminalMdmBlockedEventSetReg(term, RV_TRUE);
//如果Sip协议在使用,当前已经使用
if (rvCCBasePhoneIsUsed_(RV_MTF_PROTOCOL_SIP))
//继续执行物理终端注册的后续处理,主要是自动注册触发
//该函数后面在另一文档进行单独分析。
sipPhoneRegisterPhysTermAsyncStep(mdmTerm, x, c, id, termProperties, userData);
//如果用户配置了注册完成超时时间,则在上面已经创建了注册完成定时器,这里 //需要启动该定时器。
timer = &mdmTerminal->registerCompleteTimer;
if (timer->callback != NULL)
IppTimerStart(timer,IPP_TIMER_DONT_CHECK_IF_STARTED, 0);
-------------------------------------------------------------------------------------------------------------------------------
//MTF处理终端注册事件
processBlockedEventRegisterTerm
//为当前终端安装数图
rvCCTerminalMdmInstallDigitMap(x, RV_FALSE);
//从当前终端中查找索引为“dialplan0”的数图,并构成数图描述符对象
rvStringConstruct(&name, "dialplan0", term->alloc);
dm = rvMdmTermGetDigitMap(term, &name);
rvMdmDigitMapDescriptorConstruct(&dmDescr, "dialplan0", dm);
//人为构造请求事件,用于向终端安装数图
buildReqEventCE(term, &dmDescr,activateDigitMap);
//构造一个kp/ce包的请求事件对象
rvMdmPackageItemConstruct(&pkgItem, "kp", "ce");
rvMdmRequestedEventConstruct(&reqEvent, &pkgItem);
rvMdmDigitMapDescriptorCopy(&reqEvent.digitMap, dmDescr);
//安装数图,这里activateDigitMap = false
rvMdmTermProcessDigitMapParameter(x, &reqEvent,activateDigitMap);
//从请求事件对象中抽取数图描述符对象及请求包的标识
digitMapDescr = rvMdmRequestedEventGetEmbDigitMap(reqEvent);
name = rvMdmRequestedEventGetName(reqEvent);
//数图定时器关闭,去激活
rvMdmTermDeactivateDigitMap(x);
//初始化状态,并保存请求事务对象
rvStringResize(&x->dialString,0);
x->digitMapStat = RV_MDMDIGITMAP_PARTIALMATCH;
x->digitMapMedia = NULL;
x->digitMapReqEvent = reqEvent;
//从终端管理对象中获取之前已经注册的“kp”包对象
x->digitMapEC = rvMdmTermMgrGetDigitMapPkgInfo_(…);
//取出请求事件中的数图复制到终端digitMap中,用于终端之后数图处理
//的匹配。
rvMdmDigitMapCopy(&x->digitMap,rvMdmDigitMapDescriptorGetDigitMap
(digitMapDescr));
//从数图描述符中获取数图,重新存储到终端对象storedDigitMaps中
rvMdmTermProcessDigitMap(term, &dmDescr);
//清除终端的RV_BLOCKEDEVENT_REGISTER标记
rvCCTerminalMdmBlockedEventSetReg(term, RV_FALSE);
//调用当前终端类的rvRegisterTermCompletedCB回调来处理终端注册完成通知,最终
//rvRegisterTermCompletedCB函数会调用MTF中注册的registerAnalogTermCompletedCB
//回调来通知用户层。
rvMdmTermRegisterPhysTermDone_(&term->mdmTerm);
框架初始化
最新推荐文章于 2021-09-05 19:20:01 发布