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

📄 call.cpp

📁 学习sip协议的好工具
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    /* This is an ACK or a response, and its index is greater than the    * current active retransmission message, so we stop the retrans timer. */  if(((reply_code) ||      (!strcmp(request, "ACK")))  &&      (search_index > last_send_index)) {    next_retrans = 0;  }    /* This is a response with 200 so set the flag indicating that an   * ACK is pending (used to prevent from release a call with CANCEL   * when an ACK+BYE should be sent instead)                         */  if (reply_code == 200) {    ack_is_pending = true;  }    /* If this message can be used to compute RTD, do it now */  if(!rtd_done) {    if(scenario[search_index] -> start_rtd) {      start_time_rtd = clock_tick;    }    if(scenario[search_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;    }  }  /* Increment the recv counter */  scenario[search_index] -> nb_recv++;  /* store the route set only once. TODO: does not support target refreshes!! */  if (scenario[search_index] -> bShouldRecordRoutes &&          NULL == dialog_route_set ) {      /* should cache the route set */      if (reply_code) {          /* is a reply. */          char rr[MAX_HEADER_LEN];          strcpy(rr, get_header_content(msg, (char*)"Record-Route:"));          char actual_rr[MAX_HEADER_LEN];          memset(actual_rr, 0, sizeof(actual_rr));          bool isFirst(true);          while (1)          {              char* pointer = strrchr(rr, ',');              if (pointer) {                if (!isFirst) {                  strcat(actual_rr, pointer + 1);                } else {                  isFirst = false;                }              } else {                if (!isFirst) {                  strcat(actual_rr, rr);                }                break;              }              *pointer = '\0';          }          /* lose the bottom most record route -- that is the SUT */          char ch[MAX_HEADER_LEN];          strcpy(ch, get_header_content(msg, (char*)"Contact:"));          if (strlen(actual_rr)) {              dialog_route_set = (char *)                  calloc(1, strlen(actual_rr) + strlen(ch) + 2);              sprintf(dialog_route_set, "%s,%s", actual_rr, ch);          } else {              dialog_route_set = (char *)                  calloc(1, strlen(ch) + 2);              sprintf(dialog_route_set, "%s", ch);          }      }      else {          /* is a request. */          char rr[MAX_HEADER_LEN];          strcpy(rr, get_header_content(msg, (char*)"Record-Route:"));          /* toss the first RR, it is going to be the SUT */          char* actual_rr = strchr(rr, ',');          if (actual_rr) {              actual_rr += 1;          }          char ch[MAX_HEADER_LEN];          strcpy(ch, get_header_content(msg, (char*)"Contact:"));          if (actual_rr) {              dialog_route_set = (char *)                  calloc(1, strlen(actual_rr) + strlen(ch) + 2);              sprintf(dialog_route_set, "%s,%s", actual_rr, ch);          } else {              dialog_route_set = (char *)                  calloc(1, strlen(ch) + 2);              sprintf(dialog_route_set, "%s", ch);          }      }  }  /* If this was a mandatory message, and keeps its cookie for   * future retransmissions, and its body for fields inclusion   * in our messages. */  if(!(scenario[search_index] -> optional)) {    msg_index = search_index;    /* Store last recv msg information */    last_recv_index = search_index;    last_recv_hash = cookie;    last_recv_msg = (char *) realloc(last_recv_msg, strlen(msg) + 1);    strcpy(last_recv_msg, msg);       return next();  }  return true;}  call::T_ActionResult call::executeAction(char * msg, int scenarioIndex){  CActions*  actions;  CAction*   currentAction;  CVariable* scenVariable;  char       msgPart[MAX_SUB_MESSAGE_LENGTH];  int        currentId;  actions = scenario[scenarioIndex]->M_actions;  // looking for action to do on this message  if(actions != NULL) {    for(int i=0; i<actions->getUsedAction(); i++) {      currentAction = actions->getAction(i);      if(currentAction != NULL) {        if(currentAction->getActionType() == CAction::E_AT_ASSIGN_FROM_REGEXP) {          currentId = currentAction->getVarId();          scenVariable = scenVariableTable[currentId];          if(scenVariable != NULL) {            if(currentAction->getLookingPlace() == CAction::E_LP_HDR) {              extractSubMessage                                (msg,                                 currentAction->getLookingChar(),                                 msgPart);                      if(strlen(msgPart) > 0) {                scenVariable->extractOneMatchedExpression                                  (msgPart,                                   M_callVariableTable[currentId]);                          if( (!(M_callVariableTable[currentId]->isSet()))                 && (currentAction->getCheckIt() == true) ) {                  // the message doesn't match and the checkit                   // action say it MUST match                  // Allow easier regexp debugging                  WARNING_P2("Failed regexp match: looking "                  "in '%s', with regexp '%s'",                   msgPart,                   scenVariable->                  getRegularExpression());                  // --> Call will be marked as failed                  return(call::E_AR_REGEXP_DOESNT_MATCH);                }              } else {// sub part of message not found                if( currentAction->getCheckIt() == true ) {                  // the sub message is not found and the                  // checking action say it MUST match                  // --> Call will be marked as failed but                   // will go on                  return(call::E_AR_HDR_NOT_FOUND);                }               }            } else {// we must look in the entire message              // WARNING_P1("LOOKING IN MSG -%s-", msg);              scenVariable->extractOneMatchedExpression                              (msg,                               M_callVariableTable[currentId]);              if((!(M_callVariableTable[currentId]->isSet()))               && (currentAction->getCheckIt() == true) ) {                // the message doesn't match and the checkit                 // action say it MUST match                // Allow easier regexp debugging                WARNING_P2("Failed regexp match: looking in '%s'"                ", with regexp '%s'",                 msg,                 scenVariable->getRegularExpression());                // --> rejecting the call                return(call::E_AR_REGEXP_DOESNT_MATCH);              }            }          } // end if scen variable != null        } else {// end action == ASSIGN_FROM_REG_EXP          ERROR("call::executeAction unknown action");        }      } // end if current action != null    } // end for  }  return(call::E_AR_NO_ERROR);}void call::extractSubMessage(char * msg, char * matchingString, char* result){  char * ptr;  int sizeOf;  int i = 0;  int len;  ptr = strstr(msg, matchingString);   if(ptr != NULL) {    len = strlen(matchingString);    strcpy(result, ptr+len);    sizeOf = strlen(result);    if(sizeOf >= MAX_SUB_MESSAGE_LENGTH)        sizeOf = MAX_SUB_MESSAGE_LENGTH-1;    while((i<sizeOf) && (result[i] != '\n') && (result[i] != '\r'))      i++;    result[i] = '\0';  } else {    result[0] = '\0';  }}void call::dumpFileContents(void){    WARNING_P3("Line choosing strategy is [%s]. m_counter [%d] numLinesInFile [%d]",               m_usage == InputFileSequentialOrder ? "SEQUENTIAL" : "RANDOM",               m_counter, numLinesInFile);    for (int i(0); i < numLinesInFile && fileContents[i][0]; ++i) {        WARNING_P2("%dth line reads [%s]", i, fileContents[i].c_str());    }}/* Read MAX_CHAR_BUFFER_SIZE size lines from the * "fileName" and populate it in the fileContents * vector. The file should not be more than * MAX_LINES_IN_FILE lines long and each line * should be terminated with a '\n' */void call::readInputFileContents(const char* fileName){  ifstream *inFile    = new ifstream(fileName);  ifstream &inFileObj = *inFile;  char      line[MAX_CHAR_BUFFER_SIZE];    if (!inFile->good()) {    ERROR_P1("Unable to open file %s", fileName);    return ;  }  numLinesInFile = 0;  call::m_counter = 0;  line[0] = '\0';  inFileObj.getline(line, MAX_CHAR_BUFFER_SIZE);  if (NULL != strstr(line, "RANDOM")) {      call::m_usage = InputFileRandomOrder;  } else if (NULL != strstr(line, "SEQUENTIAL")) {      call::m_usage = InputFileSequentialOrder;  } else {      // default      call::m_usage = InputFileSequentialOrder;  }  while (!inFileObj.eof()) {    line[0] = '\0';    inFileObj.getline(line, MAX_CHAR_BUFFER_SIZE);    if (line[0]) {      if ('#' != line[0]) {        fileContents.push_back(line);      }      numLinesInFile++;    } else {      break;    }  }  // call::dumpFileContents();  delete inFile;} void call::getFieldFromInputFile(const char* keyword, int lineNum, char*& dest){  int nthField    = atoi(keyword+5 /*strlen("field")*/);    if (fileContents.size() > lineNum) {    const string& line = fileContents[lineNum];        // WARNING_P3("lineNum [%d] nthField [%d] line [%s]",    //         lineNum, nthField, line.c_str());        int pos(0), oldpos(0);    do {      oldpos = pos;      int localint = line.find(';', oldpos);            if (localint != string::npos) {        pos = localint + 1;      } else {        pos = localint;        break;      }            string x = line.substr(oldpos, pos - oldpos);      // WARNING_P3("pos [%d] oldpos [%d] is [%s]", pos, oldpos, x.c_str());            if (nthField) {        --nthField;      } else {        break;      }          } while (oldpos != string::npos);        if (nthField) {      WARNING_P1("Field %d not found in the file", nthField+2);      // field not found in line    } else {      if (string::npos != oldpos) {        if (line[oldpos] == ';') {          ++oldpos; // should not be incremeneted for field0        }          if (string::npos != pos) {          // should not be decremented for fieldN          pos -= (oldpos + 1);        }            string x = line.substr(oldpos, pos);        dest += sprintf(dest, "%s", x.c_str());                // WARNING_P2("nthField [%d] is [%s]", nthField, x.c_str());      }    }  } else {    WARNING_P1("Field %d definition not found", nthField);  }}int  call::checkAutomaticResponseMode(char * P_recv) {  int L_res = 0 ;  if (strcmp(P_recv, "BYE")==0) {    L_res = 1 ;  } else if (strcmp(P_recv, "CANCEL") == 0) {    L_res = 2 ;  } else if (strcmp(P_recv, "PING") == 0) {    L_res = 3 ;  }  return (L_res) ;  }void call::automaticResponseMode(int P_case, char * P_recv){  int res ;  // usage of last_ keywords  last_recv_msg = (char *) realloc(last_recv_msg, strlen(P_recv) + 1);  strcpy(last_recv_msg, P_recv);  switch (P_case) {  case 1: // response for an unexpected BYE    WARNING_P1("Automatic response mode for an unexpected BYE for call: %s", (id==NULL)?"none":id);    res = sendBuffer(createSendingMessage(                    (char*)"SIP/2.0 200 OK\n"                    "[last_Via:]\n"                    "[last_From:]\n"                    "[last_To:]\n"                    "[last_Call-ID:]\n"                    "[last_CSeq:]\n"                    "Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"                    "Content-Length: 0\n"                    , -1)) ;#ifdef __3PCC__    // if twin socket call => reset the other part here     if (twinSippSocket && (msg_index > 0)) {      res = sendCmdBuffer      (createSendingMessage((char*)"call-id: [call_id]\ninternal-cmd: abort_call\n", -1));    }#endif /* __3PCC__ */            CStat::instance()->computeStat(CStat::E_CALL_FAILED);      CStat::instance()->computeStat(CStat::E_FAILED_UNEXPECTED_MSG);      delete_call(id);      break ;        case 2: // response for an unexpected cancel    WARNING_P1("Automatic response mode for an unexpected CANCEL for call: %s", (id==NULL)?"none":id);    res = sendBuffer(createSendingMessage(                      (char*)"SIP/2.0 200 OK\n"                      "[last_Via:]\n"                      "[last_From:]\n"                      "[last_To:]\n"                      "[last_Call-ID:]\n"                      "[last_CSeq:]\n"                      "Contact: sip:sipp@[local_ip]:[local_port]\n"                      "Content-Length: 0"                      , -1)) ;    #ifdef __3PCC__    // if twin socket call => reset the other part here     if (twinSippSocket && (msg_index > 0)) {      res = sendCmdBuffer      (createSendingMessage((char*)"call-id: [call_id]\ninternal-cmd: abort_call\n", -1));    }#endif /* __3PCC__ */        CStat::instance()->computeStat(CStat::E_CALL_FAILED);    CStat::instance()->computeStat(CStat::E_FAILED_UNEXPECTED_MSG);    delete_call(id);    break ;        case 3: // response for a random ping    WARNING_P1("Automatic response mode for an unexpected PING for call: %s", (id==NULL)?"none":id);    count_in_stats = false; // Call must not be counted in statistics    res = sendBuffer(createSendingMessage(                    (char*)"SIP/2.0 200 OK\n"                    "[last_Via:]\n"                    "[last_Call-ID:]\n"                    "[last_To:]\n"                    "[last_From:]\n"                    "[last_CSeq:]\n"                    "Contact: sip:sipp@[local_ip]:[local_port]\n"                    "Content-Length: 0"                    , -1)) ;    // Note: the call ends here but it is not marked as bad. PING is a     //       normal message.#ifdef __3PCC__    // if twin socket call => reset the other part here     if (twinSippSocket && (msg_index > 0)) {      res = sendCmdBuffer      (createSendingMessage((char*)"call-id: [call_id]\ninternal-cmd: abort_call\n",-1));    }#endif /* __3PCC__ */        CStat::instance()->computeStat(CStat::E_AUTO_ANSWERED);    delete_call(id);    break ;    default:    ERROR_P1("Internal error for automaticResponseMode %d", P_case);    break ;  }  }

⌨️ 快捷键说明

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