00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "C_CallControl.hpp"
00021 #include "Utils.hpp"
00022 #include "GeneratorTrace.hpp"
00023 #include "C_MultiList.cpp"
00024
00025 #include "C_ScenarioStats.hpp"
00026
00027 #include <cerrno>
00028 #include <cstring>
00029 #include <cmath>
00030
00031
00032 C_CallControl::C_CallControl(C_GeneratorConfig *P_config,
00033 T_pC_ScenarioControl P_scenControl,
00034 C_ChannelControl *P_channel_ctrl) : C_TaskControl() {
00035 GEN_DEBUG (1, "C_CallControl::C_CallControl() start");
00036
00037 int L_i ;
00038
00039 NEW_VAR(m_msg_rcv_ctxt_list, T_RcvMsgCtxtList());
00040 NEW_VAR(m_event_list, T_EventRecvList());
00041 m_call_ctxt_table = NULL ;
00042 m_call_ctxt_table_size = 0 ;
00043 m_scenario_control = NULL ;
00044 m_call_ctxt_mlist = NULL ;
00045 m_stat = C_GeneratorStats::instance() ;
00046
00047 m_config = NULL ;
00048 m_max_send_loop = 0 ;
00049 m_max_receive_loop = 0 ;
00050 m_call_timeout_ms = 0 ;
00051
00052 m_accept_new_call = true ;
00053
00054 m_call_created = 0 ;
00055 m_pause = false ;
00056
00057
00058 m_type = E_TRAFFIC_SERVER ;
00059
00060 m_nb_wait_values = 0 ;
00061 m_wait_values = NULL ;
00062
00063 m_call_timeout_abort = false ;
00064 m_open_timeout_ms = 0 ;
00065
00066 m_max_retrans = 0 ;
00067 m_retrans_enabled = false ;
00068 m_retrans_context_list = NULL ;
00069 m_retrans_delay_values = NULL ;
00070 m_nb_retrans_delay_values = 0 ;
00071
00072 m_nb_send_per_scene = 0 ;
00073 m_nb_recv_per_scene = 0 ;
00074
00075 NEW_VAR(m_call_suspended, T_SuspendMap());
00076
00077 m_config = P_config ;
00078 m_scenario_control = P_scenControl ;
00079 m_channel_control = P_channel_ctrl ;
00080
00081 m_nb_channel = m_channel_control->nb_channel();
00082
00083 ALLOC_TABLE(m_call_map_table,
00084 T_pCallMap*,
00085 sizeof(T_pCallMap),
00086 m_nb_channel);
00087 for(L_i=0; L_i < m_nb_channel; L_i++) {
00088 NEW_VAR(m_call_map_table[L_i], T_CallMap());
00089 }
00090
00091 GEN_DEBUG (1, "C_CallControl::C_CallControl() end");
00092 }
00093
00094 T_pCallMap* C_CallControl::get_call_map () {
00095 return (m_call_map_table) ;
00096 }
00097
00098 void C_CallControl::start_traffic() {
00099 }
00100
00101 C_CallControl::~C_CallControl() {
00102
00103 int L_i ;
00104
00105 GEN_DEBUG (1, "C_CallControl::~C_CallControl() start");
00106
00107 DELETE_VAR(m_msg_rcv_ctxt_list);
00108 DELETE_VAR(m_event_list);
00109 FREE_TABLE(m_call_ctxt_table);
00110 m_call_ctxt_table_size = 0 ;
00111 m_scenario_control = NULL ;
00112 DELETE_VAR(m_call_ctxt_mlist);
00113 m_stat = NULL ;
00114
00115 m_config = NULL ;
00116 m_max_send_loop = 0 ;
00117 m_max_receive_loop = 0 ;
00118 m_pause = false ;
00119
00120 FREE_TABLE(m_wait_values);
00121 m_nb_wait_values = 0 ;
00122
00123 m_config = NULL ;
00124 m_scenario_control = NULL ;
00125
00126 m_call_timeout_ms = 0 ;
00127 m_open_timeout_ms = 0 ;
00128
00129 m_max_retrans = 0 ;
00130 m_retrans_enabled = false ;
00131
00132 m_nb_send_per_scene = 0 ;
00133 m_nb_recv_per_scene = 0 ;
00134
00135
00136 if (m_nb_retrans_delay_values > 0 ) {
00137
00138 for(L_i=0; L_i < (int)m_nb_retrans_delay_values; L_i++) {
00139 if (!m_retrans_context_list[L_i]->empty()) {
00140 m_retrans_context_list[L_i]->erase(m_retrans_context_list[L_i]->begin(),
00141 m_retrans_context_list[L_i]->end());
00142 }
00143 DELETE_VAR(m_retrans_context_list[L_i]);
00144 }
00145 FREE_TABLE(m_retrans_context_list);
00146 }
00147
00148 FREE_TABLE(m_retrans_delay_values);
00149 m_nb_retrans_delay_values = 0;
00150
00151 m_call_timeout_abort = false ;
00152
00153 for(L_i=0; L_i < m_nb_channel; L_i++) {
00154 if (!m_call_map_table[L_i]->empty()) {
00155 m_call_map_table[L_i]->erase(m_call_map_table[L_i]->begin(),
00156 m_call_map_table[L_i]->end());
00157 }
00158 DELETE_VAR(m_call_map_table[L_i]);
00159 }
00160 FREE_TABLE(m_call_map_table);
00161 GEN_DEBUG (1, "C_CallControl::~C_CallControl() end");
00162 }
00163
00164 void C_CallControl::init_done() {
00165 GEN_DEBUG (1, "C_CallControl::init_done() start");
00166 m_scenario_control->switch_to_traffic();
00167 GEN_DEBUG (1, "C_CallControl::init_done() end");
00168 }
00169
00170 void C_CallControlClient::init_done() {
00171 GEN_DEBUG (1, "C_CallControlClient::init_done() start");
00172 m_outgoing_traffic = true ;
00173 m_traffic_model->start();
00174 C_CallControl::init_done() ;
00175 GEN_DEBUG (1, "C_CallControlClient::init_done() end");
00176 }
00177
00178
00179 void C_CallControl::eventReceived (T_pEventRecv P_event) {
00180 GEN_DEBUG (1, "C_CallControl::openEvent() start");
00181 m_event_list->push_back(*P_event);
00182 GEN_DEBUG (1, "C_CallControl::openEvent() end");
00183 }
00184
00185 void C_CallControl::messageReceived (T_pReceiveMsgContext P_ctxt) {
00186 GEN_DEBUG (1, "C_CallControl::messageReceived() start");
00187 m_stat -> executeStatAction (C_GeneratorStats::E_RECV_MSG);
00188 m_msg_rcv_ctxt_list -> push_back (*P_ctxt) ;
00189 GEN_DEBUG (1, "C_CallControl::messageReceived() end");
00190 }
00191
00192 T_pCallContext C_CallControl::makeCallContextUnavailable (C_Scenario *P_scen) {
00193
00194 T_pCallContext L_pCallContext = NULL ;
00195 int L_callContextIdx ;
00196 T_CallContextState L_state ;
00197
00198
00199 if (m_call_ctxt_mlist->getNbElements(E_CTXT_AVAILABLE)!= 0) {
00200
00201
00202 L_callContextIdx = m_call_ctxt_mlist->getFirst(E_CTXT_AVAILABLE);
00203 L_pCallContext = m_call_ctxt_table[L_callContextIdx];
00204
00205 L_state = L_pCallContext -> init_state (P_scen) ;
00206 m_call_ctxt_mlist -> moveToList(L_state, L_callContextIdx);
00207
00208
00209
00210 L_pCallContext -> m_created_call = true ;
00211
00212
00213 m_stat -> executeStatAction (C_GeneratorStats::E_CREATE_OUTGOING_CALL);
00214 }
00215
00216 return (L_pCallContext) ;
00217 }
00218
00219
00220 void C_CallControlClient::start_traffic() {
00221
00222 T_pC_Scenario L_scenario ;
00223 T_TrafficType L_type ;
00224 T_pCallContext L_call_ctxt ;
00225
00226 L_scenario = m_scenario_control->init_scenario_defined(&L_type) ;
00227 if (L_scenario != NULL) {
00228 GEN_DEBUG (1, "C_CallControl::InitProcedure() E_TRAFFIC_CLIENT");
00229 L_call_ctxt = C_CallControl::makeCallContextUnavailable(L_scenario);
00230 if (L_call_ctxt == NULL) {
00231 GEN_ERROR(E_GEN_FATAL_ERROR,
00232 "No context available to execute init scenario");
00233 }
00234 } else {
00235 m_outgoing_traffic = true ;
00236 m_traffic_model->start();
00237 }
00238 }
00239
00240 T_pCallContext C_CallControlClient::makeCallContextUnavailable () {
00241
00242 T_pCallContext L_pCallContext = NULL ;
00243 int L_callContextIdx ;
00244 T_CallContextState L_state ;
00245
00246
00247 if (m_call_ctxt_mlist->getNbElements(E_CTXT_AVAILABLE)!= 0) {
00248
00249
00250 L_callContextIdx = m_call_ctxt_mlist->getFirst(E_CTXT_AVAILABLE);
00251 L_pCallContext = m_call_ctxt_table[L_callContextIdx] ;
00252
00253 L_state = L_pCallContext -> init_state (m_traffic_scen);
00254 m_call_ctxt_mlist -> moveToList(L_state, L_callContextIdx);
00255
00256
00257
00258 L_pCallContext -> m_created_call = true ;
00259
00260
00261 m_traffic_model->call_created() ;
00262 m_stat -> executeStatAction (C_GeneratorStats::E_CREATE_OUTGOING_CALL);
00263 }
00264
00265 return (L_pCallContext) ;
00266 }
00267
00268 void C_CallControl::makeCallContextAvailable (T_pCallContext *P_pCallCtxt) {
00269
00270 int L_id ;
00271 T_pCallContext L_callCtxt ;
00272 T_CallMap::iterator L_call_it ;
00273 int L_i ;
00274
00275 GEN_DEBUG (1, "C_CallControl::makeCallContextAvailable() start");
00276
00277 L_callCtxt = *P_pCallCtxt ;
00278
00279 L_id = L_callCtxt -> get_internal_id();
00280
00281
00282 for(L_i=0; L_i < m_nb_channel; L_i++) {
00283 L_call_it = m_call_map_table[L_i]
00284 ->find (T_CallMap::key_type(L_callCtxt->m_id_table[L_i]));
00285 if (L_call_it != m_call_map_table[L_i]->end()) {
00286 m_call_map_table[L_i]->erase (L_call_it);
00287 }
00288 }
00289
00290
00291 L_callCtxt->init();
00292 m_channel_control->reset_channel(L_callCtxt->m_channel_table);
00293 m_call_ctxt_mlist->moveToList(E_CTXT_AVAILABLE, L_id);
00294
00295 *P_pCallCtxt = NULL ;
00296
00297 GEN_DEBUG (1, "C_CallControl::makeCallContextAvailable() end");
00298
00299 }
00300
00301 void C_CallControl::messageReceivedControl () {
00302
00303 int L_nbMsgReceived, L_nbMsg, L_i ;
00304
00305 C_MessageFrame *L_msg = NULL ;
00306 T_ReceiveMsgContext L_rcvCtxt ;
00307
00308 T_pCallContext L_pCallContext = NULL ;
00309 T_pC_Scenario L_scenario = NULL ;
00310 T_exeCode L_exeResult ;
00311
00312 int L_callContextIdx ;
00313
00314
00315
00316 #ifdef INIT_CALL_FILTER
00317 T_ValueData L_filtered_value ;
00318 bool L_filter = false ;
00319 #endif //INIT_CALL_FILTER
00320
00321 T_pValueData L_value_id = NULL ;
00322
00323
00324
00325 GEN_DEBUG (1, "C_CallControl::messageReceivedControl() start");
00326
00327 L_nbMsgReceived = m_msg_rcv_ctxt_list -> size();
00328
00329 L_nbMsg = (L_nbMsgReceived > m_max_receive_loop)
00330 ? m_max_receive_loop : L_nbMsgReceived;
00331
00332 for(L_i=0; L_i < L_nbMsg; L_i++) {
00333
00334 L_rcvCtxt = *(m_msg_rcv_ctxt_list -> begin()) ;
00335 m_msg_rcv_ctxt_list -> erase (m_msg_rcv_ctxt_list->begin()) ;
00336
00337 L_msg = L_rcvCtxt.m_msg ;
00338
00339 L_value_id = L_msg -> get_session_id (&L_rcvCtxt) ;
00340 if (L_value_id == NULL) {
00341 GEN_DEBUG(1, "C_CallControl::messageReceivedControl() L_value_id == NULL and now is " << L_value_id);
00342 #ifdef INIT_CALL_FILTER
00343 L_filter = false ;
00344 #endif // INIT_CALL_FILTER
00345 }
00346 #ifdef INIT_CALL_FILTER
00347 else {
00348 if (L_value_id->m_type == E_TYPE_STRUCT) {
00349 L_filtered_value = *L_value_id ;
00350 L_filtered_value.m_value.m_val_struct.m_id_2 = 0 ;
00351 L_filter = true ;
00352 } else L_filter = false ;
00353 }
00354 #endif // INIT_CALL_FILTER
00355
00356 if (L_value_id != NULL) {
00357 L_pCallContext = retrieve_call_context (L_rcvCtxt.m_channel, L_value_id);
00358
00359 #ifdef INIT_CALL_FILTER
00360 if ((L_pCallContext == NULL) && (L_filter == true)) {
00361 L_pCallContext = retrieve_call_context (L_rcvCtxt.m_channel, &L_filtered_value);
00362 }
00363 #endif // INIT_CALL_FILTER
00364
00365 } else {
00366 L_pCallContext = NULL ;
00367 }
00368
00369 if (L_pCallContext == NULL) {
00370
00371
00372 GEN_DEBUG(1, "C_CallControl::messageReceivedControl() L_pCallContext == NULL");
00373
00374 if (m_accept_new_call == true) {
00375 GEN_DEBUG(1, "C_CallControl::messageReceivedControl() m_accept_new_call == true");
00376 L_scenario = m_scenario_control -> find_scenario (&L_rcvCtxt);
00377 if (L_scenario != NULL) {
00378
00379
00380 if (m_call_ctxt_mlist->getNbElements(E_CTXT_AVAILABLE)!= 0) {
00381
00382 L_callContextIdx
00383 = m_call_ctxt_mlist->getFirst(E_CTXT_AVAILABLE);
00384 L_pCallContext = m_call_ctxt_table[L_callContextIdx];
00385 L_pCallContext -> init_state (L_scenario, &L_rcvCtxt);
00386
00387
00388
00389 if (L_scenario->get_exe_end_code() != E_EXE_IGNORE ) {
00390 m_stat -> executeStatAction (C_GeneratorStats::E_CREATE_INCOMING_CALL);
00391 if (m_type == E_TRAFFIC_SERVER) {
00392 m_call_created ++ ;
00393 }
00394 }
00395 } else {
00396
00397
00398
00399 GEN_ERROR(1, "No more context available");
00400 L_pCallContext = NULL ;
00401 GEN_LOG_EVENT_CONDITIONAL (LOG_LEVEL_TRAFFIC_ERR,
00402 L_value_id != NULL,
00403 "Refused (no more context) call with session-id ["
00404 << *L_value_id << "]");
00405 m_stat -> executeStatAction (C_GeneratorStats::E_CALL_REFUSED) ;
00406 }
00407 } else {
00408
00409
00410
00411
00412
00413
00414 GEN_ERROR(1,"Unexpexted message that doesn't match the scenario.");
00415
00416 if (!(genTraceLevel & gen_mask_table[LOG_LEVEL_TRAFFIC_ERR])) {
00417 GEN_ERROR(1,"Activate 'T' log level");
00418 }
00419
00420 L_pCallContext = NULL ;
00421
00422 GEN_LOG_EVENT_CONDITIONAL (LOG_LEVEL_TRAFFIC_ERR,
00423 L_value_id != NULL,
00424 "Unexpected (no scenario found) call with session-id ["
00425 << *L_value_id << "]");
00426
00427
00428 GEN_LOG_EVENT(LOG_LEVEL_TRAFFIC_ERR,
00429 "Unexpected message received [ " << (*L_msg) <<
00430 GEN_HEADER_LOG << GEN_HEADER_NO_LEVEL << "]" );
00431
00432 m_stat -> executeStatAction (C_GeneratorStats::E_FAILED_UNEXPECTED_MSG);
00433 }
00434 } else {
00435
00436
00437 GEN_LOG_EVENT_CONDITIONAL (LOG_LEVEL_TRAFFIC_ERR,
00438 L_value_id != NULL,
00439 "Refused (new) call with session-id ["
00440 << *L_value_id << "]");
00441 m_stat -> executeStatAction (C_GeneratorStats::E_CALL_REFUSED) ;
00442 }
00443 } else {
00444
00445 GEN_DEBUG(1, "C_CallControl::messageReceivedControl() "<<
00446 "scenario in execution for this call");
00447
00448 if (m_retrans_enabled) {
00449 stopRetrans(L_pCallContext);
00450 }
00451
00452
00453 if (L_pCallContext -> msg_received (&L_rcvCtxt) == false) {
00454
00455 GEN_LOG_EVENT_CONDITIONAL (LOG_LEVEL_TRAFFIC_ERR,
00456 L_value_id != NULL,
00457
00458 "Received a message (while not in receive state) for call with session-id ["
00459 << *L_value_id << "]");
00460
00461
00462
00463
00464
00465 m_stat -> executeStatAction (C_GeneratorStats::E_FAILED_UNEXPECTED_MSG);
00466
00467
00468 L_scenario = m_scenario_control->find_default_scenario (&L_rcvCtxt) ;
00469 if (L_scenario == NULL) {
00470
00471 L_scenario = m_scenario_control->get_abort_scenario();
00472 if (L_scenario != NULL) {
00473 GEN_LOG_EVENT (LOG_LEVEL_TRAFFIC_ERR,
00474 "Switching to abort scenario");
00475 L_pCallContext -> switch_to_scenario (L_scenario);
00476 m_call_ctxt_mlist
00477 ->moveToList(L_pCallContext->get_state(),
00478 L_pCallContext->get_internal_id());
00479 L_pCallContext = NULL ;
00480 } else {
00481 GEN_LOG_EVENT (LOG_LEVEL_TRAFFIC_ERR,
00482 "Unable to find an abort/default scenario");
00483 makeCallContextAvailable(&L_pCallContext);
00484 m_stat -> executeStatAction (C_GeneratorStats::E_CALL_FAILED) ;
00485 }
00486 } else {
00487 T_CallContextState L_state ;
00488 GEN_LOG_EVENT (LOG_LEVEL_TRAFFIC_ERR,
00489 "Switching to default scenario");
00490
00491 L_state = L_pCallContext->get_state() ;
00492 L_pCallContext -> switch_to_scenario (L_scenario);
00493 if (L_state != L_pCallContext->get_state()) {
00494 m_call_ctxt_mlist
00495 ->moveToList(L_pCallContext->get_state(),
00496 L_pCallContext->get_internal_id());
00497 }
00498 (void)L_pCallContext -> msg_received (&L_rcvCtxt);
00499 }
00500 }
00501 }
00502
00503 if (L_pCallContext != NULL) {
00504
00505 L_exeResult = execute_scenario_cmd (L_pCallContext) ;
00506 if (L_exeResult == E_EXE_ERROR_MSG) {
00507
00508 L_scenario = m_scenario_control->find_default_scenario (&L_rcvCtxt) ;
00509 if (L_scenario == NULL) {
00510
00511 L_scenario = m_scenario_control->get_abort_scenario();
00512 if (L_scenario != NULL) {
00513 L_pCallContext -> switch_to_scenario (L_scenario);
00514
00515 m_call_ctxt_mlist
00516 ->moveToList(L_pCallContext->get_state(),
00517 L_pCallContext->get_internal_id());
00518 } else {
00519 makeCallContextAvailable(&L_pCallContext);
00520 m_stat -> executeStatAction (C_GeneratorStats::E_CALL_FAILED) ;
00521 }
00522 } else {
00523 L_pCallContext -> switch_to_scenario (L_scenario);
00524 execute_scenario_cmd (L_pCallContext);
00525 }
00526 }
00527 }
00528
00529 DELETE_VAR(L_msg);
00530 }
00531 GEN_DEBUG (1, "C_CallControl::messageReceivedControl() end");
00532 }
00533
00534 void C_CallControl::endTrafficControl() {
00535
00536 int L_i;
00537 int L_remaining_calls = 0;
00538
00539 GEN_DEBUG (1, "C_CallControl::endTrafficControl() start");
00540
00541 switch (M_state) {
00542 case C_TaskControl::E_STATE_RUNNING:
00543 if (m_call_to_simulate) {
00544 if (m_call_created >= m_call_to_simulate) {
00545 stop();
00546 }
00547 }
00548 break ;
00549 case C_TaskControl::E_STATE_STOPPING:
00550 for(L_i = 0 ; L_i < m_nb_channel ; L_i++) {
00551 L_remaining_calls = m_call_map_table[L_i]->size() ;
00552 if (L_remaining_calls != 0) break ;
00553 }
00554 if (L_remaining_calls == 0) {
00555 M_state = C_TaskControl::E_STATE_STOPPED ;
00556 }
00557 break ;
00558 default:
00559 break ;
00560 }
00561
00562 GEN_DEBUG (1, "C_CallControl::endTrafficControl() end");
00563 }
00564
00565 void C_CallControl::insert_retrans_list(T_pCallContext P_callContext) {
00566
00567 int L_index, L_retrans_index ;
00568
00569 GEN_DEBUG (1, "C_CallControl::insert_retrans_list() start");
00570
00571 L_index = P_callContext->m_retrans_context.m_retrans_delay_index ;
00572 L_retrans_index = P_callContext->m_retrans_context.m_retrans_index ;
00573
00574 m_retrans_context_list[L_index]->push_back(P_callContext->m_retrans_context);
00575 P_callContext->m_retrans_it[L_retrans_index] = m_retrans_context_list[L_index]->end() ;
00576 P_callContext->m_retrans_it[L_retrans_index] -- ;
00577 P_callContext->m_retrans_it_available[L_retrans_index] = true ;
00578
00579 GEN_DEBUG (1, "C_CallControl::insert_retrans_list() end");
00580 }
00581
00582 void C_CallControl::stopRetrans (T_pCallContext P_callContext) {
00583
00584 int L_i, L_cmdIdx ;
00585 int L_retrans_delay_index ;
00586
00587
00588 GEN_DEBUG (1, "C_CallControl::stopRetrans() start");
00589
00590 for (L_i = 0 ; L_i < P_callContext->m_nb_retrans; L_i++) {
00591 if (P_callContext->m_retrans_it_available[L_i] == true) {
00592 L_cmdIdx = P_callContext->m_retrans_cmd_idx[L_i];
00593 L_retrans_delay_index =
00594 (P_callContext->get_scenario()->get_commands())[L_cmdIdx].m_retrans_delay_index ;
00595 m_retrans_context_list[L_retrans_delay_index]->erase(P_callContext->m_retrans_it[L_i]) ;
00596 P_callContext->m_retrans_it_available[L_i] = false ;
00597 }
00598 }
00599
00600 GEN_DEBUG (1, "C_CallControl::stopRetrans() end");
00601 }
00602
00603
00604 void C_CallControl::messageRetransControl () {
00605
00606 GEN_DEBUG (1, "C_CallControl::messageRetransControl() start");
00607
00608 int L_i ;
00609 int L_retrans_idx ;
00610 int L_nbRetrans, L_nbRetransToDo ;
00611 struct timeval L_current_time ;
00612 C_CallContext *L_pCallContext ;
00613 C_CallContext::T_retransContext L_retrans_ctxt ;
00614 C_CallContext::T_retransContextList::iterator L_it;
00615
00616 list_t<C_CallContext*> L_stopRetransList ;
00617 list_t<C_CallContext*>::iterator L_stopRetransListIt ;
00618
00619 list_t<C_CallContext::T_retransContextList::iterator> L_deleteList ;
00620 list_t<C_CallContext::T_retransContextList::iterator>::iterator L_deleteListIt ;
00621
00622 C_CallContext::T_retransContextList L_doRetransList ;
00623 C_CallContext::T_retransContextList::iterator L_doRetransListIt ;
00624
00625 bool L_first_get = false ;
00626
00627 L_stopRetransList.clear();
00628 L_doRetransList.clear();
00629 L_deleteList.clear() ;
00630
00631 for (L_i=0; L_i < (int)m_nb_retrans_delay_values; L_i++) {
00632 if (!(m_retrans_context_list[L_i]->empty())) {
00633 L_nbRetrans = m_retrans_context_list[L_i]->size();
00634 L_nbRetransToDo = (L_nbRetrans > m_max_send_loop)
00635 ? m_max_send_loop : L_nbRetrans ;
00636
00637 GEN_DEBUG (1, "C_CallControl::messageRetransControl() L_nbRetrans " << L_nbRetrans);
00638 if (L_nbRetrans) {
00639 if (L_first_get == false) {
00640 GET_TIME(&L_current_time);
00641 L_first_get = true ;
00642 }
00643 }
00644
00645 for (L_it = m_retrans_context_list[L_i]->begin() ;
00646 L_it != m_retrans_context_list[L_i]->end() ;
00647 L_it++) {
00648
00649 L_retrans_ctxt = *L_it;
00650 L_pCallContext = L_retrans_ctxt.m_context ;
00651 L_retrans_idx = L_retrans_ctxt.m_retrans_index ;
00652
00653 if ( ms_difftime(&L_current_time, &L_pCallContext->m_retrans_time[L_retrans_idx])
00654 < (long) m_retrans_delay_values[L_i] ) {
00655 break ;
00656 } else {
00657 if (L_pCallContext->m_nb_retrans_done[L_retrans_idx] <= (int)m_max_retrans) {
00658 execute_scenario_cmd_retrans (L_retrans_idx, L_pCallContext) ;
00659 L_doRetransList.push_back(L_retrans_ctxt);
00660 L_deleteList.push_back(L_it);
00661 } else {
00662 L_stopRetransList.push_back(L_pCallContext) ;
00663 }
00664 }
00665
00666 L_nbRetransToDo -- ;
00667 if (L_nbRetransToDo == 0) break ;
00668
00669 }
00670
00671 if (!L_deleteList.empty()) {
00672 for (L_deleteListIt = L_deleteList.begin();
00673 L_deleteListIt != L_deleteList.end();
00674 L_deleteListIt ++) {
00675 m_retrans_context_list[L_i]->erase(*L_deleteListIt);
00676 }
00677 }
00678 }
00679
00680 if (!L_stopRetransList.empty()) {
00681 for (L_stopRetransListIt = L_stopRetransList.begin();
00682 L_stopRetransListIt != L_stopRetransList.end();
00683 L_stopRetransListIt++) {
00684 L_pCallContext = *L_stopRetransListIt ;
00685 stopRetrans(L_pCallContext);
00686 makeCallContextAvailable(&L_pCallContext) ;
00687 m_stat -> executeStatAction (C_GeneratorStats::E_CALL_FAILED) ;
00688 }
00689 L_stopRetransList.erase(L_stopRetransList.begin(),
00690 L_stopRetransList.end());
00691 }
00692
00693 if (!L_doRetransList.empty()) {
00694 for (L_doRetransListIt = L_doRetransList.begin();
00695 L_doRetransListIt != L_doRetransList.end();
00696 L_doRetransListIt++) {
00697 L_retrans_ctxt = *L_doRetransListIt;
00698 m_retrans_context_list[L_i]->push_back(L_retrans_ctxt);
00699 L_pCallContext = L_retrans_ctxt.m_context ;
00700 L_pCallContext->m_retrans_it[L_retrans_ctxt.m_retrans_index] =
00701 m_retrans_context_list[L_i]->end();
00702 (L_pCallContext->m_retrans_it[L_retrans_ctxt.m_retrans_index])--;
00703 }
00704 L_doRetransList.erase(L_doRetransList.begin(),
00705 L_doRetransList.end());
00706 }
00707 }
00708
00709 GEN_DEBUG (1, "C_CallControl::messageRetranstControl() end");
00710 }
00711
00712 T_exeCode C_CallControl::execute_scenario_cmd_retrans (int P_index, T_pCallContext P_callContext) {
00713 T_pC_Scenario L_scenario ;
00714 T_exeCode L_exeResult ;
00715 T_pCallContext L_callContext = P_callContext ;
00716
00717 GEN_DEBUG (1, "C_CallControl::execute_scenario_cmd_retrans() start");
00718
00719 L_scenario = L_callContext->get_scenario() ;
00720
00721 L_exeResult = L_scenario->execute_cmd_retrans (P_index, L_callContext);
00722
00723 switch (L_exeResult) {
00724 case E_EXE_NOERROR:
00725 break ;
00726 case E_EXE_ERROR_SEND:
00727 makeCallContextAvailable(&L_callContext) ;
00728 m_stat -> executeStatAction (C_GeneratorStats::E_CALL_FAILED) ;
00729 m_stat -> executeStatAction (C_GeneratorStats::E_FAILED_CANNOT_SEND_MSG);
00730 m_stat -> err_msg ((char*) "Send error");
00731 break ;
00732 default:
00733 m_stat -> executeStatAction (C_GeneratorStats::E_CALL_FAILED) ;
00734 makeCallContextAvailable(&L_callContext) ;
00735 break ;
00736 }
00737 GEN_DEBUG (1, "C_CallControl::execute_scenario_cmd_retrans() end");
00738 return (L_exeResult);
00739 }
00740
00741 void C_CallControl::messageSendControl() {
00742 int L_nbSend, L_nbSendToDo ;
00743 T_pCallContext L_pCallContext ;
00744
00745
00746 GEN_DEBUG (1, "C_CallControl::messageSendControl() start");
00747 L_nbSend = m_call_ctxt_mlist -> getNbElements (E_CTXT_SEND) ;
00748 L_nbSendToDo = (L_nbSend > m_max_send_loop)
00749 ? m_max_send_loop : L_nbSend ;
00750
00751 while (L_nbSendToDo > 0) {
00752 L_pCallContext
00753 = m_call_ctxt_table[m_call_ctxt_mlist->getFirst(E_CTXT_SEND)];
00754 execute_scenario_cmd (L_pCallContext);
00755
00756 if (m_retrans_enabled) {
00757 if ((L_pCallContext->m_retrans_to_do) == true) {
00758 insert_retrans_list(L_pCallContext) ;
00759 L_pCallContext->m_retrans_to_do = false ;
00760 }
00761 }
00762
00763 L_nbSendToDo -- ;
00764 }
00765 GEN_DEBUG (1, "C_CallControl::messageSendControl() end");
00766 }
00767
00768 T_exeCode C_CallControl::execute_scenario_cmd (T_pCallContext P_callContext,
00769 bool P_resume) {
00770
00771 T_pC_Scenario L_scenario ;
00772 T_exeCode L_exeResult ;
00773 T_pCallContext L_callContext = P_callContext ;
00774
00775 GEN_DEBUG (1, "C_CallControl::execute_scenario_cmd() start");
00776
00777 L_scenario = L_callContext->get_scenario() ;
00778 L_exeResult = L_scenario->execute_cmd (L_callContext, P_resume);
00779
00780 switch (L_exeResult) {
00781
00782
00783 case E_EXE_NOERROR:
00784 m_call_ctxt_mlist
00785 ->moveToList(L_callContext->get_state(),
00786 L_callContext->get_internal_id());
00787 break ;
00788
00789
00790 case E_EXE_TRAFFIC_END:
00791 makeCallContextAvailable(&L_callContext) ;
00792 m_stat -> executeStatAction (C_GeneratorStats::E_CALL_TRAFFIC_SUCCESSFULLY_ENDED);
00793 break ;
00794
00795 case E_EXE_ABORT_END:
00796 makeCallContextAvailable(&L_callContext) ;
00797 m_stat -> executeStatAction (C_GeneratorStats::E_CALL_ABORT_SUCCESSFULLY_ENDED);
00798 break ;
00799
00800 case E_EXE_DEFAULT_END:
00801 makeCallContextAvailable(&L_callContext) ;
00802 m_stat -> executeStatAction (C_GeneratorStats::E_CALL_DEFAULT_SUCCESSFULLY_ENDED);
00803 break ;
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813 case E_EXE_ERROR_SEND:
00814 makeCallContextAvailable(&L_callContext) ;
00815 m_stat -> executeStatAction (C_GeneratorStats::E_CALL_FAILED) ;
00816 m_stat -> executeStatAction (C_GeneratorStats::E_FAILED_CANNOT_SEND_MSG);
00817 m_stat -> err_msg ((char*) "Send error");
00818 break ;
00819
00820 case E_EXE_INIT_END:
00821 makeCallContextAvailable(&L_callContext) ;
00822 m_stat -> executeStatAction (C_GeneratorStats::E_CALL_INIT_SUCCESSFULLY_ENDED);
00823 init_done() ;
00824 break ;
00825
00826 case E_EXE_ERROR_MSG:
00827 m_stat -> executeStatAction (C_GeneratorStats::E_FAILED_UNEXPECTED_MSG);
00828
00829 break ;
00830
00831 case E_EXE_ERROR_CHECK:
00832 m_stat -> executeStatAction (C_GeneratorStats::E_FAILED_UNEXPECTED_MSG);
00833 m_stat -> executeStatAction (C_GeneratorStats::E_CALL_FAILED) ;
00834 makeCallContextAvailable(&L_callContext) ;
00835 break ;
00836
00837 case E_EXE_ABORT_CHECK: {
00838
00839 T_pC_Scenario L_scenario = NULL ;
00840 L_scenario = m_scenario_control->get_abort_scenario();
00841 if (L_scenario != NULL) {
00842 GEN_LOG_EVENT (LOG_LEVEL_TRAFFIC_ERR,
00843 "Switching to abort scenario");
00844 L_callContext -> switch_to_scenario (L_scenario);
00845
00846 m_call_ctxt_mlist
00847 ->moveToList(L_callContext->get_state(),
00848 L_callContext->get_internal_id());
00849 } else {
00850 makeCallContextAvailable(&L_callContext);
00851 m_stat->executeStatAction(C_GeneratorStats::E_CALL_FAILED);
00852 }
00853
00854 }
00855 break ;
00856
00857 case E_EXE_SUSPEND:
00858 makeCallContextSuspended(L_callContext);
00859 break ;
00860
00861
00862 case E_EXE_IGNORE:
00863 makeCallContextAvailable(&L_callContext) ;
00864 break ;
00865
00866 default:
00867 m_stat -> executeStatAction (C_GeneratorStats::E_CALL_FAILED) ;
00868 makeCallContextAvailable(&L_callContext) ;
00869 break ;
00870
00871 }
00872
00873 GEN_DEBUG (1, "C_CallControl::execute_scenario_cmd() end");
00874
00875 return (L_exeResult);
00876 }
00877
00878 T_GeneratorError C_CallControl::TaskProcedure() {
00879
00880 GEN_DEBUG (1, "C_CallControl::TaskProcedure() start");
00881 if (m_call_timeout_ms) {
00882 messageTimeoutControl() ;
00883 }
00884
00885 if (m_open_timeout_ms) {
00886 messageOpenTimeoutControl();
00887 }
00888
00889 if (m_retrans_enabled) {
00890 messageRetransControl () ;
00891 }
00892
00893 messageReceivedControl () ;
00894 if (m_nb_wait_values) { waitControl() ; }
00895 eventControl () ;
00896 messageSendControl () ;
00897 endTrafficControl() ;
00898 GEN_DEBUG (1, "C_CallControl::TaskProcedure() end");
00899
00900 return (E_GEN_NO_ERROR);
00901 }
00902
00903 T_GeneratorError C_CallControl::InitProcedure() {
00904
00905 T_GeneratorError L_error = E_GEN_NO_ERROR ;
00906 int L_i ;
00907 int L_memory_used, L_channel_used, L_nb_retrans ;
00908 C_CallContext *L_pCallContext ;
00909 unsigned long L_config_value ;
00910
00911 T_pC_Scenario L_scenario ;
00912
00913 T_TrafficType L_type ;
00914
00915 T_pWaitValuesSet L_wait_values ;
00916
00917 T_pRetransDelayValuesSet L_retrans_delay_values ;
00918
00919 GEN_DEBUG (1, "C_CallControl::InitProcedure() start");
00920
00921 if (!m_config->get_value(E_CFG_OPT_MAX_SIMULTANEOUS_CALLS,
00922 &L_config_value)) {
00923 GEN_FATAL(E_GEN_FATAL_ERROR,
00924 "Internal max simultaneous call not specified");
00925 }
00926 m_call_ctxt_table_size = (size_t)L_config_value ;
00927
00928 if (!m_config->get_value(E_CFG_OPT_MAX_SEND,
00929 &L_config_value)) {
00930 GEN_FATAL(E_GEN_FATAL_ERROR,
00931 "Internal max send not specified");
00932 }
00933 m_max_send_loop = (int) L_config_value ;
00934
00935 if (!m_config->get_value(E_CFG_OPT_MAX_RECEIVE,
00936 &L_config_value)) {
00937 GEN_FATAL(E_GEN_FATAL_ERROR,
00938 "Internal max receive not specified");
00939 }
00940 m_max_receive_loop = (int) L_config_value ;
00941
00942 if (!m_config->get_value(E_CFG_OPT_CALL_TIMEOUT,
00943 &m_call_timeout_ms)) {
00944 GEN_FATAL(E_GEN_FATAL_ERROR,
00945 "Internal call timeout (ms) not specified");
00946 }
00947
00948 if (!m_config->get_value(E_CFG_OPT_NUMBER_CALLS,
00949 &m_call_to_simulate)) {
00950 GEN_FATAL(E_GEN_FATAL_ERROR,
00951 "Internal number calls not specified");
00952 }
00953
00954 if (!m_config->get_value(E_CFG_OPT_OPEN_TIMEOUT,
00955 &m_open_timeout_ms)) {
00956 GEN_FATAL(E_GEN_FATAL_ERROR,
00957 "Internal open timeout (ms) not specified");
00958 }
00959
00960 m_call_timeout_abort = m_config -> get_call_timeout_beh_abr ();
00961
00962 if (!m_config->get_value(E_CFG_OPT_MAX_RETRANS,
00963 &m_max_retrans)) {
00964 GEN_FATAL(E_GEN_FATAL_ERROR,
00965 "Internal max retrans is not specified");
00966 }
00967
00968 m_retrans_enabled = m_config -> get_retrans_enabled();
00969
00970
00971 L_wait_values = m_scenario_control->get_wait_values() ;
00972 m_nb_wait_values = L_wait_values -> size() ;
00973 if (m_nb_wait_values != 0) {
00974
00975 T_waitValuesSet::iterator L_waitIt ;
00976 int L_i ;
00977
00978 ALLOC_TABLE(m_wait_values,
00979 unsigned long*,
00980 sizeof(unsigned long),
00981 m_nb_wait_values);
00982 L_i = 0 ;
00983 for (L_waitIt = L_wait_values->begin();
00984 L_waitIt != L_wait_values->end() ;
00985 L_waitIt++) {
00986 m_wait_values[L_i] = *L_waitIt ;
00987 L_i ++ ;
00988 }
00989 NEW_VAR(m_call_ctxt_mlist,
00990 T_CallContextList(E_CTXT_NBSTATE+(m_nb_wait_values-1),
00991 (long)m_call_ctxt_table_size));
00992 m_scenario_control -> update_wait_cmd (m_nb_wait_values, m_wait_values);
00993 } else {
00994 NEW_VAR(m_call_ctxt_mlist,
00995 T_CallContextList(E_CTXT_NBSTATE,
00996 (long)m_call_ctxt_table_size));
00997 }
00998 m_call_ctxt_mlist->initList (E_CTXT_AVAILABLE);
00999
01000 ALLOC_TABLE(m_call_ctxt_table,
01001 T_pCallContext*,
01002 sizeof(T_pCallContext),
01003 m_call_ctxt_table_size);
01004
01005 L_memory_used = m_scenario_control->memory_used() ;
01006 L_channel_used = m_channel_control->nb_channel() ;
01007 L_nb_retrans = m_scenario_control->get_max_nb_retrans();
01008
01009 if (m_retrans_enabled == false) {
01010 L_nb_retrans = 0 ;
01011 }
01012
01013
01014 m_nb_send_per_scene = m_scenario_control->get_max_nb_send () ;
01015 m_nb_recv_per_scene = m_scenario_control->get_max_nb_recv () ;
01016
01017 for(L_i = 0; L_i < (int)m_call_ctxt_table_size; L_i++) {
01018 NEW_VAR(L_pCallContext, C_CallContext(this,
01019 L_i,
01020 L_channel_used,
01021 L_memory_used,
01022 L_nb_retrans));
01023 m_call_ctxt_table[L_i] = L_pCallContext ;
01024 m_call_ctxt_mlist->setElementPayload((long)L_i, L_pCallContext);
01025 }
01026
01027
01028 L_scenario = m_scenario_control->init_scenario_defined(&L_type) ;
01029
01030 if (m_retrans_enabled) {
01031 L_retrans_delay_values = m_scenario_control->get_retrans_delay_values() ;
01032 m_nb_retrans_delay_values = L_retrans_delay_values -> size() ;
01033
01034
01035
01036 if (m_nb_retrans_delay_values != 0) {
01037
01038 T_retransDelayValuesSet::iterator L_retransDelayIt ;
01039 int L_i ;
01040
01041 ALLOC_TABLE(m_retrans_delay_values,
01042 unsigned long*,
01043 sizeof(unsigned long),
01044 m_nb_retrans_delay_values);
01045 L_i = 0 ;
01046 for (L_retransDelayIt = L_retrans_delay_values->begin();
01047 L_retransDelayIt != L_retrans_delay_values->end() ;
01048 L_retransDelayIt++) {
01049 m_retrans_delay_values[L_i] = *L_retransDelayIt ;
01050 L_i ++ ;
01051 }
01052
01053 ALLOC_TABLE(m_retrans_context_list, C_CallContext::T_pRetransContextList*, sizeof(C_CallContext::T_pRetransContextList), m_nb_retrans_delay_values);
01054 for (L_i = 0 ; L_i < (int)m_nb_retrans_delay_values; L_i++) {
01055 NEW_VAR(m_retrans_context_list[L_i],
01056 C_CallContext::T_retransContextList());
01057 }
01058
01059
01060 m_scenario_control -> update_retrans_delay_cmd (m_nb_retrans_delay_values,
01061 m_retrans_delay_values);
01062 }
01063
01064 }
01065
01066 m_stat->init();
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095 GEN_DEBUG (1, "C_CallControl::InitProcedure() end");
01096 return (L_error);
01097 }
01098
01099 T_GeneratorError C_CallControl::EndProcedure() {
01100
01101 int L_i ;
01102
01103
01104 int L_nbMessageSuspend ;
01105 int L_event_id ;
01106 T_pCallContext L_pCallContext ;
01107
01108
01109 GEN_DEBUG (1, "C_CallControl::EndProcedure() start");
01110
01111 if (!m_msg_rcv_ctxt_list->empty()) {
01112 m_msg_rcv_ctxt_list->erase(m_msg_rcv_ctxt_list->begin(),
01113 m_msg_rcv_ctxt_list->end());
01114 }
01115
01116
01117 L_nbMessageSuspend = m_call_ctxt_mlist -> getNbElements (E_CTXT_SUSPEND) ;
01118 while (L_nbMessageSuspend > 0) {
01119 L_pCallContext
01120 = m_call_ctxt_table[m_call_ctxt_mlist->getFirst(E_CTXT_SUSPEND)];
01121
01122 L_event_id = L_pCallContext->m_suspend_id ;
01123 L_pCallContext->clean_suspended() ;
01124 m_channel_control->close_local_channel(L_pCallContext->m_channel_id,
01125 L_pCallContext->m_channel_table);
01126
01127 m_call_ctxt_mlist->moveToList(E_CTXT_AVAILABLE,
01128 L_pCallContext -> get_internal_id());
01129
01130 L_nbMessageSuspend -- ;
01131 }
01132
01133
01134 if (!m_call_suspended->empty()) {
01135 m_call_suspended->erase(m_call_suspended->begin(),
01136 m_call_suspended->end());
01137 }
01138 DELETE_VAR (m_call_suspended);
01139
01140
01141 for(L_i = 0; L_i < (int)m_call_ctxt_table_size; L_i++) {
01142 DELETE_VAR(m_call_ctxt_table[L_i]);
01143 }
01144
01145 GEN_DEBUG (1, "C_CallControl::EndProcedure() end");
01146 return (E_GEN_NO_ERROR);
01147 }
01148
01149 void C_CallControl::stopServer() {
01150 m_accept_new_call = false ;
01151 m_stat->info_msg ((char*) "Stopping traffic");
01152 }
01153
01154 T_GeneratorError C_CallControl::StoppingProcedure() {
01155 GEN_DEBUG (1, "C_CallControl::StoppingProcedure() start");
01156 stopServer();
01157 GEN_DEBUG (1, "C_CallControl::StoppingProcedure() end");
01158 return (E_GEN_NO_ERROR);
01159 }
01160
01161 T_GeneratorError C_CallControl::ForcedStoppingProcedure() {
01162
01163 if (M_state == C_TaskControl::E_STATE_STOPPING) {
01164 M_state = C_TaskControl::E_STATE_STOPPED ;
01165 }
01166 return (E_GEN_NO_ERROR);
01167 }
01168
01169 void C_CallControl::waitControl () {
01170 int L_i, L_nbWaiting ;
01171 T_CallContextState L_waitQueue ;
01172 C_CallContext *L_pCallContext ;
01173 struct timeval L_current_time ;
01174 bool L_first_get = false ;
01175
01176 GEN_DEBUG (1, "C_CallControl::waitControl() start with " << m_nb_wait_values);
01177 for (L_i=0; L_i < (int)m_nb_wait_values; L_i++) {
01178 L_waitQueue = E_CTXT_WAIT + L_i ;
01179 L_nbWaiting = m_call_ctxt_mlist->getNbElements(L_waitQueue);
01180 GEN_DEBUG (1, "C_CallControl::waitControl() L_nbWaining " << L_nbWaiting);
01181 if (L_nbWaiting) {
01182 if (L_first_get == false) {
01183 GET_TIME(&L_current_time);
01184 L_first_get = true ;
01185 }
01186 }
01187 while (L_nbWaiting != 0) {
01188 L_pCallContext
01189 = m_call_ctxt_table[m_call_ctxt_mlist->getFirst(L_waitQueue)];
01190 if ( ms_difftime(&L_current_time, &L_pCallContext->m_current_time)
01191 < (long) m_wait_values[L_i] ) {
01192 break ;
01193 } else {
01194 (void) execute_scenario_cmd (L_pCallContext) ;
01195 L_pCallContext->m_current_time = L_current_time ;
01196 }
01197 L_nbWaiting -- ;
01198 }
01199 }
01200
01201 GEN_DEBUG (1, "C_CallControl::waitControl() end");
01202 }
01203
01204 C_CallControlClient::C_CallControlClient(C_GeneratorConfig *P_config,
01205 T_pC_ScenarioControl P_scenControl,
01206 C_ChannelControl *P_channel_ctrl)
01207 : C_CallControl(P_config, P_scenControl, P_channel_ctrl) {
01208
01209 GEN_DEBUG (1, "C_CallControlClient::C_CallControlClient() start");
01210 m_traffic_scen = NULL ;
01211 m_update_param_traffic = NULL ;
01212 m_type = E_TRAFFIC_CLIENT ;
01213
01214 GEN_DEBUG (1, "C_CallControlClient::C_CallControlClient() end");
01215
01216 }
01217
01218 C_CallControlClient::~C_CallControlClient() {
01219 GEN_DEBUG (1, "C_CallControlClient::~C_CallControlClient() start");
01220 m_outgoing_traffic = false ;
01221 m_traffic_scen = NULL ;
01222 DELETE_VAR(m_traffic_model);
01223 GEN_DEBUG (1, "C_CallControlClient::~C_CallControlClient() end");
01224 }
01225
01226 T_GeneratorError C_CallControlClient::InitProcedure() {
01227 T_GeneratorError L_ret ;
01228 T_TrafficType L_type ;
01229
01230 GEN_DEBUG (1, "C_CallControlClient::InitProcedure() start");
01231
01232 if (!m_config->get_value(E_CFG_OPT_CALL_RATE,
01233 (unsigned long*)&m_call_rate)) {
01234 GEN_FATAL(E_GEN_FATAL_ERROR, "Internal call rate not specified");
01235 }
01236 if (!m_config->get_value(E_CFG_OPT_BURST_LIMIT,
01237 (unsigned long*)&m_burst_limit)) {
01238 GEN_FATAL(E_GEN_FATAL_ERROR, "Internal burst limit not specified");
01239 }
01240 if (!m_config->get_value(E_CFG_OPT_CALL_RATE_SCALE,
01241 (unsigned long*)&m_call_rate_scale)) {
01242 GEN_FATAL(E_GEN_FATAL_ERROR, "Internal call rate scale not specified");
01243 }
01244
01245 if (!m_config->get_value (E_CFG_OPT_MODEL_TRAFFIC_SELECT,
01246 &m_model_traffic_select)) {
01247 GEN_FATAL(E_GEN_FATAL_ERROR, "Model traffic not specified");
01248 }
01249
01250 switch (m_model_traffic_select) {
01251 case 0:
01252 NEW_VAR(m_traffic_model, C_TrafficDistribUniform());
01253 m_update_param_traffic = &C_CallControlClient::calculUpdateParamTraffic ;
01254 break ;
01255 case 1:
01256 NEW_VAR(m_traffic_model, C_TrafficDistribBestEffort());
01257 m_update_param_traffic = &C_CallControlClient::calculNilParamTraffic ;
01258 break ;
01259 case 2:
01260 NEW_VAR(m_traffic_model, C_TrafficDistribPoisson());
01261 m_update_param_traffic = &C_CallControlClient::calculNilParamTraffic ;
01262 break ;
01263
01264 default:
01265 GEN_FATAL(E_GEN_FATAL_ERROR, "Internal: Selection option not recognized for traffic model");
01266 break ;
01267 }
01268
01269
01270 m_traffic_model->init(m_call_rate, m_burst_limit,(long)0, m_call_rate_scale) ;
01271
01272 L_ret = C_CallControl::InitProcedure();
01273
01274 m_traffic_scen = m_scenario_control->outgoing_scenario() ;
01275 if (m_traffic_scen == NULL) {
01276 GEN_FATAL(E_GEN_FATAL_ERROR, "Client scenario needed");
01277 }
01278
01279 if (m_scenario_control->init_scenario_defined(&L_type) != NULL) {
01280 m_outgoing_traffic = false;
01281
01282 } else {
01283 init_done() ;
01284 }
01285 GEN_DEBUG (1, "C_CallControlClient::InitProcedure() end");
01286 return (L_ret);
01287 }
01288
01289 T_GeneratorError C_CallControlClient::TaskProcedure() {
01290 GEN_DEBUG (1, "C_CallControlClient::TaskProcedure() start");
01291 if (m_outgoing_traffic == true) {
01292 newCallControl() ;
01293 }
01294 GEN_DEBUG (1, "C_CallControlClient::TaskProcedure() end");
01295 return (C_CallControl::TaskProcedure());
01296 }
01297
01298 void C_CallControlClient::calculNilParamTraffic() {
01299
01300 }
01301
01302 void C_CallControlClient::calculUpdateParamTraffic() {
01303
01304 long L_currentPeriodDuration ;
01305
01306 L_currentPeriodDuration = m_traffic_model -> get_current_period_duration() ;
01307
01308
01309
01310
01311
01312 L_currentPeriodDuration = (L_currentPeriodDuration == 0) ? 1 : L_currentPeriodDuration ;
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322 m_max_send_loop = (int)floor (0.5 +
01323 ((m_call_rate * m_nb_send_per_scene)/
01324 (float)(L_currentPeriodDuration/1000.0))) ;
01325
01326
01327
01328 m_max_receive_loop = (int) floor (0.5 +
01329 ((m_call_rate * m_nb_recv_per_scene)/
01330 (float)(L_currentPeriodDuration/1000.0))) ;
01331
01332
01333
01334
01335 }
01336
01337
01338 void C_CallControlClient::newCallControl() {
01339
01340 int L_nbNewCalls ;
01341 T_pCallContext L_pCallContext ;
01342
01343
01344 GEN_DEBUG (1, "C_CallControlClient::newCallControl() start");
01345
01346
01347 L_nbNewCalls = m_traffic_model -> authorize_new_call() ;
01348
01349 ((this)->*(m_update_param_traffic))();
01350
01351 while (L_nbNewCalls) {
01352
01353 if (m_call_to_simulate) {
01354 if (m_call_created == m_call_to_simulate) break ;
01355 }
01356
01357 L_pCallContext
01358 = makeCallContextUnavailable();
01359
01360 if (L_pCallContext == NULL) {
01361 GEN_WARNING("No more call context available");
01362 break ;
01363 }
01364
01365 m_call_created ++ ;
01366
01367 L_nbNewCalls -- ;
01368 }
01369
01370 GEN_DEBUG (1, "C_CallControlClient::newCallControl() end");
01371 }
01372
01373 T_GeneratorError C_CallControl::close () {
01374
01375 return (E_GEN_NO_ERROR);
01376 }
01377
01378 void C_CallControl::eventControl() {
01379
01380 int L_nbEventReceived, L_nbEvent ;
01381 T_EventRecvList::iterator L_it ;
01382 int L_id ;
01383 T_SuspendMap::iterator L_itSuspend ;
01384 T_pCallContext L_callContext ;
01385 T_EventRecv L_event ;
01386
01387 L_nbEventReceived = m_event_list->size () ;
01388
01389 if (L_nbEventReceived) {
01390
01391 L_nbEvent = (L_nbEventReceived > m_max_send_loop)
01392 ? m_max_send_loop : L_nbEventReceived ;
01393
01394 while (L_nbEvent) {
01395 L_it = m_event_list->begin() ;
01396 L_event = *L_it ;
01397 L_id = L_event.m_id ;
01398 m_event_list->erase(L_it);
01399
01400 L_itSuspend = m_call_suspended->find(T_SuspendMap::key_type(L_id));
01401 if (L_itSuspend != m_call_suspended->end()) {
01402 L_callContext = L_itSuspend->second ;
01403 m_call_suspended->erase(L_itSuspend);
01404
01405
01406 switch (L_event.m_type) {
01407 case C_TransportEvent::E_TRANS_OPEN:
01408 m_call_ctxt_mlist
01409 ->moveToList(L_callContext->get_state(),
01410 L_callContext->get_internal_id());
01411 execute_scenario_cmd(L_callContext, true );
01412 break ;
01413 case C_TransportEvent::E_TRANS_OPEN_FAILED:
01414 makeCallContextAvailable(&L_callContext);
01415 m_stat->executeStatAction(C_GeneratorStats::E_CALL_FAILED);
01416 break ;
01417 default:
01418 GEN_FATAL(0, "Internal error: Unexpected event");
01419 break ;
01420 }
01421 }
01422
01423 L_nbEvent -- ;
01424 }
01425 }
01426
01427 }
01428
01429 void C_CallControl::messageOpenTimeoutControl() {
01430
01431 int L_nbMessageSuspend ;
01432 T_pCallContext L_pCallContext ;
01433 struct timeval L_current_time ;
01434 int L_event_id ;
01435 T_SuspendMap::iterator L_itSuspend ;
01436
01437 GEN_DEBUG(1, "C_CallControl::messageOpenTimeoutControl() start");
01438
01439 L_nbMessageSuspend = m_call_ctxt_mlist -> getNbElements (E_CTXT_SUSPEND) ;
01440
01441 if (L_nbMessageSuspend > 0) { GET_TIME(&L_current_time); }
01442
01443 while (L_nbMessageSuspend > 0) {
01444 L_pCallContext
01445 = m_call_ctxt_table[m_call_ctxt_mlist->getFirst(E_CTXT_SUSPEND)];
01446 if ( ms_difftime(&L_current_time, &L_pCallContext->m_current_time)
01447 < (long)m_open_timeout_ms ) {
01448 break ;
01449 } else {
01450
01451 GEN_LOG_EVENT(LOG_LEVEL_TRAFFIC_ERR,
01452 "Call open timeout detected");
01453 m_stat->executeStatAction(C_GeneratorStats::E_FAILED_TIMEOUT);
01454
01455 L_event_id = L_pCallContext->m_suspend_id ;
01456 L_itSuspend = m_call_suspended->find(T_SuspendMap::key_type(L_event_id));
01457 if (L_itSuspend != m_call_suspended->end()) {
01458 m_call_suspended->erase(L_itSuspend);
01459 }
01460
01461 L_pCallContext->clean_suspended() ;
01462 m_channel_control->close_local_channel(L_pCallContext->m_channel_id,
01463 L_pCallContext->m_channel_table);
01464 makeCallContextAvailable (&L_pCallContext) ;
01465 }
01466 L_nbMessageSuspend -- ;
01467 }
01468
01469 GEN_DEBUG(1, "C_CallControl::messageOpenTimeoutControl() end");
01470
01471 }
01472
01473
01474 void C_CallControl::messageTimeoutControl() {
01475
01476 int L_nbRecv ;
01477 T_pCallContext L_pCallContext ;
01478 struct timeval L_current_time ;
01479 C_ScenarioStats *L_stats ;
01480
01481 GEN_DEBUG(1, "C_CallControl::messageTimeoutControl() start");
01482
01483 L_nbRecv = m_call_ctxt_mlist -> getNbElements (E_CTXT_RECEIVE) ;
01484
01485 if (L_nbRecv > 0) { GET_TIME(&L_current_time); }
01486
01487 while (L_nbRecv > 0) {
01488 L_pCallContext
01489 = m_call_ctxt_table[m_call_ctxt_mlist->getFirst(E_CTXT_RECEIVE)];
01490 if ( ms_difftime(&L_current_time, &L_pCallContext->m_current_time)
01491 < (long)m_call_timeout_ms ) {
01492 break ;
01493 } else {
01494 m_stat->executeStatAction(C_GeneratorStats::E_FAILED_TIMEOUT);
01495
01496
01497
01498 GEN_LOG_EVENT(LOG_LEVEL_TRAFFIC_ERR,
01499 "Call timeout detected");
01500
01501 if (m_retrans_enabled) {
01502 stopRetrans(L_pCallContext);
01503 }
01504
01505
01506 if ((L_stats = (L_pCallContext->get_scenario())->get_stats()) != NULL) {
01507 L_stats -> updateStats(L_pCallContext->get_current_cmd_idx(),
01508 C_ScenarioStats::E_TIMEOUT,
01509 0);
01510 }
01511
01512 if (m_call_timeout_abort == true) {
01513 T_pC_Scenario L_scenario = NULL ;
01514 L_scenario = m_scenario_control->get_abort_scenario();
01515 if (L_scenario != NULL) {
01516 L_pCallContext -> switch_to_scenario (L_scenario);
01517
01518 m_call_ctxt_mlist
01519 ->moveToList(L_pCallContext->get_state(),
01520 L_pCallContext->get_internal_id());
01521 } else {
01522
01523 m_stat->executeStatAction(C_GeneratorStats::E_CALL_FAILED);
01524 makeCallContextAvailable(&L_pCallContext);
01525 }
01526 } else {
01527
01528 m_stat->executeStatAction(C_GeneratorStats::E_CALL_FAILED);
01529 makeCallContextAvailable (&L_pCallContext) ;
01530 }
01531
01532
01533
01534
01535 }
01536 L_nbRecv -- ;
01537 }
01538
01539 GEN_DEBUG(1, "C_CallControl::messageTimeoutControl() end");
01540 }
01541
01542 T_GeneratorError C_CallControlClient::StoppingProcedure() {
01543 GEN_DEBUG (1, "C_CallControl::StoppingProcedure() start");
01544 m_outgoing_traffic = false ;
01545 stopServer();
01546 GEN_DEBUG (1, "C_CallControl::StoppingProcedure() end");
01547 return (E_GEN_NO_ERROR);
01548 }
01549
01550 void C_CallControl::pause_traffic() {
01551 GEN_DEBUG (1, "C_CallControl::pause_traffic() start");
01552 switch(m_pause) {
01553 case true:
01554 m_accept_new_call = true ;
01555 m_pause = false ;
01556 m_stat->info_msg((char*)"Incomming traffic (pause end)");
01557 break ;
01558 case false:
01559 m_accept_new_call = false ;
01560 m_pause = true ;
01561 m_stat->info_msg((char*)"Incomming traffic (paused)");
01562 break ;
01563 }
01564 GEN_DEBUG (1, "C_CallControl::pause_traffic() end");
01565 }
01566
01567 void C_CallControl::restart_traffic() {
01568 pause_traffic() ;
01569 }
01570
01571 void C_CallControlClient::pause_traffic() {
01572 GEN_DEBUG (1, "C_CallControl::pause_traffic() start");
01573 switch(m_pause) {
01574 case true :
01575 m_pause = false ;
01576 m_outgoing_traffic = true ;
01577 m_stat->info_msg((char*)"Outgoing traffic (pause end)");
01578 break ;
01579 case false :
01580 m_pause = true ;
01581 m_outgoing_traffic = false ;
01582 m_stat->info_msg((char*)"Outgoing traffic (paused)");
01583 break ;
01584 }
01585 GEN_DEBUG (1, "C_CallControl::pause_traffic() end");
01586 }
01587
01588 void C_CallControlClient::restart_traffic() {
01589 GEN_DEBUG (1, "C_CallControl::restart_traffic() start");
01590 switch(m_pause) {
01591 case true :
01592 m_pause = false ;
01593 m_outgoing_traffic = true ;
01594 m_traffic_model->init(m_call_rate, m_burst_limit,(long)0, m_call_rate_scale) ;
01595 m_traffic_model->start() ;
01596 m_stat->info_msg((char*)"Outgoing traffic (restart)");
01597 break ;
01598 default:
01599 break ;
01600 }
01601 GEN_DEBUG (1, "C_CallControl::restart_traffic() end");
01602 }
01603
01604 void C_CallControl::force_init() {
01605 init_done() ;
01606 }
01607
01608 unsigned long C_CallControl::get_call_rate () {
01609 return(0UL);
01610 }
01611 void C_CallControl::change_call_rate(T_GenChangeOperation P_op,
01612 unsigned long P_rate) {
01613 }
01614 void C_CallControl::change_rate_scale(unsigned long P_scale) {
01615 }
01616
01617
01618 void C_CallControl::change_burst(unsigned long P_burst) {
01619
01620 }
01621
01622 unsigned long C_CallControlClient::get_call_rate () {
01623 return(m_traffic_model->get_desired_rate());
01624 }
01625
01626 void C_CallControlClient::change_call_rate(T_GenChangeOperation P_op,
01627 unsigned long P_rate) {
01628
01629 switch (P_op) {
01630 case E_GEN_OP_SET_VALUE:
01631 m_call_rate = P_rate ;
01632 m_traffic_model->change_desired_rate(m_call_rate);
01633 break ;
01634 case E_GEN_OP_INCREASE:
01635 m_call_rate += m_call_rate_scale ;
01636 m_traffic_model->increase_desired_rate();
01637 break ;
01638 case E_GEN_OP_DECREASE:
01639 if (m_call_rate > m_call_rate_scale) {
01640 m_call_rate -= m_call_rate_scale ;
01641 }
01642 m_traffic_model->decrease_desired_rate();
01643 break ;
01644 }
01645 }
01646
01647 void C_CallControlClient::change_rate_scale(unsigned long P_scale) {
01648 m_traffic_model->change_rate_scale(P_scale);
01649 }
01650
01651
01652 void C_CallControlClient::change_burst(unsigned long P_burst) {
01653 m_burst_limit = P_burst ;
01654 m_traffic_model->change_max_created_calls(m_burst_limit);
01655 }
01656
01657 void C_CallControl::makeCallContextSuspended(T_pCallContext P_callContext) {
01658
01659 int L_id, L_event_id ;
01660
01661 GEN_DEBUG (1, "C_CallControl::makeCallContextSuspended() start");
01662
01663 L_id = P_callContext -> get_internal_id();
01664 m_call_ctxt_mlist->moveToList(E_CTXT_SUSPEND, L_id);
01665
01666
01667 L_event_id = P_callContext->m_suspend_id ;
01668 m_call_suspended->insert(T_SuspendMap::value_type(L_event_id, P_callContext));
01669
01670 }
01671
01672 T_pCallContext C_CallControl::retrieve_call_context (int P_channel_id, T_pValueData P_id) {
01673
01674 T_pCallContext L_pCallContext = NULL ;
01675 T_CallMap::iterator L_call_it ;
01676
01677 L_call_it
01678 = m_call_map_table[P_channel_id]->find(T_CallMap::key_type(*P_id));
01679
01680 if (L_call_it != m_call_map_table[P_channel_id]->end()) {
01681 L_pCallContext = L_call_it -> second ;
01682 } else {
01683 L_pCallContext = NULL ;
01684 }
01685
01686 return (L_pCallContext);
01687 }
01688
01689
01690
01691 C_CallControlServer::C_CallControlServer(C_GeneratorConfig *P_config,
01692 T_pC_ScenarioControl P_scenControl,
01693 C_ChannelControl *P_channel_ctrl)
01694 : C_CallControl(P_config, P_scenControl, P_channel_ctrl) {
01695
01696 GEN_DEBUG (1, "C_CallControlServer::C_CallControlServer() start");
01697 GEN_DEBUG (1, "C_CallControlServer::C_CallControlServer() end");
01698
01699 }
01700
01701 C_CallControlServer::~C_CallControlServer() {
01702 GEN_DEBUG (1, "C_CallControlServer::~C_CallControlServer() start");
01703 GEN_DEBUG (1, "C_CallControlServer::~C_CallControlServer() end");
01704 }
01705
01706 T_GeneratorError C_CallControlServer::InitProcedure() {
01707
01708 T_GeneratorError L_ret ;
01709 T_pC_Scenario L_scenario ;
01710 T_TrafficType L_type ;
01711
01712 L_ret = C_CallControl::InitProcedure() ;
01713
01714 L_scenario = m_scenario_control->init_scenario_defined(&L_type) ;
01715 if (L_scenario == NULL) {
01716 GEN_WARNING("no init scenario defined");
01717 } else {
01718 GEN_DEBUG (1, "C_CallControl::InitProcedure() E_TRAFFIC_SERVER:");
01719 m_scenario_control->switch_to_init();
01720 }
01721
01722 return (L_ret) ;
01723 }
01724
01725
01726 void C_CallControl::clean_mlist (long P_id) {
01727 T_pCallContext L_pCallContext ;
01728 int L_nbElem = m_call_ctxt_mlist -> getNbElements (P_id) ;
01729 while (L_nbElem) {
01730 L_pCallContext
01731 = m_call_ctxt_table[m_call_ctxt_mlist->getFirst(P_id)];
01732 makeCallContextAvailable(&L_pCallContext);
01733 m_stat->executeStatAction(C_GeneratorStats::E_CALL_FAILED);
01734 L_nbElem-- ;
01735 }
01736 }
01737
01738
01739 void C_CallControl::clean_traffic() {
01740
01741 long L_i ;
01742
01743 m_accept_new_call = false ;
01744
01745 if (!m_msg_rcv_ctxt_list->empty()) {
01746 m_msg_rcv_ctxt_list->erase(m_msg_rcv_ctxt_list->begin(),
01747 m_msg_rcv_ctxt_list->end());
01748 }
01749 if (!m_event_list->empty()) {
01750 m_event_list->erase(m_event_list->begin(),
01751 m_event_list->end());
01752 }
01753 if (!m_call_suspended->empty()) {
01754 m_call_suspended->erase(m_call_suspended->begin(),
01755 m_call_suspended->end());
01756 }
01757
01758 clean_mlist(E_CTXT_SEND);
01759 {
01760 int L_nbElem = m_call_ctxt_mlist -> getNbElements (E_CTXT_SUSPEND) ;
01761 T_pCallContext L_pCallContext ;
01762 while (L_nbElem) {
01763 L_pCallContext
01764 = m_call_ctxt_table[m_call_ctxt_mlist->getFirst(E_CTXT_SUSPEND)];
01765 L_pCallContext->clean_suspended() ;
01766 }
01767 }
01768 clean_mlist(E_CTXT_SUSPEND);
01769 clean_mlist(E_CTXT_RECEIVE);
01770 for (L_i=0; L_i < (int)m_nb_wait_values; L_i++) {
01771 clean_mlist(E_CTXT_WAIT + L_i);
01772 }
01773 m_stat->info_msg((char*)"Traffic cleaned (channel lost)");
01774
01775 }
01776
01777 void C_CallControlClient::clean_traffic() {
01778 m_outgoing_traffic = false ;
01779 C_CallControl::clean_traffic() ;
01780 }
01781
01782 void C_CallControlServer::clean_traffic() {
01783 C_CallControl::clean_traffic() ;
01784 }
01785
01786
01787