📄 scenario.cpp
字号:
/* * 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 * Olivier Jacques * From Hewlett Packard Company. * Shriram Natarajan * Peter Higginson * Venkatesh * Lee Ballard * Guillaume TEISSIER from FTR&D * Wolfgang Beck */#include "sipp.hpp"#ifdef HAVE_GSL#include <gsl/gsl_rng.h>#include <gsl/gsl_randist.h>#include <gsl/gsl_cdf.h>#endif/************************ Class Constructor *************************/message::message(){ //ugly memset(this, 0, sizeof(message)); pause_function = NULL; pause_desc = NULL; pause_param = 0; pause_param2 = 0; pause_dparam = 0; pause_dparam2 = 0; sessions = 0; bShouldRecordRoutes = 0;#ifdef _USE_OPENSSL bShouldAuthenticate = 0;#endif send_scheme = NULL; retrans_delay = 0; recv_response = 0; recv_request = NULL; optional = 0; /* Anyway */ start_rtd = 0; stop_rtd = 0; lost = 0; crlf = 0; test = 0; next = 0; on_timeout = 0; /* Statistics */ nb_sent = 0; nb_recv = 0; nb_sent_retrans = 0; nb_recv_retrans = 0; nb_timeout = 0; nb_unexp = 0; nb_lost = 0; counter = 0; M_actions = NULL; M_type = 0;#ifdef __3PCC__ M_sendCmdData = NULL; M_nbCmdSent = 0; M_nbCmdRecv = 0;#endif content_length_flag = ContentLengthNoPresent;}message::~message(){ if(M_actions != NULL) delete(M_actions); M_actions = NULL; if(send_scheme != NULL) free (send_scheme); send_scheme = NULL; if(recv_request != NULL) free (recv_request); recv_request = NULL;#ifdef __3PCC__ if(M_sendCmdData != NULL) delete(M_sendCmdData); M_sendCmdData = NULL;#endif}/******** Global variables which compose the scenario file **********/message* scenario[SCEN_MAX_MESSAGES];CVariable* scenVariableTable[SCEN_VARIABLE_SIZE][SCEN_MAX_MESSAGES];int scenario_len = 0;char scenario_name[255];int toolMode = MODE_CLIENT;unsigned long scenario_duration = 0;unsigned int labelArray[MAX_LABELS];/*************** Helper functions for various types *****************/long get_long(const char *ptr, const char *what) { char *endptr; long ret; ret = strtol(ptr, &endptr, 0); if (*endptr) { ERROR_P2("%s, \"%s\" is not a valid integer!\n", what, ptr); } return ret;}double get_double(const char *ptr, const char *what) { char *endptr; double ret; ret = strtod(ptr, &endptr); if (*endptr) { ERROR_P2("%s, \"%s\" is not a floating point number!\n", what, ptr); } return ret;}bool get_bool(const char *ptr, const char *what) { char *endptr; long ret; if (!strcmp(ptr, "true")) { return true; } if (!strcmp(ptr, "false")) { return false; } ret = strtol(ptr, &endptr, 0); if (*endptr) { ERROR_P2("%s, \"%s\" is not a valid boolean!\n", what, ptr); } return ret ? true : false;}/* Pretty print a time. */char *time_string(int ms) { static char tmp[20]; if (ms < 10000) { snprintf(tmp, sizeof(tmp), "%dms", ms); } else if (ms < 100000) { snprintf(tmp, sizeof(tmp), "%.1fs", ((float)ms)/1000); } else { snprintf(tmp, sizeof(tmp), "%ds", ms/1000); } return tmp;}char *double_time_string(double ms) { static char tmp[20]; if (ms < 1000) { snprintf(tmp, sizeof(tmp), "%.2lfms", ms); } else if (ms < 10000) { snprintf(tmp, sizeof(tmp), "%.1lfms", ms); } else if (ms < 100000) { snprintf(tmp, sizeof(tmp), "%.1lfms", ms / 1000); } else { snprintf(tmp, sizeof(tmp), "%ds", (int)(ms/1000)); } return tmp;}/* For backwards compatibility, we assign "true" to slot 1, false to 0, and * allow other valid integers. */int get_rtd(const char *ptr) { char *endptr; int ret; if(!strcmp(ptr, (char *)"true")) return 1; if(!strcmp(ptr, (char *)"false")) return 0; ret = strtol(ptr, &endptr, 0); if (*endptr) { ERROR_P1("rtd \"%s\" is not a valid integer!\n", ptr); } if (ret >= MAX_RTD_INFO_LENGTH) { ERROR_P2("rtd %d exceeds MAX_RTD_INFO_LENGTH %d!\n", ret, MAX_RTD_INFO_LENGTH); } return ret;}/* Get a counter */long get_counter(const char *ptr, const char *what) { long ret; ret = get_long(ptr, what); if (ret < 1 || ret > MAX_COUNTER) { ERROR_P2("Counter %d exceeds MAX_COUNTER %d!\n", ret, MAX_COUNTER); } return ret;}/*************** Helper functions for computing pauses *************/unsigned int pause_default(message *msg) { if (msg -> pause_param == -1) { return duration; } return msg -> pause_param;}unsigned int pause_uniform(message *msg) { return msg-> pause_param + rand() % (msg -> pause_param2 - msg -> pause_param);}#ifdef HAVE_GSLgsl_rng *rng;void init_rng() { if (rng) { return; } gsl_rng_env_setup(); rng = gsl_rng_alloc(gsl_rng_default); if (!rng) { ERROR("Could not initialize GSL random number generator.\n"); }}unsigned int pause_normal(message *msg) { double duration; duration = gsl_ran_gaussian(rng, (double)msg->pause_param2); duration += msg->pause_param; /* The normal distribution can include negative numbers, which make no sense * for a pause. */ if (duration < 0) { duration = 0; } return (unsigned int)duration;}unsigned int pause_lognormal(message *msg) { double duration; duration = gsl_ran_lognormal(rng, msg->pause_dparam, msg->pause_dparam2); return (unsigned int)duration;}unsigned int pause_exponential(message *msg) { double duration = 0; duration = gsl_ran_exponential(rng, (double)msg->pause_param); return (unsigned int)duration;}#endif/********************** Scenario File analyser **********************/void load_scenario(char * filename, int deflt){ char * elem; char method_list[METHOD_LIST_LENGTH]; // hopefully the method list wont be longer than this char method_list_length = 0; // Enforce length, in case... unsigned int scenario_file_cursor = 0; int L_content_length = 0 ; unsigned int recv_count = 0; unsigned int recv_opt_count = 0; memset (method_list, 0, sizeof (method_list)); if(filename) { if(!xp_set_xml_buffer_from_file(filename)) { ERROR_P1("Unable to load or parse '%s' xml scenario file", filename); } } else { if(!xp_set_xml_buffer_from_string(default_scenario[deflt])) { ERROR("Unable to load default xml scenario file"); } } // set all variable in scenVariable table to NULL for(int i=0; i<SCEN_VARIABLE_SIZE; i++) { for (int j=0; j<SCEN_MAX_MESSAGES; j++) { scenVariableTable[i][j] = NULL; } } elem = xp_open_element(0); if(strcmp("scenario", elem)) { ERROR("No 'scenario' section in xml scenario file"); } if(xp_get_value((char *)"name")) { strcpy(scenario_name, xp_get_value((char *)"name")); } else { scenario_name[0] = 0; } scenario_len = 0; scenario_file_cursor = 0; while(elem = xp_open_element(scenario_file_cursor)) { char * ptr; scenario_file_cursor ++; if(!strcmp(elem, "CallLengthRepartition")) { ptr = xp_get_value((char *)"value"); CStat::instance()->setRepartitionCallLength(ptr); } else if(!strcmp(elem, "ResponseTimeRepartition")) { ptr = xp_get_value((char *)"value"); CStat::instance()->setRepartitionResponseTime(ptr); } else if(!strcmp(elem, "label")) { ptr = xp_get_value((char *)"id"); unsigned int labelNumber = get_long(ptr, "label identifier"); if (labelNumber < (sizeof(labelArray)/sizeof(labelArray[0]))) { labelArray[labelNumber] = ::scenario_len; } } else { /** Message Case */ scenario[scenario_len] = new message(); scenario[scenario_len] -> content_length_flag = message::ContentLengthNoPresent; // Initialize to No present if(!strcmp(elem, "send")) { if (recv_count) { if (recv_count != recv_opt_count) { recv_count = 0; recv_opt_count = 0; } else { ERROR_P1("<recv> before <send> sequence without a mandatory message. Please remove one 'optional=true'.", scenario_file_cursor); } } scenario[scenario_len]->M_type = MSG_TYPE_SEND; /* Sent messages descriptions */ if(ptr = xp_get_cdata()) { char * msg; int removed_clrf = 0; while((*ptr == ' ') || (*ptr == '\t') || (*ptr == '\n')) ptr++; msg = scenario[scenario_len] -> send_scheme =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -