From: <aa...@us...> - 2006-08-01 16:32:02
|
Revision: 45 Author: aajjan Date: 2006-08-01 09:31:33 -0700 (Tue, 01 Aug 2006) ViewCVS: http://svn.sourceforge.net/gull/?rev=45&view=rev Log Message: ----------- support UDP transport with retrans Modified Paths: -------------- seagull/trunk/src/exe-env/h248-env/scenario/client.xml seagull/trunk/src/generator-core/C_GeneratorConfig.cpp seagull/trunk/src/generator-core/C_GeneratorConfig.hpp seagull/trunk/src/generator-core/GeneratorDefaults.h seagull/trunk/src/generator-scenario/C_Scenario.cpp seagull/trunk/src/generator-scenario/C_Scenario.hpp seagull/trunk/src/generator-scenario/C_ScenarioControl.cpp seagull/trunk/src/generator-scenario/C_ScenarioControl.hpp seagull/trunk/src/generator-traffic/C_CallContext.cpp seagull/trunk/src/generator-traffic/C_CallContext.hpp seagull/trunk/src/generator-traffic/C_CallControl.cpp seagull/trunk/src/generator-traffic/C_CallControl.hpp seagull/trunk/src/library-trans-ip/C_Socket.cpp seagull/trunk/src/library-trans-ip/C_Socket.hpp seagull/trunk/src/library-trans-ip/C_TransIP.cpp seagull/trunk/src/library-trans-ip/C_TransIP.hpp seagull/trunk/src/library-trans-ip/S_IpAddr.cpp seagull/trunk/src/library-trans-ip/S_IpAddr.hpp seagull/trunk/src/protocol-text/C_ProtocolText.cpp Modified: seagull/trunk/src/exe-env/h248-env/scenario/client.xml =================================================================== --- seagull/trunk/src/exe-env/h248-env/scenario/client.xml 2006-07-13 12:23:27 UTC (rev 44) +++ seagull/trunk/src/exe-env/h248-env/scenario/client.xml 2006-08-01 16:31:33 UTC (rev 45) @@ -91,8 +91,8 @@ <close></close> --> </action> + </receive> - </receive> </traffic> </scenario> Modified: seagull/trunk/src/generator-core/C_GeneratorConfig.cpp =================================================================== --- seagull/trunk/src/generator-core/C_GeneratorConfig.cpp 2006-07-13 12:23:27 UTC (rev 44) +++ seagull/trunk/src/generator-core/C_GeneratorConfig.cpp 2006-08-01 16:31:33 UTC (rev 45) @@ -67,7 +67,9 @@ "files-no-timestamp", "call-timeout-behaviour-abort", "call-open-timeout-ms", - "execute-check-action" + "execute-check-action", + "max-retrans", + "retrans-enabled" }; static const char _check_level_char [] = { @@ -292,9 +294,11 @@ m_call_timeout_beh_abr = DEF_CALL_TIMEOUT_BEH_ABRT ; m_execute_check_action = DEF_EXECUTE_CHECK_ACTION ; + m_open_timeout = DEF_OPEN_TIMEOUT ; + m_max_retrans = DEF_MAX_RETRANS ; + m_retrans_enabled = DEF_RETRANS_ENABLED ; - m_open_timeout = DEF_OPEN_TIMEOUT ; m_call_rate_scale = DEF_CALL_RATE_SCALE ; @@ -407,7 +411,11 @@ return (m_execute_check_action) ; } +bool C_GeneratorConfig::get_retrans_enabled () { + return (m_retrans_enabled) ; +} + bool C_GeneratorConfig::set_value (T_GeneratorConfigOption P_opt, char *P_value) { bool L_ret = true ; @@ -659,6 +667,25 @@ break ; + case E_CFG_OPT_MAX_RETRANS : + m_max_retrans = strtoul_f(P_value, &L_end_str, 10) ; + if (L_end_str[0] != '\0') { // not a number + L_ret = false ; + } + break ; + + case E_CFG_OPT_RETRANS_ENABLED: + + if(strcmp(P_value, (char *)"true") == 0) { + m_retrans_enabled = true ; + } else { + if(strcmp(P_value, (char *)"false") != 0) { + L_ret = false ; + } + } + break ; + + default: L_ret = false ; break ; @@ -754,6 +781,11 @@ *P_val = m_open_timeout ; break ; + case E_CFG_OPT_MAX_RETRANS : + *P_val = m_max_retrans ; + break ; + + default: L_ret = false ; break ; Modified: seagull/trunk/src/generator-core/C_GeneratorConfig.hpp =================================================================== --- seagull/trunk/src/generator-core/C_GeneratorConfig.hpp 2006-07-13 12:23:27 UTC (rev 44) +++ seagull/trunk/src/generator-core/C_GeneratorConfig.hpp 2006-08-01 16:31:33 UTC (rev 45) @@ -100,6 +100,8 @@ E_CFG_OPT_CALL_TIMEOUT_BEH_ABR, E_CFG_OPT_OPEN_TIMEOUT, E_CFG_OPT_EXECUTE_CHECK_ACTION, + E_CFG_OPT_MAX_RETRANS, + E_CFG_OPT_RETRANS_ENABLED, E_CFG_OPT_Number } T_GeneratorConfigOption ; @@ -152,7 +154,9 @@ bool get_execute_check_action () ; + bool get_retrans_enabled () ; + T_pConfigValueList get_config_param_list() ; int analyze_protocol_stat(char *P_logProtocolStat, T_charPlist *P_protocol_list, @@ -214,6 +218,9 @@ unsigned long m_open_timeout ; + unsigned long m_max_retrans ; + bool m_retrans_enabled ; + unsigned long m_call_rate_scale ; T_pConfigValueList m_configValueList ; Modified: seagull/trunk/src/generator-core/GeneratorDefaults.h =================================================================== --- seagull/trunk/src/generator-core/GeneratorDefaults.h 2006-07-13 12:23:27 UTC (rev 44) +++ seagull/trunk/src/generator-core/GeneratorDefaults.h 2006-08-01 16:31:33 UTC (rev 45) @@ -59,7 +59,10 @@ #define DEF_CALL_TIMEOUT_BEH_ABRT false #define DEF_OPEN_TIMEOUT 0 #define DEF_EXECUTE_CHECK_ACTION true +#define DEF_MAX_RETRANS 0 +#define DEF_RETRANS_ENABLED false + #endif Modified: seagull/trunk/src/generator-scenario/C_Scenario.cpp =================================================================== --- seagull/trunk/src/generator-scenario/C_Scenario.cpp 2006-07-13 12:23:27 UTC (rev 44) +++ seagull/trunk/src/generator-scenario/C_Scenario.cpp 2006-08-01 16:31:33 UTC (rev 45) @@ -61,6 +61,7 @@ C_ExternalDataControl *P_external_data_control, T_exeCode P_exe_code, char *P_behaviour, + bool P_retrans_enabled, unsigned int P_check_mask, T_CheckBehaviour P_checkBehaviour ) { @@ -79,6 +80,8 @@ m_stats = NULL ; m_exe_end_code = P_exe_code ; + m_retrans_enabled = P_retrans_enabled ; + m_nb_retrans = 0 ; if (P_behaviour == NULL) { m_behaviour = E_BEHAVIOUR_SCEN_SUCCESS ; @@ -134,7 +137,10 @@ FREE_VAR(m_cmd_sequence[L_i].m_pre_act_table[L_j]. m_string_expr); - // free regexp + // free regexp ??? + DELETE_VAR(m_cmd_sequence[L_i].m_pre_act_table[L_j]. + m_regexp_data); + } } FREE_TABLE(m_cmd_sequence[L_i].m_pre_act_table); @@ -160,7 +166,10 @@ FREE_VAR(m_cmd_sequence[L_i].m_post_act_table[L_j]. m_string_expr); - // free regexp + // free regexp + DELETE_VAR(m_cmd_sequence[L_i].m_post_act_table[L_j]. + m_regexp_data); + } } FREE_TABLE(m_cmd_sequence[L_i].m_post_act_table); @@ -174,6 +183,8 @@ m_stat = NULL ; m_stats = NULL ; + m_nb_retrans = 0 ; + GEN_DEBUG(1, "C_Scenario::~C_Scenario() end"); } @@ -208,8 +219,66 @@ return (L_ret); } -T_exeCode C_Scenario::execute_cmd (T_pCallContext P_callCtxt, bool P_resume) { +T_exeCode C_Scenario::execute_cmd_retrans (int P_index, T_pCallContext P_callCtxt) { + T_exeCode L_exeCode = E_EXE_NOERROR ; + int L_cmdIdx ; + T_pCmd_scenario L_pCmd ; + + struct timezone L_timeZone ; + + C_MessageFrame *L_retransMsg = NULL ; + int L_channel_id = -1 ; + GEN_DEBUG(1, "C_Scenario::execute_cmd_retrans() start"); + + // retrieve command execution informations + L_cmdIdx = P_callCtxt->m_retrans_cmd_idx[P_index]; + L_pCmd = &m_cmd_sequence[L_cmdIdx] ; + + switch (L_pCmd->m_type) { + + case E_CMD_SCEN_SEND: { + + L_channel_id = L_pCmd -> m_channel_id ; + L_retransMsg = P_callCtxt->m_retrans_msg[P_index] ; + + if (m_channel_ctrl-> + send_to_channel(L_channel_id, P_callCtxt->m_channel_table, L_retransMsg)) { + + GEN_LOG_EVENT(LOG_LEVEL_TRAFFIC_ERR, + "Send error on call with session-id [" + << P_callCtxt->m_id_table[L_channel_id] << "]"); + + L_exeCode = E_EXE_ERROR_SEND ; + } else { + // to modify use a new counter + m_stat -> executeStatAction (C_GeneratorStats::E_SEND_MSG); + gettimeofday(&(P_callCtxt->m_retrans_time[P_index]), &L_timeZone) ; + (P_callCtxt->m_nb_retrans_done[P_index]) ++; + if (m_stats) { + m_stats->updateStats(L_cmdIdx,C_ScenarioStats::E_RETRANS,0); + // m_stats->updateStats(L_cmdIdx,C_ScenarioStats::E_MESSAGE,0); + + } + } + } + break ; + default: + GEN_DEBUG (1, "C_Scenario::execute_cmd() Incorrect type " + << L_pCmd->m_type + << " command execution"); + L_exeCode = E_EXE_ERROR; + break ; + } + + GEN_DEBUG(1, "C_Scenario::execute_cmd_retrans() end"); + return (L_exeCode); +} + + +T_exeCode C_Scenario::execute_cmd (T_pCallContext P_callCtxt, + bool P_resume) { + T_exeCode L_exeCode = E_EXE_NOERROR ; int L_cmdIdx ; T_pCmd_scenario L_pCmd ; @@ -270,8 +339,21 @@ if (m_stats) { m_stats->updateStats(L_cmdIdx,C_ScenarioStats::E_MESSAGE,0); } + + + if (m_retrans_enabled) { + if (L_pCmd->m_retrans_delay > 0) { + P_callCtxt->m_retrans_context.m_retrans_index = L_pCmd->m_retrans_index ; + P_callCtxt->m_retrans_context.m_retrans_delay_index = L_pCmd->m_retrans_delay_index ; + P_callCtxt->m_retrans_context.m_context = P_callCtxt ; + // std::cerr << "m_retrans_context.m_context =" << P_callCtxt << std::endl ; + P_callCtxt->m_retrans_time[L_pCmd->m_retrans_index] = P_callCtxt->m_current_time ; + P_callCtxt->m_retrans_cmd_idx[L_pCmd->m_retrans_index] = L_cmdIdx; + P_callCtxt->m_retrans_msg[L_pCmd->m_retrans_index] = L_sendMsg ; + P_callCtxt->m_retrans_to_do = true ; + } + } } - } if ((L_exeCode == E_EXE_NOERROR) && (L_exeCode != E_EXE_SUSPEND)) { @@ -285,10 +367,16 @@ } } + if (L_exeCode != E_EXE_SUSPEND) { - DELETE_VAR(L_sendMsg); + if ((m_retrans_enabled) && (L_pCmd->m_retrans_delay > 0)) { + L_sendMsg = NULL ; + } else { + DELETE_VAR(L_sendMsg); + } } + } break ; @@ -537,7 +625,9 @@ int P_channel_id, T_pC_MessageFrame P_msg, int P_nb_pre_action, - T_pCmdAction P_pre_act_table) { + T_pCmdAction P_pre_act_table, + unsigned long P_retrans_delay) { + GEN_DEBUG(1, "C_Scenario::add_cmd() start"); if (m_sequence_max < m_sequence_size) { @@ -548,6 +638,22 @@ L_cmd_sequence->m_message = P_msg ; L_cmd_sequence->m_channel_id = P_channel_id ; + + if (m_retrans_enabled == false) { + L_cmd_sequence->m_retrans_delay = 0 ; + L_cmd_sequence->m_retrans_index = 0 ; + L_cmd_sequence->m_retrans_delay_index = 0 ; + } else { + L_cmd_sequence->m_retrans_delay = P_retrans_delay ; + if (P_retrans_delay > 0) { + L_cmd_sequence->m_retrans_index = m_nb_retrans ; + m_nb_retrans++; + } else { + L_cmd_sequence->m_retrans_index = 0 ; + } + L_cmd_sequence->m_retrans_delay_index = 0 ; + } + if ((P_nb_pre_action != 0) && (P_pre_act_table != NULL)) { L_cmd_sequence->m_pre_action = P_nb_pre_action ; L_cmd_sequence->m_pre_act_table = P_pre_act_table ; @@ -580,6 +686,10 @@ L_cmd_sequence->m_post_action = 0 ; L_cmd_sequence->m_post_act_table = NULL ; + L_cmd_sequence->m_retrans_delay = 0 ; + L_cmd_sequence->m_retrans_index = 0 ; + L_cmd_sequence->m_retrans_delay_index = 0 ; + m_sequence_max++ ; GEN_DEBUG(1, "C_Scenario::add_cmd() end"); return (m_sequence_max); @@ -600,6 +710,10 @@ L_cmd_sequence->m_post_action = 0 ; L_cmd_sequence->m_post_act_table = NULL ; + L_cmd_sequence->m_retrans_delay = 0 ; + L_cmd_sequence->m_retrans_index = 0 ; + L_cmd_sequence->m_retrans_delay_index = 0 ; + m_sequence_max++ ; GEN_DEBUG(1, "C_Scenario::add_cmd() end"); return (m_sequence_max); @@ -1383,6 +1497,20 @@ return (L_exeCode); } +void C_Scenario::update_retrans_delay_cmd (size_t P_nb, unsigned long *P_table) { + int L_i ; + size_t L_j ; + for(L_i=0; L_i < m_sequence_max; L_i++) { + if (m_cmd_sequence[L_i].m_retrans_delay > 0 ) { + for (L_j = 0; L_j < P_nb; L_j++) { + if (m_cmd_sequence[L_i].m_retrans_delay == P_table[L_j]) { + m_cmd_sequence[L_i].m_retrans_delay_index = L_j ; + break ; + } + } + } + } +} void C_Scenario::update_wait_cmd (size_t P_nb, unsigned long *P_table) { int L_i ; @@ -1422,6 +1550,9 @@ m_string_expr); // free regexp???? + DELETE_VAR(m_cmd_sequence[P_cmd_index].m_post_act_table[L_j]. + m_regexp_data); + } } @@ -1446,3 +1577,12 @@ T_exeCode C_Scenario::get_exe_end_code() { return (m_exe_end_code) ; } + +int C_Scenario::get_nb_retrans () +{ + return (m_nb_retrans); +} + +T_pCmd_scenario C_Scenario::get_commands() { + return (m_cmd_sequence); +} Modified: seagull/trunk/src/generator-scenario/C_Scenario.hpp =================================================================== --- seagull/trunk/src/generator-scenario/C_Scenario.hpp 2006-07-13 12:23:27 UTC (rev 44) +++ seagull/trunk/src/generator-scenario/C_Scenario.hpp 2006-08-01 16:31:33 UTC (rev 45) @@ -170,6 +170,10 @@ T_pCmdAction m_pre_act_table ; T_pCmdAction m_post_act_table ; + unsigned long m_retrans_delay ; + unsigned long m_retrans_index ; + unsigned long m_retrans_delay_index ; + } T_cmd_scenario, *T_pCmd_scenario ; @@ -184,6 +188,7 @@ C_ExternalDataControl *P_external_data_control, T_exeCode P_exe_code, char *P_behaviour, + bool P_retrans_enabled, unsigned int P_check_mask = 0, T_CheckBehaviour P_checkBehaviour = E_CHECK_BEHAVIOUR_WARNING @@ -198,8 +203,10 @@ int P_channel_id, T_pC_MessageFrame P_msg, int P_nb_pre_action, - T_pCmdAction P_pre_act_table); + T_pCmdAction P_pre_act_table, + unsigned long P_retrans_delay); + // define post actions for the last command added size_t define_post_actions (int P_nb_post_action, T_pCmdAction P_post_act_table) ; @@ -212,9 +219,14 @@ bool check_msg_received (T_pReceiveMsgContext P_rcvMsg) ; - T_exeCode execute_cmd (T_pCallContext P_callCtxt, bool P_resume); + T_exeCode execute_cmd (T_pCallContext P_callCtxt, + bool P_resume); + T_CallContextState first_state(); + T_exeCode execute_cmd_retrans (int P_index, T_pCallContext P_callCtxt); + void update_retrans_delay_cmd (size_t P_nb, unsigned long *P_table) ; + void update_wait_cmd (size_t P_nb, unsigned long *P_table) ; friend iostream_output& operator<<(iostream_output&, C_Scenario&); @@ -228,6 +240,10 @@ T_exeCode get_exe_end_code() ; + int get_nb_retrans(); + + T_pCmd_scenario get_commands() ; + friend class C_ScenarioStats ; private: @@ -263,8 +279,17 @@ T_BehaviourScenario m_behaviour ; + bool m_retrans_enabled ; + int m_nb_retrans ; + } ; typedef C_Scenario *T_pC_Scenario ; #endif // _C_SCENARIO_H + + + + + + Modified: seagull/trunk/src/generator-scenario/C_ScenarioControl.cpp =================================================================== --- seagull/trunk/src/generator-scenario/C_ScenarioControl.cpp 2006-07-13 12:23:27 UTC (rev 44) +++ seagull/trunk/src/generator-scenario/C_ScenarioControl.cpp 2006-08-01 16:31:33 UTC (rev 45) @@ -60,6 +60,9 @@ m_log = NULL ; NEW_VAR(m_wait_values, T_waitValuesSet()); + m_retrans_enabled = false; + NEW_VAR(m_retrans_delay_values, T_retransDelayValuesSet()); + m_external_data = NULL ; m_external_data_used = false ; @@ -72,8 +75,6 @@ m_nb_counter = 0 ; m_counter_table = NULL ; m_action_check_abort = false ; - - } C_ScenarioControl::~C_ScenarioControl() { @@ -121,6 +122,11 @@ } DELETE_VAR(m_wait_values); + if (!m_retrans_delay_values->empty()) { + m_retrans_delay_values->erase(m_retrans_delay_values->begin(), m_retrans_delay_values->end()); + } + DELETE_VAR(m_retrans_delay_values); + if (m_nb_counter != 0){ for (L_i = 0; L_i < m_nb_counter; L_i++) { FREE_VAR(m_counter_table[L_i]); @@ -322,6 +328,10 @@ GEN_DEBUG(1, "C_ScenarioControl::add_scenario() start"); (*P_nbOpen) = 0 ; + if (m_config != NULL) { + m_retrans_enabled = m_config -> get_retrans_enabled(); + } + L_behaviour_scen = get_behaviour_scenario(P_scen) ; if (L_behaviour_scen != NULL) { if ((strcmp(L_behaviour_scen, (char*)"failed") != 0) && @@ -359,6 +369,7 @@ m_external_data, E_EXE_TRAFFIC_END, L_behaviour_scen, + m_retrans_enabled, L_check_level, L_check_behave )); @@ -369,7 +380,10 @@ case E_SCENARIO_INIT: NEW_VAR(m_init_scen, C_Scenario(this, m_channel_ctrl, - m_external_data,E_EXE_INIT_END,L_behaviour_scen)) ; + m_external_data, + E_EXE_INIT_END, + L_behaviour_scen, + m_retrans_enabled)) ; L_current_scen = m_init_scen ; m_nb_scenario++; @@ -381,7 +395,11 @@ GEN_FATAL(E_GEN_FATAL_ERROR, "Maximum number of default scenario reached"); } NEW_VAR(m_default_scen[m_nb_default], - C_Scenario(this, m_channel_ctrl, m_external_data,E_EXE_DEFAULT_END,L_behaviour_scen)); + C_Scenario(this, m_channel_ctrl, + m_external_data, + E_EXE_DEFAULT_END, + L_behaviour_scen, + m_retrans_enabled)); L_current_scen = m_default_scen[m_nb_default] ; GEN_DEBUG(1, "C_ScenarioControl::add_scenario() E_SCENARIO_DEFAULT "); m_nb_default ++ ; @@ -390,7 +408,11 @@ case E_SCENARIO_ABORT: NEW_VAR(m_abort_scen, - C_Scenario(this, m_channel_ctrl, m_external_data,E_EXE_ABORT_END,L_behaviour_scen)); + C_Scenario(this, m_channel_ctrl, + m_external_data, + E_EXE_ABORT_END, + L_behaviour_scen, + m_retrans_enabled)); L_current_scen = m_abort_scen ; m_nb_scenario++; GEN_DEBUG(1, "C_ScenarioControl::add_scenario() E_SCENARIO_ABORT "); @@ -549,6 +571,9 @@ int L_msg_id = -1 ; + char *L_value_retrans = NULL ; + unsigned long L_retrans_delay = 0 ; + char *L_end_str ; GEN_DEBUG(1, "C_ScenarioControl::add_command() start"); @@ -605,9 +630,19 @@ break ; } - L_protocol = m_channel_ctrl->get_channel_protocol(L_channel_id) ; + L_value_retrans = P_data->find_value((char*)"retrans"); + if (L_value_retrans != NULL) { + L_retrans_delay = strtoul_f (L_value_retrans, &L_end_str, 10); + if (L_end_str[0] != '\0') { + GEN_ERROR(E_GEN_FATAL_ERROR, "bad format, [" + << L_value_retrans << "] not a number"); + L_ret = -1 ; + break; + } + } + L_subList = P_data -> get_sub_data() ; for(L_listIt = L_subList->begin() ; L_listIt != L_subList->end() ; @@ -648,16 +683,20 @@ // finally add message on the scenario sequence if ((L_msg != NULL) && (L_channel_id != -1)) { - (void) P_scen ->add_cmd (P_cmd_type, L_channel_id, L_msg, 0, - NULL); + NULL, + L_retrans_delay); L_cmd_inserted = true ; + if (L_retrans_delay > 0 ) { + m_retrans_delay_values->insert(T_retransDelayValuesSet::value_type(L_retrans_delay)); + } + if (*P_trafficType == E_TRAFFIC_UNKNOWN) { switch (P_cmd_type) { case E_CMD_SCEN_RECEIVE: @@ -2268,6 +2307,35 @@ return (m_wait_values); } + +T_pRetransDelayValuesSet C_ScenarioControl::get_retrans_delay_values () { + return (m_retrans_delay_values); +} + +void C_ScenarioControl::update_retrans_delay_cmd (size_t P_nb, + unsigned long *P_table) { + + int L_i ; + if (m_abort_scen != NULL) { + m_abort_scen -> update_retrans_delay_cmd (P_nb, P_table); + } + if (m_traffic_scen != NULL) { + m_traffic_scen -> update_retrans_delay_cmd (P_nb, P_table); + } + if (m_save_traffic_scen != NULL) { + m_save_traffic_scen -> update_retrans_delay_cmd(P_nb, P_table); + } + if (m_init_scen != NULL) { + m_init_scen -> update_retrans_delay_cmd (P_nb, P_table); + } + if (m_nb_default != 0) { + for(L_i=0; L_i < m_nb_default; L_i++) { + m_default_scen[L_i] -> update_retrans_delay_cmd (P_nb, P_table); + } + } +} + + void C_ScenarioControl::update_wait_cmd (size_t P_nb, unsigned long *P_table) { @@ -2690,7 +2758,7 @@ int C_ScenarioControl::get_nb_scenario () { - return m_nb_scenario; + return (m_nb_scenario); } @@ -2699,5 +2767,36 @@ return (m_nb_default); } +int C_ScenarioControl::get_max_nb_retrans () +{ + int L_i ; + int L_res = 0 ; + int L_max = 0 ; + if (m_abort_scen != NULL) { + L_res = m_abort_scen->get_nb_retrans (); + } + if (L_res > L_max) { L_max = L_res ; } + if (m_traffic_scen != NULL) { + L_res = m_traffic_scen->get_nb_retrans(); + } + if (L_res > L_max) { L_max = L_res ; } + if (m_save_traffic_scen != NULL) { + L_res = m_save_traffic_scen->get_nb_retrans(); + } + if (L_res > L_max) { L_max = L_res ; } + if (m_init_scen != NULL) { + L_res = m_init_scen->get_nb_retrans () ; + } + if (L_res > L_max) { L_max = L_res ; } + if (m_nb_default != 0) { + for(L_i=0; L_i < m_nb_default ; L_i++) { + L_res = m_default_scen[L_i]->get_nb_retrans(); + if (L_res > L_max) { L_max = L_res ; } + } + } + return (L_max); +} + + Modified: seagull/trunk/src/generator-scenario/C_ScenarioControl.hpp =================================================================== --- seagull/trunk/src/generator-scenario/C_ScenarioControl.hpp 2006-07-13 12:23:27 UTC (rev 44) +++ seagull/trunk/src/generator-scenario/C_ScenarioControl.hpp 2006-08-01 16:31:33 UTC (rev 45) @@ -47,6 +47,7 @@ } T_CounterDef, *T_pCounterDef ; typedef set_t<unsigned long> T_waitValuesSet, *T_pWaitValuesSet ; +typedef set_t<unsigned long> T_retransDelayValuesSet, *T_pRetransDelayValuesSet ; class C_ReadControl ; // prevent from circular include @@ -96,8 +97,11 @@ int memory_used () ; T_pWaitValuesSet get_wait_values () ; + T_pRetransDelayValuesSet get_retrans_delay_values () ; void update_wait_cmd (size_t P_nb, unsigned long *P_table); + void update_retrans_delay_cmd (size_t P_nb, unsigned long *P_table); + friend iostream_output& operator<<(iostream_output&, C_ScenarioControl&); bool set_counters (C_XmlData *P_xml_counter_def); @@ -109,6 +113,7 @@ int get_nb_scenario (); int get_nb_default_scenario () ; + int get_max_nb_retrans () ; private: @@ -157,8 +162,11 @@ bool m_external_data_used ; // wait values - T_pWaitValuesSet m_wait_values ; + T_pWaitValuesSet m_wait_values ; + bool m_retrans_enabled ; + T_pRetransDelayValuesSet m_retrans_delay_values ; + // generator model C_ProtocolControl *m_protocol_ctrl ; C_TransportControl *m_transport_ctrl ; @@ -236,3 +244,4 @@ + Modified: seagull/trunk/src/generator-traffic/C_CallContext.cpp =================================================================== --- seagull/trunk/src/generator-traffic/C_CallContext.cpp 2006-07-13 12:23:27 UTC (rev 44) +++ seagull/trunk/src/generator-traffic/C_CallContext.cpp 2006-08-01 16:31:33 UTC (rev 45) @@ -77,7 +77,7 @@ } -C_CallContext::C_CallContext(int P_id, int P_nbChannel, int P_mem) : C_ContextFrame() { +C_CallContext::C_CallContext(int P_id, int P_nbChannel, int P_mem, int P_nbRetrans) : C_ContextFrame() { int L_i ; m_internal_call_id = P_id ; m_state = E_CTXT_ERROR ; @@ -119,8 +119,35 @@ m_id_table[L_i].m_value.m_val_number = 0 ; } } - + m_nb_retrans = P_nbRetrans ; + if (P_nbRetrans) { + ALLOC_TABLE(m_retrans_msg, C_MessageFrame**, sizeof(C_MessageFrame*), P_nbRetrans); + ALLOC_TABLE(m_retrans_time, struct timeval*, sizeof(struct timeval), P_nbRetrans); + ALLOC_TABLE(m_nb_retrans_done, int*, sizeof(int), P_nbRetrans); + ALLOC_TABLE(m_retrans_cmd_idx, int*, sizeof(int), P_nbRetrans); + + ALLOC_TABLE(m_retrans_it, T_retransContextList::iterator*, sizeof(T_retransContextList::iterator), P_nbRetrans); + ALLOC_TABLE(m_retrans_it_available, bool*, sizeof(bool), P_nbRetrans); + + + for(L_i = 0 ; L_i < P_nbRetrans; L_i++) { + m_nb_retrans_done[L_i] = 0 ; + m_retrans_cmd_idx[L_i] = 0 ; + m_retrans_msg[L_i] = NULL ; + m_retrans_it_available[L_i] = false ; + } + } else { + m_retrans_msg = NULL ; + m_retrans_time = NULL ; + m_nb_retrans_done = NULL ; + m_retrans_cmd_idx = NULL ; + m_retrans_it = NULL ; + m_retrans_it_available = NULL ; + } + + m_retrans_to_do = false ; + } C_CallContext::~C_CallContext() { @@ -145,6 +172,16 @@ FREE_TABLE(m_channel_table); FREE_TABLE(m_id_table); + + clean_retrans(); + + FREE_TABLE(m_retrans_time); + FREE_TABLE(m_nb_retrans_done); + FREE_TABLE(m_retrans_cmd_idx); + + FREE_TABLE(m_retrans_it); + FREE_TABLE(m_retrans_it_available); + } void C_CallContext::init() { @@ -156,12 +193,15 @@ for (L_i = 0 ; L_i < m_nb_mem; L_i++) { reset_memory(L_i) ; } + + clean_retrans () ; } void C_CallContext::reset() { m_state = E_CTXT_AVAILABLE ; m_current_cmd_idx = 0 ; m_created_call = false ; + clean_retrans () ; } T_CallContextState C_CallContext::get_state() { @@ -202,7 +242,7 @@ reset_id(); m_created_call = false ; m_current_time = *P_time ; - + clean_retrans () ; return (m_state); } @@ -214,7 +254,7 @@ m_current_cmd_idx = 0 ; reset_id(); m_created_call = false ; - + clean_retrans () ; return (m_state); } @@ -225,7 +265,7 @@ m_channel_received = P_rcvCtxt->m_channel ; m_current_cmd_idx = 0 ; // m_id to be tested - + clean_retrans () ; m_created_call = false ; m_current_time = P_rcvCtxt->m_time ; @@ -267,8 +307,25 @@ m_scenario = P_scen ; m_state = P_scen->first_state(); m_current_cmd_idx = 0 ; + m_retrans_to_do = false ; } void C_CallContext::clean_suspended () { DELETE_VAR(m_suspend_msg) ; } + +void C_CallContext::clean_retrans () { + int L_i = 0 ; + for (L_i = 0 ; L_i < m_nb_retrans; L_i++) { + m_nb_retrans_done[L_i] = 0 ; + m_retrans_cmd_idx[L_i] = 0 ; + DELETE_VAR(m_retrans_msg[L_i]); + m_retrans_it_available[L_i] = false ; + } + m_retrans_to_do = false ; +} + + + + + Modified: seagull/trunk/src/generator-traffic/C_CallContext.hpp =================================================================== --- seagull/trunk/src/generator-traffic/C_CallContext.hpp 2006-07-13 12:23:27 UTC (rev 44) +++ seagull/trunk/src/generator-traffic/C_CallContext.hpp 2006-08-01 16:31:33 UTC (rev 45) @@ -42,6 +42,23 @@ class C_CallContext : public C_ContextFrame { public: + typedef struct _retrans_context { + C_CallContext * m_context ; + int m_retrans_index ; // id table internal + int m_retrans_delay_index ; // delay value index + } T_retransContext, *T_pRetransContext ; + + typedef list_t<T_retransContext> + T_retransContextList, *T_pRetransContextList; + + typedef struct _retrans_data { + T_retransContextList::iterator m_iterator ; + int m_index ; + } T_retransData, *T_pRetransData ; + + typedef list_t <T_retransData> T_retransDataList, *T_pRetransDataList ; + + // TEMPORARY bool m_created_call ; // TEMPORARY @@ -51,7 +68,19 @@ int m_suspend_id ; C_MessageFrame *m_suspend_msg ; int m_channel_id ; + + C_MessageFrame **m_retrans_msg ; + struct timeval *m_retrans_time ; + int *m_nb_retrans_done ; + int *m_retrans_cmd_idx ; + int m_nb_retrans ; + T_retransContextList::iterator *m_retrans_it; + bool *m_retrans_it_available ; + + T_retransContext m_retrans_context ; + bool m_retrans_to_do ; + T_pValueData m_id_table ; int *m_channel_table ; // response channel table @@ -60,7 +89,7 @@ int m_channel_received ; - C_CallContext(int P_id, int P_nbChannel, int P_mem=0); + C_CallContext(int P_id, int P_nbChannel, int P_mem=0, int P_nbRetrans=0); ~C_CallContext() ; T_pValueData @@ -98,6 +127,7 @@ int get_internal_id (); void clean_suspended () ; + void clean_retrans () ; private: Modified: seagull/trunk/src/generator-traffic/C_CallControl.cpp =================================================================== --- seagull/trunk/src/generator-traffic/C_CallControl.cpp 2006-07-13 12:23:27 UTC (rev 44) +++ seagull/trunk/src/generator-traffic/C_CallControl.cpp 2006-08-01 16:31:33 UTC (rev 45) @@ -58,6 +58,11 @@ m_call_timeout_abort = false ; m_open_timeout_ms = 0 ; + m_max_retrans = 0 ; + m_retrans_enabled = false ; + m_retrans_context_list = NULL ; + m_retrans_delay_values = NULL ; + m_nb_retrans_delay_values = 0 ; NEW_VAR(m_call_suspended, T_SuspendMap()); @@ -106,6 +111,24 @@ m_call_timeout_ms = 0 ; m_open_timeout_ms = 0 ; + m_max_retrans = 0 ; + m_retrans_enabled = false ; + + if (m_nb_retrans_delay_values > 0 ) { + // std::cerr << "m_nb_retrans_delay_values " << m_nb_retrans_delay_values << std::endl ; + for(L_i=0; L_i < (int)m_nb_retrans_delay_values; L_i++) { + if (!m_retrans_context_list[L_i]->empty()) { + m_retrans_context_list[L_i]->erase(m_retrans_context_list[L_i]->begin(), + m_retrans_context_list[L_i]->end()); + } + DELETE_VAR(m_retrans_context_list[L_i]); + } + FREE_TABLE(m_retrans_context_list); + } + + FREE_TABLE(m_retrans_delay_values); + m_nb_retrans_delay_values = 0; + m_call_timeout_abort = false ; for(L_i=0; L_i < m_nb_channel; L_i++) { @@ -382,6 +405,11 @@ GEN_DEBUG(1, "C_CallControl::messageReceivedControl() "<< "scenario in execution for this call"); + if (m_retrans_enabled) { + stopRetrans(L_pCallContext); + } + + if (L_pCallContext -> msg_received (&L_rcvCtxt) == false) { // scenario in execution but not in receive state GEN_LOG_EVENT_CONDITIONAL (LOG_LEVEL_TRAFFIC_ERR, @@ -494,19 +522,206 @@ GEN_DEBUG (1, "C_CallControl::endTrafficControl() end"); } +void C_CallControl::insert_retrans_list(T_pCallContext P_callContext) { + + int L_index, L_retrans_index ; + + GEN_DEBUG (1, "C_CallControl::insert_retrans_list() start"); + + L_index = P_callContext->m_retrans_context.m_retrans_delay_index ; + L_retrans_index = P_callContext->m_retrans_context.m_retrans_index ; + + m_retrans_context_list[L_index]->push_back(P_callContext->m_retrans_context); + P_callContext->m_retrans_it[L_retrans_index] = m_retrans_context_list[L_index]->end() ; + P_callContext->m_retrans_it[L_retrans_index] -- ; + P_callContext->m_retrans_it_available[L_retrans_index] = true ; + + GEN_DEBUG (1, "C_CallControl::insert_retrans_list() end"); +} + +void C_CallControl::stopRetrans (T_pCallContext P_callContext) { + + int L_i, L_cmdIdx ; + int L_retrans_delay_index ; + + + GEN_DEBUG (1, "C_CallControl::stopRetrans() start"); + + for (L_i = 0 ; L_i < P_callContext->m_nb_retrans; L_i++) { + if (P_callContext->m_retrans_it_available[L_i] == true) { + L_cmdIdx = P_callContext->m_retrans_cmd_idx[L_i]; + L_retrans_delay_index = + (P_callContext->get_scenario()->get_commands())[L_cmdIdx].m_retrans_delay_index ; + m_retrans_context_list[L_retrans_delay_index]->erase(P_callContext->m_retrans_it[L_i]) ; + P_callContext->m_retrans_it_available[L_i] = false ; + } + } + + GEN_DEBUG (1, "C_CallControl::stopRetrans() end"); +} + + +void C_CallControl::messageRetransControl () { + + GEN_DEBUG (1, "C_CallControl::messageRetransControl() start"); + + int L_i ; + int L_retrans_idx ; + int L_nbRetrans, L_nbRetransToDo ; + struct timeval L_current_time ; + C_CallContext *L_pCallContext ; + C_CallContext::T_retransContext L_retrans_ctxt ; + C_CallContext::T_retransContextList::iterator L_it; + + list_t<C_CallContext*> L_stopRetransList ; + list_t<C_CallContext*>::iterator L_stopRetransListIt ; + + list_t<C_CallContext::T_retransContextList::iterator> L_deleteList ; + list_t<C_CallContext::T_retransContextList::iterator>::iterator L_deleteListIt ; + + C_CallContext::T_retransContextList L_doRetransList ; + C_CallContext::T_retransContextList::iterator L_doRetransListIt ; + + bool L_first_get = false ; + + L_stopRetransList.clear(); + L_doRetransList.clear(); + L_deleteList.clear() ; + + for (L_i=0; L_i < (int)m_nb_retrans_delay_values; L_i++) { + if (!(m_retrans_context_list[L_i]->empty())) { + L_nbRetrans = m_retrans_context_list[L_i]->size(); + L_nbRetransToDo = (L_nbRetrans > m_max_send_loop) + ? m_max_send_loop : L_nbRetrans ; + + GEN_DEBUG (1, "C_CallControl::messageRetransControl() L_nbRetrans " << L_nbRetrans); + if (L_nbRetrans) { + if (L_first_get == false) { + GET_TIME(&L_current_time); + L_first_get = true ; + } + } + + for (L_it = m_retrans_context_list[L_i]->begin() ; + L_it != m_retrans_context_list[L_i]->end() ; + L_it++) { + + L_retrans_ctxt = *L_it; + L_pCallContext = L_retrans_ctxt.m_context ; + L_retrans_idx = L_retrans_ctxt.m_retrans_index ; + + if ( ms_difftime(&L_current_time, &L_pCallContext->m_retrans_time[L_retrans_idx]) + < (long) m_retrans_delay_values[L_i] ) { + break ; + } else { // retrans to do + if (L_pCallContext->m_nb_retrans_done[L_retrans_idx] <= (int)m_max_retrans) { + // std::cerr << "do retrans = " << L_pCallContext << std::endl ; + execute_scenario_cmd_retrans (L_retrans_idx, L_pCallContext) ; + L_doRetransList.push_back(L_retrans_ctxt); + L_deleteList.push_back(L_it); + } else { + // std::cerr << "stop (max retrans) = " << L_pCallContext << std::endl ; + L_stopRetransList.push_back(L_pCallContext) ; + } + } + + L_nbRetransToDo -- ; + if (L_nbRetransToDo == 0) break ; + + } + + if (!L_deleteList.empty()) { + for (L_deleteListIt = L_deleteList.begin(); + L_deleteListIt != L_deleteList.end(); + L_deleteListIt ++) { + m_retrans_context_list[L_i]->erase(*L_deleteListIt); + } + } + } + + if (!L_stopRetransList.empty()) { + for (L_stopRetransListIt = L_stopRetransList.begin(); + L_stopRetransListIt != L_stopRetransList.end(); + L_stopRetransListIt++) { + L_pCallContext = *L_stopRetransListIt ; + stopRetrans(L_pCallContext); + makeCallContextAvailable(&L_pCallContext) ; + m_stat -> executeStatAction (C_GeneratorStats::E_CALL_FAILED) ; + } + L_stopRetransList.erase(L_stopRetransList.begin(), + L_stopRetransList.end()); + } + + if (!L_doRetransList.empty()) { + for (L_doRetransListIt = L_doRetransList.begin(); + L_doRetransListIt != L_doRetransList.end(); + L_doRetransListIt++) { + L_retrans_ctxt = *L_doRetransListIt; + m_retrans_context_list[L_i]->push_back(L_retrans_ctxt); + L_pCallContext = L_retrans_ctxt.m_context ; + L_pCallContext->m_retrans_it[L_retrans_ctxt.m_retrans_index] = + m_retrans_context_list[L_i]->end(); + (L_pCallContext->m_retrans_it[L_retrans_ctxt.m_retrans_index])--; + } + L_doRetransList.erase(L_doRetransList.begin(), + L_doRetransList.end()); + } + } + + GEN_DEBUG (1, "C_CallControl::messageRetranstControl() end"); +} + +T_exeCode C_CallControl::execute_scenario_cmd_retrans (int P_index, T_pCallContext P_callContext) { + T_pC_Scenario L_scenario ; + T_exeCode L_exeResult ; + T_pCallContext L_callContext = P_callContext ; + + GEN_DEBUG (1, "C_CallControl::execute_scenario_cmd_retrans() start"); + + L_scenario = L_callContext->get_scenario() ; + // ctrl to max_retrans and delay + L_exeResult = L_scenario->execute_cmd_retrans (P_index, L_callContext); + + switch (L_exeResult) { + case E_EXE_NOERROR: + break ; + case E_EXE_ERROR_SEND: + makeCallContextAvailable(&L_callContext) ; + m_stat -> executeStatAction (C_GeneratorStats::E_CALL_FAILED) ; + m_stat -> executeStatAction (C_GeneratorStats::E_FAILED_CANNOT_SEND_MSG); + m_stat -> err_msg ((char*) "Send error"); + break ; + default: + m_stat -> executeStatAction (C_GeneratorStats::E_CALL_FAILED) ; + makeCallContextAvailable(&L_callContext) ; + break ; + } + GEN_DEBUG (1, "C_CallControl::execute_scenario_cmd_retrans() end"); + return (L_exeResult); +} + void C_CallControl::messageSendControl() { int L_nbSend, L_nbSendToDo ; T_pCallContext L_pCallContext ; + GEN_DEBUG (1, "C_CallControl::messageSendControl() start"); L_nbSend = m_call_ctxt_mlist -> getNbElements (E_CTXT_SEND) ; L_nbSendToDo = (L_nbSend > m_max_send_loop) ? m_max_send_loop : L_nbSend ; while (L_nbSendToDo > 0) { - L_pCallContext - = m_call_ctxt_table[m_call_ctxt_mlist->getFirst(E_CTXT_SEND)]; + L_pCallContext + = m_call_ctxt_table[m_call_ctxt_mlist->getFirst(E_CTXT_SEND)]; execute_scenario_cmd (L_pCallContext); + + if (m_retrans_enabled) { + if ((L_pCallContext->m_retrans_to_do) == true) { + insert_retrans_list(L_pCallContext) ; + L_pCallContext->m_retrans_to_do = false ; + } + } + L_nbSendToDo -- ; } GEN_DEBUG (1, "C_CallControl::messageSendControl() end"); @@ -633,6 +848,10 @@ messageOpenTimeoutControl(); } + if (m_retrans_enabled) { + messageRetransControl () ; + } + messageReceivedControl () ; if (m_nb_wait_values) { waitControl() ; } eventControl () ; @@ -647,7 +866,7 @@ T_GeneratorError L_error = E_GEN_NO_ERROR ; int L_i ; - int L_memory_used, L_channel_used ; + int L_memory_used, L_channel_used, L_nb_retrans ; C_CallContext *L_pCallContext ; unsigned long L_config_value ; @@ -655,7 +874,9 @@ T_pCallContext L_call_ctxt ; T_TrafficType L_type ; - T_pWaitValuesSet L_wait_values ; + T_pWaitValuesSet L_wait_values ; + + T_pRetransDelayValuesSet L_retrans_delay_values ; GEN_DEBUG (1, "C_CallControl::InitProcedure() start"); @@ -698,9 +919,16 @@ "Internal open timeout (ms) not specified"); } - m_call_timeout_abort = m_config -> get_call_timeout_beh_abr (); + if (!m_config->get_value(E_CFG_OPT_MAX_RETRANS, + &m_max_retrans)) { + GEN_FATAL(E_GEN_FATAL_ERROR, + "Internal max retrans is not specified"); + } + + m_retrans_enabled = m_config -> get_retrans_enabled(); + // wait values management L_wait_values = m_scenario_control->get_wait_values() ; m_nb_wait_values = L_wait_values -> size() ; @@ -738,11 +966,17 @@ L_memory_used = m_scenario_control->memory_used() ; L_channel_used = m_channel_control->nb_channel() ; + L_nb_retrans = m_scenario_control->get_max_nb_retrans(); + if (m_retrans_enabled == false) { + L_nb_retrans = 0 ; + } + for(L_i = 0; L_i < (int)m_call_ctxt_table_size; L_i++) { NEW_VAR(L_pCallContext, C_CallContext(L_i, L_channel_used, - L_memory_used)); + L_memory_used, + L_nb_retrans)); m_call_ctxt_table[L_i] = L_pCallContext ; m_call_ctxt_mlist->setElementPayload((long)L_i, L_pCallContext); } @@ -750,11 +984,47 @@ // test if an init scenario is defined L_scenario = m_scenario_control->init_scenario_defined(&L_type) ; + if (m_retrans_enabled) { + L_retrans_delay_values = m_scenario_control->get_retrans_delay_values() ; + m_nb_retrans_delay_values = L_retrans_delay_values -> size() ; + + // std::cerr << "m_nb_retrans_delay_values=" << m_nb_retrans_delay_values << std::endl ; + + if (m_nb_retrans_delay_values != 0) { + + T_retransDelayValuesSet::iterator L_retransDelayIt ; + int L_i ; + + ALLOC_TABLE(m_retrans_delay_values, + unsigned long*, + sizeof(unsigned long), + m_nb_retrans_delay_values); + L_i = 0 ; + for (L_retransDelayIt = L_retrans_delay_values->begin(); + L_retransDelayIt != L_retrans_delay_values->end() ; + L_retransDelayIt++) { + m_retrans_delay_values[L_i] = *L_retransDelayIt ; + L_i ++ ; + } + + ALLOC_TABLE(m_retrans_context_list, C_CallContext::T_pRetransContextList*, sizeof(C_CallContext::T_pRetransContextList), m_nb_retrans_delay_values); + for (L_i = 0 ; L_i < (int)m_nb_retrans_delay_values; L_i++) { + NEW_VAR(m_retrans_context_list[L_i], + C_CallContext::T_retransContextList()); + } + + + m_scenario_control -> update_retrans_delay_cmd (m_nb_retrans_delay_values, + m_retrans_delay_values); + } + + } + m_stat->init(); if (L_scenario == NULL) { GEN_WARNING("no init scenario defined"); } else { - + switch(L_type) { case E_TRAFFIC_CLIENT: @@ -1115,6 +1385,10 @@ GEN_LOG_EVENT(LOG_LEVEL_TRAFFIC_ERR, "Call timeout detected"); + if (m_retrans_enabled) { + stopRetrans(L_pCallContext); + } + // Timeout for scenario stats if ((L_stats = (L_pCallContext->get_scenario())->get_stats()) != NULL) { L_stats -> updateStats(L_pCallContext->get_current_cmd_idx(), @@ -1132,10 +1406,12 @@ ->moveToList(L_pCallContext->get_state(), L_pCallContext->get_internal_id()); } else { + m_stat->executeStatAction(C_GeneratorStats::E_CALL_FAILED); makeCallContextAvailable(&L_pCallContext); } } else { + m_stat->executeStatAction(C_GeneratorStats::E_CALL_FAILED); makeCallContextAvailable (&L_pCallContext) ; } Modified: seagull/trunk/src/generator-traffic/C_CallControl.hpp =================================================================== --- seagull/trunk/src/generator-traffic/C_CallControl.hpp 2006-07-13 12:23:27 UTC (rev 44) +++ seagull/trunk/src/generator-traffic/C_CallControl.hpp 2006-08-01 16:31:33 UTC (rev 45) @@ -38,6 +38,7 @@ #include "list_t.hpp" #include "map_t.hpp" + #include "gen_operation_t.hpp" #include "ProtocolData.hpp" @@ -60,7 +61,7 @@ T_pCallContext> T_CallMap, *T_pCallMap ; typedef map_t<int, T_pCallContext> T_SuspendMap, *T_pSuspendMap ; - + C_CallControl(C_GeneratorConfig *P_config, T_pC_ScenarioControl P_scenControl, C_ChannelControl *P_channel_ctrl); @@ -131,6 +132,13 @@ unsigned long m_open_timeout_ms ; + unsigned long m_max_retrans ; + unsigned long m_retrans_enabled ; + C_CallContext::T_pRetransContextList *m_retrans_context_list ; + + unsigned long *m_retrans_delay_values ; + size_t m_nb_retrans_delay_values ; + // TaskController related methods T_GeneratorError TaskProcedure(); T_GeneratorError InitProcedure(); @@ -152,6 +160,12 @@ T_exeCode execute_scenario_cmd (T_pCallContext P_callContext, bool P_resume=false) ; + void messageRetransControl () ; + T_exeCode execute_scenario_cmd_retrans (int P_index, T_pCallContext P_callContext); + void insert_retrans_list(T_pCallContext P_callContext) ; + + void stopRetrans (T_pCallContext P_callContext) ; + void makeCallContextAvailable (T_pCallContext *P_pCallCxt) ; T_pCallContext makeCallContextUnavailable (C_Scenario *P_scen); T_pCallContext retrieve_call_context (int P_channel_id, T_pValueData P_id); Modified: seagull/trunk/src/library-trans-ip/C_Socket.cpp =================================================================== --- seagull/trunk/src/library-trans-ip/C_Socket.cpp 2006-07-13 12:23:27 UTC (rev 44) +++ seagull/trunk/src/library-trans-ip/C_Socket.cpp 2006-08-01 16:31:33 UTC (rev 45) @@ -212,6 +212,12 @@ &L_linger, sizeof (L_linger)) < 0) { SOCKET_ERROR(1, "Unable to set SO_LINGER option"); } + + // non blocking mode (for connect only ?) + L_flags = call_fcntl(m_socket_id, F_GETFL , NULL); + L_flags |= O_NONBLOCK; + call_fcntl(m_socket_id, F_SETFL , L_flags); + } // size of recv buf @@ -229,9 +235,9 @@ } // non blocking mode (for connect only ?) - L_flags = call_fcntl(m_socket_id, F_GETFL , NULL); - L_flags |= O_NONBLOCK; - call_fcntl(m_socket_id, F_SETFL , L_flags); + // L_flags = call_fcntl(m_socket_id, F_GETFL , NULL); + // L_flags |= O_NONBLOCK; + // call_fcntl(m_socket_id, F_SETFL , L_flags); } @@ -259,6 +265,14 @@ return (0); } +T_SockAddrStorage* C_SocketListen::get_remote_sockaddr_ptr() { + return (NULL); +} + +tool_socklen_t* C_SocketListen::get_len_remote_sockaddr_ptr() { + return (NULL); +} + int C_SocketListen::_open (size_t P_buffer_size, C_ProtocolBinaryFrame *P_protocol) { @@ -271,7 +285,7 @@ P_protocol) ; if (L_rc == 0) { - + set_properties() ; /* bind the socket to the newly formed address */ @@ -319,20 +333,20 @@ m_read_buf_size, m_segm_buf_size)); L_ret = L_socket->_open(m_buffer_size, m_protocol) ; if (L_ret == 0) { - SOCKET_DEBUG(0, "C_SocketWithData::process_fd_set() CNX"); + SOCKET_DEBUG(0, "C_SocketListen::process_fd_set() CNX"); P_event->m_type = C_TransportEvent::E_TRANS_CONNECTION ; P_event->m_channel_id = m_channel_id ; P_event->m_id = L_socket->get_id() ; } else { - SOCKET_DEBUG(0, "C_SocketWithData::process_fd_set() NOEVENT open failed"); + SOCKET_DEBUG(0, "C_SocketListen::process_fd_set() NOEVENT open failed"); DELETE_VAR(L_socket); P_event->m_type = C_TransportEvent::E_TRANS_NO_EVENT ; } } else { - SOCKET_DEBUG(0, "C_SocketWithData::process_fd_set() NOEVENT"); + SOCKET_DEBUG(0, "C_SocketListen::process_fd_set() NOEVENT"); P_event->m_type = C_TransportEvent::E_TRANS_NO_EVENT ; } - + return (L_socket); } @@ -340,11 +354,9 @@ return(&(m_source_addr_info->m_addr)); } -// UDP T_SocketType C_SocketListen::get_trans_type() { return(m_type); } -// UDP C_SocketServer::C_SocketServer(C_SocketListen *P_listen, int P_channel_id, @@ -353,17 +365,62 @@ : C_SocketWithData(P_channel_id, P_read_buf_size, P_segm_buf_size) { SOCKET_DEBUG(0, "C_SocketServer::C_SocketServer() id=" << m_socket_id); m_listen_sock = P_listen ; - // UDP + m_source_udp_addr_info = NULL ; m_type = m_listen_sock->get_trans_type(); - if (m_type == E_SOCKET_UDP_MODE) { - // std::cerr << "m_socket_id before " << m_socket_id << std::endl; - m_socket_id = m_listen_sock->get_id(); - // std::cerr << "m_socket_id " << m_socket_id << std::endl; - } - // UDP - // std::cerr << "m_type " << m_type << std::endl; } +C_SocketServer::C_SocketServer(T_SocketType P_type, + T_pIpAddr P_addr, + int P_channel_id, + size_t P_read_buf_size, + size_t P_segm_buf_size) + : C_SocketWithData(P_type, + P_addr, + P_channel_id, + P_read_buf_size, + P_segm_buf_size) { + m_listen_sock = NULL ; + m_source_udp_addr_info = P_addr ; + SOCKET_DEBUG(0, "C_SocketServer::C_SocketServer() id=" << m_socket_id); +} + +int C_SocketServer::_open_udp (size_t P_buffer_size, + C_ProtocolBinaryFrame *P_protocol) { + + int L_rc ; /* system calls return value storage */ + + SOCKET_DEBUG(0, "C_SocketServer::_open_udp()"); + + L_rc = C_Socket::_open(get_domain(m_source_udp_addr_info), + P_buffer_size, + P_protocol) ; + + if (L_rc == 0) { + + m_protocol = P_protocol ; + + m_buffer_size = P_buffer_size ; + + set_properties() ; + + /* bind the socket to the newly formed address */ + L_rc = call_bind(m_socket_id, + (sockaddr *)(void *)&(m_source_udp_addr_info->m_addr), + SOCKADDR_IN_SIZE(&(m_source_udp_addr_info->m_addr))); + /* check there was no error */ + if (L_rc) { + SOCKET_ERROR(1, "bind [" << strerror(errno) << "]"); + } else { + m_remote_sockaddr = m_source_udp_addr_info->m_addr; + m_len_remote_sockaddr = SOCKADDR_IN_SIZE(&(m_source_udp_addr_info->m_addr)); + m_remote_sockaddr_ptr = &m_remote_sockaddr ; + m_len_remote_sockaddr_ptr = &m_len_remote_sockaddr ; + m_state = E_SOCKET_STATE_READY ; + } + } + return (L_rc); +} + C_SocketServer::~C_SocketServer() { SOCKET_DEBUG(0, "C_SocketServer::~C_SocketServer() id=" << m_socket_id); } @@ -376,17 +433,13 @@ SOCKET_DEBUG(0, "C_SocketServer::_open()"); - // UDP - if (m_type == E_SOCKET_TCP_MODE) { - L_size = SOCKADDR_IN_SIZE(m_listen_sock->get_source_address()); memset(&m_accepted_addr, 0, L_size); - + m_socket_id = call_accept (m_listen_sock->get_id(), - (sockaddr *)(void *)&m_accepted_addr, - &L_size); + (sockaddr *)(void *)&m_accepted_addr, + &L_size); - } // UDP m_protocol = P_protocol ; @@ -432,38 +485,45 @@ if (L_rc == 0) { set_properties() ; - // UDP - if (m_type == E_SOCKET_TCP_MODE) { + if (m_type == E_SOCKET_TCP_MODE) { - L_rc = call_connect (m_socket_id, - (struct sockaddr*)(void*)&(m_remote_addr_info->m_addr), - SOCKADDR_IN_SIZE(&(m_remote_addr_info->m_addr))) ; - if (L_rc) { - if (errno != EINPROGRESS) { - SOCKET_ERROR(1, "connect failed [" - << L_rc << "][" - << strerror(errno) << "]"); - *P_status = E_OPEN_FAILED ; + L_rc = call_connect (m_socket_id, + (struct sockaddr*)(void*)&(m_remote_addr_info->m_addr), + SOCKADDR_IN_SIZE(&(m_remote_addr_info->m_addr))) ; + if (L_rc) { + if (errno != EINPROGRESS) { + SOCKET_ERROR(1, "connect failed [" + << L_rc << "][" + << strerror(errno) << "]"); + *P_status = E_OPEN_FAILED ; + } else { + m_state = E_SOCKET_STATE_INPROGESS ; + *P_status = E_OPEN_DELAYED ; + L_rc = 0 ; + } + } else { - m_state = E_SOCKET_STATE_INPROGESS ; - *P_status = E_OPEN_DELAYED ; - L_rc = 0 ; + m_state = E_SOCKET_STATE_READY ; + *P_status = E_OPEN_OK ; } - } else { - m_state = E_SOCKET_STATE_READY ; - *P_status = E_OPEN_OK ; + L_rc = call_bind(m_socket_id, + (sockaddr *)(void *)&(m_remote_addr_info->m_addr_src), + SOCKADDR_IN_SIZE(&(m_remote_addr_info->m_addr_src))); + + if (L_rc) { + SOCKET_ERROR(1, "bind [" << strerror(errno) << "]"); + } else { + m_remote_sockaddr = m_remote_addr_info->m_addr; + m_len_remote_sockaddr = SOCKADDR_IN_SIZE(&(m_remote_addr_info->m_addr)); + m_remote_sockaddr_ptr = &m_remote_sockaddr ; + m_len_remote_sockaddr_ptr = &m_len_remote_sockaddr ; + + m_state = E_SOCKET_STATE_READY ; + *P_status = E_OPEN_OK ; + } } - } else { - - // UDP - // bind - m_state = E_SOCKET_STATE_READY ; - *P_status = E_OPEN_OK ; } - // UDP - - } return (L_rc); } @@ -499,9 +559,21 @@ m_read_buf_size = P_read_buf_size ; ALLOC_TABLE(m_read_buf, char*, sizeof(char), m_read_buf_size); + m_remote_sockaddr_ptr = NULL ; + m_len_remote_sockaddr_ptr = NULL ; + + m_len_remote_sockaddr = SOCKADDR_IN_SIZE(&m_remote_sockaddr); + memset(&m_remote_sockaddr, 0, m_len_remote_sockaddr); } +T_SockAddrStorage* C_SocketWithData::get_remote_sockaddr_ptr() { + return (m_remote_sockaddr_ptr); +} +tool_socklen_t* C_SocketWithData::get_len_remote_sockaddr_ptr() { + return (m_len_remote_sockaddr_ptr); +} + C_SocketWithData::~C_SocketWithData() { SOCKET_DEBUG(0, "C_SocketWithData::~C_SocketWithData()"); if (!m_data_queue.empty()) { @@ -532,14 +604,17 @@ SOCKET_DEBUG(0, "C_SocketWithData::process_fd_set() id=" << m_socket_id); - switch (m_state) { case E_SOCKET_STATE_READY: if (FD_ISSET(m_socket_id, P_rSet)) { - L_rc = call_read(m_socket_id, L_buf, m_read_buf_size); - // UDP + if (m_type == E_SOCKET_TCP_MODE) { + L_rc = call_read(m_socket_id, L_buf, m_read_buf_size); + } else { + L_rc = _read(L_buf); + } + if (L_rc <= 0) { SOCKET_DEBUG(0, "C_SocketWithData::process_fd_set() CLOSED"); P_event->m_type = C_TransportEvent::E_TRANS_CLOSED ; @@ -630,3 +705,20 @@ return (L_size); } +int C_SocketServer::_read (void* P_buffer) { + return (call_recvfrom(m_socket_id, + P_buffer, + m_read_buf_size, + 0, + (sockaddr *)(void *)m_remote_sockaddr_ptr, + m_len_remote_sockaddr_ptr)); +} + +int C_SocketClient::_read (void* P_buffer) { + return (call_recvfrom(m_socket_id, + P_buffer, + m_read_buf_size, + 0, + NULL, + NULL)); +} Modified: seagull/trunk/src/library-trans-ip/C_Socket.hpp =================================================================== --- seagull/trunk/src/library-trans-ip/C_Socket.hpp 2006-07-13 12:23:27 UTC (rev 44) +++ seagull/trunk/src/library-trans-ip/C_Socket.hpp 2006-08-01 16:31:33 UTC (rev 45) @@ -75,6 +75,10 @@ virtual C_Socket* process_fd_set(fd_set *P_rSet, fd_set *P_wSet, C_TransportEvent *P_event) = 0 ; + + virtual T_SockAddrStorage* get_remote_sockaddr_ptr() = 0 ; + virtual tool_socklen_t* get_len_remote_sockaddr_ptr() = 0 ; + void set_channel_id(int P_channel_id); void set_properties () ; C_pDataDecode get_decode () ; @@ -111,10 +115,15 @@ size_t P_read_buf_size, size_t P_segm_buf_size) ; virtual ~C_SocketWithData() ; - C_Socket* process_fd_set(fd_set *P_rSet, fd_set *P_wSet, C_TransportEvent *P_event) ; + virtual C_Socket* process_fd_set(fd_set *P_rSet, fd_set *P_wSet, C_TransportEvent *P_event) ; + virtual int _read (void *P_buf) = 0 ; size_t received_buffer (unsigned char *P_data, size_t P_size_buf, struct timeval *P_time) ; + + T_SockAddrStorage* get_remote_sockaddr_ptr() ; + tool_socklen_t* get_len_remote_sockaddr_ptr() ; + protected: @@ -125,6 +134,14 @@ size_t m_read_buf_size ; char *m_read_buf ; + + T_SockAddrStorage m_remote_sockaddr ; + tool_socklen_t m_len_remote_sockaddr ; + + T_SockAddrStorage* m_remote_sockaddr_ptr ; + tool_socklen_t* m_len_remote_sockaddr_ptr ; + + } ; class C_SocketListen : public C_Socket { @@ -138,17 +155,18 @@ size_t P_segm_buf_size) ; virtual ~C_SocketListen() ; int _open (size_t P_buffer_size, C_ProtocolBinaryFrame *P_protocol) ; - C_Socket* process_fd_set(fd_set *P_rSet, + virtual C_Socket* process_fd_set(fd_set *P_rSet, fd_set *P_wSet, C_TransportEvent *P_event) ; size_t received_buffer (unsigned char *P_data, size_t P_size_buf, struct timeval *P_time) ; T_SockAddrStorage * get_source_address () ; - // UDP - T_SocketType get_trans_type() ; ; + + T_SocketType get_trans_type() ; + T_SockAddrStorage* get_remote_sockaddr_ptr() ; + tool_socklen_t* get_len_remote_sockaddr_ptr() ; - protected: T_pIpAddr m_source_addr_info ; @@ -167,11 +185,25 @@ int P_channel_id, size_t P_read_buf_size, size_t P_segm_buf_size); + + C_SocketServer(T_SocketType P_type, + T_pIpAddr P_addr, + int P_channel_id, + size_t P_read_buf_size, + size_t P_segm_buf_size) ; + + virtual ~C_SocketServer(); int _open (size_t P_buffer_size, C_ProtocolBinaryFrame *P_protocol) ; + int _open_udp (size_t P_buffer_size, + C_ProtocolBinaryFrame *P_protocol) ; + + int _read (void *P_buf) ; + private: - C_SocketListen *m_listen_sock ; + C_SocketListen *m_listen_sock ; + T_pIpAddr m_source_udp_addr_info ; } ; @@ -187,6 +219,8 @@ int _open (T_pOpenStatus P_status, size_t P_buffer_size, C_ProtocolBinaryFrame *P_protocol); + int _read (void *P_buf) ; + } ; typedef map_t<int, C_Socket*> T_SocketMap, *T_pSocketMap ; Modified: seagull/trunk/src/library-trans-ip/C_TransIP.cpp =================================================================== --- seagull/trunk/src/library-trans-ip/C_TransIP.cpp 2006-07-13 12:23:27 UTC (rev 44) +++ seagull/trunk/src/library-trans-ip/C_TransIP.cpp 2006-08-01 16:31:33 UTC (rev 45) @@ -303,7 +303,11 @@ unsigned char *L_data = m_encode_buffer ; C_ProtocolBinaryFrame *L_protocol ; + + T_SockAddrStorage *L_remote_sockaddr = NULL ; + tool_socklen_t *L_len_remote_sockaddr = NULL ; + C_ProtocolFrame::T_MsgError L_error = C_ProtocolFrame::E_MSG_OK ; @@ -315,33 +319,46 @@ L_socket = L_it->second ; L_protocol = L_socket -> get_protocol() ; + if (m_trans_type == E_SOCKET_UDP_MODE) { + L_remote_sockaddr = L_socket->get_remote_sockaddr_ptr () ; + L_len_remote_sockaddr = L_socket->get_len_remote_sockaddr_ptr() ; + } + L_error = L_protocol->encode_message(P_msg, L_data, &L_size); if (L_error == C_ProtocolFrame::E_MSG_OK) { L_protocol->log_buffer((char*)"sent", L_data, L_size); - // L_ret = send_buffer2(P_id, L_data, L_size) ; - (void) send_buffer(P_id, L_data, L_size) ; + (void) send_buffer(P_id, L_data, L_size, L_remote_sockaddr, L_len_remote_sockaddr) ; } } return (0) ; } -size_t C_TransIP::send_buffer (int P_id, - unsigned char *P_data, - size_t P_size) { +size_t C_TransIP::send_buffer (int P_id, + ... [truncated message content] |