#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; }