RvSIP发送注册包及重传流程

//发送注册包
AppSimpleRegister
	//创建一个注册客户端对象
	RvSipRegClientMgrCreateRegClient(g_hRegClientMgr,NULL,&hRegClient);
		//分配一个注册客户端对象
		RLIST_InsertTail(pRegClientMgr->hRegClientListPool, pRegClientMgr->hRegClientList,
		(RLIST_ITEM_HANDLE *)phRegClient);
		
		//初始化注册客户端对象
		RegClientInitiate(pRegClientMgr, (RegClient *)(*phRegClient), hAppRegClient);
			pRegClient->eState          = RVSIP_REG_CLIENT_STATE_IDLE;
			pRegClient->hAppRegClient   = hAppRegClient;		//NULL
			pRegClient->regClientEvHandlers = &(pRegClientMgr->regClientEvHandlers);
			pRegClient->hContactList    = NULL;
			
			pRegClient->responseCode=0;
			
			pRegClient->bIsDetach        = RV_TRUE;
			
			//分配一个内存页
			RPOOL_GetPage(pRegClientMgr->hGeneralMemPool, 0,
&pRegClient->hContactPage);
			
			//初始化一个事务客户端对象
			SipTranscClientInitiate(pRegClientMgr->hTranscClientMgr, pRegClient,
			RVSIP_COMMON_STACK_OBJECT_TYPE_REG_CLIENT,
			&pRegClient->transcClient);
				evHandler.pfnConnStateChangedEvHandler = 
					TranscClientConnStateChangedEv;
				
				//初始化outbound地址
				SipTransportInitObjectOutboundAddr(pTranscClient->pMgr->hTransportMgr,
				&pTranscClient->outboundAddr)
					outboundAddr->eCompType = RVSIP_COMP_UNDEFINED;
					outboundAddr->rpoolSigcompId.offset = UNDEFINED;
					
					outboundAddr->ipAddress.eTransport= RVSIP_TRANSPORT_UNDEFINED;
RvAddressConstruct(RV_ADDRESS_TYPE_NONE,、
&outboundAddr->ipAddress.addr);
					outboundAddr->rpoolHostName.offset = UNDEFINED;
				
				pTranscClient->bIsPersistent  = pTranscClientMgr->bIsPersistent;
				pTranscClient->hTcpConn       = NULL;
				SipCommonCSeqSetStep(0,&pTranscClient->cseq);
				pTranscClient->hActiveTransc   = NULL;
				pTranscClient->hRequestUri     = NULL;
				pTranscClient->hExpireHeader   = NULL;
				pTranscClient->hFromHeader     = NULL;
				pTranscClient->hToHeader       = NULL;
				pTranscClient->hReceivedMsg    = NULL;
				pTranscClient->hOutboundMsg    = NULL;
				// eOwnerType  =  RVSIP_COMMON_STACK_OBJECT_TYPE_REG_CLIENT
				pTranscClient->eOwnerType = eOwnerType;
				pTranscClient->hOwner	  = hOwner;	// pRegClient
				pTranscClient->eState	  = SIP_TRANSC_CLIENT_STATE_IDLE;
				pTranscClient->bWasActivated = RV_FALSE;
				
				// timer->bTimerStarted = RV_FALSE;
				SipCommonCoreRvTimerInit(&pTranscClient->alertTimer);
				pTranscClient->bWasAlerted = RV_FALSE;
				
				pTranscClient->strCallId        = UNDEFINED;
				pTranscClient->bUseFirstRouteRequest = RV_FALSE;
				
				pTranscClient->pAuthListInfo = NULL;
				pTranscClient->hListAuthObj  = NULL;
				
				pTranscClient->bSigCompEnabled     = RV_TRUE;
	    		
pTranscClient->hInitialAuthorization = NULL;
				pTranscClient->hSecAgree             = NULL;
				pTranscClient->hSecObj               = NULL;
				
				pTranscClient->pTimers = NULL;
				
				//获取一个内存页
				RPOOL_GetPage(pTranscClientMgr->hGeneralMemPool, 0,
				&pTranscClient->hPage);
				
				pTranscClient->tripleLock = &pTranscClient->transcClientTripleLock;
				
				//从pTransportMgr->hLocalUdpAddrList中获取本地地址
				SipTransportLocalAddressInitDefaults(pTranscClientMgr->hTransportMgr,
				&pTranscClient->localAddr);
				
				//获取一个唯一的随机值
				RvRandomGeneratorGetInRange(pTranscClient->pMgr->seed,
RV_INT32_MAX, &pTranscClient->transcClientUniqueIdentifier);
				
	//发起注册
	// REG_FROM = From:sip:bv@172.20.1.77:5060
	// REG_TO = "To:<sip:x@172.28.53.203:5060>"
	// REGISTRAR = sip:172.28.53.203
	// CONTACT1 = "Contact:<sip:y@172.20.1.77:5060>"
	RvSipRegClientMake(hRegClient,REG_FROM,REG_TO,REGISTRAR,CONTACT1);
		//设置事务客户端对象详细信息,最后一个参数表示上层传入的字符串中是否
		//已经含有字段头(from、to这类),如果有,则传入FALSE
		SipTranscClientSetActivateDetails(&pRegClient->transcClient, strFrom, strTo,
strRegistrar, RV_FALSE)
	//从事务客户端对象内存页中分配一个FROM消息字段BUF
	SipTranscClientGetNewMsgElementHandle(pTranscClient,
RVSIP_HEADERTYPE_FROM, RVSIP_ADDRTYPE_UNDEFINED, (void**)&hFrom);
	SipHeaderConstruct(pTranscClient->pMgr->hMsgMgr, 
eHeaderType,pTranscClient->pMgr->hGeneralMemPool, pTranscClient->hPage, phHeader);
			
			//将外部传来的FROM字符串转换为RV需要的Party头对象
			RvSipPartyHeaderParse(hFrom,RV_FALSE,strFrom);
				//复位Party对象参数
				PartyHeaderClean(pHeader, RV_FALSE);
				
				//解析标准头
				MsgParserParseStandAloneHeader(pHeader->pMsgMgr, eType, buffer,
				RV_FALSE, hHeader);
					//查找冒号
					while(*pBuf != ':' && *pBuf != MSG_NULL_CHAR && 
safeCounter < HEADER_SAFE_COUNTER_LIMIT)
	++safeCounter;
	++pBuf;
	++ headerNameLen;
					
					//根据冒号位置,分别取字段名字和字段值。
					pHeaderNameEnd = pBuf-1;
					pHeaderVal = ++pBuf;
					
					//解析字段头
ParseHeader(pMsgMgr, pHeader, eHeaderType, RV_FALSE, pStrHeader,
pHeaderNameEnd, headerNameLen, pHeaderVal, 1);
	//获取消息头类型,注意信令压缩中的单个字符查找消息头类型
	//也是在这里。
	GetHeaderType(pHeaderStart, pHeaderNameEnd, headerNameLen,
	&bCompactForm, &eSpecificHeaderType);
	//分析字段值,先跳过空格符
while((*pHeaderVal == ' ' ||  *pHeaderVal == 0x09 /*tab */) &&
*pHeaderVal != MSG_NULL_CHAR)
		++pHeaderVal;
	
	//指向要解析的字符串
	pStringForParsing = pHeaderVal;
	
	//这里调用了协议栈自己的解析编译器,这块代码不是人工写的
	//,是不能看懂的。
	ParseLegalHeader(pMsgMgr, pObj, eObjType, eHeaderType, 
	bCompactForm, bStartLine, eSpecificHeaderType, lineNumber,
pStringForParsing);

//如果解析语法错误,同时要解析的对象类型为
//SIP_PARSETYPE_MSG,则将解析语法错误的行数写到消息对象
//的pBadSyntaxReasonPhrase成员中。
			
			//将上面解析好的From头对象设置到pTranscClient->hFromHeader中
			SipTranscClientSetFromHeader(pTranscClient,hFrom);
			
			//后面To和Destination的流程同上面From字段的设置流程类似,分别设置到
			//pTranscClient的hToHeader和hRequestUri中。
		
		//从注册客户端对象的内存页中分配一个hContact资源对象
		RvSipRegClientGetNewContactHeaderHandle(hRegClient,&hContact);
		
		//将上层设置的contact字符串解析为RV需要的消息字段对象
		RvSipContactHeaderParse(hContact,strContact);
		
		//将上面构造好的 Contact对象设置到Contact列表中
		RvSipRegClientSetContactHeader(hRegClient,hContact);
			//在注册客户端对象中构造一个contact列表,并从列表中获取一个
			//列表条目对象
			RegClientGetNewContactHeaderHandle(pRegClient, &phNewContact);
			
			//将分配好的列表元素指针指向构造好的Contact对象
			*phNewContact = hContactHeader;
		
		//发起注册
		RvSipRegClientRegister(hRegClient);
			//发送事务请求
			SipTranscClientActivate(&pRegClient->transcClient,
SIP_TRANSACTION_METHOD_REGISTER, NULL);
	//创建一个新的事务客户端
				TranscClientCreateNewTransaction(pTranscClient);
					//递增事务的Cseq
					SipCommonCSeqPromoteStep(&pTranscClient->cseq);
					
					//分配CallID,并设置到事务客户端对象的内存页中
					TranscClientGenerateCallId(pTranscClient->pMgr, pTranscClient->hPage,
					&(pTranscClient->strCallId), NULL);
					
					//创建事务KEY
					SipCommonCSeqGetStep(&pTranscClient->cseq,&transcKey.cseqStep);
					transcKey.hFromHeader = pTranscClient->hFromHeader;
					transcKey.hToHeader = pTranscClient->hToHeader;
					transcKey.strCallId.offset = pTranscClient->strCallId;
					transcKey.strCallId.hPage = pTranscClient->hPage;
					transcKey.strCallId.hPool = pTranscClient->pMgr->hGeneralMemPool;
					transcKey.localAddr = pTranscClient->localAddr;
					
					//事务创建
					SipTransactionCreate(pTranscClient->pMgr->hTranscMgr , &transcKey,
					pTranscClient, SIP_TRANSACTION_OWNER_TRANSC_CLIENT,
					pTranscClient->tripleLock, &(pTranscClient->hActiveTransc))
						TransactionCreate(hTranscMgr,pKey,pOwner,eOwnerType,
tripleLock, RV_TRUE,phTransaction);
							//使用事务管理对象创建事务
							TransactionMgrCreateTransaction(pMgr,b_isUac, &pTransc);
								//从事务列表中分配一个资源
								RLIST_InsertTail(pTranscMgr->hTranasactionsListPool ,
								pTranscMgr->hTranasactionsList, &listItem);
								
								pTransc = (Transaction*)listItem;
								
								//初始化分配的事务资源
								TransactionInitialize(pTranscMgr,pTransc,b_isUac);
									//主要初始化事务对象各成员参数
									
									//创建传送对象,将事务客户端对象做为传送对
//象的拥有者
									SipTransmitterMgrCreateTransmitter(
									pTransc->pMgr->hTrxMgr, pTransc,
									&pTransc->pMgr->transcTrxEvHandlers,
									pTransc->pMgr->hGeneralPool, 
									pTransc->memoryPage,
									pTransc->tripleLock, &pTransc->hTrx);
										//使用传送管理对象构造传送器
										TransmitterMgrCreateTransmitter(pTrxMgr,
RV_FALSE,hAppTrx,hPool,hPage,pTripleLock,phTrx);
		//从传送列表中分配一个资源
		RLIST_InsertTail(pTrxMgr->hTrxListPool,
		pTrxMgr->hTrxList, &hListItem);
		
		pTrx = (Transmitter*)hListItem;
		
		//传送对象初始化,这里构造了一个空的
		//DNS列表、创建了一个解析器对象、消
		//息发送列表……
		TransmitterInitialize(pTrx,bIsAppTrx,
hAppTrx, hPool,hPage,pTripleLock);
	
//设置该传送器的事件回调为事务管理对
//象设置的回调,该回调是在事务模块初始
//化事务管理对象时设置的
//(TransactionMgrInitialize)
pTrx->evHandlers = pEvHandlers
							
							//将事务KEY的值设置到事务对象中
							TransactionAttachKey(pTransc, pKey);
							
							//设置事务拥有者
							TransactionInitiateOwner(pTransc, pOwner, eOwnerType, 
							tripleLock);
								//注意这里的事务对象拥有者为事务客户端对象
								// pTranscClient,而该客户端对象的拥有者才是
								//注册客户端对象,并且事务客户端拥有者在
								//之前已经设置过了。
								pTransc->pOwner = pOwner;	// pTranscClient
								// SIP_TRANSACTION_OWNER_TRANSC_CLIENT
								pTransc->eOwnerType = eOwnerType;
					
					//设置传输层设置outbound,当前outbound还没有
					SipTransactionSetOutboundAddress(pTranscClient->hActiveTransc, 
					&pTranscClient->outboundAddr);
					
					//当前还没有定时器参数
					if(pTranscClient->pTimers != NULL)
						……
					
					//TCP传输模式的相关设置,暂不关心
					if(pTranscClient->bIsPersistent == RV_TRUE)
						……
					
					if(pTranscClient->hTcpConn != NULL)
						……
					
					//当前为TRUE,支持信令压缩,如果不支持,则设置传送对象
					//的信令压缩标记为FALSE(pTrx->bSigCompEnabled = RV_FALSE)
					if (pTranscClient->bSigCompEnabled == RV_FALSE)
						RvSipTransactionDisableCompression
(pTranscClient->hActiveTransc);
					
					//安全对象是否设置,暂不关心
					if (NULL != pTranscClient->hSecObj)
						……
				
				//事务发送
				TranscClientSendRequest(pTranscClient, eTranscMethod, strMethod);
					switch (eMethod)
					case SIP_TRANSACTION_METHOD_REGISTER:
						//发起注册事务请求
						SipTransactionRequest(pTranscClient->hActiveTransc, eMethod,
						pTranscClient->hRequestUri);
							//发送请求
							TransactionControlSendRequest(pTransc, hRequestUri,
RV_TRUE);
	//从消息池中分配一块资源
								if (pTransc->hOutboundMsg == NULL)
									RvSipMsgConstruct(pTransc->pMgr->hMsgMgr, 
									pTransc->pMgr->hMessagePool,
&pTransc->hOutboundMsg);
								
								//如果当前事务对象有一组消息字段列表,则设置到
								//当前即将发送的消息对象中
								if(pTransc->hHeadersListToSetInInitialRequest != NULL)									SipMsgPushHeadersFromList(
pTransc->hOutboundMsg,
pTransc->hHeadersListToSetInInitialRequest);
								
								//发送请求
								GenerateAndSendRequest(pTransc,hRequestUri,
pTransc->hOutboundMsg,bResolveAddr);
	//获取事务KEY
									TransactionGetKeyFromTransc(pTransc, &key);
									
									//给当前事务添加From Tag
									TransactionAddTag(pTransc, RV_FALSE);
									
									//创建事务请求消息
									TransactionCreateRequestMessage(pTransc,
hRequestUri, hMsgToSend);
	//从消息内存页中分配基本字段资源,并
	//使用事务参数进行填冲,基本字段包括
	// Method、Request-Uri、CSeq、To, From, 
//CSeq, Call-ID、MaxForwards
										TransactionFillBasicRequestMessage(…)
										
										//向消息中添加VIA字段
										TransactionAddViaToMsg(pTransc, hMsg)
											pTrx->bTrxCreatedVia = RV_TRUE;
											
											//从消息池中分配资源
											RvSipViaHeaderConstructInMsg(hMsg, 
											RV_TRUE, &hViaHeader)
	
	//从本地列表中获取地址			 ChooseLocalAddressForViaFromLocalAddresses(pTrx,eTransport,&hLocalAddr)
	
	//给VIA设置传送协议参数
SipTransportLocalAddressGetTransportType(hLocalAddr,&eTransport)
											
											RvSipViaHeaderSetTransport
(hViaHeader,eTransport,NULL)
											
											//设置VIA主机地址
											SetViaSentByParamByLocalAddress(pTrx,
hLocalAddr, hViaHeader,
											
											//生成事务branch并设置到消息中
											TransmitterGenerateBranchStr
(pTrx,strBranch);
											
											RPOOL_AppendFromExternal(pTrx->hPool,
											pTrx->hPage, strBranch,
											strlen(strBranch) + 1, RV_FALSE,
											&(pTrx->viaBranchOffset), NULL);
											RvSipViaHeaderSetBranchParam
(hViaHeader, strBranch)
										
										//添加Supported字段到消息中,该
										//支持列表是在StackConstructModules中
										//设置的。
										AddSupportedListToMsg(pTransc,hMsg)
										
										//当前注册消息还不涉及到安全联盟字段
										//暂不关心
										TransactionSecAgreeMsgToSend(pTransc, hMsg)
									
									//将消息中的VIA字段复制到
//pTransc->hTopViaHeader中
									TransactionUpdateTopViaFromMsg(pTransc, 
									hMsgToSend)
									
									pTransc->bInitialRequest = RV_TRUE;
									
									//在事务管理对象的HASH表中查找是否事务
									//已经存在,如果存在则直接返回。
									if(TransactionMgrCheckIfExists(pTransc->pMgr
									&key, pTransc->eMethod, pTransc->strMethod,
									RV_TRUE, hMsgToSend))
										return RV_ERROR_OBJECT_ALREADY_EXISTS;
									
									//设置事务的请求URI
									TransactionSetRequestUri(pTransc,hRequestUri)
									
									//如果事务存在ReferredBy字段,则设置到消息中
									AddReferredByHeaderIfExists(pTransc,hMsgToSend)
									
									//这里调用了事务客户端管理对象的事件回调
									// TranscClientTranscEvMsgToSend,该回调函数在
//下面单独描述
									TransactionCallbackMsgToSendEv(pTransc, 
									hMsgToSend)
									
									//将消息中的VIA字段复制到
//pTransc->hTopViaHeader中
									TransactionUpdateTopViaFromMsg(pTransc, 
									hMsgToSend)
									
									//将事务对象插入到事务管理对象的Hash表中
									TransactionMgrHashInsert(pTransc)
									
									//下一步状态为
//RVSIP_TRANSC_STATE_CLIENT_GEN_REQUEST_SE
//NT
									pTransc->eState =
TransactionGetNextUacState(pTransc)
									
									pTransc->msgType = 
										SIP_TRANSPORT_MSG_REQUEST_SENT;
									
									//发送消息
									TransactionTransportSendMsg(pTransc, 
									bResolveAddress)
										//该函数在下面单独列出,传送层发送消息
										SipTransmitterSendMessage(pTransc->hTrx, 
										pTransc->hOutboundMsg, pTransc->msgType);
										
										pTransc->hOutboundMsg = NULL;
								
								//消息资源释放
								if(pTransc->hOutboundMsg != NULL)
									RvSipMsgDestruct(pTransc->hOutboundMsg);
									pTransc->hOutboundMsg = NULL;
								
								//事务状态更新,当前事务状态更新为
								// RVSIP_TRANSC_STATE_CLIENT_GEN_REQUEST_ SENT
								//并通知上层回调,这里的上层回调即为当前事务拥有
								//者(事务客户端对象)的pfnEvStateChanged回调函
								//数=TranscClientTranscEvStateChanged,该函数对当前
								//状态没有做特殊处理。
								TransactionChangeToNextUacState(pTransc,
								RVSIP_TRANSC_REASON_USER_COMMAND);
							
							pTransc->bTagInTo = RV_FALSE;	//没有设置To tag
				
				//更新事务客户端状态
				TranscClientChangeState(SIP_TRANSC_CLIENT_STATE_ACTIVATING,
				SIP_TRANSC_CLIENT_REASON_USER_REQUEST, pTranscClient, 0);
					//标识当前事务客户端已经激活
					if(pTranscClient->eState == SIP_TRANSC_CLIENT_STATE_ACTIVATED)
						pTranscClient->bWasActivated = RV_TRUE;
					
					//事务客户端状态更新回调,当前事务客户端的拥有者为注册客户端
					//回调函数为RegClientTranscClientEvStateChanged,该回调函数最终
					//是调用了上层用户设置的注册回调,以确认注册状态变更时,上层
					//对应做什么处理。
					TranscClientCallbackStateChangeEv(eNewState, eReason, pTranscClient, 
					responseCode)

-------------------------------------------------------------------------------------------------------------------------------
TranscClientTranscEvMsgToSend
	//当前事务没有Expire参数,不执行
	if (NULL != pTranscClient->hExpireHeader)
		RvSipMsgPushHeader(……)
	//鉴权设置
	SipAuthenticatorBuildAuthorizationListInMsg(pTranscClient->pMgr->hAuthModule,
	hMsgToSend, pTranscClient->hOwner, pTranscClient->eOwnerType,
	pTranscClient->tripleLock, pTranscClient->pAuthListInfo, pTranscClient->hListAuthObj);
		//当前没有预置鉴权参数
		if (NULL != pAuthMgr->hGlobalAuth)
			……
		
		//当前事务客户端没有设置鉴权对象,所以直接跳出鉴权的处理。
		if (NULL == hAuthList)
			return RV_OK;
		
		……
	
	//当前事务客户端没有设置初始鉴权值
	if(NULL!=pTranscClient->hInitialAuthorization && 
	RVSIP_MSG_REQUEST==RvSipMsgGetMsgType(hMsgToSend))
		……
	
	//安全联盟参数设置,暂不关心
	TranscClientSecAgreeMsgToSend(pTranscClient, hMsgToSend)
	
	//这里调用了注册客户端设置的事件回调函数RegClientTranscClientEvMsgToSend
	//该回调函数比较简单,仅仅向消息设置contacts字段,并调用应用层设置的
	//事件通知回调。
	TranscClientCallbackMsgToSendEv((SipTranscClientHandle)pTranscClient, hMsgToSend)

--------------------------------------------------------------------------------------------------------------------------------
SipTransmitterSendMessage(pTransc->hTrx, pTransc->hOutboundMsg, pTransc->msgType);
pTrx->eMsgType          = eMsgType;	// SIP_TRANSPORT_MSG_REQUEST_SENT
    pTrx->hMsgToSend        = hMsgToSend;
    pTrx->hNextMessageHop   = NULL;
pTrx->msgParams.transportType = RVSIP_TRANSPORT_UNDEFINED;
	
TransmitterControlStartMessageSending(pTrx);
		TransmitterDestDiscovery(pTrx,RV_TRUE);
			//当前传输层的解析初始化为UNDEFINED状态,这里将pTrx->eState
//切为RESOLVING_ADDR状态
			//同时调用事务管理对象的回调,该状态没有特别处理。
			if (TRANSMITTER_RESOLUTION_STATE_UNDEFINED == pTrx->eResolutionState)
				TransmitterChangeState(pTrx,
RVSIP_TRANSMITTER_STATE_RESOLVING_ADDR, pTrx->hMsgToSend,NULL);
			
			//尝试查看是不是域名已经解析成功,因为TransmitterDestDiscovery函数
			//在使用DNS引擎时,会做为回调函数设置,待域名解析成功后,会再次调用
			//TransmitterDestDiscovery函数。
			rv = DestTryPreDnsList(pTrx);
				//如果当前状态为没有解析完成,则查找IP地址列表中是否已经有了值
				//,当前第一次调用,所以还没有。
				if (TRANSMITTER_RESOLUTION_STATE_RESOLVED != pTrx->eResolutionState)
					RvSipTransportDNSListPopIPElement(pTrxMgr->hTransportMgr,
					pTrx->hDnsList,&ipElement);
				
				//后面两个分别是主机、SRV记录的查询,暂不关心。
				
				return RV_ERROR_NOT_FOUND;	//返回还没有找到
			
			//如果没找到,则标记RV为OK,为了继续下一步处理
			if (RV_ERROR_NOT_FOUND == rv)
				rv = RV_OK;
			
			while (RV_OK == rv)
				switch (pTrx->eResolutionState)
				case TRANSMITTER_RESOLUTION_STATE_UNDEFINED:
					//初始处理
					DestHandleResolutionStateUndefined(pTrx);
						//DNS相关参数初始化
						TransmitterDestReset(pTrx);
						
						// pTrx->eResolutionState改变
						DestResolutionStateChange(pTrx,
TRANSMITTER_RESOLUTION_STATE_RESOLUTION_STARTED);

//查找下一跳地址
DestIdentifyNextHopParams(pTrx)
	//type = RVSIP_MSG_REQUEST
	pTrx->msgParams.msgType = 
	RvSipMsgGetMsgType(pTrx->hMsgToSend);
	
	switch (pTrx->msgParams.msgType)
	case RVSIP_MSG_REQUEST:
		//当前我们没有使用outband,并且也没有使用route
		//,所以pTrx->hNextMessageHop取自请求URL。
		//同时将pTrx->eResolutionState的状态切换为
		// TRANSMITTER_RESOLUTION_STATE_URI_FOUND
		DestGetRequestAddressFromMsg(pTrx,
		pTrx->hMsgToSend, pTrx->bSendToFirstRoute,
		&pTrx->msgParams.strHostName,
		&pTrx->msgParams.hostNameOffset,
		&pTrx->msgParams.port,
		&pTrx->msgParams.transportType,
		&pTrx->msgParams.bIsSecure);

//查看用户是否设置了自己的解析处理,当前没有,不关心

//当前已经找到要处理的地址,进行下一步处理
break;
				
				case TRANSMITTER_RESOLUTION_STATE_URI_FOUND:
					HandleUriFoundState(pTrx);
						//检查当前目标地址是否是IP,假设我们是域名,所以这里不返
						//回OK
						rv = TransportMgrConvertString2Address(
pTrx->msgParams.strHostName, &addr, RV_TRUE,RV_TRUE);
						
						if(rv != RV_OK)
							//TCP相关的,暂不关心,不返回OK
							rv = SearchConnectionByAlias(pTrx, &hConn);
						
						//获取当前是UDP还是其它,假设为UDP,同时将
						// pTrx->eResolutionState状态更新为
						// TRANSMITTER_RESOLUTION_STATE_TRANSPORT_FOUND
						return DestProtocolInitialFind(pTrx);
				
				case TRANSMITTER_RESOLUTION_STATE_TRANSPORT_FOUND:
					DestHostPortDiscovery(pTrx);
						//如果是IP地址则返回OK,并直接处理,这里我们假设是域名
						rv = DestPortIPDiscoveryByRawIP(pTrx);
						if(rv == RV_OK)
							……
						
						//设置目的地端口
						RvAddressSetIpPort(&pTrx->destAddr.addr,DestChoosePort(pTrx));
						
						//进行域名解析处理,这里设置了一个回调函数
						// DestDataReportedEvHandler,该回调函数的实现其实就是调用
						//了上面的 TransmitterDestDiscovery ,就是在进行域名解析数
						//据包交互时,先退出这里处理,待解析完成后直接调用回调进
						//行处理续接。
						SipResolverResolve(pTrx->hRslv,
RVSIP_RESOLVER_MODE_FIND_IP_BY_HOST,
pTrx->msgParams.strHostName,
RVSIP_RESOLVER_SCHEME_UNDEFINED,
pTrx->msgParams.bIsSecure,
RvAddressGetIpPort(&pTrx->destAddr.addr),
pTrx->destAddr.eTransport,
pTrx->hDnsList,
DestDataReportedEvHandler);
    pRslv->pfnReport        = DestDataReportedEvHandler;
    pRslv->strQueryString   = strQueryString;//要解析的域名
    pRslv->eScheme          = eScheme;//SIP
    pRslv->eState           = RESOLVER_STATE_UNDEFINED;
    pRslv->knownPort        = knownPort;//已经的端口
	;//已经的传输层类型
    pRslv->knownTransport   = knownTransport
	//域名解析结果的存储列表
    pRslv->hDns             = hDns;// pTrx->hDnsList
	// RVSIP_RESOLVER_MODE_FIND_IP_BY_HOST
    pRslv->eMode            = eMode;
	pRslv->bIsSecure		= bIsSecure;//FALSE
	
	//域名解析
	ResolverDnsResolveIpByHost(pRslv);
		eNextQuery = RV_DNS_HOST_IPV4_TYPE;
		eNextState = RESOLVER_STATE_TRY_A;
		
		//发送请求报文
		//这块代码不重点分析了,大体流程就是构造DNS请求
		//报文,然后使用当前select引擎机制进行发送,同时
		//启动一个随机定时器,用于一直没有收到应答时,给
		//用户回应错误,如果通过select引擎得到了DNS应答,
		//则最终会使用DestDataReportedEvHandler回调再次
		//触发当前TransmitterDestDiscovery函数,此时如果
		//DNS解析成功,则使用DestTryPreDnsList可以查到
		//DNSList里有IP地址,同时将pTrx->eResolutionState
		//更新为TRANSMITTER_RESOLUTION_STATE_RESOLVED。
		AllocateAndSendQuery(pRslv,eNextQuery,
pRslv->strQueryString, RV_FALSE);
	RvAresSendQuery(pRslv->pRslvMgr->pDnsEngine,
	dnsQuery, dnsName, bAsIs, pQbuff, &bufLen, pRslv,
	&pRslv->queryId);

// pRslv->eState = RESOLVER_STATE_TRY_A
ResolverChangeState(pRslv,eNextState);
				
				case TRANSMITTER_RESOLUTION_STATE_RESOLVED:
					//目标解析完成处理
					DestStateResolved(pTrx);
						//传输层最后完成状态处理
						TransmitterMoveToStateFinalDestResolved(pTrx,
RVSIP_TRANSMITTER_REASON_UNDEFINED,
pTrx->hMsgToSend, NULL);
							//主要查找当前已经解析出的地址类型,如当前是UDP
							//根据此类型在进行本地列表选择
	TransmitterSetInUseLocalAddrByDestAddr(pTrx);
	
	//根据目的类型更新VIA
	TransmitterUpdateViaByFinalLocalAddress(pTrx,
(pTrx->bFixVia||pTrx->bTrxCreatedVia))

//pTrx->eState更新为
// RVSIP_TRANSMITTER_STATE_FINAL_DEST_RESOLVED
//同时通知上层
TransmitterChangeState(pTrx,
RVSIP_TRANSMITTER_STATE_FINAL_DEST_RESOLVED,
RVSIP_TRANSMITTER_REASON_UNDEFINED, hMsg,NULL);
					
					//已经知道了目标地址,发送消息,该函数后面单独分析。 
					TransmitterControlSend(pTrx,bReachedFromApp);
------------------------------------------------------------------------------------------------------------------------------
TransmitterControlSend
	ProcessAndTransmit(pTrx)
		//主要查找当前已经解析出的地址类型,如当前是UDP
		//根据此类型在进行本地列表选择
		TransmitterSetInUseLocalAddrByDestAddr(pTrx)
		
		//根据目的类型更新VIA
		TransmitterUpdateViaByFinalLocalAddress(pTrx,pTrx->bFixVia);
		// pTrx->eState更新为
		// RVSIP_TRANSMITTER_STATE_READY_FOR_SENDING,同时通知事务层,事务层收
		//到此状态后,更新VIA
		TransmitterChangeState(pTrx, RVSIP_TRANSMITTER_STATE_READY_FOR_SENDING,
		RVSIP_TRANSMITTER_REASON_UNDEFINED,  pTrx->hMsgToSend, NULL);
		
		//消息编码
		PrepareSentOutboundMsg(pTrx,pTrx->hMsgToSend,NULL,0);
		
		//将编码好的消息加入到pTrx->hMsgToSendList发送列表中
		TransmitterMsgToSendListAddElement(pTrx,pTrx->hSentOutboundMsg);
		
		//编码好的消息已经完成,释放不需要使用的hMsgToSend
		RvSipMsgDestruct(pTrx->hMsgToSend);
		pTrx->hMsgToSend = NULL;
		
		//传送层发送消息
		TransmitterControlTransmitMessage(pTrx);
			//当前使用UDP进行发送
			SipTransportUdpSendMessage(pTrx->pTrxMgr->hTransportMgr,
			pTrx->pTrxMgr->hMessagePool, pTrx->hSentOutboundMsg,
			*(pTrx->localAddr.hAddrInUse), &pTrx->destAddr.addr);
			
			msg.msgType   = pTrx->eMsgType;
			msg.msgToSend = pTrx->hSentOutboundMsg;
			PostMessageSendingActiviteis(pTrx,&msg);
				//释放不使用的消息页
				TransmitterMsgToSendListRemoveElement(pTrx,hMsgPage);
				
				// pTrx->eState 更新为RVSIP_TRANSMITTER_STATE_MSG_SENT
				//同时通知事务层该变更后的状态,这个地方很重要,因为消息发送
				//完后,事务的重传就在这里,事务层处理传送层的状态改变的回调函
				//数为 TransactionTransportTrxStateChangeEv ,后面单独分析。
				TransmitterChangeState(pTrx,RVSIP_TRANSMITTER_STATE_MSG_SENT,
				RVSIP_TRANSMITTER_REASON_UNDEFINED,NULL,(void*)pSendInfo);

----------------------------------------------------------------------------------------------------------------------------
TransactionTransportTrxStateChangeEv
	switch (eState)
	case RVSIP_TRANSMITTER_STATE_MSG_SENT:
		//设置事务定时器
		TransactionTimerSetTimers(pTransc,((SipTransportSendInfo*)pExtraInfo)->msgType);
			//如果消息是代理200应符号则不需要重传
			if(msgType == SIP_TRANSPORT_MSG_PROXY_2XX_SENT &&
			pTransc->bIsProxySend2xxTimer == RV_TRUE)
				return RV_OK;
			
			//如果INVITE事务已经触发cancel,则不需要重传
			if(pTransc->eState == RVSIP_TRANSC_STATE_CLIENT_GEN_CANCELLING ||
			pTransc->eState == RVSIP_TRANSC_STATE_CLIENT_INVITE_CANCELLING)
				return RV_OK;
			
			//如果消息是第一次发送,先停止所有定时器
			if(pTransc->retransmissionsCount == 0)
				TransactionTimerReleaseAllTimers(pTransc);
			
			//临时应答消息不需要重传
			if(msgType == SIP_TRANSPORT_MSG_PROV_RESP_SENT)
				return RV_OK;
			
			switch (pTransc->eTranspType)
			case RVSIP_TRANSPORT_UDP:
				//基于UDP传输协议的事务定时器设置
				UDPTimersDecide(pTransc, msgType, &bSetMainTimer, &mainTimerInterval,
				&bSetLongReqestTimer, &longTimerInterval);
					switch(pTransc->eState)
					default:
						*bSetMainTimer = RV_FALSE;
					
					//当前的消息第一次发送,不进入此流程
					if (pTransc->retransmissionsCount != 0)
						……
					
					switch (pTransc->eState)
					case RVSIP_TRANSC_STATE_CLIENT_GEN_REQUEST_SENT:
						//标记启用长定时器,就是非INVITE事务的总超时处理时间
						//默认使用 T1 * 64
						*longTimerInterval   = 
							(pTransc->pTimers->generalRequestTimeoutTimeout);
						*bSetLongReqestTimer = RV_TRUE;
						
						//标记启用事务主定时器,就是事务一次重传的定时器,
						//默认使用T1(500ms)
						*mainTimerInterval   = (pTransc->pTimers->T1Timeout);
						*bSetMainTimer       = RV_TRUE;
					
					//消息发送次数递增,下次走重传处理流程
					pTransc->retransmissionsCount = 1;
			
			//开启事务重传定时器,定时器超时处理函数为
			// TransactionTimerHandleMainTimerTimeout ,后面单独分析此函数。
			TransactionTimerMainTimerStart(pTransc, mainTimerInterval, 
			"TransactionTimerSetTimers");
				SipCommonCoreRvTimerStartEx(&pTransc->hMainTimer,
				pTransc->pMgr->pSelect,  timerInterval, 
				TransactionTimerHandleMainTimerTimeout,
				pTransc);
			
			//开启事务总超时定时器,定时器超时处理函数为
			// TransactionTimerHandleRequestLongTimerTimeout,后面单独分析。
			SipCommonCoreRvTimerStartEx(&pTransc->hRequestLongTimer,
			pTransc->pMgr->pSelect, longTimerInterval, 
			TransactionTimerHandleRequestLongTimerTimeout, pTransc);

-------------------------------------------------------------------------------------------------------------------------------
//事务重传定时器处理
TransactionTimerHandleMainTimerTimeout
	//如果定时器已经变更或者终止,则直接返回
	if(SipCommonCoreRvTimerIgnoreExpiration(&(pTransc->hMainTimer), timerInfo) == 
	RV_TRUE)
		return RV_FALSE;
	
	//定时器停止并释放
	SipCommonCoreRvTimerExpired(&pTransc->hMainTimer);
	TransactionTimerMainTimerRelease(pTransc);
	
	switch (pTransc->eState)
	case (RVSIP_TRANSC_STATE_CLIENT_GEN_REQUEST_SENT)://假设发出去注册,没收到应答
		//进行非INVITE事务重传
		HandleMainTimerNonInviteRetransmission(pTransc);
			//信令压缩,暂不关心
			if (TransactionGetOutboundMsgCompType(pTransc) == RVSIP_COMP_SIGCOMP)
				XXX
			
			// maxRetrans = -1,默认为-1,也就是说不进行事务重传次数限制,整个事务
			//超时是靠长定时器处理回调来完成,这里的回调只负责每次的事务重传。
			maxRetrans = pTransc->pTimers->maxGeneralRequestRetransmissions;
			
			//重传处理
			TransactionTimerRetransmit(pTransc, maxRetrans, RV_TRUE);
				//没有到达重传次数上限或没有次数上限,继续重传
				if ((pTransc->retransmissionsCount < maxRetransmissions) ||
				(maxRetransmissions == -1))
					//消息重传
					TransactionTransportRetransmitMessage(pTransc);
						//主要用于信令压缩机制,当事务重传时,可以尝试使用非压缩
						//的机制再重新发送。
						SipTransmitterMatchSentOutboundMsgToNextMsgType(
						pTransc->hTrx,&bZeroRetrans);
						
						//传输层重传处理
						SipTransmitterRetransmit(pTransc->hTrx);
							//传送层控制消息发送,和之前最终消息发送是使用相同的
							//接口函数。
							TransmitterControlTransmitMessage(pTrx);
								//当前使用UDP进行发送
								SipTransportUdpSendMessage(……)
								
								//同之前消息发送的处理相同,再次重起定时器等,不
								//再分析。
								msg.msgType   = pTrx->eMsgType;
								msg.msgToSend = pTrx->hSentOutboundMsg;
								PostMessageSendingActiviteis(pTrx,&msg);

--------------------------------------------------------------------------------------------------------------------------------
//事务总超时定时器处理
TransactionTimerHandleRequestLongTimerTimeout
	//如果定时器已经变更或者终止,则直接返回
	if(SipCommonCoreRvTimerIgnoreExpiration(&(pTransc->hRequestLongTimer), timerInfo) == 
	RV_TRUE)
		return RV_FALSE;
	
	//定时器停止并释放
	SipCommonCoreRvTimerExpired(&pTransc->hRequestLongTimer);
	TransactionTimerReleaseAllTimers(pTransc);
	
	switch (pTransc->eState)
	case RVSIP_TRANSC_STATE_CLIENT_GEN_REQUEST_SENT:
		//事务层状态改变的回调处理存在,并当前消息不是CANCEL,进入此处理流程
		if ((pTransc->pEvHandlers)->pfnEvStateChanged != NULL &&
		pTransc->eMethod != SIP_TRANSACTION_METHOD_CANCEL)
			//标记本函数中不需要处理事务终止,事务终止放在
			// TransactionHandleMsgSentFailureEvent之后的流程中处理。
			enableTransactionTermination = RV_FALSE;
			
			//处理事务消息失败
			TransactionHandleMsgSentFailureEvent(pTransc,
RVSIP_TRANSC_REASON_TIME_OUT);
	//停止所有事务定时器
	TransactionTimerReleaseAllTimers(pTransc);
				
				//使用TCP机制时的相关处理,暂不关心
				SipTransmitterDetachFromConnection(pTransc->hTrx);
				TransactionDetachFromConnection(pTransc, pTransc->hActiveConn, 
				RV_TRUE);
				
				pTransc->bMsgSentFailureInQueue = RV_TRUE;
				
				//向事务队列中插入发送消息错误的事件,中间的过程处理就不描述了,
//最终构造一个内部对象事件丢给事务处理队列,
// TransportPreemptionSelectPreemptionDispatchEventsEvHandler函数负责
//处理事务事件队列,然后调用当前传入的事处回调函数
// MsgSendFailureEventHandler来执行当前的事件,
//MsgSendFailureEventHandler在下面单独分解。
				SipTransportSendStateObjectEvent(pTransc->pMgr->hTransport,
				pTransc, pTransc->transactionUniqueIdentifier, eReason, UNDEFINED,
				MsgSendFailureEventHandler, RV_TRUE, 
				TRANSC_STATE_CLIENT_MSG_SEND_FAILURE_STR, 
				TRANSC_OBJECT_NAME_STR);
	
	//上面已经标记本函数不需要处理事务终止,不进这里流程。
	if (enableTransactionTermination == RV_TRUE)
		TransactionTerminate(RVSIP_TRANSC_REASON_TIME_OUT, pTransc);

---------------------------------------------------------------------------------------------------------------------------------
MsgSendFailureEventHandler
	//IMS安全联盟和信令压缩处理暂不关心
	TransactionSecAgreeMsgSendFailure(pTransc);
	DetachFromInternalSigcompCompartment(pTransc);
	
	// pTransc->eState = RVSIP_TRANSC_STATE_CLIENT_MSG_SEND_FAILURE
	//调用当前事务的事件处理回调pfnEvStateChanged,当前这个注册事务的拥有者是事务
	//客户端对象,所以事件处理的回调函数为 TranscClientTranscEvStateChanged
	TransactionChangeState(pTransc, RVSIP_TRANSC_STATE_CLIENT_MSG_SEND_FAILURE,
	(RvSipTransactionStateChangeReason)reason);

------------------------------------------------------------------------------------------------------------------------------
TranscClientTranscEvStateChanged
	switch (eNewState)
	case RVSIP_TRANSC_STATE_CLIENT_MSG_SEND_FAILURE:
		//处理消息发送失败
		// eReason = RVSIP_TRANSC_REASON_TIME_OUT
		HandleTranscStateMsgSendFailure(pTranscClient,hTransaction,eReason);
			switch(eStateReason)
			case RVSIP_TRANSC_REASON_TIME_OUT:
				eReason = SIP_TRANSC_CLIENT_REASON_TRANSACTION_TIMEOUT;
			
			TranscClientChangeState(SIP_TRANSC_CLIENT_STATE_MSG_SEND_FAILURE,
			eReason,pTranscClient, 0);
				//状态更新
				pTranscClient->eState = eNewState;
				
				//事务客户端对象通知它的拥有者,状态已经改变,当前事务客户端
				//对象是注册客户端对象,处理的回调函数为
				// RegClientTranscClientEvStateChanged
				TranscClientCallbackStateChangeEv(eNewState, eReason, pTranscClient, 
				responseCode);

--------------------------------------------------------------------------------------------------------------------------
RegClientTranscClientEvStateChanged
	// RVSIP_REG_CLIENT_STATE_MSG_SEND_FAILURE
	eRegClientConvertedState = RegClientConvertTranscClientState(eNewState);
	
	// RVSIP_REG_CLIENT_REASON_TRANSACTION_TIMEOUT
	eRegClientConvertedReason = RegClientConvertTranscClientReason(eReason, 
	responseCode);
	
	RegClientChangeState(eRegClientConvertedState, eRegClientConvertedReason, pRegClient);
		//状态更新
		pRegClient->eState = eNewState;
		
		//通知应用层注册发送超时,由应用层最终结束此注册事务。
		RegClientCallbackStateChangeEv(eNewState, eReason, pRegClient);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值