//发送注册包
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);
RvSIP发送注册包及重传流程
最新推荐文章于 2019-06-05 19:50:04 发布