|
Mixe for Privacy and Anonymity in the Internet
|
00001 /* 00002 Copyright (c) The JAP-Team, JonDos GmbH 00003 00004 All rights reserved. 00005 00006 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 00007 00008 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 00009 * Redistributions in binary form must reproduce the above copyright notice, 00010 this list of conditions and the following disclaimer in the documentation and/or 00011 other materials provided with the distribution. 00012 * Neither the name of the University of Technology Dresden, Germany, nor the name of 00013 the JonDos GmbH, nor the names of their contributors may be used to endorse or 00014 promote products derived from this software without specific prior written permission. 00015 00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00017 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00018 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00019 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 00020 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00021 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00022 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00023 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00024 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00025 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00026 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 */ 00028 00029 #include "CAStatusManager.hpp" 00030 00031 #ifdef SERVER_MONITORING 00032 00033 #include "CAMsg.hpp" 00034 #include "CAMutex.hpp" 00035 #include "CAUtil.hpp" 00036 #include "xml/DOM_Output.hpp" 00037 #include "CALibProxytest.hpp" 00038 #include "monitoringDefs.h" 00039 00046 CAStatusManager *CAStatusManager::ms_pStatusManager = NULL; 00047 state_t ***CAStatusManager::ms_pAllStates = NULL; 00048 event_t ***CAStatusManager::ms_pAllEvents = NULL; 00049 00050 void CAStatusManager::init() 00051 { 00052 if(ms_pAllEvents == NULL) 00053 { 00054 initEvents(); 00055 } 00056 if(ms_pAllStates == NULL) 00057 { 00058 initStates(); 00059 } 00060 if(ms_pStatusManager == NULL) 00061 { 00062 ms_pStatusManager = new CAStatusManager(); 00063 } 00064 } 00065 00066 void CAStatusManager::cleanup() 00067 { 00068 #ifdef DEBUG 00069 CAMsg::printMsg(LOG_DEBUG, 00070 "CAStatusManager: doing cleanup\n"); 00071 #endif 00072 /*if(ms_pStatusManager->m_pStatusSocket != NULL) 00073 { 00074 if(!(ms_pStatusManager->m_pStatusSocket->isClosed())) 00075 { 00076 ms_pStatusManager->m_pStatusSocket->close(); 00077 } 00078 }*/ 00079 00080 if(ms_pStatusManager != NULL) 00081 { 00082 delete ms_pStatusManager; 00083 ms_pStatusManager = NULL; 00084 } 00085 if(ms_pAllStates != NULL) 00086 { 00087 deleteStates(); 00088 } 00089 if(ms_pAllEvents != NULL) 00090 { 00091 deleteEvents(); 00092 } 00093 } 00094 00095 SINT32 CAStatusManager::fireEvent(event_type_t e_type, enum status_type s_type) 00096 { 00097 if(ms_pStatusManager != NULL) 00098 { 00099 return ms_pStatusManager->transition(e_type, s_type); 00100 } 00101 else 00102 { 00103 CAMsg::printMsg(LOG_CRIT, 00104 "StatusManager: cannot handle event %d/%d " 00105 "because there is no StatusManager deployed\n", 00106 s_type, e_type); 00107 return E_UNKNOWN; 00108 } 00109 } 00110 00111 CAStatusManager::CAStatusManager() 00112 { 00113 int i = 0, ret = 0; 00114 m_pCurrentStates = NULL; 00115 m_pCurrentStatesInfo = NULL; 00116 m_pStatusLock = NULL; 00117 m_pStatusSocket = NULL; 00118 m_pListenAddr = NULL; 00119 m_pMonitoringThread = NULL; 00120 m_pPreparedStatusMessage = NULL; 00121 m_bTryListen = false; 00122 00123 m_pCurrentStates = new state_t*[NR_STATUS_TYPES]; 00124 00125 for(i = FIRST_STATUS; i < NR_STATUS_TYPES; i++) 00126 { 00127 m_pCurrentStates[i] = 00128 ms_pAllStates[i][ENTRY_STATE]; 00129 #ifdef DEBUG 00130 CAMsg::printMsg(LOG_DEBUG, "Init state: %s - %s\n", STATUS_NAMES[i], 00131 m_pCurrentStates[i]->st_description); 00132 #endif 00133 } 00134 00135 m_pStatusLock = new CAMutex(); 00136 m_pStatusSocket = new CASocket(); 00137 ret = initSocket(); 00138 if( (ret == E_SUCCESS)) 00139 { 00140 m_pMonitoringThread = new CAThread((UINT8*)"Monitoring Thread"); 00141 m_pMonitoringThread->setMainLoop(serveMonitoringRequests); 00142 m_pMonitoringThread->start(this); 00143 } 00144 else 00145 { 00146 CAMsg::printMsg(LOG_ERR, 00147 "StatusManager: an error occured while initializing the" 00148 " server monitoring socket\n"); 00149 } 00150 initStatusMessage(); 00151 /* pass entry state staus information to the DOM structure */ 00152 for(i = FIRST_STATUS; i < NR_STATUS_TYPES; i++) 00153 { 00154 setDOMElementValue( 00155 (m_pCurrentStatesInfo[i]).dsi_stateType, 00156 (UINT32)(m_pCurrentStates[i])->st_type); 00157 setDOMElementValue( 00158 (m_pCurrentStatesInfo[i]).dsi_stateDesc, 00159 (UINT8*)(m_pCurrentStates[i])->st_description); 00160 setDOMElementValue( 00161 (m_pCurrentStatesInfo[i]).dsi_stateLevel, 00162 (UINT8*)(STATUS_LEVEL_NAMES[(m_pCurrentStates[i])->st_stateLevel])); 00163 } 00164 } 00165 00166 CAStatusManager::~CAStatusManager() 00167 { 00168 int i = 0; 00169 if(m_pMonitoringThread != NULL) 00170 { 00171 if(m_pStatusSocket != NULL) 00172 { 00173 if( !(m_pStatusSocket->isClosed()) ) 00174 { 00175 m_pStatusSocket->close(); 00176 } 00177 } 00178 00179 delete m_pMonitoringThread; 00180 #ifdef DEBUG 00181 CAMsg::printMsg(LOG_DEBUG, 00182 "CAStatusManager: The monitoring thread is no more.\n"); 00183 #endif 00184 m_pMonitoringThread = NULL; 00185 } 00186 if(m_pStatusLock != NULL) 00187 { 00188 delete m_pStatusLock; 00189 m_pStatusLock = NULL; 00190 } 00191 if(m_pCurrentStates != NULL) 00192 { 00193 for(i = FIRST_STATUS; i < NR_STATUS_TYPES; i++) 00194 { 00195 m_pCurrentStates[i] = NULL; 00196 } 00197 delete[] m_pCurrentStates; 00198 m_pCurrentStates = NULL; 00199 } 00200 if(m_pStatusSocket != NULL) 00201 { 00202 delete m_pStatusSocket; 00203 m_pStatusSocket = NULL; 00204 } 00205 if(m_pListenAddr != NULL) 00206 { 00207 delete m_pListenAddr; 00208 m_pListenAddr = NULL; 00209 } 00210 if(m_pPreparedStatusMessage != NULL) 00211 { 00212 m_pPreparedStatusMessage->release(); 00213 m_pPreparedStatusMessage = NULL; 00214 } 00215 } 00216 SINT32 CAStatusManager::initSocket() 00217 { 00218 SINT32 ret = E_UNKNOWN; 00219 int errnum = 0; 00220 00221 if(m_pStatusSocket == NULL) 00222 { 00223 m_pStatusSocket = new CASocket(); 00224 } 00225 00226 if( !(m_pStatusSocket->isClosed()) ) 00227 { 00228 CAMsg::printMsg(LOG_ERR, 00229 "StatusManager: server monitoring socket already connected.\n"); 00230 return E_UNKNOWN; 00231 } 00232 00233 ret = m_pStatusSocket->create(); 00234 if(ret != E_SUCCESS) 00235 { 00236 CAMsg::printMsg(LOG_ERR, 00237 "StatusManager: could not create server monitoring socket.\n"); 00238 return ret; 00239 } 00240 m_pStatusSocket->setReuseAddr(true); 00241 /* listen to default server address, if nothing is specified: 00242 * localhost:8080 00243 */ 00244 char *hostname = "localhost"; 00245 UINT16 port = MONITORING_SERVER_PORT; 00246 bool userdefined = false; 00247 00248 if(CALibProxytest::getOptions()->getMonitoringListenerHost()!= NULL) 00249 { 00250 hostname = CALibProxytest::getOptions()->getMonitoringListenerHost(); 00251 userdefined = true; 00252 } 00253 if(CALibProxytest::getOptions()->getMonitoringListenerPort()!= 0xFFFF) 00254 { 00255 port = CALibProxytest::getOptions()->getMonitoringListenerPort(); 00256 userdefined = true; 00257 } 00258 00259 m_pListenAddr = new CASocketAddrINet(); 00260 ret = m_pListenAddr->setAddr((UINT8 *) hostname, port); 00261 if(ret != E_SUCCESS) 00262 { 00263 if(ret == E_UNKNOWN_HOST) 00264 { 00265 CAMsg::printMsg(LOG_ERR, 00266 "StatusManager: could not initialize specified listener interface:" 00267 " invalid host %s\n", hostname); 00268 if(userdefined) 00269 { 00270 hostname = "localhost"; 00271 CAMsg::printMsg(LOG_ERR, 00272 "StatusManager: trying %s.\n", hostname); 00273 00274 ret = m_pListenAddr->setAddr((UINT8 *) hostname, port); 00275 if(ret != E_SUCCESS) 00276 { 00277 CAMsg::printMsg(LOG_ERR, 00278 "StatusManager: setting up listener interface %s:%d for " 00279 "server monitoring failed\n", 00280 hostname, port); 00281 return ret; 00282 } 00283 } 00284 } 00285 else 00286 { 00287 CAMsg::printMsg(LOG_ERR, 00288 "StatusManager: setting up listener interface %s:%d for " 00289 "server monitoring failed\n", 00290 hostname, port); 00291 return ret; 00292 } 00293 } 00294 ret = m_pStatusSocket->listen(*m_pListenAddr); 00295 00296 if(ret != E_SUCCESS) 00297 { 00298 if(ret != E_UNKNOWN) 00299 { 00300 errnum = GET_NET_ERROR; 00301 CAMsg::printMsg(LOG_ERR, 00302 "StatusManager: not able to init server socket %s:%d " 00303 "for server monitoring. %s failed because: %s\n", 00304 hostname, port, 00305 ((ret == E_SOCKET_BIND) ? "Bind" : "Listen"), 00306 GET_NET_ERROR_STR(errnum)); 00307 } 00308 return ret; 00309 } 00310 #ifdef DEBUG 00311 CAMsg::printMsg(LOG_DEBUG, 00312 "StatusManager: listen to monitoring socket on %s:%d\n", 00313 hostname, port); 00314 #endif 00315 return E_SUCCESS; 00316 } 00317 00318 SINT32 CAStatusManager::transition(event_type_t e_type, status_type_t s_type) 00319 { 00320 transition_t transitionToNextState = st_ignore; 00321 state_t *prev = NULL; 00322 00323 if( (m_pStatusLock == NULL) || 00324 (m_pCurrentStates == NULL) ) 00325 { 00326 CAMsg::printMsg(LOG_CRIT, 00327 "StatusManager: fatal error\n"); 00328 return E_UNKNOWN; 00329 } 00330 if((s_type >= NR_STATUS_TYPES) || (s_type < FIRST_STATUS)) 00331 { 00332 CAMsg::printMsg(LOG_ERR, 00333 "StatusManager: received event for an invalid status type: %d\n", s_type); 00334 return E_INVALID; 00335 } 00336 if((e_type >= EVENT_COUNT[s_type]) || (e_type < FIRST_EVENT)) 00337 { 00338 CAMsg::printMsg(LOG_ERR, 00339 "StatusManager: received an invalid event: %d\n", e_type); 00340 return E_INVALID; 00341 } 00342 00343 /* We process incoming events synchronously, so the calling thread 00344 * should perform state transition very quickly to avoid long blocking 00345 * of other calling threads 00346 */ 00347 m_pStatusLock->lock(); 00348 if(m_pCurrentStates[s_type]->st_transitions == NULL) 00349 { 00350 m_pStatusLock->unlock(); 00351 CAMsg::printMsg(LOG_CRIT, 00352 "StatusManager: current state is corrupt\n"); 00353 return E_UNKNOWN; 00354 } 00355 transitionToNextState = m_pCurrentStates[s_type]->st_transitions[e_type]; 00356 if(transitionToNextState >= STATE_COUNT[s_type]) 00357 { 00358 m_pStatusLock->unlock(); 00359 CAMsg::printMsg(LOG_ERR, 00360 "StatusManager: transition to invalid state %d\n", transitionToNextState); 00361 return E_INVALID; 00362 } 00363 if(transitionToNextState != st_ignore) 00364 { 00365 prev = m_pCurrentStates[s_type]; 00366 m_pCurrentStates[s_type] = ms_pAllStates[s_type][transitionToNextState]; 00367 m_pCurrentStates[s_type]->st_prev = prev; 00368 m_pCurrentStates[s_type]->st_cause = ms_pAllEvents[s_type][e_type]; 00369 00370 /* setting the xml elements of the info message won't be too expensive */ 00371 setDOMElementValue( 00372 (m_pCurrentStatesInfo[s_type]).dsi_stateType, 00373 (UINT32)(m_pCurrentStates[s_type])->st_type); 00374 setDOMElementValue( 00375 (m_pCurrentStatesInfo[s_type]).dsi_stateDesc, 00376 (UINT8*)(m_pCurrentStates[s_type])->st_description); 00377 setDOMElementValue( 00378 (m_pCurrentStatesInfo[s_type]).dsi_stateLevel, 00379 (UINT8*)(STATUS_LEVEL_NAMES[(m_pCurrentStates[s_type])->st_stateLevel])); 00380 #ifdef DEBUG 00381 CAMsg::printMsg(LOG_DEBUG, 00382 "StatusManager: status %s: " 00383 "transition from state %d (%s) " 00384 "to state %d (%s) caused by event %d (%s)\n", 00385 STATUS_NAMES[s_type], 00386 prev->st_type, prev->st_description, 00387 m_pCurrentStates[s_type]->st_type, m_pCurrentStates[s_type]->st_description, 00388 e_type, (ms_pAllEvents[s_type][e_type])->ev_description); 00389 #endif 00390 } 00391 m_pStatusLock->unlock(); 00392 return E_SUCCESS; 00393 } 00394 00395 /* prepares (once) a DOM template for all status messages */ 00396 SINT32 CAStatusManager::initStatusMessage() 00397 { 00398 int i = 0; 00399 m_pPreparedStatusMessage = createDOMDocument(); 00400 m_pCurrentStatesInfo = new dom_state_info[NR_STATUS_TYPES]; 00401 DOMElement *elemRoot = createDOMElement(m_pPreparedStatusMessage, DOM_ELEMENT_STATUS_MESSAGE_NAME); 00402 DOMElement *status_dom_element = NULL; 00403 00404 for(i = FIRST_STATUS; i < NR_STATUS_TYPES; i++) 00405 { 00406 status_dom_element = 00407 createDOMElement(m_pPreparedStatusMessage, STATUS_NAMES[i]); 00408 (m_pCurrentStatesInfo[i]).dsi_stateType = 00409 createDOMElement(m_pPreparedStatusMessage, DOM_ELEMENT_STATE_NAME); 00410 #ifdef DEBUG 00411 setDOMElementValue((m_pCurrentStatesInfo[i]).dsi_stateType, (UINT8*)"Statenumber"); 00412 #endif 00413 (m_pCurrentStatesInfo[i]).dsi_stateLevel = 00414 createDOMElement(m_pPreparedStatusMessage, DOM_ELEMENT_STATE_LEVEL_NAME); 00415 #ifdef DEBUG 00416 setDOMElementValue((m_pCurrentStatesInfo[i]).dsi_stateLevel, (UINT8*)"OK or Critcal or something"); 00417 #endif 00418 (m_pCurrentStatesInfo[i]).dsi_stateDesc = 00419 createDOMElement(m_pPreparedStatusMessage, DOM_ELEMENT_STATE_DESCRIPTION_NAME); 00420 #ifdef DEBUG 00421 setDOMElementValue((m_pCurrentStatesInfo[i]).dsi_stateDesc, (UINT8*)"Description of the state"); 00422 #endif 00423 status_dom_element->appendChild((m_pCurrentStatesInfo[i]).dsi_stateType); 00424 status_dom_element->appendChild((m_pCurrentStatesInfo[i]).dsi_stateLevel); 00425 status_dom_element->appendChild((m_pCurrentStatesInfo[i]).dsi_stateDesc); 00426 elemRoot->appendChild(status_dom_element); 00427 } 00428 m_pPreparedStatusMessage->appendChild(elemRoot); 00429 #ifdef DEBUG 00430 UINT32 debuglen = XML_STATUS_MESSAGE_MAX_SIZE - 1; 00431 UINT8 debugout[XML_STATUS_MESSAGE_MAX_SIZE]; 00432 memset(debugout, 0, (sizeof(UINT8)*XML_STATUS_MESSAGE_MAX_SIZE)); 00433 DOM_Output::dumpToMem(m_pPreparedStatusMessage,debugout,&debuglen); 00434 CAMsg::printMsg(LOG_DEBUG, "the status message template looks like this: %s \n",debugout); 00435 #endif 00436 return E_SUCCESS; 00437 } 00438 00439 THREAD_RETURN serveMonitoringRequests(void* param) 00440 { 00441 CASocket monitoringRequestSocket; 00442 int ret = 0; 00443 CAStatusManager *statusManager = (CAStatusManager*) param; 00444 00445 if(statusManager == NULL) 00446 { 00447 CAMsg::printMsg(LOG_CRIT, 00448 "Monitoring Thread: fatal error, exiting.\n"); 00449 THREAD_RETURN_ERROR; 00450 } 00451 00452 for(;EVER;) 00453 { 00454 00455 if(statusManager->m_pStatusSocket != NULL) 00456 { 00457 if(statusManager->m_pStatusSocket->isClosed()) 00458 { 00459 CAMsg::printMsg(LOG_INFO, 00460 "Monitoring Thread: server socket closed, leaving loop.\n"); 00461 THREAD_RETURN_SUCCESS; 00462 } 00463 } 00464 else 00465 { 00466 CAMsg::printMsg(LOG_ERR, 00467 "Monitoring Thread: server socket disposed, leaving loop.\n"); 00468 THREAD_RETURN_ERROR; 00469 } 00470 00471 if(statusManager->m_pStatusSocket->accept(monitoringRequestSocket) == E_SUCCESS) 00472 { 00473 UINT32 xmlStatusMessageLength = XML_STATUS_MESSAGE_MAX_SIZE - 1; 00474 char xmlStatusMessage[XML_STATUS_MESSAGE_MAX_SIZE]; 00475 memset(xmlStatusMessage, 0, (sizeof(char)*XML_STATUS_MESSAGE_MAX_SIZE)); 00476 statusManager->m_pStatusLock->lock(); 00477 DOM_Output::dumpToMem( 00478 statusManager->m_pPreparedStatusMessage, 00479 (UINT8*)xmlStatusMessage, 00480 &xmlStatusMessageLength); 00481 statusManager->m_pStatusLock->unlock(); 00482 00483 char http_prefix[HTTP_ANSWER_PREFIX_MAX_LENGTH]; 00484 memset(http_prefix, 0, (sizeof(char)*HTTP_ANSWER_PREFIX_MAX_LENGTH)); 00485 snprintf(http_prefix, HTTP_ANSWER_PREFIX_MAX_LENGTH, 00486 HTTP_ANSWER_PREFIX_FORMAT, xmlStatusMessageLength); 00487 size_t http_prefix_length = strlen(http_prefix); 00488 00489 char statusMessageResponse[http_prefix_length+xmlStatusMessageLength+1]; 00490 strncpy(statusMessageResponse, http_prefix, http_prefix_length); 00491 strncpy((statusMessageResponse+http_prefix_length), xmlStatusMessage, xmlStatusMessageLength); 00492 statusMessageResponse[xmlStatusMessageLength+http_prefix_length]=0; 00493 00494 #ifdef DEBUG 00495 CAMsg::printMsg(LOG_DEBUG, "the status message looks like this: %s \n",statusMessageResponse); 00496 #endif 00497 00498 if(monitoringRequestSocket.send((UINT8*)statusMessageResponse, 00499 (http_prefix_length+xmlStatusMessageLength)) < 0) 00500 { 00501 CAMsg::printMsg(LOG_ERR, 00502 "StatusManager: error: could not send status message.\n"); 00503 } 00504 monitoringRequestSocket.close(); 00505 } 00506 else 00507 { 00508 SINT32 errnum = GET_NET_ERROR; 00509 CAMsg::printMsg(LOG_ERR, 00510 "StatusManager: error: could not process monitoring request: %s\n", GET_NET_ERROR_STR(errnum)); 00511 switch (errnum) 00512 { 00513 //case ECONNABORTED: 00514 case EBADF: 00515 case EINVAL: 00516 THREAD_RETURN_ERROR; 00517 } 00518 } 00519 } 00520 } 00521 00522 void CAStatusManager::initStates() 00523 { 00524 int i = 0, j = 0; 00525 ms_pAllStates = new state_t**[NR_STATUS_TYPES]; 00526 00527 for(i = FIRST_STATUS; i < NR_STATUS_TYPES; i++) 00528 { 00529 ms_pAllStates[i] = 00530 new state_t*[STATE_COUNT[i]]; 00531 00532 for(j = ENTRY_STATE; j < STATE_COUNT[i]; j++) 00533 { 00534 ms_pAllStates[i][j] = new state_t; 00535 /* only state identifier are set, transitions and state description 00536 * must be set via macro 00537 **/ 00538 ms_pAllStates[i][j]->st_type = (state_type_t) j; 00539 ms_pAllStates[i][j]->st_statusType = (status_type_t) i; 00540 } 00541 } 00542 FINISH_STATE_DEFINITIONS(ms_pAllStates); 00543 00544 } 00545 00546 void CAStatusManager::deleteStates() 00547 { 00548 int i = 0, j = 0; 00549 00550 for(i = FIRST_STATUS; i < NR_STATUS_TYPES; i++) 00551 { 00552 for(j = ENTRY_STATE; j < STATE_COUNT[i]; j++) 00553 { 00554 if(ms_pAllStates[i][j] != NULL) 00555 { 00556 if(ms_pAllStates[i][j]->st_transitions != NULL) 00557 { 00558 delete[] ms_pAllStates[i][j]->st_transitions; 00559 ms_pAllStates[i][j]->st_transitions = NULL; 00560 } 00561 delete ms_pAllStates[i][j]; 00562 ms_pAllStates[i][j] = NULL; 00563 } 00564 } 00565 delete[] ms_pAllStates[i]; 00566 ms_pAllStates[i] = NULL; 00567 } 00568 delete[] ms_pAllStates; 00569 ms_pAllStates = NULL; 00570 } 00571 00572 void CAStatusManager::initEvents() 00573 { 00574 int i = 0, j = 0; 00575 ms_pAllEvents = new event_t**[NR_STATUS_TYPES]; 00576 00577 for(i = FIRST_STATUS; i < NR_STATUS_TYPES; i++) 00578 { 00579 ms_pAllEvents[i] = new event_t*[EVENT_COUNT[i]]; 00580 for(j = FIRST_EVENT; j < EVENT_COUNT[i]; j++) 00581 { 00582 ms_pAllEvents[i][j] = new event_t; 00583 ms_pAllEvents[i][j]->ev_type = (event_type_t) j; 00584 ms_pAllEvents[i][j]->ev_statusType = (status_type_t) i; 00585 } 00586 } 00587 FINISH_EVENT_DEFINITIONS(ms_pAllEvents); 00588 } 00589 00590 void CAStatusManager::deleteEvents() 00591 { 00592 int i = 0, j = 0; 00593 00594 for(i = FIRST_STATUS; i < NR_STATUS_TYPES; i++) 00595 { 00596 for(j = FIRST_EVENT; j < EVENT_COUNT[i]; j++) 00597 { 00598 delete ms_pAllEvents[i][j]; 00599 ms_pAllEvents[i][j] = NULL; 00600 } 00601 delete[] ms_pAllEvents[i]; 00602 ms_pAllEvents[i] = NULL; 00603 } 00604 delete[] ms_pAllEvents; 00605 ms_pAllEvents = NULL; 00606 } 00607 00608 transition_t *defineTransitions(status_type_t s_type, SINT32 transitionCount, ...) 00609 { 00610 int i = 0; 00611 va_list ap; 00612 transition_t *transitions = NULL; 00613 event_type_t specifiedEventTypes[transitionCount]; 00614 transition_t specifiedTransitions[transitionCount]; 00615 00616 /* read in the specified events with the corresponding transitions */ 00617 va_start(ap, transitionCount); 00618 for(i = 0; i < transitionCount; i++) 00619 { 00620 specifiedEventTypes[i] = (event_type_t) va_arg(ap, int); 00621 specifiedTransitions[i] = (transition_t) va_arg(ap, int); 00622 } 00623 va_end(ap); 00624 00625 if((s_type >= NR_STATUS_TYPES) || (s_type < FIRST_STATUS)) 00626 { 00627 /* invalid status type specified */ 00628 return NULL; 00629 } 00630 if(transitionCount > (EVENT_COUNT[s_type])) 00631 { 00632 /* more transitions specified than events defined*/ 00633 return NULL; 00634 } 00635 00636 transitions = new transition_t[(EVENT_COUNT[s_type])]; 00637 memset(transitions, st_ignore, (sizeof(transition_t)*(EVENT_COUNT[s_type]))); 00638 for(i = 0; i < transitionCount; i++) 00639 { 00640 if((specifiedEventTypes[i] >= EVENT_COUNT[s_type]) || 00641 (specifiedEventTypes[i] < 0)) 00642 { 00643 /* specified event is invalid */ 00644 CAMsg::printMsg(LOG_WARNING, 00645 "StatusManager: definition of an invalid state transition (invalid event %d).\n", 00646 specifiedEventTypes[i]); 00647 continue; 00648 } 00649 if((specifiedTransitions[i] >= STATE_COUNT[s_type]) || 00650 (specifiedTransitions[i] < st_ignore)) 00651 { 00652 /* corresponding transition to event is not valid */ 00653 CAMsg::printMsg(LOG_WARNING, 00654 "StatusManager: definition of an invalid state transition (invalid state %d).\n", 00655 specifiedTransitions[i]); 00656 continue; 00657 } 00658 transitions[specifiedEventTypes[i]] = specifiedTransitions[i]; 00659 } 00660 00661 return transitions; 00662 00663 } 00664 #endif
1.7.6.1