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

📄 call.cpp

📁 学习sip协议的好工具
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    memmove(ptr, ptr+1, strlen(ptr));  }  return last_header;}char * call::get_header_content(char* message, char * name){  /* non reentrant. consider accepting char buffer as param */  static char last_header[MAX_HEADER_LEN * 10];  char * src, *dest, *ptr;  /* returns empty string in case of error */  memset(last_header, 0, sizeof(last_header));  if((!message) || (!strlen(message))) {    return last_header;  }  src = message;  dest = last_header;    /* for safety's sake */  if (NULL == name || NULL == strrchr(name, ':')) {      return last_header;  }  while(src = strstr(src, name)) {      /* just want the header's content */      src += strlen(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 "," when several headers are present    if (dest != last_header) {      dest += sprintf(dest, ",");    }    dest += sprintf(dest, "%s", src);    if(ptr) { *ptr = '\n'; }        src++;  }    if(dest == last_header) {    return last_header;  }  *(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 */    memmove(ptr, ptr+1, strlen(ptr));  }  return last_header;}char * call::send_scene(int index, int *send_status){  static char msg_buffer[SIPP_MAX_MSG_SIZE];#define MAX_MSG_NAME_SIZE 30  static char msg_name[MAX_MSG_NAME_SIZE];  char *L_ptr1 ;  char *L_ptr2 ;  /* Socket port must be known before string substitution */  connect_socket_if_needed();    if(scenario[index] -> send_scheme) {    char * dest;    dest = createSendingMessage(scenario[index] -> send_scheme, index);    strcpy(msg_buffer, dest);    if (dest) {      L_ptr1=msg_name ;      L_ptr2=msg_buffer ;      while ((*L_ptr2 != ' ') && (*L_ptr2 != '\n') && (*L_ptr2 != '\t'))  {        *L_ptr1 = *L_ptr2;        L_ptr1 ++;        L_ptr2 ++;      }      *L_ptr1 = '\0' ;    }    if (strcmp(msg_name,"ACK") == 0) {      call_established = true ;      ack_is_pending = false ;    }    if(send_status) {      *send_status =         send_raw(msg_buffer, index);    } else {      send_raw(msg_buffer, index);    }  } else {    ERROR("Unsupported 'send' message in scenario");  }  return msg_buffer;}bool call::next(){  msg_index++;  if(msg_index >= scenario_len) {    // Call end -> was it successful?    if(call::last_action_result != call::E_AR_NO_ERROR) {      switch(call::last_action_result) {        case call::E_AR_REGEXP_DOESNT_MATCH:          CStat::instance()->computeStat(CStat::E_CALL_FAILED);          CStat::instance()->computeStat(CStat::E_FAILED_REGEXP_DOESNT_MATCH);          break;        case call::E_AR_HDR_NOT_FOUND:          CStat::instance()->computeStat(CStat::E_CALL_FAILED);          CStat::instance()->computeStat(CStat::E_FAILED_REGEXP_HDR_NOT_FOUND);          break;      }    } else {      CStat::instance()->computeStat(CStat::E_CALL_SUCCESSFULLY_ENDED);    }    delete_call(id);    return false;  }  return run();}bool call::run(){  if(msg_index >= scenario_len) {    ERROR_P3("Scenario overrun for call %s (%08x) (index = %d)\n",              id, this, msg_index);  }  /* Manages retransmissions or delete if max retrans reached */  if(next_retrans && (next_retrans < clock_tick)) {    nb_retrans++;        if(nb_retrans > UDP_MAX_RETRANS) {      scenario[last_send_index] -> nb_timeout ++;      TRACE_TIMEOUT((s, "Timeout for call id: %s\n", id));      CStat::instance()->computeStat(CStat::E_CALL_FAILED);      CStat::instance()->computeStat(CStat::E_FAILED_MAX_UDP_RETRANS);      delete_call(id);      return false;    } else {      unsigned int delay = scenario[last_send_index] -> retrans_delay;      unsigned int pow = nb_retrans;      while(pow--) {        delay *= 2;      }      if(send_raw(last_send_msg, last_send_index) < -1) {        return false;      }      scenario[last_send_index] -> nb_sent_retrans++;      next_retrans = clock_tick + delay;    }  }  if(paused_until) {    /* Process a pending pause instruction until delay expiration */    if(paused_until > clock_tick) {      return true;    } else {      paused_until = 0;      return next();    }  } else if(scenario[msg_index] -> pause) {    /* Starts a pause instruction */    if((scenario[msg_index] -> pause) &&       ((scenario[msg_index] -> pause) == -1)) {      paused_until = clock_tick + duration;    } else {      paused_until = clock_tick + scenario[msg_index] -> pause;    }    return run(); /* In case delay is 0 */      } #ifdef __3PCC__  else if(scenario[msg_index] -> M_type == MSG_TYPE_SENDCMD) {    int send_status;    if(next_retrans) {      return true;    }    send_status = sendCmdMessage(msg_index);    if(send_status != 0) { /* Send error */      return false; /* call deleted */    }    scenario[msg_index] -> M_nbCmdSent++;    next_retrans = 0;    return(next());  }#endif  else if(scenario[msg_index] -> send_scheme) {    char * msg_snd;    int send_status;    /* Do not send a new message until the previous one which had     * retransmission enabled is acknowledged */    if(next_retrans) {      return true;    }    /* If this message can be used to compute RTD, do it now */    if(!rtd_done) {      if(scenario[msg_index] -> start_rtd) {        start_time_rtd = clock_tick;      }        if(scenario[msg_index] -> stop_rtd) {        rtd_sum += clock_tick - start_time_rtd;        CStat::instance()->computeStat(CStat::E_ADD_RESPONSE_TIME_DURATION,                                           clock_tick - start_time_rtd);        rtd_nb ++;        rtd_done = true;      }    }      msg_snd = send_scene(msg_index, &send_status);    if(send_status == -1) { /* Would Block on TCP */      return true; /* No step, nothing done, retry later */    }    if(send_status <-1) { /* Send error */      return false; /* call deleted */    }        last_send_index = msg_index;    last_send_msg = (char *) realloc(last_send_msg, strlen(msg_snd) + 1);    strcpy(last_send_msg, msg_snd);    if(last_recv_hash) {      /* We are sending just after msg reception. There is a great       * chance that we will be asked to retransmit this message */      recv_retrans_hash       = last_recv_hash;      recv_retrans_recv_index = last_recv_index;      recv_retrans_send_index = msg_index;          /* Prevent from detecting the cause relation between send and recv        * in the next valid send */      last_recv_hash = 0;    }    /* Update retransmission information */    if(scenario[msg_index] -> retrans_delay) {      if((transport == T_UDP) && (retrans_enabled)) {        next_retrans = clock_tick + scenario[msg_index] -> retrans_delay;        nb_retrans = 0;      }    } else {      next_retrans = 0;    }        /* Update scenario statistics */    scenario[msg_index] -> nb_sent++;    return next();  }  return true;}bool call::process_unexpected(char * msg){  int search_index;  static int first = 1;  int res ;    scenario[msg_index] -> nb_unexp++;    if (scenario[msg_index] -> recv_request) {    WARNING_P3("Unexpected message for Call-ID '%s': while expecting '%s', received '%s' ",                id, scenario[msg_index] -> recv_request, msg);  } else {    WARNING_P3("Unexpected message for Call-ID '%s': while expecting '%d' response, received '%s' ",                 id, scenario[msg_index] -> recv_response, msg);  }    TRACE_MSG((s, "-----------------------------------------------\n"             "Unexpected %s message received:\n\n%s\n",             TRANSPORT_TO_STRING(transport),             msg));  #ifdef __3PCC__  // if twin socket call => reset the other part here   if (twinSippSocket && (msg_index > 0)) {    //WARNING_P2("call-ID '%s', internal-cmd: abort_call %s",id, "");    res = sendCmdBuffer      (createSendingMessage((char*)"call-id: [call_id]\ninternal-cmd: abort_call\n", -1));  }#endif /* __3PCC__ */  // usage of last_ keywords => for call aborting  last_recv_msg = (char *) realloc(last_recv_msg, strlen(msg) + 1);  strcpy(last_recv_msg, msg);  return (abortCall());}bool call::abortCall(){  int res ;  if ((toolMode != MODE_SERVER) && (msg_index > 0)) {    if (call_established == false) {      char * src = last_recv_msg ;      char * dest   ;      char   L_msg_buffer[SIPP_MAX_MSG_SIZE];      L_msg_buffer[0] = '\0';      char * L_param = L_msg_buffer;      // Answer unexpected errors (4XX, 5XX and beyond) with an ACK       // Contributed by F. Tarek Rogers      if(get_reply_code(src) > 400) {       sendBuffer(createSendingMessage(         (char*)"ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"           "Via: SIP/2.0/[transport] [local_ip]:[local_port]\n"           "From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]\n"           "To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"           "Call-ID: [call_id]\n"           "Cseq: 1 ACK\n"           "Contact: sip:sipp@[local_ip]:[local_port]\n"           "Max-Forwards: 70\n"           "Subject: Performance Test\n"           "Content-Length: 0\n\n"         , -1));      } else {        /* Call is not established and the reply is not a 4XX, 5XX */        if (ack_is_pending == true) {          /* If an ACK is expected from the other side, send it           * and send a BYE afterwards                           */          ack_is_pending = false;          /* Send an ACK */          strcpy(L_param, "ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n");          sprintf(L_param, "%s%s", L_param, "[last_Via:]\n");          sprintf(L_param, "%s%s", L_param, "[last_From:]\n");          sprintf(L_param, "%s%s", L_param, "[last_To:]\n");          sprintf(L_param, "%s%s",  L_param, "[last_Call-ID:]\n");          /* The CSeq of an ACK relating to an INVITE must be the same as  */          /* the one from the INVITE.                                      */          /* Let's simplify this by putting 1 (no support for re-invite in */          /* 3PCC?)                                                        */          /* FIXME: store CSeq from last INVITE and re-use it              */          sprintf(L_param, "%sCSeq: 1 ACK\n", L_param);          sprintf(L_param, "%s%s", L_param, "Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n");          sprintf(L_param, "%s%s", L_param,  "Content-Length: 0\n");          res = sendBuffer(createSendingMessage((char*)(L_param),-1));                    /* Send the BYE */          strcpy(L_param, "BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n");          sprintf(L_param, "%s%s", L_param, "[last_Via:]\n");          sprintf(L_param, "%s%s", L_param, "[last_From:]\n");          sprintf(L_param, "%s%s", L_param, "[last_To:]\n");          sprintf(L_param, "%s%s",  L_param, "[last_Call-ID:]\n");          char * cseq;          cseq = compute_cseq(src);          if (cseq != NULL) {            sprintf(L_param, "%s%s BYE\n", L_param, compute_cseq(src));          }          sprintf(L_param, "%s%s", L_param, "Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n");          sprintf(L_param, "%s%s", L_param,  "Content-Length: 0\n");          res = sendBuffer(createSendingMessage((char*)(L_param),-1));        } else {          /* Send a CANCEL */          strcpy(L_param, "CANCEL sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n");          sprintf(L_param, "%s%s", L_param, "[last_Via:]\n");          sprintf(L_param, "%s%s", L_param, "[last_From:]\n");          sprintf(L_param, "%s%s", L_param, "[last_To:]\n");          sprintf(L_param, "%s%s",  L_param, "[last_Call-ID:]\n");          char * cseq;          cseq = compute_cseq(src);          if (cseq != NULL) {            sprintf(L_param, "%s%s CANCEL\n", L_param, compute_cseq(src));          }          sprintf(L_param, "%s%s", L_param, "Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n");          sprintf(L_param, "%s%s", L_param,  "Content-Length: 0\n");          res = sendBuffer(createSendingMessage((char*)(L_param),-1));        }      }    } else {      /* Call is established */      char * src = last_recv_msg ;      char   L_msg_buffer[SIPP_MAX_MSG_SIZE];      L_msg_buffer[0] = '\0';      char * L_param = L_msg_buffer;      strcpy(L_param, "BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n");      sprintf(L_param, "%s%s", L_param, "[last_Via:]\n");      sprintf(L_param, "%s%s", L_param, "[last_From:]\n");      sprintf(L_param, "%s%s", L_param, "[last_To:]\n");      sprintf(L_param, "%s%s",  L_param, "[last_Call-ID:]\n");      char * cseq;      cseq = compute_cseq(src);      if (cseq != NULL) {        sprintf(L_param, "%s%s BYE\n", L_param, compute_cseq(src));      }      sprintf(L_param, "%s%s", L_param, "Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n");      sprintf(L_param, "%s%s", L_param,  "Content-Length: 0\n");      res = sendBuffer(createSendingMessage((char*)(L_param),-1));    }  }  CStat::instance()->computeStat(CStat::E_CALL_FAILED);  CStat::instance()->computeStat(CStat::E_FAILED_UNEXPECTED_MSG);  delete_call(id);  return false;}bool call::rejectCall(){  CStat::instance()->computeStat(CStat::E_CALL_FAILED);  CStat::instance()->computeStat(CStat::E_FAILED_CALL_REJECTED);  delete_call(id);  return false;}#ifdef __3PCC__int call::sendCmdMessage(int index){  char * dest;  char delimitor[2];  delimitor[0]=27;  delimitor[1]=0;  if(scenario[index] -> M_sendCmdData) {    // WARNING_P1("---PREPARING_TWIN_CMD---%s---", scenario[index] -> M_sendCmdData);     dest = createSendingMessage(scenario[index] -> M_sendCmdData, -2);    strcat(dest, delimitor);    //WARNING_P1("---SEND_TWIN_CMD---%s---", dest);     int rc;    rc = send(twinSippSocket,               dest, 

⌨️ 快捷键说明

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