00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "C_ReadControl.hpp"
00021 #include "Utils.hpp"
00022
00023 #include "GeneratorTrace.hpp"
00024 #include "BufferUtils.hpp"
00025
00026 #include <cerrno>
00027 #include <cstring>
00028
00029 #include "dlfcn_t.hpp"
00030
00031
00032
00033 C_ReadControl::C_ReadControl(C_ChannelControl *P_channel_ctrl,
00034 C_TransportControl *P_transport_ctrl) : C_TaskControl() {
00035
00036
00037 GEN_DEBUG(1, "C_ReadControl::C_ReadControl() start");
00038
00039 m_scen_controller = NULL ;
00040
00041 m_stat = C_GeneratorStats::instance () ;
00042
00043 m_max_event_nb = 0 ;
00044 m_events = NULL ;
00045
00046 m_call_select = &select ;
00047
00048 m_last_traffic_type = E_TRAFFIC_SERVER ;
00049
00050 m_channel_ctrl = P_channel_ctrl ;
00051 m_transport_ctrl = P_transport_ctrl ;
00052 m_transport_table = NULL ;
00053 m_transport_table_size = 0 ;
00054
00055 m_nb_global_channel = 0 ;
00056 m_call_controller = NULL ;
00057
00058
00059 GEN_DEBUG(1, "C_ReadControl::C_ReadControl() end");
00060 }
00061
00062 C_ReadControl::~C_ReadControl() {
00063
00064 GEN_DEBUG(1, "C_ReadControl::~C_ReadControl() start");
00065
00066 DELETE_VAR(m_call_controller);
00067 m_scen_controller = NULL ;
00068 m_stat = NULL ;
00069
00070 DELETE_TABLE(m_events);
00071 m_max_event_nb = 0 ;
00072
00073 m_channel_ctrl = NULL ;
00074 m_transport_table = NULL ;
00075 m_transport_table_size = 0 ;
00076
00077 m_nb_global_channel = 0 ;
00078
00079 GEN_DEBUG(1, "C_ReadControl::~C_ReadControl() end");
00080 }
00081
00082 T_GeneratorError C_ReadControl::TaskProcedure() {
00083
00084 T_GeneratorError L_error_code ;
00085
00086 GEN_DEBUG(1, "C_ReadControl::TaskProcedure() start");
00087 L_error_code = receiveControl() ;
00088 if ((L_error_code == E_GEN_NO_ERROR) && (m_call_controller != NULL)) {
00089 L_error_code = m_call_controller -> run_task_once() ;
00090 }
00091 endTrafficControl();
00092 GEN_DEBUG(1, "C_ReadControl::TaskProcedure() end");
00093
00094 return (L_error_code);
00095
00096 }
00097
00098 T_GeneratorError C_ReadControl::InitProcedure() {
00099
00100 unsigned long L_config_value ;
00101 GEN_DEBUG(1, "C_ReadControl::InitProcedure() start");
00102
00103 if (!m_config->get_value(E_CFG_OPT_SELECT_TIMEOUT_MS,
00104 &L_config_value)) {
00105 GEN_FATAL(E_GEN_FATAL_ERROR, "Internal select timeout not specified");
00106 }
00107 m_select_timeout.tv_sec = L_config_value / 1000 ;
00108 m_select_timeout.tv_usec = (L_config_value % 1000) * 1000 ;
00109
00110 if (!m_config->get_value(E_CFG_OPT_MAX_SIMULTANEOUS_CALLS,
00111 &L_config_value)) {
00112 GEN_FATAL(E_GEN_FATAL_ERROR, "Internal max simultaneous call not specified");
00113 }
00114 m_max_event_nb = 2 * L_config_value ;
00115
00116 GEN_DEBUG(1, "C_ReadControl::InitProcedure() m_max_event_nb: "
00117 << m_max_event_nb << " sizeof(C_TransportEvent) = "
00118 << sizeof(C_TransportEvent));
00119 NEW_TABLE(m_events, C_TransportEvent, m_max_event_nb);
00120 GEN_DEBUG(1, "C_ReadControl::InitProcedure() m_events: " << m_events);
00121
00122 m_nb_global_channel = m_channel_ctrl->nb_global_channel() ;
00123
00124
00125 m_call_select = m_transport_ctrl -> get_call_select () ;
00126
00127 create_call_controller() ;
00128 transport_table () ;
00129
00130 GEN_DEBUG(1, "C_ReadControl::InitProcedure() end");
00131 return (E_GEN_NO_ERROR);
00132
00133 }
00134
00135 T_GeneratorError C_ReadControl::EndProcedure() {
00136
00137 int L_i ;
00138
00139 GEN_DEBUG(1, "C_ReadControl::EndProcedure() start");
00140
00141 if (m_call_controller != NULL) {
00142
00143 m_call_controller -> run_task_once() ;
00144 m_call_controller->close() ;
00145 }
00146
00147
00148
00149 for(L_i=0; L_i < m_transport_table_size ; L_i++) {
00150 m_transport_table[L_i]->close() ;
00151 }
00152
00153 GEN_DEBUG(1, "C_ReadControl::EndProcedure() end");
00154
00155 return (E_GEN_NO_ERROR);
00156 }
00157
00158 T_GeneratorError C_ReadControl::StoppingProcedure() {
00159
00160 GEN_DEBUG(1, "C_ReadControl::StoppingProcedure() start");
00161 if (m_call_controller != NULL) m_call_controller->stop() ;
00162 GEN_DEBUG(1, "C_ReadControl::StoppingProcedure() end");
00163
00164 return (E_GEN_NO_ERROR);
00165 }
00166
00167 T_GeneratorError C_ReadControl::ForcedStoppingProcedure() {
00168 if (m_call_controller != NULL) m_call_controller->stop ();
00169 return (E_GEN_NO_ERROR);
00170 }
00171
00172 T_GeneratorError C_ReadControl::receiveControl () {
00173
00174 fd_set L_ReadMask ;
00175 fd_set L_WriteMask ;
00176 fd_set L_ExceptionMask ;
00177 int L_n = 0 ;
00178
00179
00180 int L_MaxFd = 0 ;
00181 int L_error = 0 ;
00182
00183 struct timeval L_TimeOut ;
00184 struct timeval *L_pTimeOut=&L_TimeOut ;
00185
00186 T_ReceiveMsgContext L_currentRcvCtxt ;
00187
00188 size_t L_nb_event ;
00189 size_t L_i ;
00190
00191 int L_j ;
00192
00193 GEN_DEBUG(1, "C_ReadControl::receiveControl() start");
00194
00195 L_TimeOut = m_select_timeout ;
00196
00197
00198 FD_ZERO(&L_ReadMask);
00199 FD_ZERO(&L_WriteMask);
00200 FD_ZERO(&L_ExceptionMask);
00201
00202 L_MaxFd = 0 ;
00203
00204 for (L_j = 0 ; L_j < m_transport_table_size; L_j ++) {
00205
00206 L_MaxFd = m_transport_table[L_j]->pre_select
00207 ( L_MaxFd,
00208 &L_ReadMask,
00209 &L_WriteMask,
00210 &L_ExceptionMask,
00211 L_pTimeOut,
00212 NULL,
00213 0) ;
00214 }
00215
00216 if (L_MaxFd >= 1) {
00217
00218
00219 L_n = (*m_call_select) (L_MaxFd+1,
00220 &L_ReadMask,
00221 &L_WriteMask,
00222 &L_ExceptionMask,
00223 L_pTimeOut);
00224
00225 }
00226
00227
00228
00229
00230 if (L_n < 0) {
00231 switch (errno) {
00232 case EINTR :
00233
00234
00235
00236
00237 break;
00238 default :
00239
00240 GEN_ERROR(E_GEN_FATAL_ERROR,
00241 "select failed " << strerror(errno));
00242 break;
00243 }
00244 }
00245
00246
00247 GEN_DEBUG(1, "select return = " << L_n);
00248
00249
00250 if (L_n > 0) {
00251
00252
00253 for (L_j = 0 ; L_j < m_transport_table_size; L_j ++) {
00254
00255 L_nb_event = m_max_event_nb ;
00256 L_error = m_transport_table[L_j]->post_select
00257 (L_n, &L_ReadMask,&L_WriteMask, &L_ExceptionMask,
00258 m_events,
00259 (size_t*)&L_nb_event);
00260
00261 if (L_error <0) {
00262
00263 GEN_ERROR(E_GEN_FATAL_ERROR, "Post select (" << L_error << ")");
00264
00265 } else {
00266
00267 GEN_DEBUG(1, "C_ReadControl::receiveControl() nb events = " << L_nb_event);
00268
00269 for (L_i = 0 ; L_i < L_nb_event ; L_i++) {
00270
00271 process_event (m_transport_table[L_j], &m_events[L_i]);
00272
00273 }
00274
00275 }
00276 }
00277
00278 }
00279
00280 m_channel_ctrl->check_global_channel() ;
00281
00282
00283 GEN_DEBUG(1, "C_ReadControl::receiveControl() end");
00284 return (E_GEN_NO_ERROR);
00285
00286 }
00287
00288 void C_ReadControl::process_event (C_Transport *P_transport, T_pC_TransportEvent P_event) {
00289
00290 int L_event_id = P_event->m_id ;
00291 int L_channel_id = P_event->m_channel_id ;
00292
00293 GEN_DEBUG(1, "C_ReadControl::process_event() start");
00294
00295 switch (P_event->m_type) {
00296
00297 case C_TransportEvent::E_TRANS_RECEIVED: {
00298 T_ReceiveMsgContext L_currentRcvCtxt ;
00299
00300 GEN_DEBUG(1,
00301 "C_ReadControl::receiveControl() E_TRANS_RECEIVED id ["
00302 << L_event_id << "]");
00303
00304 while ((P_transport
00305 ->get_message(P_event->m_id, &L_currentRcvCtxt)) == true) {
00306 m_call_controller
00307 ->messageReceived (&L_currentRcvCtxt) ;
00308 }
00309 break ;
00310 }
00311
00312 case C_TransportEvent::E_TRANS_CLOSED: {
00313
00314 GEN_DEBUG(1, "C_ReadControl::receiveControl() E_TRANS_CLOSED id["
00315 << L_event_id << "]");
00316
00317 GEN_LOG_EVENT(LOG_LEVEL_TRAFFIC_ERR,
00318 "channel ["
00319 << m_channel_ctrl->get_channel_name(L_channel_id) << "] closed");
00320
00321
00322 m_channel_ctrl->closed(L_channel_id, L_event_id);
00323 if (m_call_controller != NULL) {
00324 if (! m_channel_ctrl->reconnect() ) {
00325 if (m_nb_global_channel != m_channel_ctrl->opened()) {
00326 m_call_controller->stop() ;
00327 }
00328 } else {
00329
00330
00331 m_call_controller->clean_traffic();
00332 }
00333 } else {
00334 if (m_nb_global_channel != m_channel_ctrl->opened()) {
00335 stop() ;
00336 }
00337 }
00338
00339 if (m_last_traffic_type == E_TRAFFIC_CLIENT) {
00340 m_call_controller->stop();
00341 GEN_FATAL(E_GEN_FATAL_ERROR, "Connection closed (Client traffic stopped)");
00342 }
00343 break ;
00344 }
00345
00346 case C_TransportEvent::E_TRANS_CONNECTION: {
00347 GEN_DEBUG(1,
00348 "C_ReadControl::receiveControl() E_TRANS_CONNECTION id["
00349 << L_event_id << "]");
00350 break ;
00351 }
00352
00353 case C_TransportEvent::E_TRANS_OPEN: {
00354 T_EventRecv L_event_recv ;
00355 GEN_DEBUG(1,
00356 "C_ReadControl::receiveControl() E_TRANS_OPEN id ["
00357 << L_event_id << "]");
00358
00359 m_channel_ctrl->opened(L_channel_id, L_event_id);
00360
00361 L_event_recv.m_id = L_event_id ;
00362 L_event_recv.m_type = P_event->m_type ;
00363 m_call_controller->eventReceived (&L_event_recv);
00364
00365 if (m_nb_global_channel == m_channel_ctrl->opened()) {
00366 start_call_controller() ;
00367 }
00368 break ;
00369 }
00370
00371
00372 case C_TransportEvent::E_TRANS_OPEN_FAILED: {
00373
00374 GEN_DEBUG(1,
00375 "C_ReadControl::receiveControl() E_TRANS_OPEN_FAILED id ["
00376 << L_event_id << "]");
00377
00378 m_channel_ctrl->open_failed(L_channel_id, L_event_id);
00379 if (m_call_controller != NULL) {
00380 T_EventRecv L_event_recv ;
00381 L_event_recv.m_id = L_event_id ;
00382 L_event_recv.m_type = P_event->m_type ;
00383 m_call_controller->eventReceived (&L_event_recv);
00384 } else {
00385 if (m_nb_global_channel != m_channel_ctrl->opened()) {
00386 stop() ;
00387 }
00388 }
00389 break ;
00390 }
00391
00392 case C_TransportEvent::E_TRANS_NO_EVENT: {
00393 GEN_DEBUG(1,
00394 "C_ReadControl::receiveControl() E_TRANS_NO_EVENT id ["
00395 << L_event_id << "]");
00396 break ;
00397 }
00398
00399 }
00400
00401 GEN_DEBUG(1, "C_ReadControl::process_event() end");
00402 }
00403
00404
00405 void C_ReadControl::set_scenario_control
00406 (T_pC_ScenarioControl P_scenControl,
00407 T_TrafficType P_trafficType) {
00408
00409 GEN_DEBUG(1, "C_ReadControl::set_scenario_control() start");
00410 m_scen_controller = P_scenControl ;
00411 m_traffic_type = P_trafficType ;
00412 GEN_DEBUG(1, "C_ReadControl::set_scenario_control() end");
00413
00414 }
00415
00416 void C_ReadControl::set_config(C_GeneratorConfig *P_config) {
00417 GEN_DEBUG(1, "C_ReadControl::set_config() start");
00418 m_config = P_config ;
00419 GEN_DEBUG(1, "C_ReadControl::set_config() end");
00420 }
00421
00422
00423
00424 void C_ReadControl::endTrafficControl() {
00425
00426 GEN_DEBUG(1, "C_ReadControl::endTrafficControl() start");
00427 GEN_DEBUG(1, "C_ReadControl::endTrafficControl() state [" << M_state << "]");
00428
00429
00430 switch(M_state) {
00431
00432 case C_CallControl::E_STATE_RUNNING:
00433 if (m_call_controller != NULL) {
00434 if ( m_call_controller->get_state()
00435 == C_TaskControl::E_STATE_STOPPED) {
00436 M_state = C_TaskControl::E_STATE_STOPPING ;
00437 }
00438 }
00439
00440
00441 break ;
00442
00443 case C_CallControl::E_STATE_STOPPING:
00444 if (m_call_controller != NULL) {
00445 if ( m_call_controller->get_state()
00446 == C_TaskControl::E_STATE_STOPPED) {
00447 M_state = C_TaskControl::E_STATE_STOPPED ;
00448 }
00449 } else {
00450 M_state = C_TaskControl::E_STATE_STOPPED ;
00451 }
00452 break ;
00453
00454 default:
00455 break ;
00456 }
00457
00458 GEN_DEBUG(1, "C_ReadControl::endTrafficControl() end");
00459 }
00460
00461 void C_ReadControl::pause_traffic() {
00462 GEN_DEBUG(1, "C_ReadControl::pause_traffic() start");
00463 if (m_call_controller != NULL) {
00464 m_call_controller -> pause_traffic() ;
00465 }
00466 GEN_DEBUG(1, "C_ReadControl::pause_traffic() end");
00467 }
00468
00469 void C_ReadControl::restart_traffic() {
00470 GEN_DEBUG(1, "C_ReadControl::restart_traffic() start");
00471 if (m_call_controller != NULL) {
00472 m_call_controller -> restart_traffic() ;
00473 }
00474 GEN_DEBUG(1, "C_ReadControl::restart_traffic() end");
00475 }
00476
00477 void C_ReadControl::force_init() {
00478 if (m_call_controller != NULL) {
00479 m_call_controller->force_init();
00480 }
00481 }
00482
00483 unsigned long C_ReadControl::get_call_rate() {
00484 unsigned long L_ret = 0 ;
00485 if (m_call_controller != NULL) {
00486 L_ret = m_call_controller->get_call_rate();
00487 }
00488 return (L_ret);
00489 }
00490
00491 void C_ReadControl::change_call_rate(T_GenChangeOperation P_op,
00492 unsigned long P_rate) {
00493 if (m_call_controller != NULL) {
00494 m_call_controller->change_call_rate(P_op, P_rate);
00495 }
00496 }
00497
00498 void C_ReadControl::change_rate_scale(unsigned long P_scale) {
00499 if (m_call_controller != NULL) {
00500 m_call_controller->change_rate_scale(P_scale);
00501 }
00502 }
00503
00504 void C_ReadControl::change_burst (unsigned long P_burst) {
00505 if (m_call_controller != NULL) {
00506 m_call_controller->change_burst(P_burst);
00507 }
00508 }
00509
00510
00511 void C_ReadControl::transport_table () {
00512 int L_nb_open ;
00513
00514 GEN_DEBUG(1, "C_ReadControl::transport_table() start");
00515 m_transport_table =
00516 m_channel_ctrl->get_transport_table(&m_transport_table_size);
00517 L_nb_open = m_channel_ctrl->open_global_channel();
00518 GEN_DEBUG(1, "C_ReadControl::transport_table() opened global channel ["
00519 << L_nb_open << "] expected [" << m_channel_ctrl->nb_global_channel()
00520 << "]");
00521 if (L_nb_open
00522 == m_channel_ctrl->nb_global_channel()) {
00523 start_call_controller () ;
00524 }
00525
00526
00527
00528
00529 GEN_DEBUG(1, "C_ReadControl::transport_table() end");
00530 }
00531
00532 void C_ReadControl::create_call_controller () {
00533
00534
00535 GEN_DEBUG(1, "C_ReadControl::create_call_controller() start");
00536 if (m_traffic_type == E_TRAFFIC_CLIENT) {
00537 NEW_VAR(m_call_controller, C_CallControlClient(m_config,
00538 m_scen_controller,
00539 m_channel_ctrl)) ;
00540 } else {
00541 NEW_VAR(m_call_controller, C_CallControlServer(m_config,
00542 m_scen_controller,
00543 m_channel_ctrl)) ;
00544 }
00545 m_call_controller -> init () ;
00546
00547 GEN_DEBUG(1, "C_ReadControl::create_call_controller() end");
00548 }
00549
00550 void C_ReadControl::start_call_controller () {
00551 GEN_DEBUG(1, "C_ReadControl::start_call_controller() start");
00552 m_call_controller -> start_traffic () ;
00553 GEN_DEBUG(1, "C_ReadControl::start_call_controller() end");
00554 }