1003 lines
38 KiB
C
1003 lines
38 KiB
C
#include "./include/sip_pub.h"
|
|
#include "./include/sip.h"
|
|
#include "./include/sip_const.h"
|
|
#include "./include/sip_struct.h"
|
|
#include "./include/sip_ext.h"
|
|
#include "./include/sip_transport.h"
|
|
#include "./include/sip_msg.h"
|
|
|
|
int sip_create_trans_branch(WORD transId, SIP_GEN_PARA *branch)
|
|
{
|
|
branch->paraName = SIP_API_PNAME_BRANCH;
|
|
branch->paraType = SIP_API_PTYPE_STRING;
|
|
sprintf(branch->para.paraStr, "z9hG4bk-%d-%ld", SIP_BRANCH_BASE_TRANS_ID + transId, time(NULL));
|
|
|
|
return 0;
|
|
}
|
|
|
|
DWORD sip_min(DWORD A, DWORD B)
|
|
{
|
|
if (A <= B)
|
|
return A;
|
|
|
|
return B;
|
|
}
|
|
|
|
void sip_trans_init(WORD trans_id)
|
|
{
|
|
memset((BYTE *)&sipTrans[trans_id], 0, sizeof(SIP_TRANSACTION));
|
|
}
|
|
|
|
int sip_request_uri_match(SIP_URI *uriFirst, SIP_URI *uriSecond)
|
|
{
|
|
if (strcmp(uriFirst->userName, uriSecond->userName) != 0)
|
|
return -1;
|
|
|
|
if (strcmp(uriFirst->host.addr.domain, uriSecond->host.addr.domain) != 0)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sip_call_id_match(SIP_HDR_CALL_ID *callIdFirst, SIP_HDR_CALL_ID *callIdSecond)
|
|
{
|
|
if (strcmp(callIdFirst->value, callIdSecond->value) !=0)
|
|
return -1;
|
|
|
|
if (strcmp(callIdFirst->host, callIdSecond->host) != 0)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sip_top_via_match(SIP_HDR_VIA *viaFirst, SIP_HDR_VIA *viaSecond)
|
|
{
|
|
if (strcmp(viaFirst->url.domain, viaSecond->url.domain) != 0)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
WORD sip_request_match_server_trans(SIP_API_STRUCT *recvMsg)
|
|
{
|
|
WORD transId;
|
|
char *branchRecvd, *branchCreated;
|
|
char *sentByRecvd, *sentByCreated;
|
|
char methodRecvd, methodCreated;
|
|
SIP_MSG *sipMsgRecvd;
|
|
SIP_CR_MSG *sipMsgCreated;
|
|
SIP_URI *requestUriRecvd, *requestUriCreated;
|
|
char *toTagRecvd, *toTagCreated;//, *toTagResponse;//improve
|
|
char *fromTagRecvd, *fromTagCreated;
|
|
SIP_HDR_CALL_ID *callIdRecvd, *callIdCreated;
|
|
SIP_HDR_CSEQ *cseqRecvd, *cseqCreated;
|
|
SIP_HDR_VIA *viaRecvd, *viaCreated;
|
|
|
|
sipMsgRecvd = &recvMsg->sipApiMsg.sipMsg;
|
|
methodRecvd = sipMsgRecvd->sipStartLine.sipMethod;
|
|
viaRecvd = &sipMsgRecvd->sipHdrVias.vias[1];
|
|
branchRecvd = viaRecvd->params.para[0].para.paraStr;
|
|
|
|
if (strncmp(branchRecvd, "z9hG4bK", 7) == 0)
|
|
{ // RFC 3261
|
|
sentByRecvd = sipMsgRecvd->sipHdrVias.vias[1].url.domain;
|
|
|
|
for (transId = 0; transId < SIP_MAX_NUM_OF_TRANS; transId++)
|
|
{
|
|
if ((sipTrans[transId].flag != 1) ||
|
|
(sipTrans[transId].client != SIP_TRANS_SERVER))
|
|
continue;
|
|
|
|
sipMsgCreated = &sipTrans[transId].crMsg;
|
|
branchCreated = sipMsgCreated->sipCrHdrVia.params.para[0].para.paraStr;
|
|
sentByCreated = sipMsgCreated->sipCrHdrVia.url.domain;
|
|
methodCreated = sipMsgCreated->sipCrStartLine.sipMethod;
|
|
|
|
if ((strcmp(branchRecvd, branchCreated) == 0) &&
|
|
(strcmp(sentByRecvd, sentByCreated) == 0))//
|
|
{
|
|
if (methodRecvd == SIP_METHOD_ACK)
|
|
return transId;
|
|
else if (methodRecvd == methodCreated)
|
|
return transId;
|
|
}
|
|
}
|
|
}
|
|
|
|
// RFC 2543
|
|
|
|
requestUriRecvd = &sipMsgRecvd->sipStartLine.requestUri;
|
|
toTagRecvd = sipMsgRecvd->sipHdrTo.params.para[0].para.paraStr;
|
|
fromTagRecvd = sipMsgRecvd->sipHdrFrom.params.para[0].para.paraStr;
|
|
callIdRecvd = &sipMsgRecvd->sipHdrCallId;
|
|
cseqRecvd = &sipMsgRecvd->sipHdrCseq;
|
|
|
|
for (transId = 0; transId < SIP_MAX_NUM_OF_TRANS; transId++)
|
|
{
|
|
if ((sipTrans[transId].flag != 1) ||
|
|
(sipTrans[transId].client != SIP_TRANS_SERVER))
|
|
continue;
|
|
|
|
sipMsgCreated = &sipTrans[transId].crMsg;
|
|
requestUriCreated = &sipMsgCreated->sipCrStartLine.requestUri;
|
|
toTagCreated = sipMsgCreated->sipCrHdrTo.params.para[0].para.paraStr;
|
|
// toTagResponse = sipTrans[transId].sdMsg.sipApiMsg.sipMsg.sipHdrTo.params.para[0].para.paraStr;//improve
|
|
fromTagCreated = sipMsgCreated->sipCrHdrFrom.params.para[0].para.paraStr;
|
|
callIdCreated = &sipMsgCreated->sipCrHdrCallId;
|
|
cseqCreated = &sipMsgCreated->sipCrHdrCseq;
|
|
viaCreated = &sipMsgCreated->sipCrHdrVia;
|
|
|
|
if ((sip_request_uri_match(requestUriRecvd, requestUriCreated) == 0) &&
|
|
(strcmp(fromTagRecvd, fromTagCreated) == 0) &&
|
|
(sip_call_id_match(callIdRecvd, callIdCreated) == 0) &&
|
|
(cseqRecvd->value == cseqCreated->value) &&
|
|
(sip_top_via_match(viaRecvd, viaCreated) == 0))
|
|
{
|
|
if (methodRecvd == SIP_METHOD_ACK)
|
|
{
|
|
if (strcmp(toTagRecvd, toTagCreated) == 0)//if (strcmp(toTagRecvd, toTagResponse) == 0)//improve
|
|
return transId;
|
|
}
|
|
else
|
|
{
|
|
if ((strcmp(toTagRecvd, toTagCreated) == 0) &&
|
|
(cseqRecvd->method == cseqCreated->method))
|
|
return transId;
|
|
}
|
|
}
|
|
}
|
|
|
|
return SIP_MAX_NUM_OF_TRANS;
|
|
}
|
|
|
|
WORD sip_response_match_client_trans(SIP_API_STRUCT *recvMsg)
|
|
{
|
|
char *first;
|
|
char *second;
|
|
char tmp[8] = "";
|
|
char *branchRecvd, *branchCreated;
|
|
BYTE methodRecvd, methodCreated;
|
|
WORD transId;
|
|
|
|
branchRecvd = recvMsg->sipApiMsg.sipMsg.sipHdrVias.vias[1].params.para[0].para.paraStr;
|
|
|
|
first = strchr(branchRecvd, '-');
|
|
if (first == NULL)
|
|
return SIP_MAX_NUM_OF_TRANS;
|
|
|
|
second = strchr(first + 1, '-');
|
|
if (second == NULL)
|
|
return SIP_MAX_NUM_OF_TRANS;
|
|
|
|
if ((second - first - 1) != SIP_BRANCH_BASE_TRANS_ID_LEN)
|
|
return SIP_MAX_NUM_OF_TRANS;
|
|
strncpy(tmp, first + 1, SIP_BRANCH_BASE_TRANS_ID_LEN);
|
|
|
|
transId = atol(tmp);
|
|
transId = transId - SIP_BRANCH_BASE_TRANS_ID;
|
|
if (transId >= SIP_MAX_NUM_OF_TRANS)
|
|
return SIP_MAX_NUM_OF_TRANS;
|
|
|
|
methodRecvd = recvMsg->sipApiMsg.sipMsg.sipHdrCseq.method;
|
|
|
|
methodCreated = sipTrans[transId].crMsg.sipCrHdrCseq.method;
|
|
branchCreated = sipTrans[transId].crMsg.sipCrHdrVia.params.para[0].para.paraStr;
|
|
|
|
if ((strcmp(branchRecvd, branchCreated) == 0) &&
|
|
(methodRecvd == methodCreated))
|
|
return transId;
|
|
else
|
|
{
|
|
for (transId = 0; transId < SIP_MAX_NUM_OF_TRANS; transId++)
|
|
{
|
|
if ((sipTrans[transId].flag != 1) ||
|
|
(sipTrans[transId].client != SIP_TRANS_CLIENT))
|
|
continue;
|
|
|
|
methodCreated = sipTrans[transId].crMsg.sipCrHdrCseq.method;
|
|
branchCreated = sipTrans[transId].crMsg.sipCrHdrVia.params.para[0].para.paraStr;
|
|
|
|
if ((strcmp(branchRecvd, branchCreated) == 0) &&
|
|
(methodRecvd == methodCreated))
|
|
return transId;
|
|
}
|
|
}
|
|
|
|
return SIP_MAX_NUM_OF_TRANS;
|
|
}
|
|
|
|
int sip_trans_srv_non_inv_proc(WORD transId)
|
|
{
|
|
SIP_TRANSACTION *sipTransPtr;
|
|
WORD sdCmd;
|
|
WORD rvCmd;
|
|
SIP_USER *sipUser;
|
|
|
|
sipTransPtr = &sipTrans[transId];
|
|
sdCmd = sipTransPtr->sdCmd;
|
|
rvCmd = sipTransPtr->rvCmd;
|
|
sipUser = &sipUsers.sipUsers[sipTransPtr->userIndex].sipUser;
|
|
|
|
switch (sipTransPtr->state)
|
|
{
|
|
case SIP_TRANS_STATE_IDLE:
|
|
// Request received, pass to TU
|
|
sipTransPtr->state = SIP_TRANS_STATE_TRYING;
|
|
sipTransPtr->timer = (18 * SIP_TIMER_T4);
|
|
return sip_trans_srv_non_inv_proc(transId);
|
|
case SIP_TRANS_STATE_TRYING:
|
|
if (sdCmd != SIP_COMMAND_IDLE)
|
|
{
|
|
sipTransPtr->sdCmd = SIP_COMMAND_IDLE;
|
|
if ((sdCmd >= 100) && (sdCmd <= 199))
|
|
{ // If 1XX from TU, send response
|
|
sip_transport_send_trans_msg(&sipTransPtr->transSdMsg);
|
|
// sip_transport_send_msg(&sipTransPtr->sdMsg);//improve
|
|
sipTransPtr->state = SIP_TRANS_STATE_PROCEEDING;
|
|
sipTransPtr->timer = (18 * SIP_TIMER_T4);
|
|
}
|
|
else if ((sdCmd >= 200) && (sdCmd <= 699))
|
|
{ // If 200-699 from TU, send response
|
|
sip_transport_send_trans_msg(&sipTransPtr->transSdMsg);
|
|
// sip_transport_send_msg(&sipTransPtr->sdMsg);//improve
|
|
sipTransPtr->state = SIP_TRANS_STATE_COMPLETED;
|
|
sipTransPtr->timer = SIP_TIMER_J;
|
|
}
|
|
}
|
|
|
|
if ((SIP_TRANS_STATE_TRYING == sipTransPtr->state) && (sipTransPtr->timer > 0))
|
|
{
|
|
if (--sipTransPtr->timer == 0)
|
|
{
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
case SIP_TRANS_STATE_PROCEEDING:
|
|
if (sdCmd != SIP_COMMAND_IDLE)
|
|
{
|
|
sipTransPtr->sdCmd = SIP_COMMAND_IDLE;
|
|
if ((sdCmd >= 100) && (sdCmd <= 199))
|
|
{ // If 1XX from TU, send response
|
|
sip_transport_send_trans_msg(&sipTransPtr->transSdMsg);
|
|
// sip_transport_send_msg(&sipTransPtr->sdMsg);//improve
|
|
}
|
|
else if ((sdCmd >= 200) && (sdCmd <= 699))
|
|
{ // If 200-699 from TU, send response
|
|
sip_transport_send_trans_msg(&sipTransPtr->transSdMsg);
|
|
// sip_transport_send_msg(&sipTransPtr->sdMsg);//improve
|
|
sipTransPtr->state = SIP_TRANS_STATE_COMPLETED;
|
|
sipTransPtr->timer = SIP_TIMER_J;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (rvCmd != SIP_COMMAND_IDLE)
|
|
{
|
|
sipTransPtr->rvCmd = SIP_COMMAND_IDLE;
|
|
if (rvCmd == SIP_TRANSPORT_ERROR)
|
|
{ // If transport error, inform TU
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
else
|
|
{ // If request, send response
|
|
sip_transport_send_trans_msg(&sipTransPtr->transSdMsg);
|
|
// sip_transport_send_msg(&sipTransPtr->sdMsg);//improve
|
|
}
|
|
}
|
|
|
|
if ((SIP_TRANS_STATE_PROCEEDING == sipTransPtr->state) && (sipTransPtr->timer > 0))
|
|
{
|
|
if (--sipTransPtr->timer == 0)
|
|
{
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
break;
|
|
case SIP_TRANS_STATE_COMPLETED:
|
|
if (rvCmd != SIP_COMMAND_IDLE)
|
|
{
|
|
sipTransPtr->rvCmd = SIP_COMMAND_IDLE;
|
|
// Request, send response
|
|
if (rvCmd == SIP_TRANSPORT_ERROR)
|
|
{ // If transport error, inform TU
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
else
|
|
{ // If request, send response
|
|
sip_transport_send_trans_msg(&sipTransPtr->transSdMsg);
|
|
// sip_transport_send_msg(&sipTransPtr->sdMsg);//improve
|
|
}
|
|
}
|
|
|
|
if (sipTransPtr->timer > 0)
|
|
sipTransPtr->timer--;
|
|
|
|
if (sipTransPtr->timer == 0)
|
|
{ // if timer J fires
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
break;
|
|
default:
|
|
sipTransPtr->state = SIP_TRANS_STATE_IDLE;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sip_trans_srv_inv_proc(WORD transId)
|
|
{
|
|
SIP_TRANSACTION *sipTransPtr;
|
|
WORD sdCmd;
|
|
WORD rvCmd;
|
|
SIP_USER *sipUser;
|
|
|
|
sipTransPtr = &sipTrans[transId];
|
|
sdCmd = sipTransPtr->sdCmd;
|
|
rvCmd = sipTransPtr->rvCmd;
|
|
sipUser = &sipUsers.sipUsers[sipTransPtr->userIndex].sipUser;
|
|
|
|
switch (sipTransPtr->state)
|
|
{
|
|
case SIP_TRANS_STATE_IDLE:
|
|
// INVITE received, pass to TU
|
|
sipTransPtr->timer2= SIP_TIMER_200MS;
|
|
sipTransPtr->timer = (18 * SIP_TIMER_T4);
|
|
sipTransPtr->state = SIP_TRANS_STATE_PROCEEDING;
|
|
return sip_trans_srv_inv_proc(transId);
|
|
break;
|
|
case SIP_TRANS_STATE_PROCEEDING:
|
|
if (sdCmd != SIP_COMMAND_IDLE)
|
|
{
|
|
sipTransPtr->sdCmd = SIP_COMMAND_IDLE;
|
|
if ((sdCmd >= 101) && (sdCmd <= 199))
|
|
{ // if 101-199 from TU, send response
|
|
sip_transport_send_trans_msg(&sipTransPtr->transSdMsg);
|
|
// sip_transport_send_msg(&sipTransPtr->sdMsg);//improve
|
|
sipTransPtr->timer2 = 0;
|
|
}
|
|
else if ((sdCmd >= 200) && (sdCmd <= 299))
|
|
{ // if 2xx from TU, send response
|
|
sip_transport_send_trans_msg(&sipTransPtr->transSdMsg);
|
|
// sip_transport_send_msg(&sipTransPtr->sdMsg);//improve
|
|
sipTransPtr->timer2 = 0;
|
|
sipTransPtr->timer = 0;
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
else if ((sdCmd >= 300) && (sdCmd <= 699))
|
|
{ // if 300-699 from TU, send response
|
|
sip_transport_send_trans_msg(&sipTransPtr->transSdMsg);
|
|
// sip_transport_send_msg(&sipTransPtr->sdMsg);//improve
|
|
sipTransPtr->state = SIP_TRANS_STATE_COMPLETED;
|
|
sipTransPtr->timer2 = SIP_TIMER_G;
|
|
sipTransPtr->timer = SIP_TIMER_H;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (rvCmd != SIP_COMMAND_IDLE)
|
|
{
|
|
sipTransPtr->rvCmd = SIP_COMMAND_IDLE;
|
|
if (rvCmd == SIP_TRANSPORT_ERROR)
|
|
{ // If transport error, inform TU
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
else if (rvCmd == SIP_METHOD_INVITE)
|
|
{ // If INVITE, send response
|
|
sip_transport_send_trans_msg(&sipTransPtr->transSdMsg);
|
|
// sip_transport_send_msg(&sipTransPtr->sdMsg);//improve
|
|
}
|
|
}
|
|
|
|
if ((SIP_TRANS_STATE_PROCEEDING == sipTransPtr->state) && (sipTransPtr->timer2 > 0))
|
|
{
|
|
if (--sipTransPtr->timer2== 0)
|
|
sip_send_100(&sipTransPtr->crMsg, sipTransPtr);
|
|
}
|
|
|
|
if ((SIP_TRANS_STATE_PROCEEDING == sipTransPtr->state) && (sipTransPtr->timer > 0))
|
|
{
|
|
if (--sipTransPtr->timer == 0)
|
|
{
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
case SIP_TRANS_STATE_COMPLETED:
|
|
if (rvCmd != SIP_COMMAND_IDLE)
|
|
{
|
|
sipTransPtr->rvCmd = SIP_COMMAND_IDLE;
|
|
if (rvCmd == SIP_TRANSPORT_ERROR)
|
|
{ // If transport error, inform TU
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
else if (rvCmd == SIP_METHOD_ACK)
|
|
{ // If ACK
|
|
sipTransPtr->state = SIP_TRANS_STATE_CONFIRMED;
|
|
sipTransPtr->timer = SIP_TIMER_I;
|
|
return 0;
|
|
}
|
|
else if (rvCmd == SIP_METHOD_INVITE)
|
|
{ // If INVITE, send response
|
|
sip_transport_send_trans_msg(&sipTransPtr->transSdMsg);
|
|
// sip_transport_send_msg(&sipTransPtr->sdMsg);//improve
|
|
}
|
|
}
|
|
|
|
if ((SIP_TRANS_STATE_COMPLETED == sipTransPtr->state) && (sipTransPtr->timer2 > 0))
|
|
{
|
|
if (--sipTransPtr->timer2 == 0)
|
|
{// If timer G fires, send response
|
|
sip_transport_send_trans_msg(&sipTransPtr->transSdMsg);
|
|
// sip_transport_send_msg(&sipTransPtr->sdMsg);//improve
|
|
sipTransPtr->retransTimes++;
|
|
sipTransPtr->timer2 = sip_min((1 << sipTransPtr->retransTimes) * SIP_TIMER_E_INITIAL, SIP_TIMER_T2);
|
|
}
|
|
}
|
|
|
|
if ((SIP_TRANS_STATE_COMPLETED == sipTransPtr->state) && (sipTransPtr->timer > 0))
|
|
{
|
|
if (--sipTransPtr->timer == 0)
|
|
{ // If timer H fires
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
case SIP_TRANS_STATE_CONFIRMED:
|
|
if (sipTransPtr->timer > 0)
|
|
sipTransPtr->timer--;
|
|
|
|
if (sipTransPtr->timer == 0)
|
|
{ // If timer I fires
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
break;
|
|
default:
|
|
sipTransPtr->state = SIP_TRANS_STATE_IDLE;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sip_trans_clt_non_inv_proc(WORD transId)
|
|
{
|
|
SIP_TRANSACTION *sipTransPtr;
|
|
SIP_USER *sipUser;
|
|
WORD sdCmd;
|
|
WORD rvCmd;
|
|
|
|
sipTransPtr = &sipTrans[transId];
|
|
sdCmd = sipTransPtr->sdCmd;
|
|
rvCmd = sipTransPtr->rvCmd;
|
|
sipUser = &sipUsers.sipUsers[sipTransPtr->userIndex].sipUser;
|
|
|
|
switch (sipTransPtr->state)
|
|
{
|
|
case SIP_TRANS_STATE_IDLE:
|
|
if (sdCmd != SIP_COMMAND_IDLE)
|
|
{
|
|
sipTransPtr->sdCmd = SIP_COMMAND_IDLE;
|
|
if (sdCmd != SIP_METHOD_INVITE)
|
|
{ // Request from TU, send request
|
|
// sip_fill_cr_msg(&sipTransPtr->crMsg, &sipTransPtr->sdMsg);//improve
|
|
sip_transport_send_trans_msg(&sipTransPtr->transSdMsg);
|
|
// sip_transport_send_msg(&sipTransPtr->sdMsg);//improve
|
|
|
|
if (sdCmd == SIP_METHOD_ACK)
|
|
{
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
sipTransPtr->timer = SIP_TIMER_F;
|
|
sipTransPtr->timer2 = SIP_TIMER_E_INITIAL;
|
|
sipTransPtr->retransTimes = 0;
|
|
sipTransPtr->state = SIP_TRANS_STATE_TRYING;
|
|
}
|
|
}
|
|
else
|
|
return 1;
|
|
}
|
|
break;
|
|
case SIP_TRANS_STATE_TRYING:
|
|
if (rvCmd != SIP_COMMAND_IDLE)
|
|
{
|
|
sipTransPtr->rvCmd = SIP_COMMAND_IDLE;
|
|
if ((rvCmd >= 200) & (rvCmd <= 699))
|
|
{ // 200-699, resp. to TU
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_COMPLETED;
|
|
sipTransPtr->timer = SIP_TIMER_K;
|
|
return 0;
|
|
}
|
|
else if (rvCmd == SIP_TRANSPORT_ERROR)
|
|
{ // Transport error, inform TU
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
else if ((rvCmd >= 100) & (rvCmd <= 199))
|
|
{ // 1xx, 1xx to TU
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_PROCEEDING;
|
|
sipTransPtr->timer = SIP_TIMER_F;
|
|
// sipTransPtr->timer2 = SIP_TIMER_T2;//??
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if ((SIP_TRANS_STATE_TRYING == sipTransPtr->state) && (sipTransPtr->timer2 > 0))
|
|
{
|
|
if (--sipTransPtr->timer2 == 0)
|
|
{// Timer E fires, send request
|
|
sip_transport_send_trans_msg(&sipTransPtr->transSdMsg);
|
|
// sip_transport_send_msg(&sipTransPtr->sdMsg);//improve
|
|
sipTransPtr->retransTimes++;
|
|
sipTransPtr->timer2 = sip_min((1 << sipTransPtr->retransTimes) * SIP_TIMER_E_INITIAL, SIP_TIMER_T2);
|
|
}
|
|
}
|
|
|
|
if ((SIP_TRANS_STATE_TRYING == sipTransPtr->state) && (sipTransPtr->timer > 0))
|
|
{
|
|
if (--sipTransPtr->timer == 0)
|
|
{// If timer F fires, inform TU
|
|
/* memset(&sipToUpMsg, 0, sizeof(SIP_API_STRUCT));
|
|
memcpy(&sipToUpMsg, &sipTransPtr->sdMsg, sizeof(SIP_API_STRUCT));
|
|
sipToUpMsg.sipApiType = SIP_API_RES_MSG;
|
|
sipToUpMsg.sipApiMsg.sipMsg.sipStartLine.statusCode = SIP_TRANSACTION_TIMEOUT;
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipToUpMsg);
|
|
*///improve
|
|
memset(&sipToUpMsg, 0, sizeof(SIP_API_STRUCT));
|
|
sip_fill_msg_with_cr(&sipToUpMsg.sipApiMsg.sipMsg, &sipTransPtr->crMsg);
|
|
sipToUpMsg.sipApiType = SIP_API_RES_MSG;
|
|
sipToUpMsg.sipApiMsg.sipMsg.sipStartLine.statusCode = SIP_TRANSACTION_TIMEOUT;
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipToUpMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
case SIP_TRANS_STATE_PROCEEDING:
|
|
if (rvCmd != SIP_COMMAND_IDLE)
|
|
{
|
|
sipTransPtr->rvCmd = SIP_COMMAND_IDLE;
|
|
if ((rvCmd >= 200) & (rvCmd <= 699))
|
|
{ // 100-699, resp. to TU
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_COMPLETED;
|
|
sipTransPtr->timer = SIP_TIMER_K;
|
|
return 0;
|
|
}
|
|
else if (rvCmd == SIP_TRANSPORT_ERROR)
|
|
{ // Transport error, inform TU
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
else if ((rvCmd >= 100) & (rvCmd <= 199))
|
|
{ // 1xx, 1xx to TU
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
}
|
|
}
|
|
|
|
if ((SIP_TRANS_STATE_PROCEEDING == sipTransPtr->state) && (sipTransPtr->timer2 > 0))
|
|
{
|
|
if (--sipTransPtr->timer2 == 0)
|
|
{// Timer E fires, send request
|
|
sip_transport_send_trans_msg(&sipTransPtr->transSdMsg);
|
|
// sip_transport_send_msg(&sipTransPtr->sdMsg);//improve
|
|
sipTransPtr->retransTimes++;
|
|
sipTransPtr->timer2 = SIP_TIMER_T2;
|
|
}
|
|
}
|
|
|
|
if ((SIP_TRANS_STATE_PROCEEDING == sipTransPtr->state) && (sipTransPtr->timer > 0))
|
|
{
|
|
if (--sipTransPtr->timer == 0)
|
|
{// If timer F fires, inform TU
|
|
/* memset(&sipToUpMsg, 0, sizeof(SIP_API_STRUCT));
|
|
memcpy(&sipToUpMsg, &sipTransPtr->sdMsg, sizeof(SIP_API_STRUCT));
|
|
sipToUpMsg.sipApiType = SIP_API_RES_MSG;
|
|
sipToUpMsg.sipApiMsg.sipMsg.sipStartLine.statusCode = SIP_TRANSACTION_TIMEOUT;
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipToUpMsg);
|
|
*///improve
|
|
memset(&sipToUpMsg, 0, sizeof(SIP_API_STRUCT));
|
|
sip_fill_msg_with_cr(&sipToUpMsg.sipApiMsg.sipMsg, &sipTransPtr->crMsg);
|
|
sipToUpMsg.sipApiType = SIP_API_RES_MSG;
|
|
sipToUpMsg.sipApiMsg.sipMsg.sipStartLine.statusCode = SIP_TRANSACTION_TIMEOUT;
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipToUpMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
case SIP_TRANS_STATE_COMPLETED:
|
|
if (sipTransPtr->timer > 0)
|
|
sipTransPtr->timer--;
|
|
|
|
if (sipTransPtr->timer == 0)
|
|
{ // if timer K fires
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
break;
|
|
default:
|
|
sipTransPtr->state = SIP_TRANS_STATE_IDLE;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sip_trans_clt_inv_proc(WORD transId)
|
|
{
|
|
SIP_TRANSACTION *sipTransPtr;
|
|
SIP_USER *sipUser;
|
|
WORD sdCmd;
|
|
WORD rvCmd;
|
|
|
|
sipTransPtr = &sipTrans[transId];
|
|
sdCmd = sipTransPtr->sdCmd;
|
|
rvCmd = sipTransPtr->rvCmd;
|
|
sipUser = &sipUsers.sipUsers[sipTransPtr->userIndex].sipUser;
|
|
|
|
switch (sipTransPtr->state)
|
|
{
|
|
case SIP_TRANS_STATE_IDLE:
|
|
if (sdCmd != SIP_COMMAND_IDLE)
|
|
{
|
|
sipTransPtr->sdCmd = SIP_COMMAND_IDLE;
|
|
if ((sdCmd == SIP_METHOD_INVITE) || (sdCmd == SIP_METHOD_RE_INVITE))
|
|
{ // INVITE from TU, INVITE sent
|
|
// sip_fill_cr_msg(&sipTransPtr->crMsg, &sipTransPtr->sdMsg);//improve
|
|
sip_transport_send_trans_msg(&sipTransPtr->transSdMsg);
|
|
// sip_transport_send_msg(&sipTransPtr->sdMsg);//improve
|
|
sipTransPtr->timer = SIP_TIMER_B;
|
|
sipTransPtr->timer2 = SIP_TIMER_A;
|
|
sipTransPtr->state = SIP_TRANS_STATE_CALLING;
|
|
}
|
|
else
|
|
return 1;
|
|
}
|
|
break;
|
|
case SIP_TRANS_STATE_CALLING:
|
|
if (rvCmd != SIP_COMMAND_IDLE)
|
|
{
|
|
sipTransPtr->rvCmd = SIP_COMMAND_IDLE;
|
|
if ((rvCmd >= 300) & (rvCmd <= 699))
|
|
{ // 300-699, ACK sent, resp. to TU
|
|
sip_send_ack(&sipRecvMsg, sipTransPtr);
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_COMPLETED;
|
|
sipTransPtr->timer = SIP_TIMER_D;
|
|
sipTransPtr->timer2 = 0;
|
|
return 0;
|
|
}
|
|
else if ((rvCmd >= 200) & (rvCmd <= 299))
|
|
{ // 2xx, 2xx to TU
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
sipTransPtr->timer2 = 0;
|
|
return 1;
|
|
}
|
|
else if ((rvCmd >= 100) & (rvCmd <= 199))
|
|
{ // 1xx, 1xx to TU
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_PROCEEDING;
|
|
sipTransPtr->timer2 = 0;
|
|
sipTransPtr->timer = (7 * SIP_TIMER_T4);
|
|
return 0;
|
|
}
|
|
else if (rvCmd == SIP_TRANSPORT_ERROR)
|
|
{ // transport error, inform TU
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
sipTransPtr->timer2 = 0;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (sipTransPtr->timer2 > 0)
|
|
{
|
|
if (--sipTransPtr->timer2 == 0)
|
|
{ // If timer A fires, reset A, INVITE sent
|
|
sip_transport_send_trans_msg(&sipTransPtr->transSdMsg);
|
|
// sip_transport_send_msg(&sipTransPtr->sdMsg);//improve
|
|
sipTransPtr->retransTimes++;
|
|
sipTransPtr->timer2 = sip_min((1 << sipTransPtr->retransTimes) * SIP_TIMER_E_INITIAL, SIP_TIMER_B);
|
|
}
|
|
}
|
|
|
|
if ((SIP_TRANS_STATE_CALLING == sipTransPtr->state) && (sipTransPtr->timer > 0))
|
|
{
|
|
if (--sipTransPtr->timer == 0)
|
|
{// If timer B fires, inform TU
|
|
/* memset(&sipToUpMsg, 0, sizeof(SIP_API_STRUCT));
|
|
memcpy(&sipToUpMsg, &sipTransPtr->sdMsg, sizeof(SIP_API_STRUCT));
|
|
sipToUpMsg.sipApiType = SIP_API_RES_MSG;
|
|
sipToUpMsg.sipApiMsg.sipMsg.sipStartLine.statusCode = SIP_TRANSACTION_TIMEOUT;
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipToUpMsg);
|
|
*///improve
|
|
memset(&sipToUpMsg, 0, sizeof(SIP_API_STRUCT));
|
|
sip_fill_msg_with_cr(&sipToUpMsg.sipApiMsg.sipMsg, &sipTransPtr->crMsg);
|
|
sipToUpMsg.sipApiType = SIP_API_RES_MSG;
|
|
sipToUpMsg.sipApiMsg.sipMsg.sipStartLine.statusCode = SIP_TRANSACTION_TIMEOUT;
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipToUpMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
case SIP_TRANS_STATE_PROCEEDING:
|
|
if (rvCmd != SIP_COMMAND_IDLE)
|
|
{
|
|
sipTransPtr->rvCmd = SIP_COMMAND_IDLE;
|
|
if ((rvCmd >= 300) & (rvCmd <= 699))
|
|
{ // 300-699, ACK sent, resp. to TU
|
|
sip_send_ack(&sipRecvMsg, sipTransPtr);
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_COMPLETED;
|
|
sipTransPtr->timer = SIP_TIMER_D;
|
|
}
|
|
else if ((rvCmd >= 200) & (rvCmd <= 299))
|
|
{ // 2xx, 2xx to TU
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
else if ((rvCmd >= 100) & (rvCmd <= 199))
|
|
{ // 1xx, 1xx to TU
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
}
|
|
}
|
|
|
|
if ((SIP_TRANS_STATE_PROCEEDING == sipTransPtr->state) && (sipTransPtr->timer > 0))
|
|
{
|
|
if (-- sipTransPtr->timer == 0)
|
|
{
|
|
/* memset(&sipToUpMsg, 0, sizeof(SIP_API_STRUCT));
|
|
memcpy(&sipToUpMsg, &sipTransPtr->sdMsg, sizeof(SIP_API_STRUCT));
|
|
sipToUpMsg.sipApiType = SIP_API_RES_MSG;
|
|
sipToUpMsg.sipApiMsg.sipMsg.sipStartLine.statusCode = SIP_TRANSACTION_TIMEOUT;
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipToUpMsg);
|
|
*///improve
|
|
memset(&sipToUpMsg, 0, sizeof(SIP_API_STRUCT));
|
|
sip_fill_msg_with_cr(&sipToUpMsg.sipApiMsg.sipMsg, &sipTransPtr->crMsg);
|
|
sipToUpMsg.sipApiType = SIP_API_RES_MSG;
|
|
sipToUpMsg.sipApiMsg.sipMsg.sipStartLine.statusCode = SIP_TRANSACTION_TIMEOUT;
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipToUpMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
case SIP_TRANS_STATE_COMPLETED:
|
|
if (rvCmd != SIP_COMMAND_IDLE)
|
|
{
|
|
sipTransPtr->rvCmd = SIP_COMMAND_IDLE;
|
|
if ((rvCmd >= 300) & (rvCmd <= 699))
|
|
{ // 300-699, ACK sent
|
|
sip_send_ack(&sipRecvMsg, sipTransPtr);
|
|
}
|
|
else if (rvCmd == SIP_TRANSPORT_ERROR)
|
|
{ // if transport error, inform TU
|
|
sipUser->recv_proc(transId, sipTransPtr->upPort, SIP_TRANSACTION_LAYER, &sipRecvMsg);
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (sipTransPtr->timer > 0)
|
|
sipTransPtr->timer--;
|
|
|
|
if (sipTransPtr->timer == 0)
|
|
{ // if timer D fires
|
|
sipTransPtr->state = SIP_TRANS_STATE_TERMINATED;
|
|
return 1;
|
|
}
|
|
break;
|
|
default:
|
|
sipTransPtr->state = SIP_TRANS_STATE_IDLE;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void sip_transaction_proc(WORD transid)
|
|
{
|
|
switch (sipTrans[transid].mainState)
|
|
{
|
|
case SIP_TRANS_MAIN_STATE_INIT:
|
|
sip_trans_init(transid);
|
|
break;
|
|
case SIP_TRANS_MAIN_STATE_SVR_NON_INV:
|
|
switch (sip_trans_srv_non_inv_proc(transid))
|
|
{
|
|
case 0:
|
|
break;
|
|
case 1:
|
|
sipTrans[transid].mainState = SIP_TRANS_MAIN_STATE_INIT;
|
|
sip_transaction_proc(transid);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case SIP_TRANS_MAIN_STATE_SVR_INV:
|
|
switch (sip_trans_srv_inv_proc(transid))
|
|
{
|
|
case 0:
|
|
break;
|
|
case 1:
|
|
sipTrans[transid].mainState = SIP_TRANS_MAIN_STATE_INIT;
|
|
sip_transaction_proc(transid);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case SIP_TRANS_MAIN_STATE_CLT_NON_INV:
|
|
switch (sip_trans_clt_non_inv_proc(transid))
|
|
{
|
|
case 0:
|
|
break;
|
|
case 1:
|
|
sipTrans[transid].mainState = SIP_TRANS_MAIN_STATE_INIT;
|
|
sip_transaction_proc(transid);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case SIP_TRANS_MAIN_STATE_CLT_INV:
|
|
switch (sip_trans_clt_inv_proc(transid))
|
|
{
|
|
case 0:
|
|
break;
|
|
case 1:
|
|
sipTrans[transid].mainState = SIP_TRANS_MAIN_STATE_INIT;
|
|
sip_transaction_proc(transid);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
sipTrans[transid].mainState = SIP_TRANS_MAIN_STATE_INIT;
|
|
break;
|
|
}
|
|
}
|
|
|
|
int sip_msg_transport_to_transaction(SIP_API_STRUCT *recvMsg, WORD transId)
|
|
{
|
|
SIP_TRANSACTION *sipTransPtr = &sipTrans[transId];
|
|
|
|
if (recvMsg->sipApiType == SIP_API_TYPE_RESPONSE)
|
|
sipTransPtr->rvCmd = recvMsg->sipApiMsg.sipMsg.sipStartLine.statusCode;
|
|
else if (recvMsg->sipApiType == SIP_API_TYPE_REQUEST)
|
|
sipTransPtr->rvCmd = recvMsg->sipApiMsg.sipMsg.sipStartLine.sipMethod;
|
|
|
|
sip_transaction_proc(transId);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sip_set_trans_send_cmd(SIP_TRANSACTION *trans, SIP_API_STRUCT *sipApiMsg)
|
|
{
|
|
SIP_START_LINE *startLine;
|
|
|
|
startLine = &sipApiMsg->sipApiMsg.sipMsg.sipStartLine;
|
|
|
|
if (sipApiMsg->sipApiType == SIP_API_REQ_MSG)
|
|
trans->sdCmd = startLine->sipMethod;
|
|
else if (sipApiMsg->sipApiType == SIP_API_RES_MSG)
|
|
trans->sdCmd = startLine->statusCode;
|
|
else
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sip_create_transaction(BYTE client, BYTE method, BYTE userIndex, WORD upPort, SIP_API_STRUCT *msg)
|
|
{
|
|
WORD i;
|
|
WORD transId = sipTransHead;
|
|
SIP_TRANSACTION *trans;
|
|
|
|
|
|
if (msg == NULL)
|
|
{
|
|
// sip_trans_init(transId);
|
|
return -1;
|
|
}//improve
|
|
|
|
if (transId>= SIP_MAX_NUM_OF_TRANS)
|
|
{
|
|
transId = 0;
|
|
}
|
|
|
|
for (i = 0; i < SIP_MAX_NUM_OF_TRANS; i++)
|
|
{
|
|
trans = &sipTrans[transId];
|
|
|
|
if (trans->flag != 0)
|
|
{
|
|
if (++transId >= SIP_MAX_NUM_OF_TRANS)
|
|
{
|
|
transId = 0;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
sip_trans_init(transId);
|
|
trans->flag = 1;
|
|
trans->client = client;
|
|
trans->method = method;
|
|
trans->userIndex = userIndex;
|
|
trans->upPort = upPort;
|
|
/* if (client == SIP_TRANS_SERVER)
|
|
{
|
|
if (msg == NULL)
|
|
{
|
|
sip_trans_init(transId);
|
|
return -1;
|
|
}
|
|
|
|
sip_fill_cr_msg(&trans->crMsg, msg);
|
|
}
|
|
*///improve
|
|
sipTransHead = (transId+ 1) & SIP_MAX_NUM_OF_TRANS_1;
|
|
|
|
if (client == SIP_TRANS_SERVER)
|
|
{
|
|
if (method == SIP_TRANS_NON_INVITE)
|
|
trans->mainState = SIP_TRANS_MAIN_STATE_SVR_NON_INV;
|
|
else
|
|
trans->mainState = SIP_TRANS_MAIN_STATE_SVR_INV;
|
|
}
|
|
else
|
|
{
|
|
if (method == SIP_TRANS_NON_INVITE)
|
|
trans->mainState = SIP_TRANS_MAIN_STATE_CLT_NON_INV;
|
|
else
|
|
trans->mainState = SIP_TRANS_MAIN_STATE_CLT_INV;
|
|
|
|
if (msg->sipApiMsg.sipMsg.sipStartLine.sipMethod != SIP_METHOD_CANCEL)
|
|
{
|
|
sip_create_trans_branch(transId, &msg->sipApiMsg.sipMsg.sipHdrVias.vias[msg->sipApiMsg.sipMsg.sipHdrVias.head].params.para[0]);
|
|
msg->sipApiMsg.sipMsg.sipHdrVias.vias[msg->sipApiMsg.sipMsg.sipHdrVias.head].params.paraNum++;
|
|
}
|
|
}
|
|
trans->state = SIP_TRANS_STATE_IDLE;
|
|
|
|
sip_fill_cr_msg(&trans->crMsg, msg);//improve
|
|
|
|
return transId;
|
|
}
|
|
}
|
|
|
|
return SIP_MAX_NUM_OF_TRANS;
|
|
}
|