Main Page   Class Hierarchy   Compound List   File List   Compound Members  

C_ReadControl.cpp

00001 /*
00002  *  This program is free software; you can redistribute it and/or modify
00003  *  it under the terms of the GNU General Public License as published by
00004  *  the Free Software Foundation; either version 2 of the License, or
00005  *  (at your option) any later version.
00006  *
00007  *  This program is distributed in the hope that it will be useful,
00008  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00009  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010  *  GNU General Public License for more details.
00011  *
00012  *  You should have received a copy of the GNU General Public License
00013  *  along with this program; if not, write to the Free Software
00014  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00015  *
00016  * (c)Copyright 2006 Hewlett-Packard Development Company, LP.
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>  // for errno definition
00027 #include <cstring> // for strerror definition
00028 
00029 #include "dlfcn_t.hpp"
00030 
00031 //#define MAX_CTXT_TRANS 1
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   // init of the read controller
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   //  m_max_event_nb = 2048 ;
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     // In order to stop execution
00143     m_call_controller -> run_task_once() ;
00144     m_call_controller->close() ;
00145   }
00146 
00147   // close the instances of transport 
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   /* Number of Fd popped in the select */
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   /* Init masks for the select */
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   } // for L_j
00215        
00216   if (L_MaxFd >= 1) {
00217 
00218     // select system call
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     /* select failed ? */
00228 
00229   // select error cases
00230   if (L_n < 0) {
00231     switch (errno) {
00232        case EINTR :
00233          /*
00234           * NOTHING TO DO, AND MUST DO
00235           * SELECT HAS BEEN INTERRUPTED (EINTR) BY A SIGNAL
00236           */
00237          break;
00238        default :
00239 
00240          GEN_ERROR(E_GEN_FATAL_ERROR, 
00241                    "select failed " << strerror(errno));
00242          break;
00243     }
00244   }
00245 
00246   // if L_n == 0 => nothing to do => no event => just timeout 
00247   GEN_DEBUG(1, "select return = " << L_n);
00248 
00249   // select popped with events
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 { // L_error >= 0
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         } // for L_i
00274         
00275       } // if L_error
00276     } // for L_j
00277     
00278   } // if L_n > 0
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         // check global channel ?
00330         // global channel lost
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   } // switch P_event->m_type
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     } // else {
00439       //      M_state = C_TaskControl::E_STATE_STOPPED ;
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   // TO DO by protocol
00526   //  else {
00527   //  GEN_FATAL(E_GEN_FATAL_ERROR, "Global channel not opened");
00528   // }
00529   GEN_DEBUG(1, "C_ReadControl::transport_table() end");
00530 }
00531 
00532 void C_ReadControl::create_call_controller () {
00533   // initialization of the call controller
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 }

Generated on Wed Mar 7 14:44:57 2007 for Seagull by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002