RvSIP 会话刷新分析

一、对话框创建
RvSipCallLegMgrCreateCallLeg
	CallLegMgrCreateCallLeg
		CallLegInitialize
			//对话框管理对象的eSessiontimeStatus状态,在进行协议栈配置初始化时,
			//如果supportedExtensionList列表含有“timer”字符,则设置为
			// RVSIP_CALL_LEG_SESSION_TIMER_SUPPORTED
			if (pMgr->eSessiontimeStatus == RVSIP_CALL_LEG_SESSION_TIMER_SUPPORTED
 			&& RV_FALSE == bIsHidden)
				//会话定时器初始化
				CallLegSessionTimerInitialize(pCallLeg)
					//更新pNegotiationSessionTimer
					CallLegSessionTimerSetMgrDefaults(pCallLeg->pMgr,RV_TRUE,
pCallLeg->pNegotiationSessionTimer);
	// pCallLegMgr相关的值,是在协议栈配置初始化时,设置到对
	//话框管理对象中的。
	pSessionTimer->minSE = pCallLegMgr->MinSE;
	pSessionTimer->sessionExpires= pCallLegMgr->sessionExpires;
	pSessionTimer->eRefresherType=
RVSIP_SESSION_EXPIRES_REFRESHER_NONE;
						pSessionTimer->eRefresherPreference=
RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_DONT_CARE;
					
					pCallLeg->pNegotiationSessionTimer->bInRefresh = RV_FALSE;
					
					// pSessionTimer全部硬编码复位
					ResetSessionTimerParams(pCallLeg->pSessionTimer);
					
					pCallLeg->pSessionTimer->bAddReqMinSE =
pCallLeg->pMgr->bAddReqMinSE;
					pCallLeg->pSessionTimer->minSE = pCallLeg->pMgr->MinSE;
					SipCommonCoreRvTimerInit(
&pCallLeg->pSessionTimer->hSessionTimerTimer);

二、收到INVITE消息(收到UPDATE消息基本类似)
HandleInviteRequestRcvd
	//对话框管理对象支持会话刷新
	if (pCallLeg->pMgr->eSessiontimeStatus == RVSIP_CALL_LEG_SESSION_TIMER_SUPPORTED)
		CallLegSessionTimerHandleRequestRcvd
			//校验是否是INVITE或UPDATE消息,会话刷新仅处理这两种
			IsInviteOrUpdateTransc(pCallLeg,hTransc,hMsg,&bInviteTransc);
			if (rv != RV_OK)
				return RV_OK;
			
			//获取协商定时器对象,根据消息不同从不同地方取值,当前是INVITE消息,
			//取pCallLeg->pNegotiationSessionTimer
			GetSessionTimerPointer(pCallLeg,hTransc,bInviteTransc,&pSessionTimer);
			
			//从收到的INVITE消息中获取SESSION_EXPIRES及Refresher值
			GetSessionExpiresValues(pCallLeg,hMsg,&msgSessionExpires,
&eMsgRefresherType)
			
			//从收到的INVITE消息中获取MINSE值
			GetMinSEValue(pCallLeg,hMsg,&msgMinSE);
			
			//如果本地的minSE比远端小,则更新为远端的值。
			if (msgMinSE > pSessionTimer->minSE)
				pSessionTimer->minSE = msgMinSE;
			
			//如果远端的INVITE含有SESSION_EXPIRES,则标记本端需要刷新
			if (msgSessionExpires > 0)
				pSessionTimer->bInRefresh = RV_TRUE;
			//如果远端的INVITE不含有SESSION_EXPIRES,按如下情况处理
			else
				//检测远端的support列表是否支持timer
				bTimerSupported = IsSessionTimerSupportedByRemote(hMsg);
				
				//如果远端支持会话刷新,并且当前是reinvite,则表明远端希望
				//关闭会话刷新,去除本端需要刷新标记。
				if (bTimerSupported == RV_TRUE &&(bInviteTransc == RV_FALSE ||
				(bInviteTransc == RV_TRUE && 
pCallLeg->eState == RVSIP_CALL_LEG_STATE_CONNECTED)))
	pSessionTimer->bInRefresh = RV_FALSE;
	return RV_OK;
//否则即使远端不支持会话刷新,或远端支持,但当前是初始对话,本端
//也设置需要刷新标记。
				else
					pSessionTimer->bInRefresh = RV_TRUE;
				
				//本端配置了sessionExpires值
				if (pSessionTimer->sessionExpires > 0 )
					//仅当本端预配置了远端刷新,并且远端支持会话刷新的情况下
					// eRefresherType才为UAC(即由远端来刷新),其它情况下均为本
					//端来做为刷新方。
					if (pSessionTimer->eRefresherPreference ==
					RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_REMOTE)
						if (bTimerSupported == RV_TRUE)
							pSessionTimer->eRefresherType = 
							RVSIP_SESSION_EXPIRES_REFRESHER_UAC;
						else
							pSessionTimer->eRefresherType = 
							RVSIP_SESSION_EXPIRES_REFRESHER_UAS;
					else
						pSessionTimer->eRefresherType = 
						RVSIP_SESSION_EXPIRES_REFRESHER_UAS;
				return RV_OK;
			
			//如果远端的SessionExpires比本端的最小会话刷新值都小,则标记拒绝此次
			//呼叫请求。
			if(msgSessionExpires < pCallLeg->pSessionTimer->minSE)
				bDoReject = RV_TRUE;
			//否则,如果远端想要下调SessionExpires值,则根据如下情况处理
			else if (pSessionTimer->sessionExpires > 0 &&
msgSessionExpires < pSessionTimer->sessionExpires )
	//如果远端想要下调的SessionExpires值在本端min和SessionExpires之间		//则合法,将本端SessionExpires设置为远端的值。
				if(pSessionTimer->minSE > 0 &&
msgSessionExpires >= pSessionTimer->minSE)
	pSessionTimer->sessionExpires = msgSessionExpires;
//如果下调的值比本端的min还小,则非法,进行拒绝。
				else if(pSessionTimer->minSE > 0 &&
				msgSessionExpires < pSessionTimer->minSE)
					bDoReject = RV_TRUE;
				else if (pSessionTimer->minSE <= 0)
					pSessionTimer->sessionExpires = msgSessionExpires;
			//否则,如果远端的SessionExpires比本端大,同时本端的SessionExpires比远
			//端的min还小,则将本端的SessionExpires值更新为远端的min
			else if (msgSessionExpires > pSessionTimer->sessionExpires &&
			pSessionTimer->sessionExpires < msgMinSE)
				pSessionTimer->sessionExpires = msgMinSE;
			
			switch(eMsgRefresherType)
			//如果远端INVITE不含有Refresher值,则根据本端预配置值设置
			// eRefresherType,如果本端预配置值没有设置LOCAL或REMOTE,则
			// eRefresherType值将为none。
			case RVSIP_SESSION_EXPIRES_REFRESHER_NONE:
				if (pSessionTimer->eRefresherPreference==
RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_REMOTE)
					pSessionTimer->eRefresherType = 
					RVSIP_SESSION_EXPIRES_REFRESHER_UAC;
				else if(pSessionTimer->eRefresherPreference==
RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_LOCAL)
					pSessionTimer->eRefresherType =
RVSIP_SESSION_EXPIRES_REFRESHER_UAS;
				else
					pSessionTimer->eRefresherType =
RVSIP_SESSION_EXPIRES_REFRESHER_NONE;
			
			//如果远端的Refresher为UAC,则远端刷新,设置本端eRefresherType为
			//UAC。
			case RVSIP_SESSION_EXPIRES_REFRESHER_UAC:
				pSessionTimer->eRefresherType =
RVSIP_SESSION_EXPIRES_REFRESHER_UAC;
			
			//如果远端的Refresher为UAS,则要求本端刷新,设置本端eRefresherType为
			//UAS。
			case RVSIP_SESSION_EXPIRES_REFRESHER_UAS:
				pSessionTimer->eRefresherType =
				RVSIP_SESSION_EXPIRES_REFRESHER_UAS;
			
			//如果上面处理过程中标记拒绝此次请求
			if (msgSessionExpires != UNDEFINED && bDoReject==RV_TRUE)
				//当前是初始INVITE请求,则调用CallLegSessionReject进行拒绝,否则调
				//用RvSipTransactionRespond进行拒绝。
				if (bInviteTransc == RV_TRUE &&pCallLeg->eState !=
RVSIP_CALL_LEG_STATE_CONNECTED)
	CallLegSessionReject(pCallLeg,INTERVAL_TOO_SMALL_RESPONSE);
else
	RvSipTransactionRespond(hTransc,INTERVAL_TOO_SMALL_RESPONSE,
NULL)
			
			//复位pCallLeg->pNegotiationSessionTimer
			CallLegSessionTimerSetMgrDefaults(pCallLeg->pMgr, RV_TRUE, pSessionTimer);
三、收到最终应答
CallLegTranscEvHandleInviteFinalResponseRcvd
	CallLegSessionTimerHandleFinalResponseRcvd
//获取协商定时器对象,根据消息不同从不同地方取值,当前是INVITE消息,
		//取pCallLeg->pNegotiationSessionTimer
		GetSessionTimerPointer(pCallLeg,hTransc,bInviteTransc,&pSessionTimer);
		
		//如果收到422,则调用上层回调函数pfnSessionTimerNotificationEvHandler通知应
		//用层收到了一个422会话时间太短的错误。并标记需要添加一次min头域。
		if(responseCode == INTERVAL_TOO_SMALL_RESPONSE)
			CallLegCallbackSessionTimerNotificationEv(pCallLeg,
RVSIP_CALL_LEG_SESSION_TIMER_NOTIFY_REASON_422_RECEIVED);
			
			pCallLeg->pSessionTimer->bAddOnceMinSE = RV_TRUE;
		
		//如果收到了2XX应答
		if(responseCode >= 200 && responseCode<300)
			//从远端消息中获取SESSION_EXPIRES头域值。
			hSessionExpiresHeader = 
RvSipMsgGetHeaderByType(hMsg, RVSIP_HEADERTYPE_SESSION_EXPIRES……)
			
			//如果远端不含有SESSION_EXPIRES头域
			if (hSessionExpiresHeader== NULL)
				//如果当前为初始对话,或者当前协商定时器标记需要刷新处理
				if (eState != RVSIP_CALL_LEG_STATE_CONNECTED ||
				pSessionTimer->bInRefresh == RV_TRUE)
					//标记当前远端不支持会话刷新
					pCallLeg->pSessionTimer->eNegotiationReason =
					RVSIP_CALL_LEG_SESSION_TIMER_NEGOTIATION_REASON_DEST_NOT_
SUPPORTED;
					
					//动态会话刷新参数从协商定时器中提取。
					pCallLeg->pSessionTimer->sessionExpires = 
						pSessionTimer->sessionExpires;
					pCallLeg->pSessionTimer->eRefresherType   = 
						pSessionTimer->eRefresherType;
					
					//根据协商定时对象中的值确定动态会话刷新参数的刷新方
					if (RVSIP_SESSION_EXPIRES_REFRESHER_UAS == 
pSessionTimer->eRefresherType)
						pCallLeg->pSessionTimer->eCurrentRefresher =
						RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_REMOTE;
					else if (RVSIP_SESSION_EXPIRES_REFRESHER_UAC == 
					pSessionTimer->eRefresherType)
						pCallLeg->pSessionTimer->eCurrentRefresher =
						RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_LOCAL;
					
				//设置动态会话刷新参数的默认警告定时器超时时间为本地
//刷新时间一半。
					pCallLeg->pSessionTimer->defaultAlertTime = 
					pSessionTimer->sessionExpires/2;
					
					//校正动态会话刷新参数的警告定时器超时时间。
					if (pCallLeg->pSessionTimer->alertTime != UNDEFINED &&
					pCallLeg->pSessionTimer->alertTime >= pSessionTimer->sessionExpires)
						pCallLeg->pSessionTimer->alertTime = 
						pCallLeg->pSessionTimer->defaultAlertTime;
			//如果远端含有SESSION_EXPIRES头域,则复位eNegotiationReason
			else
				pCallLeg->pSessionTimer->eNegotiationReason =
				RVSIP_CALL_LEG_SESSION_TIMER_NEGOTIATION_REASON_UNDEFINED;
			
			//标记需要刷新
			pSessionTimer->bInRefresh= RV_TRUE;
			
			//从消息中分别尝试提取SESSION_EXPIRES、MIN、Refresher字段值到
			//msgSessionExpires、msgMinSE、eMsgRefresherType中
			
			//如果远端msgSessionExpires值比本端min都小,则忽略,否则取远端的
			// msgSessionExpires值。
			if (msgSessionExpires >= pCallLeg->pSessionTimer->minSE)
				pCallLeg->pSessionTimer->sessionExpires = msgSessionExpires;
			else
				pCallLeg->pSessionTimer->sessionExpires = pSessionTimer->sessionExpires;
			
			//更新动态会话刷新参数的刷新方类型为远端消息中的值
			pCallLeg->pSessionTimer->eRefresherType = eMsgRefresherType;
			
			//根据远端消息中的刷新方参数,设置动态会话刷新参数的eCurrentRefresher
			if (RVSIP_SESSION_EXPIRES_REFRESHER_UAS == eMsgRefresherType)
				pCallLeg->pSessionTimer->eCurrentRefresher =
				RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_REMOTE;
			else if (RVSIP_SESSION_EXPIRES_REFRESHER_UAC == eMsgRefresherType)
				pCallLeg->pSessionTimer->eCurrentRefresher =
				RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_LOCAL;
			
//设置动态会话刷新参数的默认警告定时器超时时间为本地刷新时间一半。
			pCallLeg->pSessionTimer->defaultAlertTime =
			pCallLeg->pSessionTimer->sessionExpires/2;
			
			//校正动态会话刷新参数的警告定时器超时时间。
			if (pCallLeg->pSessionTimer->alertTime != UNDEFINED &&
			pCallLeg->pSessionTimer->alertTime >= pCallLeg->pSessionTimer->sessionExpires)
				pCallLeg->pSessionTimer->alertTime = 
				pCallLeg->pSessionTimer->defaultAlertTime;
	
			//如果本地预置的刷新方的值与远端冲突,则标记PREFERENCE_REJECT
if(pSessionTimer->eRefresherPreference ==
RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_LOCAL &&
pCallLeg->pSessionTimer->eRefresherType != 
RVSIP_SESSION_EXPIRES_REFRESHER_UAC)
pCallLeg->pSessionTimer->eNegotiationReason =
RVSIP_CALL_LEG_SESSION_TIMER_NEGOTIATION_REASON_REFRESHER_
PREFERENCE_REJECT;
else if (pSessionTimer->eRefresherPreference ==
RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_REMOTE &&
pCallLeg->pSessionTimer->eRefresherType != 
RVSIP_SESSION_EXPIRES_REFRESHER_UAS)
pCallLeg->pSessionTimer->eNegotiationReason =
RVSIP_CALL_LEG_SESSION_TIMER_NEGOTIATION_REASON_REFRESHER_
PREFERENCE_REJECT;
else
pCallLeg->pSessionTimer->eNegotiationReason =
RVSIP_CALL_LEG_SESSION_TIMER_NEGOTIATION_REASON_UNDEFINED;
	
	
	CallLegSessionTimerHandleTimers
		//停止正在运行的定时器
		CallLegSessionTimerReleaseTimer(pCallLeg);
		
//获取协商定时器对象,根据消息不同从不同地方取值,当前是INVITE消息,
		//取pCallLeg->pNegotiationSessionTimer
		GetSessionTimerPointer(pCallLeg,hTransc,bInviteTransc,&pSessionTimer);
		
		//如果已经不需要刷新则直接返回
		if (pSessionTimer == NULL || pSessionTimer->bInRefresh == RV_FALSE)
			return RV_OK;
		
		//复位需要刷新标记。
		pSessionTimer->bInRefresh = RV_FALSE;
		
		//如果没有sessionExpires值,则不需要刷新处理。
		if (pCallLeg->pSessionTimer->sessionExpires <= 0)
			return RV_OK;
		
		//如果远端不支持会话刷新
		if (pCallLeg->pSessionTimer->eNegotiationReason ==
		RVSIP_CALL_LEG_SESSION_TIMER_NEGOTIATION_REASON_DEST_NOT_SUPPORTED)
			//使用回调通知用户层协商错误及原因,并收集用户层的反馈,如果仍继续
			//会话刷新,则bHandleSessionTimer被设置为true。
			CallLegCallbackSessionTimerNegotiationFaultEv(pCallLeg,……,
&bHandleSessionTimer)
		//如果本地预配置与远端设置的刷新方参数冲突
		else if (pCallLeg->pSessionTimer->eNegotiationReason ==
		RVSIP_CALL_LEG_SESSION_TIMER_NEGOTIATION_REASON_REFRESHER_PREFERENCE_REJECT)
			//使用回调通知用户层协商错误及原因,并收集用户层的反馈,如果仍继续
			//会话刷新,则bHandleSessionTimer被设置为true。
			CallLegCallbackSessionTimerNegotiationFaultEv(pCallLeg, ……,
&bHandleSessionTimer)
		
		//如果远端不支持会话刷新
		if (pCallLeg->pSessionTimer->eNegotiationReason ==
		RVSIP_CALL_LEG_SESSION_TIMER_NEGOTIATION_REASON_DEST_NOT_SUPPORTED)
			//如果远端不支持会话刷新,本端仍要使用会话刷新,则设置本端为刷新方。
			if(bHandleSessionTimer == RV_TRUE && bMsgRecieved == RV_TRUE)
				pCallLeg->pSessionTimer->eRefresherType =
RVSIP_SESSION_EXPIRES_REFRESHER_UAC;
			//否则,复位动态会话刷新对象
			else if (bHandleSessionTimer == RV_FALSE)
				ResetSessionTimerParams(pCallLeg->pSessionTimer);
		
		//如果本地预配置与远端设置的刷新方参数冲突
		if (pCallLeg->pSessionTimer->eNegotiationReason ==
		RVSIP_CALL_LEG_SESSION_TIMER_NEGOTIATION_REASON_REFRESHER_PREFERENCE_
REJECT )
	//???什么情况下会出现呢???都冲突了,怎么eRefresherType还会出现NONE
	//如果远端没有设置刷新方时,更新本地为刷新方。
			if (bHandleSessionTimer == RV_TRUE  &&
			pCallLeg->pSessionTimer->eRefresherType ==
RVSIP_SESSION_EXPIRES_REFRESHER_NONE)
				if(bMsgRecieved == RV_TRUE)
					pCallLeg->pSessionTimer->eRefresherType =
RVSIP_SESSION_EXPIRES_REFRESHER_UAC;
			//否则,复位动态会话刷新对象
			else if (bHandleSessionTimer == RV_FALSE)
				ResetSessionTimerParams(pCallLeg->pSessionTimer);
		
		//校正动态会话刷新参数的默认告警时间
		if (pCallLeg->pSessionTimer->defaultAlertTime <= 0)
			if (pCallLeg->pSessionTimer->sessionExpires != UNDEFINED)
				pCallLeg->pSessionTimer->defaultAlertTime = 
				pCallLeg->pSessionTimer->sessionExpires/2;
		
		//如果需要处理会话刷新
		if(bMsgRecieved == RV_TRUE &&bHandleSessionTimer == RV_TRUE &&
		pCallLeg->pSessionTimer->defaultAlertTime > 0 &&
		pCallLeg->pSessionTimer->sessionExpires   > 0)
			//如果有确切的刷新方
			if (pCallLeg->pSessionTimer->eRefresherType != 
			RVSIP_SESSION_EXPIRES_REFRESHER_NONE)
				//如果是本端刷新
				if (pCallLeg->pSessionTimer->eRefresherType == 
				RVSIP_SESSION_EXPIRES_REFRESHER_UAC)
					//更新定时器时间,如果用户没有设置alert时间,则使用
					//pSessionTimer->defaultAlertTime值,该值为正常会话刷新的
					//一半。
					timeOut = XXXXXX
					
					//设置定时器超时的回调函数为告警回调。
					timerFunc = CallLegSessionTimerRefreshAlertTimeout;
				//如果是远端刷新
				else if (pCallLeg->pSessionTimer->eRefresherType == 
				RVSIP_SESSION_EXPIRES_REFRESHER_UAS)
					//更新定时器时间,如果pSessionTimer->sessionExpires的三分之一都
					//不到32秒,则定时器时间等于sessionExpires减去sessionExpires
//的三分之一,否则定时器时间等于sessionExpires减去32秒。
					UpdateSessionTimerTimeout(pCallLeg->pSessionTimer->sessionExpires,
					&timeOut);
					
					//设置定时器超时的回调函数为会话超时回调。
					timerFunc = CallLegSessionTimerSessionExpiresTimeout;
				
				//启动会话刷新定时器
				SipCommonCoreRvTimerStartEx(
				&pCallLeg->pSessionTimer->hSessionTimerTimer, pCallLeg->pMgr->pSelect,
				timeOut, timerFunc, pCallLeg);
四、发送消息
CallLegMsgEvMsgToSendHandler
	//对话框管理对象支持会话刷新
	if (pCallLeg->pMgr->eSessiontimeStatus == RVSIP_CALL_LEG_SESSION_TIMER_SUPPORTED)
		CallLegSessionTimerHandleSendMsg(pCallLeg,hTransc,hMsg);
			//校验是否是INVITE或UPDATE消息,会话刷新仅处理这两种
			IsInviteOrUpdateTransc(pCallLeg,hTransc,hMsg,&bInviteTransc);
			if (rv != RV_OK)
				return RV_OK;
			
			//获取协商定时器对象,根据消息不同从不同地方取值,当前是INVITE消息,
			//取pCallLeg->pNegotiationSessionTimer
			GetSessionTimerPointer(pCallLeg,hTransc,bInviteTransc,&pSessionTimer);
			
			//以下两种情况下,直接返回,不继续进行处理。
			//1、发送reinvite,并且本地没有标记进行刷新。
			//2、发送非invite消息,并且本地没有标记进行刷新。
			if (bInviteTransc == RV_TRUE)
				if (eState == RVSIP_CALL_LEG_STATE_CONNECTED)
					if (pSessionTimer->bInRefresh == RV_FALSE)
						return RV_OK;
				else
					pSessionTimer->bInRefresh = RV_TRUE;
			else
				if(pSessionTimer == NULL || pSessionTimer->bInRefresh == RV_FALSE)
					return RV_OK;
			
			//如果发送的是请求消息
			if(eMsgType == RVSIP_MSG_REQUEST)
				//如果是reinvite
				if (eState == RVSIP_CALL_LEG_STATE_CONNECTED)
					//根据用户预配置,如果设置了REMOTE,则eRefresherType为
					//UAS,如果设置了LOCAL,则eRefresherType为UAC,否则根据
					//当前谁是刷新方,则进行设置。
					if (pSessionTimer->eRefresherPreference ==
					RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_REMOTE)
						pSessionTimer->eRefresherType = 
						RVSIP_SESSION_EXPIRES_REFRESHER_UAS;
					else if (pSessionTimer->eRefresherPreference ==
RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_LOCAL)
						pSessionTimer->eRefresherType =
RVSIP_SESSION_EXPIRES_REFRESHER_UAC;
					else
						pSessionTimer->eRefresherType =
						(pCallLeg->pSessionTimer->eCurrentRefresher==
RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_REMOTE)? RVSIP_SESSION_EXPIRES_REFRESHER_UAS:
RVSIP_SESSION_EXPIRES_REFRESHER_UAC;
				//如果是初始invite
				else
					//仅根据用户预配置设置eRefresherType值。
					if (pSessionTimer->eRefresherPreference==
RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_LOCAL)
	pSessionTimer->eRefresherType = 
	RVSIP_SESSION_EXPIRES_REFRESHER_UAC;
else if (pSessionTimer->eRefresherPreference==
RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_REMOTE)
	pSessionTimer->eRefresherType =
RVSIP_SESSION_EXPIRES_REFRESHER_UAS;
				
				//将会话参数添加到消息对象中
				CallLegSessionTimerAddParamsToMsg(pCallLeg,
				pSessionTimer->sessionExpires, pSessionTimer->minSE,
				pSessionTimer->eRefresherType, hMsg);
			
			//如果发送的是2XX应答消息
			if(eMsgType == RVSIP_MSG_RESPONSE && responseCode >= 200 && 
			responseCode<300 )
				//如果预配置的刷新方与当前协商会话中的值冲突,则标记协商错误原因
				if (pSessionTimer->eRefresherPreference ==
RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_LOCAL &&
pSessionTimer->eRefresherType ==
RVSIP_SESSION_EXPIRES_REFRESHER_UAC)
	pCallLeg->pSessionTimer->eNegotiationReason =
	RVSIP_CALL_LEG_SESSION_TIMER_NEGOTIATION_REASON_REFRESHER_
PREFERENCE_REJECT;
else if (pSessionTimer->eRefresherPreference ==
RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_REMOTE &&
pSessionTimer->eRefresherType == 
RVSIP_SESSION_EXPIRES_REFRESHER_UAS)
					pCallLeg->pSessionTimer->eNegotiationReason =
					RVSIP_CALL_LEG_SESSION_TIMER_NEGOTIATION_REASON_REFRESHER_
PREFERENCE_REJECT;
				else
					pCallLeg->pSessionTimer->eNegotiationReason =
					RVSIP_CALL_LEG_SESSION_TIMER_NEGOTIATION_REASON_UNDEFINED;
				
				//如果当前协商会话中的刷新方还未确定,则检测是否有预设置的值,如
				//果有,则使用预设置的值配置刷新方。
				if (RVSIP_SESSION_EXPIRES_REFRESHER_NONE ==
pSessionTimer->eRefresherType)
					if (pSessionTimer->eRefresherPreference ==
					RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_REMOTE)
						pSessionTimer->eRefresherType = 
						RVSIP_SESSION_EXPIRES_REFRESHER_UAC;
					else
						pSessionTimer->eRefresherType = 
						RVSIP_SESSION_EXPIRES_REFRESHER_UAS;
				
				//如果有会话刷新设置,并且刷新方为远端,则加上“Require: timer”域
				if (pSessionTimer->sessionExpires > 0 && pSessionTimer->eRefresherType == 
				RVSIP_SESSION_EXPIRES_REFRESHER_UAC)
					SipMsgAddNewOtherHeaderToMsg(hMsg,"Require","timer",NULL);
				
				//将会话参数添加到消息对象中
				CallLegSessionTimerAddParamsToMsg
			
			//如果是422应答,则加入本地minSE字段
			if(eMsgType == RVSIP_MSG_RESPONSE &&responseCode ==
INTERVAL_TOO_SMALL_RESPONSE)
				pSessionTimer->minSE = pCallLeg->pSessionTimer->minSE;
				CallLegSessionTimerAddMinSEToMsg(pCallLeg,pSessionTimer->minSE,hMsg);
五、发送最终应答
HandleTranscStateInviteFinalResponseSent
	if (pCallLeg->pMgr->eSessiontimeStatus == RVSIP_CALL_LEG_SESSION_TIMER_SUPPORTED 
	&& eStateReason != RVSIP_TRANSC_REASON_TRANSACTION_CANCELED)
		CallLegSessionTimerHandleFinalResponseSend
//获取协商定时器对象,根据消息不同从不同地方取值,当前是INVITE消息,
			//取pCallLeg->pNegotiationSessionTimer
			GetSessionTimerPointer(pCallLeg,hTransc,bInviteTransc,&pSessionTimer);
			
			//如果不再需要刷新,则直接返回
			if (pSessionTimer == NULL || pSessionTimer->bInRefresh== RV_FALSE)
				return RV_OK;
			
			if(responseCode >= 200 && responseCode<300)
				//更新动态会话刷新参数值
				pCallLeg->pSessionTimer->sessionExpires   =
pSessionTimer->sessionExpires;
				pCallLeg->pSessionTimer->eRefresherType   = 
					pSessionTimer->eRefresherType;
				
				//根据刷新方的值,设置动态会话刷新参数中的eCurrentRefresher
				if (RVSIP_SESSION_EXPIRES_REFRESHER_UAS == 
				pSessionTimer->eRefresherType)
					pCallLeg->pSessionTimer->eCurrentRefresher =
					RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_LOCAL;
				else if (RVSIP_SESSION_EXPIRES_REFRESHER_UAC == 
				pSessionTimer->eRefresherType)
					pCallLeg->pSessionTimer->eCurrentRefresher =
					RVSIP_CALL_LEG_SESSION_TIMER_REFRESHER_REMOTE;
				
				//设置动态会话刷新参数的默认告警时间
				pCallLeg->pSessionTimer->defaultAlertTime = 
					pCallLeg->pSessionTimer->sessionExpires/2;
				
				//校正动态会话刷新参数的告警时间
				if (pCallLeg->pSessionTimer->alertTime != UNDEFINED && 
				pCallLeg->pSessionTimer->alertTime >=
pCallLeg->pSessionTimer->sessionExpires)
					pCallLeg->pSessionTimer->alertTime = 
					pCallLeg->pSessionTimer->defaultAlertTime;
		
		if (responseStatusCode >=200 && responseStatusCode <300)
			//该函数上面分析过了,这里不再进行分析,会话刷新的主定时器启动在这里
			//触发的。
			CallLegSessionTimerHandleTimers
六、刷新告警处理
CallLegSessionTimerRefreshAlertTimeout
	//定时器复位
	SipCommonCoreRvTimerExpired(&pCallLeg->pSessionTimer->hSessionTimerTimer);
	CallLegSessionTimerReleaseTimer(pCallLeg);
	
	switch (pCallLeg->eState)
	case RVSIP_CALL_LEG_STATE_CONNECTED:
	case RVSIP_CALL_LEG_STATE_ACCEPTED:
	case RVSIP_CALL_LEG_STATE_REMOTE_ACCEPTED:
		//手动处理刷新告警
		HandleManualRefreshAlert(pCallLeg);
			//调用pfnSessionTimerRefreshAlertEvHandler回调,通知上层用户处理
			CallLegCallbackSessionTimerRefreshAlertEv
		
		//重新设置会话刷新定时器,使用会话刷新剩余时间来进行刷新超时处理。
		SetAlertTimeoutAndTimer(pCallLeg);
			if (pCallLeg->pSessionTimer->defaultAlertTime > 0  &&
			pCallLeg->pSessionTimer->sessionExpires   > 0)
				//取超时时间为总的会话刷新时间减去已经运行的告警时间,即剩余的会
				//话刷新时间来进行刷新超时处理。
				timeOut = (pCallLeg->pSessionTimer->sessionExpires) – 
					(pCallLeg->pSessionTimer->defaultAlertTime);
				
				//在上面的基础上进行超时时间的微减
				UpdateSessionTimerAlertTimeout(pCallLeg->pSessionTimer->sessionExpires, 
				&timeOut);
				
				//启动会话刷新总定时器,定时器的超时函数为
				// CallLegSessionTimerSessionExpiresTimeout
				SipCommonCoreRvTimerStartEx( 
&pCallLeg->pSessionTimer->hSessionTimerTimer, pCallLeg->pMgr->pSelect,
timeOut, CallLegSessionTimerSessionExpiresTimeout, pCallLeg);
七、刷新超时处理
CallLegSessionTimerSessionExpiresTimeout
	//定时器复位
	SipCommonCoreRvTimerExpired(&pCallLeg->pSessionTimer->hSessionTimerTimer);
	CallLegSessionTimerReleaseTimer(pCallLeg);
	
	switch (pCallLeg->eState)
	case RVSIP_CALL_LEG_STATE_CONNECTED:
	case RVSIP_CALL_LEG_STATE_ACCEPTED:
	case RVSIP_CALL_LEG_STATE_REMOTE_ACCEPTED:
		//调用回调函数通知用户层会话刷新已经超时。
		CallLegCallbackSessionTimerNotificationEv(pCallLeg,
		RVSIP_CALL_LEG_SESSION_TIMER_NOTIFY_REASON_SESSION_EXPIRES);
	
	//复位会话刷新动态参数
	ResetSessionTimerParams(pCallLeg->pSessionTimer);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值