📄 call.cpp
字号:
strlen(dest), 0); if(rc < 0) { CStat::instance()->computeStat(CStat::E_CALL_FAILED); CStat::instance()->computeStat(CStat::E_FAILED_CMD_NOT_SENT); delete_call(id); return(-1); } return(0); } else return(-1);}int call::sendCmdBuffer(char* cmd){ char * dest; char delimitor[2]; int rc; delimitor[0]=27; delimitor[1]=0; dest = cmd ; strcat(dest, delimitor); rc = send(twinSippSocket, dest, strlen(dest), 0); if(rc < 0) { CStat::instance()->computeStat(CStat::E_CALL_FAILED); CStat::instance()->computeStat(CStat::E_FAILED_CMD_NOT_SENT); delete_call(id); return(-1); } return(0);}#endifchar* call::createSendingMessage(char * src, int P_index){ static char msg_buffer[SIPP_MAX_MSG_SIZE+2]; if(src != NULL) { char * dest = msg_buffer; char * key; while(*src) { if(*src == '[') { char keyword [65]; src++; key = strchr(src, ']'); if((!key) || ((key - src) > 64) || (!(key - src))){ ERROR("Syntax error or invalid [keyword] in scenario"); } memcpy(keyword, src, key - src); keyword[key - src] = 0; src = key + 1; if(!strcmp(keyword, "remote_ip")) { dest += sprintf(dest, "%s", remote_ip); } else if(!strcmp(keyword, "remote_port")) { dest += sprintf(dest, "%u", remote_port); } else if(!strcmp(keyword, "transport")) { dest += sprintf(dest, "%s", TRANSPORT_TO_STRING(transport)); } else if(!strcmp(keyword, "local_ip")) { dest += sprintf(dest, "%s", local_ip); } else if(!strcmp(keyword, "local_port")) { if((transport == T_UDP) && (multisocket)) { dest += sprintf(dest, "%u", call_port); } else { dest += sprintf(dest, "%u", local_port); } } else if(!strcmp(keyword, "media_ip")) { dest += sprintf(dest, "%15s", media_ip); } else if(!strcmp(keyword, "media_port")) { dest += sprintf(dest, "%5u", media_port); } else if(!strcmp(keyword, "call_number")) { dest += sprintf(dest, "%lu", number); } else if(!strcmp(keyword, "call_id")) { dest += sprintf(dest, "%s", id); } else if(!strcmp(keyword, "pid")) { dest += sprintf(dest, "%u", pid); } else if(!strcmp(keyword, "service")) { dest += sprintf(dest, "%s", service); } else if(!strncmp(keyword, "field", 5)) { getFieldFromInputFile(keyword, m_localLineNumber, dest); } else if(!strcmp(keyword, "peer_tag_param")) { if(peer_tag && strlen(peer_tag)) { dest += sprintf(dest, ";tag=%s", peer_tag); } } else if(strstr(keyword, "$")) { int varId = atoi(keyword+1); if(varId < SCEN_VARIABLE_SIZE) { if(M_callVariableTable[varId] != NULL) { if(M_callVariableTable[varId]->isSet()) { dest += sprintf(dest, "%s", M_callVariableTable[varId]-> getMatchingValue()); // WARNING_P1("VARIABLE --%s--", M_callVariableTable[varId]->getMatchingValue()); } else { dest += sprintf(dest, "%s", ""); } } } } else if(strstr(keyword, "last_")) { char * last_header = get_last_header(keyword+5); if(last_header) { dest += sprintf(dest, "%s", last_header); } else { /* Jump to the end of line in scenario if nothing * to insert in place of this header. */ while((*src) && (*src != '\n')) { src++; } if(*src == '\n') { src++; } } } else if(strstr(keyword, "routes")) { if (dialog_route_set) { dest += sprintf(dest, "Route: %s", dialog_route_set); } } else { ERROR_P1("Unsupported keyword '%s' in xml scenario file", keyword); } } else if (*src == '\n') { *dest++ = '\r'; *dest++ = *src++; } else { *dest++ = *src++; } } *dest = 0; // Remove all \r, \n but 1 at the end of a message to send int len = strlen(msg_buffer); while ( (msg_buffer[len-1] == '\n') && (msg_buffer[len-2] == '\r') && (msg_buffer[len-3] == '\n') && (msg_buffer[len-4] == '\r')) { msg_buffer[len-2] = 0; len -= 2; } int L_flag_crlf = 0 ; // don't need add crlf int L_content_length = 0; if(P_index == -1 ) { L_flag_crlf = 1 ; // Add crlf } else if(P_index >= 0 ) { message::ContentLengthFlag L_flag_content = scenario[P_index] -> content_length_flag ; switch (L_flag_content) { case message::ContentLengthValueZero : L_flag_crlf = 1; break ; case message::ContentLengthValueNoZero : // the msg contains content-length field and his value is greater than 0 break ; default : // the msg does not contain content-length field // control the crlf L_content_length = xp_get_content_length(msg_buffer) ; if( L_content_length == 0) { L_flag_crlf = 1; } else if (L_content_length == -1 ) { // Error to treat? } break; } } if(L_flag_crlf) { // Add crlf msg_buffer[len] ='\r'; msg_buffer[len+1] ='\n'; msg_buffer[len+2] =0; } } else { ERROR("Unsupported 'send' message in scenario"); } return(msg_buffer);}#ifdef __3PCC__bool call::process_twinSippCom(char * msg){ char * ptr; int search_index; bool found = false; T_ActionResult actionResult; if (checkInternalCmd(msg) == false) { for(search_index = msg_index; search_index < scenario_len; search_index++) { if(scenario[search_index] -> M_type != MSG_TYPE_RECVCMD) { if(scenario[search_index] -> optional) { continue; } /* The received message is different from the expected one */ return rejectCall(); } else { found = true; break; } } if (found) { scenario[search_index]->M_nbCmdRecv ++; // variable treatment // WARNING_P1("---RECVD_TWIN_CMD---%s---", msg); // Remove \r, \n at the end of a received command // (necessary for transport, to be removed for usage) while ( (msg[strlen(msg)-1] == '\n') && (msg[strlen(msg)-2] == '\r') ) { msg[strlen(msg)-2] = 0; } // WARNING_P1("---RECVD_TWIN_CMD AFTER---%s---", msg); actionResult = executeAction(msg, search_index); if(actionResult != call::E_AR_NO_ERROR) { // Store last action result if it is an error // and go on with the scenario call::last_action_result = actionResult; } } else { return rejectCall(); } return(next()); } else { return (false); }}bool call::checkInternalCmd(char * cmd){ char * L_ptr1, * L_ptr2, L_backup; char *cmd_name ; L_ptr1 = strstr(cmd, "internal-cmd:"); if (!L_ptr1) {return (false);} L_ptr1 += 13 ; while((*L_ptr1 == ' ') || (*L_ptr1 == '\t')) { L_ptr1++; } if (!(*L_ptr1)) {return (false);} L_ptr2 = L_ptr1; while((*L_ptr2) && (*L_ptr2 != ' ') && (*L_ptr2 != '\t') && (*L_ptr2 != '\r') && (*L_ptr2 != '\n')) { L_ptr2 ++; } if(!*L_ptr2) { return (false); } L_backup = *L_ptr2; *L_ptr2 = 0; if (strcmp(L_ptr1, "abort_call") == 0) { *L_ptr2 = L_backup; abortCall(); return (true); } *L_ptr2 = L_backup; return (false);}#endifbool call::process_incomming(char * msg){ int reply_code; static char request[65]; unsigned long cookie; char * ptr; int search_index; bool found = false; T_ActionResult actionResult; int L_case = 0 ;#define MATCHES_SCENARIO(index) \ (((reply_code) && \ ((scenario[index] -> recv_response) == reply_code)) || \ ((scenario[index] -> recv_request) && \ (!strcmp(scenario[index] -> recv_request, \ request)))) if((transport == T_UDP) && (retrans_enabled)) { /* Detects retransmissions from peer and retransmit the * message which was sent just after this one was received */ cookie = hash(msg); if(recv_retrans_hash == cookie) { int status; if(lost(scenario[recv_retrans_recv_index] -> lost)) { TRACE_MSG((s, "%s message (retrans) lost (recv).", TRANSPORT_TO_STRING(transport))); if(comp_state) { comp_free(&comp_state); } scenario[recv_retrans_recv_index] -> nb_lost++; return true; } send_scene(recv_retrans_send_index, &status); if(status == 0) { scenario[recv_retrans_recv_index] -> nb_recv_retrans++; scenario[recv_retrans_send_index] -> nb_sent_retrans++; } else if(status < -1) { return false; } return true; } if(last_recv_hash == cookie) { /* This one has already been received, but not processed * yet => (has not triggered something yet) so we can discard. * * This case appears when the UAS has send a 200 but not received * a ACK yet. Thus, the UAS retransmit the 200 (invite transaction) * until it receives a ACK. In this case, it nevers sends the 200 * from the BYE, until it has reveiced the previous 200. Thus, * the UAC retransmit the BYE, and this BYE is considered as an * unexpected. * * This case can also appear in case of message duplication by * the network. This should not be considered as an unexpected. */ return true; } } /* Catch peer tag if necessary */ if((!strlen(peer_tag)) && (ptr = get_peer_tag(msg))) { if(strlen(ptr) > (MAX_HEADER_LEN - 1)) { ERROR("Peer tag too long. Change MAX_TAG_LEN and recompile sipp"); } strcpy(peer_tag, ptr); } /* Is it a response ? */ if((msg[0] == 'S') && (msg[1] == 'I') && (msg[2] == 'P') && (msg[3] == '/') && (msg[4] == '2') && (msg[5] == '.') && (msg[6] == '0') ) { reply_code = get_reply_code(msg); if(!reply_code) { return process_unexpected(msg); } request[0]=0; } else if(ptr = strchr(msg, ' ')) { if((ptr - msg) < 64) { memcpy(request, msg, ptr - msg); request[ptr - msg] = 0; // Check if we received an ACK => call established if (strcmp(request,"ACK")==0) { call_established=true; } reply_code = 0; } else { ERROR_P1("SIP method too long in received message '%s'", msg); } } else { ERROR_P1("Invalid sip message received '%s'", msg); } /* Try to find it in the expected non mandatory responses * until the first mandatory response in the scenario */ for(search_index = msg_index; search_index < scenario_len; search_index++) { if(!MATCHES_SCENARIO(search_index)) { if(scenario[search_index] -> optional) { continue; } /* The received message is different for the expected one */ break; } found = true; /* TODO : this is a little buggy: If a 100 trying from an INVITE * is delayed by the network until the BYE is sent, it may * stop BYE transmission erroneously, if the BYE also expects * a 100 trying. */ break; } /* Try to find it in the old non-mandatory receptions */ if(!found) { for(search_index = msg_index - 1; search_index >= 0; search_index--) { if(MATCHES_SCENARIO(search_index) && ((scenario[search_index] -> optional))) { found = true; break; } } } // Variable treatment if (found) { // WARNING_P1("---EXECUTE_ACTION_ON_MSG---%s---", msg); actionResult = executeAction(msg, search_index); if(actionResult != call::E_AR_NO_ERROR) { // Store last action result if it is an error // and go on with the scenario call::last_action_result = actionResult; } } /* Not found */ if(!found) { if ((L_case = checkAutomaticResponseMode(request)) == 0) { return process_unexpected(msg); } else { automaticResponseMode(L_case, msg); return false ; // call aborted by automatic response mode } } /* Simulate loss of messages */ if(lost(scenario[search_index] -> lost)) { TRACE_MSG((s, "%s message lost (recv).", TRANSPORT_TO_STRING(transport))); if(comp_state) { comp_free(&comp_state); } scenario[search_index] -> nb_lost++; return true; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -