⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 call.cpp

📁 学习sip协议的好工具
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/* *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * *  Author : Richard GAYRAUD - 04 Nov 2003 *           From Hewlett Packard Company. *           Shriram Natarajan [snatarajan@longboard.com] */#include "sipp.hpp"#include <iterator>#include <algorithm>#include <fstream>#include <iostream>call_map calls;/************** Call map and management routines **************/call_map * get_calls(){  return & calls;}static unsigned int next_number = 1;call * add_call(char * call_id){  call * new_call;  new_call = new call(call_id);  if(!new_call) {    ERROR("Memory Overflow");  }  calls[std::string(call_id)] = new_call;  if(!next_number) { next_number ++; }  new_call -> number = next_number;  /* Vital counters update */  next_number++;  open_calls++;  /* Statistics update */  calls_since_last_rate_change++;  total_calls ++;  if(open_calls > open_calls_peak) {     open_calls_peak = open_calls;    open_calls_peak_time = clock_tick / 1000;  }  return new_call;}call * add_call(){  static char call_id[MAX_HEADER_LEN];    call * new_call;    if(!next_number) { next_number ++; }    sprintf(call_id,           "%u.%u.%s@sipp.call.id",           next_number, pid, local_ip);    return add_call(call_id);}call * get_call(char * call_id){  call * call_ptr;    call_ptr = calls[std::string(call_id)];  if(!call_ptr) {    calls.erase(std::string(call_id));  }    return call_ptr;}void delete_call(char * call_id){  call * call_ptr = calls[std::string(call_id)];  if(!calls.erase(std::string(call_id))) {    ERROR("Call not erased from map");  }   if(call_ptr) {    delete call_ptr;    open_calls--;  } else {    ERROR("Call not found");  }}/******* Very simple hash for retransmission detection  *******/unsigned long hash(char * msg) {  unsigned long rv = 0;  int len = strlen(msg);  int index = 0;    if (len > 4) {    rv  = msg[0] + msg[1] + msg[2] + msg[3];  }    if (len > 12) {    rv += msg[9] + msg[10] + msg[11] + msg[12];  }  rv <<= 8;  rv += len;  rv <<= 16;    for (index = 0; index < len; index ++) {    rv += + msg[index] * index;  }    return rv;}/******************* Call class implementation ****************/call::InputFileUsage call::m_usage   = call::InputFileSequentialOrder;int                  call::m_counter = 0;call::call(char * p_id) {  memset(this, 0, sizeof(call));  id = strdup(p_id);  start_time = clock_tick;  call_established=false ;  count_in_stats=true ;  ack_is_pending=false ;  // initialising the CallVariable with the Scenario variable  for(int i=0; i<SCEN_VARIABLE_SIZE; i++)     {      if(scenVariableTable[i] != NULL) {        M_callVariableTable[i] = new CCallVariable();        if (M_callVariableTable[i] == NULL) {          ERROR ("call variable allocation failed");        }      } else {        M_callVariableTable[i] = NULL;      }    }  // If not updated by a message we use the start time   // information to compute rtd information  start_time_rtd  = clock_tick;   // by default, last action result is NO_ERROR  last_action_result = call::E_AR_NO_ERROR;  if (InputFileRandomOrder == m_usage) {      m_localLineNumber = rand() % numLinesInFile;  } else {      m_localLineNumber = m_counter++;      if (m_counter >= numLinesInFile) {          m_counter = 0;      }  }  peer_tag[0] = '\0';}call::~call(){  deleted += 1;    if(comp_state) { comp_free(&comp_state); }  if(count_in_stats) {    CStat::instance()->computeStat(CStat::E_ADD_CALL_DURATION,                                    clock_tick - start_time);  }  call_duration_sum += clock_tick - start_time;  call_duration_nb++;    if(pollset_index) {    pollset_remove(pollset_index);    shutdown(call_socket, SHUT_RDWR);    close(call_socket);  }  /* Deletion of the call variable */   for(int i=0; i<SCEN_VARIABLE_SIZE; i++) {    if(M_callVariableTable[i] != NULL) {      delete M_callVariableTable[i] ;      M_callVariableTable[i] = NULL;    }  }  if(id) { free(id); }  if(last_recv_msg) { free(last_recv_msg); }  if(last_send_msg) { free(last_send_msg); }  if(dialog_route_set) {       free(dialog_route_set);  }  call_established= false ;} void call::connect_socket_if_needed(){  if(call_socket) return;  if(!multisocket) return;  if(transport == T_UDP) {    struct sockaddr_in saddr;    sipp_socklen_t len = sizeof(saddr);        if(toolMode != MODE_CLIENT) return;    if((call_socket = socket(AF_INET,                              SOCK_DGRAM,                             0)) == -1) {      ERROR_NO("Unable to get an UDP socket");    }        saddr.sin_family      = AF_INET;    saddr.sin_addr.s_addr = INADDR_ANY;    saddr.sin_port        = 0;        if(bind(call_socket,            (sockaddr *)(void *)&saddr,            sizeof(saddr))) {      ERROR_NO("Unable to bind UDP socket");    }        getsockname(call_socket,                 (sockaddr *)(void *)&saddr,                &len);#ifdef __hpux    call_port = saddr.sin_port;#else    call_port = ntohs((short)saddr.sin_port);#endif  } else { /* TCP */    if((call_socket= socket(AF_INET,                             SOCK_STREAM,                            0))== -1) {      ERROR_NO("Unable to get a TCP socket");    }        sipp_customize_socket(call_socket);    if(connect(call_socket,               (struct sockaddr *)(void *)&remote_sockaddr,               sizeof(remote_sockaddr))) {            if(errno == EINVAL){        /* This occurs sometime on HPUX but is not a true INVAL */        ERROR("Unable to connect a TCP socket, remote peer error");      } else {        ERROR_NO("Unable to connect a TCP socket");      }    }  }  /* Asks to receive incoming messages */  pollset_index = pollset_add(this, call_socket);}bool lost(int percent){  static int inited = 0;  if(!lose_packets) return false;  if(!percent) return false;  if(!inited) {    srand((unsigned int) time(NULL));    inited = 1;  }  if((rand() % 100) < percent) {    return true;  } else {    return false;  }}int call::send_raw(char * msg, int index) {  void ** state;  int sock;  int rc;  TRACE_MSG((s, "-----------------------------------------------\n"             "%s message send:\n\n%s\n",             TRANSPORT_TO_STRING(transport),             msg));    if(lost(scenario[index] -> lost)) {    TRACE_MSG((s, "%s message lost (send).", TRANSPORT_TO_STRING(transport)));        if(comp_state) { comp_free(&comp_state); }    scenario[index] -> nb_lost++;    return 0;  }    if(call_socket) {    state = &comp_state;    sock = call_socket;  } else {    state = &monosocket_comp_state;    if(transport == T_UDP) {      sock = main_socket;    } else {      sock = tcp_multiplex;    }  }  rc = send_message(sock, state, msg);  if(rc == -1) return -1;  if(rc < -1) {    CStat::instance()->computeStat(CStat::E_CALL_FAILED);    CStat::instance()->computeStat(CStat::E_FAILED_CANNOT_SEND_MSG);    delete_call(id);  }    return rc; /* OK */}int call::sendBuffer(char * msg) {  void ** state;  int sock;  int rc;  TRACE_MSG((s, "-----------------------------------------------\n"             "%s message send:\n\n%s\n",             TRANSPORT_TO_STRING(transport),             msg));    if(call_socket) {    state = &comp_state;    sock = call_socket;  } else {    state = &monosocket_comp_state;    if(transport == T_UDP) {      sock = main_socket;    } else {      sock = tcp_multiplex;    }  }  rc = send_message(sock, state, msg);  if(rc == -1) return -1;  if(rc < -1) {    CStat::instance()->computeStat(CStat::E_CALL_FAILED);    CStat::instance()->computeStat(CStat::E_FAILED_CANNOT_SEND_MSG);    delete_call(id);  }    return rc; /* OK */}char * call::compute_cseq(char * src){  char *dest;  static char cseq[MAX_HEADER_LEN * 10];  if(dest = strstr(src, "CSeq")) {    /* If we find a CSeq in incoming msg */    char * last_header = get_last_header(dest+4);    if(last_header) {      int i;      /* Extract the integer value of the last CSeq */      last_header = strstr(last_header, ":");      last_header++;      while(isspace(*last_header)) last_header++;      sscanf(last_header,"%d", &i);      /* Add 1 to the last CSeq value */      sprintf(cseq, "%s%d",  "CSeq: ", (i+1));    } else {      sprintf(cseq, "%s",  "CSeq: 2");    }    return cseq;  } else {    return NULL;  }}char * call::get_last_header(char * name){  static char last_header[MAX_HEADER_LEN * 10];  char * src, *dest, *ptr;    if((!last_recv_msg) || (!strlen(last_recv_msg))) {    return NULL;  }  src = last_recv_msg;  dest = last_header;  while(src = strstr(src, name)) {    ptr = strchr(src, '\n');        /* Multiline headers always begin with a tab or a space     * on the subsequent lines */    while((ptr) &&          ((*(ptr+1) == ' ' ) ||           (*(ptr+1) == '\t')    )) {      ptr = strchr(ptr + 1, '\n');     }    if(ptr) { *ptr = 0; }    // Add \r\n when several Via header are present (AgM)     if (dest != last_header) {      dest += sprintf(dest, "\r\n");    }    dest += sprintf(dest, "%s", src);    if(ptr) { *ptr = '\n'; }        src++;  }    if(dest == last_header) {    return NULL;  }  *(dest--) = 0;  /* Remove trailing whitespaces, tabs, and CRs */  while ((dest > last_header) &&          ((*dest == ' ') || (*dest == '\r')|| (*dest == '\t'))) {    *(dest--) = 0;  }  /* remove enclosed CRs in multilines */  while(ptr = strchr(last_header, '\r')) {    /* Use strlen(ptr) to include trailing zero */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -