Alex Bikfalvi
SimStream Documentation
Connection.cpp
00001 #include "Headers.h" 00002 #include "Connection.h" 00003 #include "Debug.h" 00004 #include "Console.h" 00005 00006 #pragma warning(disable : 4996) 00007 00008 __uint32 CConnection::idGlobal = 0; 00009 __uint32 CConnection::flowGlobal = 0; 00010 00011 __time CConnection::timerOpenTimeout = 0.5; 00012 __time CConnection::timerCloseTimeout = 0.5; 00013 __time CConnection::timerCancelTimeout = 2.0; 00014 __time CConnection::timerRequesterWaitTimeout = 2.0; 00015 __time CConnection::timerResponderWaitTimeout = 120.0; 00016 __time CConnection::timerDefaultWaitTimeout = 30.0; 00017 00018 char* CConnection::strConnectionType[] = {"REQUESTER", "RESPONDER"}; 00019 char* CConnection::strState[] = {"CLOSED", "OPENING", "OPENED", "CLOSING", "CANCELING", "WAITING"}; 00020 00021 CConnection::CConnection( 00022 EConnectionType type, 00023 __uint32 idEntry, 00024 __uint16 port, 00025 CSimHandler* sim, 00026 IDelegate5<void, __uint16, __uint16, CAddress, __byte, CPacket*>* delegateSend, 00027 IDelegate1<void, CConnection*>* delegateDispose, 00028 CAddress remoteAddress, 00029 __uint16 remotePort 00030 ) 00031 { 00032 // Type 00033 this->type = type; 00034 00035 // Simulator 00036 this->sim = sim; 00037 00038 // Flow 00039 this->flow = 0xFFFFFFFF; 00040 00041 // State 00042 this->state = CLOSED; 00043 00044 // Local 00045 this->id = CConnection::idGlobal++; 00046 this->idEntry = idEntry; 00047 this->port = port; 00048 00049 // Remote 00050 this->remoteAddress = remoteAddress; 00051 this->remoteId = 0; 00052 this->remoteIdEntry = 0; 00053 this->remotePort = remotePort; 00054 00055 // Delegates 00056 this->delegateSend = delegateSend; 00057 00058 // Events 00059 this->eventOpen = new Event2<void, CConnection*, EOpenResult>(); 00060 this->eventClose = new Event2<void, CConnection*, ECloseResult>(); 00061 00062 // Calls 00063 this->callDispose = new Call1<CConnection*>(this->sim, delegateDispose); 00064 00065 // Timers 00066 this->timerControl = new CTimer<CConnection>(this->sim, this); 00067 00068 // Tag 00069 this->tag = NULL; 00070 00071 // Set functions 00072 switch(this->type) 00073 { 00074 case REQUESTER: 00075 this->functionOpen = &CConnection::OpenRequester; 00076 this->functionClose = &CConnection::CloseRequester; 00077 this->functionRecvMessageOpen = &CConnection::RecvMessageOpenRequester; 00078 this->functionRecvMessageOpenAck = &CConnection::RecvMessageOpenAckRequester; 00079 this->functionRecvMessageClose = &CConnection::RecvMessageCloseRequester; 00080 this->functionRecvMessageCloseAck = &CConnection::RecvMessageCloseAckRequester; 00081 this->functionRecvMessageCloseAckAck = &CConnection::RecvMessageCloseAckAckRequester; 00082 break; 00083 case RESPONDER: 00084 this->functionOpen = &CConnection::OpenResponder; 00085 this->functionClose = &CConnection::CloseResponder; 00086 this->functionRecvMessageOpen = &CConnection::RecvMessageOpenResponder; 00087 this->functionRecvMessageOpenAck = &CConnection::RecvMessageOpenAckResponder; 00088 this->functionRecvMessageClose = &CConnection::RecvMessageCloseResponder; 00089 this->functionRecvMessageCloseAck = &CConnection::RecvMessageCloseAckResponder; 00090 this->functionRecvMessageCloseAckAck = &CConnection::RecvMessageCloseAckAckResponder; 00091 break; 00092 } 00093 } 00094 00095 CConnection::~CConnection() 00096 { 00097 // Events 00098 delete this->eventOpen; 00099 delete this->eventClose; 00100 00101 // Calls 00102 delete this->callDispose; 00103 00104 // Timers 00105 delete this->timerControl; 00106 } 00107 00108 void CConnection::Open() 00109 { 00110 // Call open function for connection type 00111 (this->*this->functionOpen)(); 00112 } 00113 00114 void CConnection::OpenRequester() 00115 { 00116 // Exception for any connection state other that CLOSED 00117 assert(CLOSED == this->state); 00118 00119 #ifdef LOG_FLOW 00120 CConsole::SetColor(CConsole::DARK_RED); 00121 printf("\n\tT = %8.3lf\tOpenRequester() : %s -> ", this->sim->Time(), this->ToString()); 00122 CConsole::SetColor(CConsole::LIGHT_GRAY); 00123 #endif 00124 00125 // Initialize the flow number 00126 this->flow = CConnection::flowGlobal++; 00127 00128 // Change the state 00129 this->state = OPENING; 00130 00131 // Send an OPEN message to the sender 00132 CPacketConnectionMessage* packet = new CPacketConnectionMessage( 00133 this->flow, 00134 this->id, 00135 this->idEntry, 00136 this->sim->Time()); 00137 00138 (*this->delegateSend)(this->port, this->remotePort, this->remoteAddress, 128, packet); 00139 00140 // Set the control timer to open handler 00141 this->timerControl->SetAfter(CConnection::timerOpenTimeout, &CConnection::TimerOpen); 00142 00143 #ifdef LOG_FLOW 00144 CConsole::SetColor(CConsole::DARK_RED); 00145 printf("%s", this->ToString()); 00146 CConsole::SetColor(CConsole::LIGHT_GRAY); 00147 #endif 00148 } 00149 00150 void CConnection::OpenResponder() 00151 { 00152 #ifdef LOG_FLOW 00153 CConsole::SetColor(CConsole::DARK_BLUE); 00154 printf("\n\tT = %8.3lf\tOpenResponder() : %s -> ", this->sim->Time(), this->ToString()); 00155 CConsole::SetColor(CConsole::LIGHT_GRAY); 00156 #endif 00157 00158 // Exception for any connection state 00159 assert(0); 00160 00161 #ifdef LOG_FLOW 00162 CConsole::SetColor(CConsole::DARK_BLUE); 00163 printf("%s", this->ToString()); 00164 CConsole::SetColor(CConsole::LIGHT_GRAY); 00165 #endif 00166 } 00167 00168 void CConnection::Close() 00169 { 00170 // Call close function for connection type 00171 (this->*this->functionClose)(); 00172 } 00173 00174 void CConnection::CloseRequester() 00175 { 00176 #ifdef LOG_FLOW 00177 CConsole::SetColor(CConsole::DARK_RED); 00178 printf("\n\tT = %8.3lf\tCloseRequester() : %s -> ", this->sim->Time(), this->ToString()); 00179 CConsole::SetColor(CConsole::LIGHT_GRAY); 00180 #endif 00181 00182 // Close requester 00183 switch(this->state) 00184 { 00185 case OPENING: // Change to CANCELING / none / timer cancel 00186 { 00187 // Check the control timer is set 00188 assert(this->timerControl->IsSet()); 00189 00190 // Cancel the control timer 00191 this->timerControl->Cancel(); 00192 00193 // Change the state 00194 this->state = CANCELING; 00195 00196 // Raise open event 00197 (*this->eventOpen)(this, OPEN_CANCELED); 00198 00199 // Set the control timer to cancel handler 00200 this->timerControl->SetAfter(CConnection::timerCancelTimeout, &CConnection::TimerCancel); 00201 } 00202 break; 00203 case OPENED: // Change to CLOSING / CLOSE / timer close 00204 // If connection is opened, send a CLOSE message to remote party 00205 { 00206 // Check the control timer is not set 00207 assert(!this->timerControl->IsSet()); 00208 00209 // Send a CLOSE message to the sender 00210 CPacketConnectionMessage* packet = new CPacketConnectionMessage( 00211 this->flow, 00212 this->id, 00213 this->remoteId, 00214 this->idEntry, 00215 this->remoteIdEntry, 00216 CPacketConnectionMessage::CLOSE, 00217 this->sim->Time() 00218 ); 00219 00220 (*this->delegateSend)(this->port, this->remotePort, this->remoteAddress, 128, packet); 00221 00222 // Change the state 00223 this->state = CLOSING; 00224 00225 // Set the control timer to close handler 00226 this->timerControl->SetAfter(CConnection::timerCloseTimeout, &CConnection::TimerClose); 00227 } 00228 break; 00229 case CLOSING: break; // Ignore 00230 case WAITING: break; // Ignore 00231 default: assert(0); // Exception for all other states 00232 } 00233 00234 #ifdef LOG_FLOW 00235 CConsole::SetColor(CConsole::DARK_RED); 00236 printf("%s", this->ToString()); 00237 CConsole::SetColor(CConsole::LIGHT_GRAY); 00238 #endif 00239 } 00240 00241 void CConnection::CloseResponder() 00242 { 00243 #ifdef LOG_FLOW 00244 CConsole::SetColor(CConsole::DARK_BLUE); 00245 printf("\n\tT = %8.3lf\tCloseResponder() : %s -> ", this->sim->Time(), this->ToString()); 00246 CConsole::SetColor(CConsole::LIGHT_GRAY); 00247 #endif 00248 00249 // Close responder 00250 switch(this->state) 00251 { 00252 case OPENING: // Change to CLOSING / none / timer cancel 00253 // If connection is opened, send a CLOSE message to remote party 00254 { 00255 // Check the control timer is set 00256 assert(this->timerControl->IsSet()); 00257 00258 // Cancel the control timer 00259 this->timerControl->Cancel(); 00260 00261 // Send a CLOSE message to the sender 00262 CPacketConnectionMessage* packet = new CPacketConnectionMessage( 00263 this->flow, 00264 this->id, 00265 this->remoteId, 00266 this->idEntry, 00267 this->remoteIdEntry, 00268 CPacketConnectionMessage::CLOSE, 00269 this->sim->Time() 00270 ); 00271 00272 (*this->delegateSend)(this->port, this->remotePort, this->remoteAddress, 128, packet); 00273 00274 // Set the control timer to close handler 00275 this->timerControl->SetAfter(CConnection::timerCloseTimeout, &CConnection::TimerClose); 00276 00277 // Change the state 00278 this->state = CLOSING; 00279 00280 // Raise open event 00281 (*this->eventOpen)(this, OPEN_CANCELED); 00282 } 00283 break; 00284 case OPENED: // Change to CLOSING / CLOSE / timer close 00285 // If connection is opened, send a CLOSE message to remote party 00286 { 00287 // Check the control timer is not set 00288 assert(!this->timerControl->IsSet()); 00289 00290 // Send a CLOSE message to the sender 00291 CPacketConnectionMessage* packet = new CPacketConnectionMessage( 00292 this->flow, 00293 this->id, 00294 this->remoteId, 00295 this->idEntry, 00296 this->remoteIdEntry, 00297 CPacketConnectionMessage::CLOSE, 00298 this->sim->Time() 00299 ); 00300 00301 (*this->delegateSend)(this->port, this->remotePort, this->remoteAddress, 128, packet); 00302 00303 // Change the state 00304 this->state = CLOSING; 00305 00306 // Set the control timer to close handler 00307 this->timerControl->SetAfter(CConnection::timerCloseTimeout, &CConnection::TimerClose); 00308 } 00309 break; 00310 case CLOSING: break; // Ignore in CLOSING state 00311 case WAITING: break; // Ignore in WAITING state 00312 default: assert(0); // Exception for other states 00313 } 00314 00315 #ifdef LOG_FLOW 00316 CConsole::SetColor(CConsole::DARK_BLUE); 00317 printf("%s", this->ToString()); 00318 CConsole::SetColor(CConsole::LIGHT_GRAY); 00319 #endif 00320 } 00321 00322 bool CConnection::SendData(CPacketConnectionData* packet) 00323 { 00324 assert("To do" != 0); 00325 00326 return false; 00327 } 00328 00329 void CConnection::Recv(CAddress src, CPacketConnection* packet) 00330 { 00331 // Check the packet source and destination 00332 assert(src == this->remoteAddress); 00333 00334 switch(packet->TypeConnection()) 00335 { 00336 case CPacketConnection::MESSAGE: this->RecvMessage(type_cast<CPacketConnectionMessage*>(packet)); break; 00337 case CPacketConnection::FEEDBACK: this->RecvFeedback(type_cast<CPacketConnectionFeedback*>(packet)); break; 00338 case CPacketConnection::DATA: this->RecvData(type_cast<CPacketConnectionData*>(packet)); break; 00339 } 00340 00341 // General processing 00342 this->Recv(packet); 00343 } 00344 00345 void CConnection::RecvMessage(CPacketConnectionMessage* packet) 00346 { 00347 switch(packet->TypeMessage()) 00348 { 00349 case CPacketConnectionMessage::OPEN: (this->*this->functionRecvMessageOpen)(packet); break; 00350 case CPacketConnectionMessage::OPEN_ACK: (this->*this->functionRecvMessageOpenAck)(packet); break; 00351 case CPacketConnectionMessage::CLOSE: (this->*this->functionRecvMessageClose)(packet); break; 00352 case CPacketConnectionMessage::CLOSE_ACK: (this->*this->functionRecvMessageCloseAck)(packet); break; 00353 case CPacketConnectionMessage::CLOSE_ACK_ACK: (this->*this->functionRecvMessageCloseAckAck)(packet); break; 00354 default: assert(0); // Not supported 00355 } 00356 } 00357 00358 void CConnection::RecvMessageOpenRequester(CPacketConnectionMessage* packet) 00359 { 00360 // Received an OPEN message 00361 00362 // Exception for any connection state 00363 assert(0); 00364 } 00365 00366 void CConnection::RecvMessageOpenAckRequester(CPacketConnectionMessage* packet) 00367 { 00368 // Received an OPEN-ACK message 00369 00370 #ifdef LOG_FLOW 00371 CConsole::SetColor(CConsole::DARK_RED); 00372 printf("\n\tT = %8.3lf\tRecvRequester(OPEN_ACK) : %s -> ", this->sim->Time(), this->ToString()); 00373 CConsole::SetColor(CConsole::LIGHT_GRAY); 00374 #endif 00375 00376 // Check the packet source and destination 00377 assert(packet->Dst() == this->id); 00378 assert(packet->DstEntry() == this->idEntry); 00379 assert(packet->Flow() == this->flow); 00380 00381 // Check the state 00382 switch(this->state) 00383 { 00384 case CConnection::OPENING: // Change to OPENED / OPEN_ACK / none 00385 { 00386 // Check the control timer is set 00387 assert(this->timerControl->IsSet()); 00388 00389 // Cancel the control timer 00390 this->timerControl->Cancel(); 00391 00392 // Set the sender information 00393 this->remoteId = packet->Src(); 00394 this->remoteIdEntry = packet->SrcEntry(); 00395 00396 // Send a OPEN-ACK message 00397 CPacketConnectionMessage* reply = new CPacketConnectionMessage( 00398 this->flow, 00399 this->id, 00400 this->remoteId, 00401 this->idEntry, 00402 this->remoteIdEntry, 00403 CPacketConnectionMessage::OPEN_ACK, 00404 this->sim->Time(), 00405 packet->TimeTx() 00406 ); 00407 00408 (*this->delegateSend)(this->port, this->remotePort, this->remoteAddress, 128, reply); 00409 00410 // Change the state 00411 this->state = OPENED; 00412 00413 // Raise open event 00414 (*this->eventOpen)(this, OPEN_SUCCESS); 00415 } 00416 break; 00417 case CConnection::CANCELING: // Change to CLOSING / CLOSE / timer close 00418 { 00419 // Check the control timer is set 00420 assert(this->timerControl->IsSet()); 00421 00422 // Cancel the control timer 00423 this->timerControl->Cancel(); 00424 00425 // Set the sender information 00426 this->remoteId = packet->Src(); 00427 this->remoteIdEntry = packet->SrcEntry(); 00428 00429 // Send a CLOSE message 00430 CPacketConnectionMessage* reply = new CPacketConnectionMessage( 00431 this->flow, 00432 this->id, 00433 this->remoteId, 00434 this->idEntry, 00435 this->remoteIdEntry, 00436 CPacketConnectionMessage::CLOSE, 00437 this->sim->Time(), 00438 packet->TimeTx() 00439 ); 00440 00441 (*this->delegateSend)(this->port, this->remotePort, this->remoteAddress, 128, reply); 00442 00443 // Change the state 00444 this->state = CLOSING; 00445 00446 // Set the control timer to close handler 00447 this->timerControl->SetAfter(CConnection::timerCloseTimeout, &CConnection::TimerClose); 00448 } 00449 break; 00450 default: assert(0); // Exception for other states 00451 } 00452 00453 #ifdef LOG_FLOW 00454 CConsole::SetColor(CConsole::DARK_RED); 00455 printf("%s", this->ToString()); 00456 CConsole::SetColor(CConsole::LIGHT_GRAY); 00457 #endif 00458 } 00459 00460 void CConnection::RecvMessageCloseRequester(CPacketConnectionMessage* packet) 00461 { 00462 // Received a CLOSE message 00463 00464 #ifdef LOG_FLOW 00465 CConsole::SetColor(CConsole::DARK_RED); 00466 printf("\n\tT = %8.3lf\tRecvRequester(CLOSE) : %s -> ", this->sim->Time(), this->ToString()); 00467 CConsole::SetColor(CConsole::LIGHT_GRAY); 00468 #endif 00469 00470 // Check the packet source and destination 00471 assert(packet->Dst() == this->id); 00472 assert(packet->DstEntry() == this->idEntry); 00473 assert(packet->Flow() == this->flow); 00474 00475 // Check the state 00476 switch(this->state) 00477 { 00478 case OPENING: // Change to CLOSING / CLOSE_ACK / timer close 00479 { 00480 // Check the control timer is set 00481 assert(this->timerControl->IsSet()); 00482 00483 // Cancel the control timer 00484 this->timerControl->Cancel(); 00485 00486 // Send a CLOSE-ACK message 00487 CPacketConnectionMessage* reply = new CPacketConnectionMessage( 00488 this->flow, 00489 this->id, 00490 this->remoteId, 00491 this->idEntry, 00492 this->remoteIdEntry, 00493 CPacketConnectionMessage::CLOSE_ACK, 00494 this->sim->Time(), 00495 packet->TimeTx() 00496 ); 00497 00498 (*this->delegateSend)(this->port, this->remotePort, this->remoteAddress, 128, reply); 00499 00500 // Change the state 00501 this->state = CLOSING; 00502 00503 // Raise the event 00504 (*this->eventOpen)(this, OPEN_FAIL_REMOTE); 00505 00506 // Set the control timer to close handler 00507 this->timerControl->SetAfter(CConnection::timerCloseTimeout, &CConnection::TimerClose); 00508 } 00509 break; 00510 case OPENED: // Change to CLOSING / CLOSE_ACK / timer close 00511 { 00512 // Check the control timer is not set 00513 assert(!this->timerControl->IsSet()); 00514 00515 // Send a CLOSE-ACK message 00516 CPacketConnectionMessage* reply = new CPacketConnectionMessage( 00517 this->flow, 00518 this->id, 00519 this->remoteId, 00520 this->idEntry, 00521 this->remoteIdEntry, 00522 CPacketConnectionMessage::CLOSE_ACK, 00523 this->sim->Time(), 00524 packet->TimeTx() 00525 ); 00526 00527 (*this->delegateSend)(this->port, this->remotePort, this->remoteAddress, 128, reply); 00528 00529 // Change the state 00530 this->state = CLOSING; 00531 00532 // Set the control timer to close handler 00533 this->timerControl->SetAfter(CConnection::timerCloseTimeout, &CConnection::TimerClose); 00534 } 00535 break; 00536 case CANCELING: // Change to CLOSING / CLOSE_ACK / timer close 00537 { 00538 // Check the control timer is set 00539 assert(this->timerControl->IsSet()); 00540 00541 // Cancel the control timer 00542 this->timerControl->Cancel(); 00543 00544 // Send a CLOSE-ACK message 00545 CPacketConnectionMessage* reply = new CPacketConnectionMessage( 00546 this->flow, 00547 this->id, 00548 this->remoteId, 00549 this->idEntry, 00550 this->remoteIdEntry, 00551 CPacketConnectionMessage::CLOSE_ACK, 00552 this->sim->Time(), 00553 packet->TimeTx() 00554 ); 00555 00556 (*this->delegateSend)(this->port, this->remotePort, this->remoteAddress, 128, reply); 00557 00558 // Change the state 00559 this->state = CLOSING; 00560 00561 // Set the control timer to close handler 00562 this->timerControl->SetAfter(CConnection::timerCloseTimeout, &CConnection::TimerClose); 00563 } 00564 break; 00565 case CLOSING: // Change to CLOSING / CLOSE_ACK / none 00566 { 00567 // Check the control timer is set 00568 assert(this->timerControl->IsSet()); 00569 00570 // Send a CLOSE-ACK message 00571 CPacketConnectionMessage* reply = new CPacketConnectionMessage( 00572 this->flow, 00573 this->id, 00574 this->remoteId, 00575 this->idEntry, 00576 this->remoteIdEntry, 00577 CPacketConnectionMessage::CLOSE_ACK, 00578 this->sim->Time(), 00579 packet->TimeTx() 00580 ); 00581 00582 (*this->delegateSend)(this->port, this->remotePort, this->remoteAddress, 128, reply); 00583 00584 // Leave the current state and timer 00585 } 00586 break; 00587 default: assert(0); // Exception for other states 00588 } 00589 00590 #ifdef LOG_FLOW 00591 CConsole::SetColor(CConsole::DARK_RED); 00592 printf("%s", this->ToString()); 00593 CConsole::SetColor(CConsole::LIGHT_GRAY); 00594 #endif 00595 } 00596 00597 void CConnection::RecvMessageCloseAckRequester(CPacketConnectionMessage* packet) 00598 { 00599 // Received a CLOSE-ACK message 00600 00601 #ifdef LOG_FLOW 00602 CConsole::SetColor(CConsole::DARK_RED); 00603 printf("\n\tT = %8.3lf\tRecvRequester(CLOSE_ACK) : %s -> ", this->sim->Time(), this->ToString()); 00604 CConsole::SetColor(CConsole::LIGHT_GRAY); 00605 #endif 00606 00607 // Check the packet source and destination 00608 assert(packet->Dst() == this->id); 00609 assert(packet->DstEntry() == this->idEntry); 00610 assert(packet->Flow() == this->flow); 00611 00612 // Check the state 00613 switch(this->state) 00614 { 00615 case CLOSING: // Change to WAITING / CLOSE_ACK_ACK / timer wait 00616 { 00617 // Check the control timer is set 00618 assert(this->timerControl->IsSet()); 00619 00620 // Cancel the control timer 00621 this->timerControl->Cancel(); 00622 00623 // Send a CLOSE-ACK-ACK message 00624 CPacketConnectionMessage* reply = new CPacketConnectionMessage( 00625 this->flow, 00626 this->id, 00627 this->remoteId, 00628 this->idEntry, 00629 this->remoteIdEntry, 00630 CPacketConnectionMessage::CLOSE_ACK_ACK, 00631 this->sim->Time(), 00632 packet->TimeTx() 00633 ); 00634 00635 (*this->delegateSend)(this->port, this->remotePort, this->remoteAddress, 128, reply); 00636 00637 // Change the state 00638 this->state = WAITING; 00639 00640 // Raise the event 00641 (*this->eventClose)(this, CLOSE_CONFIRMED); 00642 00643 // Set the control timer to the waiting handler 00644 this->timerControl->SetAfter(CConnection::timerRequesterWaitTimeout, &CConnection::TimerWait); 00645 } 00646 break; 00647 default: assert(0); // Exception for other sattes 00648 } 00649 00650 #ifdef LOG_FLOW 00651 CConsole::SetColor(CConsole::DARK_RED); 00652 printf("%s", this->ToString()); 00653 CConsole::SetColor(CConsole::LIGHT_GRAY); 00654 #endif 00655 } 00656 00657 void CConnection::RecvMessageCloseAckAckRequester(CPacketConnectionMessage* packet) 00658 { 00659 // Received a CLOSE-ACK-ACK 00660 00661 #ifdef LOG_FLOW 00662 CConsole::SetColor(CConsole::DARK_RED); 00663 printf("\n\tT = %8.3lf\tRecvRequester(CLOSE_ACK_ACK) : %s -> ", this->sim->Time(), this->ToString()); 00664 CConsole::SetColor(CConsole::LIGHT_GRAY); 00665 #endif 00666 00667 // Check the packet source and destination 00668 assert(packet->Dst() == this->id); 00669 assert(packet->DstEntry() == this->idEntry); 00670 assert(packet->Flow() == this->flow); 00671 00672 // Check the state 00673 switch(this->state) 00674 { 00675 case CLOSING: // Change to WAITING / none / timer wait 00676 { 00677 // Check the control timer is set 00678 assert(this->timerControl->IsSet()); 00679 00680 // Cancel the control timer 00681 this->timerControl->Cancel(); 00682 00683 // Change the state 00684 this->state = WAITING; 00685 00686 // Raise the event 00687 (*this->eventClose)(this, CLOSE_CONFIRMED); 00688 00689 // Set the control timer to the waiting handler 00690 this->timerControl->SetAfter(CConnection::timerResponderWaitTimeout, &CConnection::TimerWait); 00691 } 00692 break; 00693 case CLOSED: 00694 case WAITING: 00695 break; // Ignore in CLOSED or WAITING state 00696 default: assert(0); // Exception for other states 00697 } 00698 00699 #ifdef LOG_FLOW 00700 CConsole::SetColor(CConsole::DARK_RED); 00701 printf("%s", this->ToString()); 00702 CConsole::SetColor(CConsole::LIGHT_GRAY); 00703 #endif 00704 } 00705 00706 void CConnection::RecvMessageOpenResponder(CPacketConnectionMessage* packet) 00707 { 00708 // Received an OPEN message 00709 00710 #ifdef LOG_FLOW 00711 CConsole::SetColor(CConsole::DARK_BLUE); 00712 printf("\n\tT = %8.3lf\tRecvResponder(OPEN) : %s -> ", this->sim->Time(), this->ToString()); 00713 CConsole::SetColor(CConsole::LIGHT_GRAY); 00714 #endif 00715 00716 // Check the packet source and destination : must be set to an invalid connection 00717 assert(packet->Dst() == PACKET_INVALID_CONNECTION); 00718 assert(packet->DstEntry() == PACKET_INVALID_CONNECTION_ENTRY); 00719 00720 // Check the state 00721 switch(this->state) 00722 { 00723 case CLOSED: // Change to OPENING / OPEN_ACK / timer open 00724 { 00725 // Check the control timer is not set 00726 assert(!this->timerControl->IsSet()); 00727 00728 // Set the flow number 00729 this->flow = packet->Flow(); 00730 00731 // Send an OPEN-ACK message 00732 CPacketConnectionMessage* reply = new CPacketConnectionMessage( 00733 this->flow, 00734 this->id, 00735 this->remoteId, 00736 this->idEntry, 00737 this->remoteIdEntry, 00738 CPacketConnectionMessage::OPEN_ACK, 00739 this->sim->Time(), 00740 packet->TimeTx() 00741 ); 00742 00743 (*this->delegateSend)(this->port, this->remotePort, this->remoteAddress, 128, reply); 00744 00745 // Change the state 00746 this->state = OPENING; 00747 00748 // Set the control timer to open handler 00749 this->timerControl->SetAfter(CConnection::timerOpenTimeout, &CConnection::TimerOpen); 00750 } 00751 break; 00752 default: assert(0); // Exception for other state 00753 } 00754 00755 #ifdef LOG_FLOW 00756 CConsole::SetColor(CConsole::DARK_BLUE); 00757 printf("%s", this->ToString()); 00758 CConsole::SetColor(CConsole::LIGHT_GRAY); 00759 #endif 00760 } 00761 00762 void CConnection::RecvMessageOpenAckResponder(CPacketConnectionMessage* packet) 00763 { 00764 // Received an OPEN-ACK message 00765 00766 #ifdef LOG_FLOW 00767 CConsole::SetColor(CConsole::DARK_BLUE); 00768 printf("\n\tT = %8.3lf\tRecvResponder(OPEN_ACK) : %s -> ", this->sim->Time(), this->ToString()); 00769 CConsole::SetColor(CConsole::LIGHT_GRAY); 00770 #endif 00771 00772 // Check the packet source and destination 00773 assert(packet->Dst() == this->id); 00774 assert(packet->DstEntry() == this->idEntry); 00775 assert(packet->Flow() == this->flow); 00776 00777 // Check the state 00778 switch(this->state) 00779 { 00780 case OPENING: // Change to OPENED / none / none 00781 { 00782 // Check the control timer is set 00783 assert(this->timerControl->IsSet()); 00784 00785 // Cancel the control timer 00786 this->timerControl->Cancel(); 00787 00788 // Change the state 00789 this->state = OPENED; 00790 00791 // Raise the event 00792 (*this->eventOpen)(this, OPEN_SUCCESS); 00793 } 00794 break; 00795 case CLOSING: break; // Ignore in CLOSING state 00796 default: assert(0); // Exception for other state 00797 } 00798 00799 #ifdef LOG_FLOW 00800 CConsole::SetColor(CConsole::DARK_BLUE); 00801 printf("%s", this->ToString()); 00802 CConsole::SetColor(CConsole::LIGHT_GRAY); 00803 #endif 00804 } 00805 00806 void CConnection::RecvMessageCloseResponder(CPacketConnectionMessage* packet) 00807 { 00808 // Received a CLOSE message 00809 00810 #ifdef LOG_FLOW 00811 CConsole::SetColor(CConsole::DARK_BLUE); 00812 printf("\n\tT = %8.3lf\tRecvResponder(CLOSE) : %s -> ", this->sim->Time(), this->ToString()); 00813 CConsole::SetColor(CConsole::LIGHT_GRAY); 00814 #endif 00815 00816 // Check the packet source and destination 00817 assert(packet->Dst() == this->id); 00818 assert(packet->DstEntry() == this->idEntry); 00819 assert(packet->Flow() == this->flow); 00820 00821 // Check the state 00822 switch(this->state) 00823 { 00824 case OPENING: // Change to CLOSING / CLOSE_ACK / timer close 00825 { 00826 // Check the control timer is set 00827 assert(this->timerControl->IsSet()); 00828 00829 // Cancel the control timer 00830 this->timerControl->Cancel(); 00831 00832 // Send a CLOSE-ACK message 00833 CPacketConnectionMessage* reply = new CPacketConnectionMessage( 00834 this->flow, 00835 this->id, 00836 this->remoteId, 00837 this->idEntry, 00838 this->remoteIdEntry, 00839 CPacketConnectionMessage::CLOSE_ACK, 00840 this->sim->Time(), 00841 packet->TimeTx() 00842 ); 00843 00844 (*this->delegateSend)(this->port, this->remotePort, this->remoteAddress, 128, reply); 00845 00846 // Change the state 00847 this->state = CLOSING; 00848 00849 // Raise the event 00850 (*this->eventOpen)(this, OPEN_FAIL_REMOTE); 00851 00852 // Set the control timer to close handler 00853 this->timerControl->SetAfter(CConnection::timerCloseTimeout, &CConnection::TimerClose); 00854 } 00855 break; 00856 case OPENED: // Change to CLOSING / CLOSE_ACK / timer close 00857 { 00858 // Check the control timer is not set 00859 assert(!this->timerControl->IsSet()); 00860 00861 // Send a CLOSE-ACK message 00862 CPacketConnectionMessage* reply = new CPacketConnectionMessage( 00863 this->flow, 00864 this->id, 00865 this->remoteId, 00866 this->idEntry, 00867 this->remoteIdEntry, 00868 CPacketConnectionMessage::CLOSE_ACK, 00869 this->sim->Time(), 00870 packet->TimeTx() 00871 ); 00872 (*this->delegateSend)(this->port, this->remotePort, this->remoteAddress, 128, reply); 00873 00874 // Change the state 00875 this->state = CLOSING; 00876 00877 // Set the control timer to close handler 00878 this->timerControl->SetAfter(CConnection::timerCloseTimeout, &CConnection::TimerClose); 00879 } 00880 break; 00881 case CLOSING: // Change to CLOSING / CLOSE_ACK / none 00882 { 00883 // Check the control timer is set 00884 assert(this->timerControl->IsSet()); 00885 00886 // Send a CLOSE-ACK message 00887 CPacketConnectionMessage* reply = new CPacketConnectionMessage( 00888 this->flow, 00889 this->id, 00890 this->remoteId, 00891 this->idEntry, 00892 this->remoteIdEntry, 00893 CPacketConnectionMessage::CLOSE_ACK, 00894 this->sim->Time(), 00895 packet->TimeTx() 00896 ); 00897 (*this->delegateSend)(this->port, this->remotePort, this->remoteAddress, 128, reply); 00898 00899 // Leave the current state and timer 00900 } 00901 break; 00902 default: assert(0); // Exception for other states 00903 } 00904 00905 #ifdef LOG_FLOW 00906 CConsole::SetColor(CConsole::DARK_BLUE); 00907 printf("%s", this->ToString()); 00908 CConsole::SetColor(CConsole::LIGHT_GRAY); 00909 #endif 00910 } 00911 00912 void CConnection::RecvMessageCloseAckResponder(CPacketConnectionMessage* packet) 00913 { 00914 // Received a CLOSE-ACK message 00915 00916 #ifdef LOG_FLOW 00917 CConsole::SetColor(CConsole::DARK_BLUE); 00918 printf("\n\tT = %8.3lf\tRecvResponder(CLOSE_ACK) : %s -> ", this->sim->Time(), this->ToString()); 00919 CConsole::SetColor(CConsole::LIGHT_GRAY); 00920 #endif 00921 00922 // Check the packet source and destination 00923 assert(packet->Dst() == this->id); 00924 assert(packet->DstEntry() == this->idEntry); 00925 assert(packet->Flow() == this->flow); 00926 00927 // Check the state 00928 switch(this->state) 00929 { 00930 case CLOSING: // Change to WAITING / CLOSE_ACK_ACK / timer wait 00931 { 00932 // Check the control timer is set 00933 assert(this->timerControl->IsSet()); 00934 00935 // Cancel the control timer 00936 this->timerControl->Cancel(); 00937 00938 // Send a CLOSE-ACK-ACK message 00939 CPacketConnectionMessage* reply = new CPacketConnectionMessage( 00940 this->flow, 00941 this->id, 00942 this->remoteId, 00943 this->idEntry, 00944 this->remoteIdEntry, 00945 CPacketConnectionMessage::CLOSE_ACK_ACK, 00946 this->sim->Time(), 00947 packet->TimeTx() 00948 ); 00949 (*this->delegateSend)(this->port, this->remotePort, this->remoteAddress, 128, reply); 00950 00951 // Change the state 00952 this->state = WAITING; 00953 00954 // Raise the event 00955 (*this->eventClose)(this, CLOSE_CONFIRMED); 00956 00957 // Set the control timer to the waiting handler 00958 this->timerControl->SetAfter(CConnection::timerResponderWaitTimeout, &CConnection::TimerWait); 00959 } 00960 break; 00961 default: assert(0); // Exception for other sattes 00962 } 00963 00964 #ifdef LOG_FLOW 00965 CConsole::SetColor(CConsole::DARK_BLUE); 00966 printf("%s", this->ToString()); 00967 CConsole::SetColor(CConsole::LIGHT_GRAY); 00968 #endif 00969 } 00970 00971 void CConnection::RecvMessageCloseAckAckResponder(CPacketConnectionMessage* packet) 00972 { 00973 // Received a CLOSE-ACK-ACK message 00974 00975 #ifdef LOG_FLOW 00976 CConsole::SetColor(CConsole::DARK_BLUE); 00977 printf("\n\tT = %8.3lf\tRecvResponder(CLOSE_ACK_ACK) : %s -> ", this->sim->Time(), this->ToString()); 00978 CConsole::SetColor(CConsole::LIGHT_GRAY); 00979 #endif 00980 00981 // Check the packet source and destination 00982 assert(packet->Dst() == this->id); 00983 assert(packet->DstEntry() == this->idEntry); 00984 assert(packet->Flow() == this->flow); 00985 00986 // Check the state 00987 switch(this->state) 00988 { 00989 case CLOSING: // Change to WAITING / none / timer wait 00990 { 00991 // Check the control timer is set 00992 assert(this->timerControl->IsSet()); 00993 00994 // Cancel the control timer 00995 this->timerControl->Cancel(); 00996 00997 // Change the state 00998 this->state = WAITING; 00999 01000 // Raise the event 01001 (*this->eventClose)(this, CLOSE_CONFIRMED); 01002 01003 // Set the control timer to the waiting handler 01004 this->timerControl->SetAfter(CConnection::timerRequesterWaitTimeout, &CConnection::TimerWait); 01005 } 01006 break; 01007 case CLOSED: 01008 case WAITING: 01009 break; // Ignore in CLOSED and WAITING state 01010 default: assert(0); // Exception for other states 01011 } 01012 01013 #ifdef LOG_FLOW 01014 CConsole::SetColor(CConsole::DARK_BLUE); 01015 printf("%s", this->ToString()); 01016 CConsole::SetColor(CConsole::LIGHT_GRAY); 01017 #endif 01018 } 01019 01020 void CConnection::TimerOpen(CTimerInfo* info) 01021 { 01022 // Check the state 01023 switch(this->state) 01024 { 01025 case OPENING: // Change to CLOSED / none / none 01026 { 01027 // Change the state 01028 this->state = CLOSED; 01029 01030 // Raise the event 01031 (*this->eventOpen)(this, OPEN_FAIL_TIMEOUT); 01032 01033 // Call the dispose function to relase the resources for this connection 01034 (*this->callDispose)(this); 01035 } 01036 break; 01037 default: assert(0); // Exception for other states 01038 } 01039 } 01040 01041 void CConnection::TimerClose(CTimerInfo* info) 01042 { 01043 // Check the state 01044 switch(this->state) 01045 { 01046 case CLOSING: // Change to WAITING / none / timer wait 01047 { 01048 // Change the state 01049 this->state = WAITING; 01050 01051 // Raise the event 01052 (*this->eventClose)(this, CLOSE_TIMEOUT); 01053 01054 // Set the control timer to the waiting handler 01055 this->timerControl->SetAfter(CConnection::timerDefaultWaitTimeout, &CConnection::TimerWait); 01056 } 01057 break; 01058 default: assert(0); // Exception for other states 01059 } 01060 } 01061 01062 void CConnection::TimerCancel(CTimerInfo* info) 01063 { 01064 // Check the state 01065 switch(this->state) 01066 { 01067 case CANCELING: // Change to CLOSED / none / none 01068 { 01069 // Change the state 01070 this->state = CLOSED; 01071 01072 // Raise the event 01073 (*this->eventClose)(this, CLOSE_TIMEOUT); 01074 01075 // Call the dispose function to relase the resources for this connection 01076 (*this->callDispose)(this); 01077 } 01078 break; 01079 default: assert(0); // Exception for other states 01080 } 01081 } 01082 01083 void CConnection::TimerWait(CTimerInfo* info) 01084 { 01085 // Check the state 01086 switch(this->state) 01087 { 01088 case WAITING: // Change to CLOSED / none / none 01089 { 01090 // Change the state 01091 this->state = CLOSED; 01092 01093 // Raise the event 01094 (*this->eventClose)(this, CLOSE_COMPLETE); 01095 01096 // Call the dispose function to release the resources for this connection 01097 (*this->callDispose)(this); 01098 } 01099 break; 01100 default: assert(0); // Exception for other states 01101 } 01102 } 01103 01104 char* CConnection::ToString() const 01105 { 01106 sprintf((char*)this->str, "[ l=*:%u:%u:%u r=%u:%u:%u:%u t=%s s=%s ]", 01107 this->port, this->id, this->idEntry, this->remoteAddress, this->remotePort, this->remoteId, this->remoteIdEntry, 01108 CConnection::strConnectionType[this->type], CConnection::strState[this->state] 01109 ); 01110 01111 return (char*)this->str; 01112 }
Last updated: February 8, 2011