Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ippSimpleServer.cpp

Go to the documentation of this file.
00001 // 
00002 // DISCLAIMER: 
00003 //  This software was produced by the National Institute of Standards 
00004 //  and Technology (NIST), an agency of the U.S. government, and by statute is 
00005 //  not subject to copyright in the United States.  Recipients of this 
00006 //  software assume all responsibility associated with its operation,
00007 //  modification,maintenance, and subsequent redistribution. 
00008 //
00009 //  See NIST Administration Manual 4.09.07 b and Appendix I. 
00010 //
00011 // History
00012 // Who When     What
00013 // --- -------- ---------------------------------------------------------------
00014 // ER  09/03/06 Fix handling of error and processing of executor responses
00015 //-----------------------------------------------------------------------------
00016 #include "stdafx.h"
00017 
00018 #include "ippdme/Server/ippSimpleServer.h"
00019 #include "ippdme/Server/ippEngine.h"
00020 #include "ippdme/parser/ippCommandParser.h"
00021 
00022 #include "ippdme/Executor/ippExecutor.h"
00023 #include "ippdme/Checker/ippCommandChecker.h"
00024 
00025 #include "ippdme/Response/ippErrorResponse.h"
00026 #include "ippdme/Response/ippCompleteResponse.h"
00027 #include "ippdme/assert.h"
00028 
00029 
00030 ippSimpleServer::ippSimpleServer(ippExecutor* executor)
00031 : _portNumber(1294)
00032 , _checker(0)
00033 , _state(uninitialized)
00034 , _inSession(false)
00035 , _tagBeingExecuted(0)
00036 , _executor(executor)
00037 , _inErrorState(false)
00038 {
00039   ippSocket::Initialize();
00040 }
00041 
00042 ippSimpleServer::~ippSimpleServer()
00043 {
00044   PowerOff();
00045 }
00046 
00047 void ippSimpleServer::HeartBeat()
00048 {
00049   ippSleep(1); // allow context switch
00050   switch(_state)
00051   {
00052   case uninitialized:
00053     return;
00054   case listening:
00055     PerformListening();
00056     return;
00057   case connected:
00058     PerformRead();
00059     PerformExecute();
00060     PerformWrite();
00061     ProbeConnection();
00062     return;
00063   }
00064 }
00065 
00066 
00067 bool ippSimpleServer::InSession() const
00068 {
00069   return _inSession;
00070 }
00071 
00072 bool ippSimpleServer::PowerOn(int portNumber)
00073 {
00074   _portNumber = portNumber;
00075   if (_state!=uninitialized ) {
00076     return false;
00077   }
00078   // Create a TCP/IP stream socket to "listen" 
00079   // incoming client connection
00080   if (!_listenSocket.Listen(_portNumber)) { 
00081           return false;
00082   }
00083   _state = listening;
00084   _inSession = false;
00085   return true;
00086 }
00087 
00088 bool ippSimpleServer::PowerOff()
00089 {
00090   _listenSocket.Close();
00091   _socket.Close();
00092   _state = uninitialized;
00093   _inSession = false;
00094   return true;
00095 }
00096 
00097 bool ippSimpleServer::GetLogDetails() const
00098 {
00099   return true;
00100 }
00101 
00102 
00103 void ippSimpleServer::OnConnectionLost()
00104 {
00105   OnClientDisconnected();
00106 
00107   // when a connection is lost the server goes
00108   // back to listen mode.
00109   // Create a TCP/IP stream socket to "listen" with
00110   if (!_listenSocket.Listen(_portNumber)) { 
00111     _state=uninitialized;
00112     _inSession = false;
00113   } else {
00114     _state=listening;
00115     _inSession = false;
00116   }
00117 }
00118 
00119 void ippSimpleServer::OnClientConnected()
00120 {
00121         // Clear All Queues
00122   _serverQueues.ClearAllQueues();
00123   
00124   if(_executor) {
00125      _executor->resetExecutor();
00126   }
00127 
00128   IPP_ASSERT(!_inSession);
00129 }
00130 void ippSimpleServer::OnClientDisconnected()
00131 {
00132         // Clear All Queues
00133   _serverQueues.ClearAllQueues(); 
00134   // a disconnection will require a StartSession to be resent
00135   _inSession = false;
00136   LogMessage(" the client has disconnected");
00137   StopAllDaemons();
00138 }
00139 
00140 void ippSimpleServer::StopAllDaemons()
00141 {
00142   if(_executor) {
00143     _executor->StopAllDaemons();
00144   }
00145 }
00146 
00147 int ippSimpleServer::DaemonCount() const
00148 {
00149   if(_executor) {
00150     return _executor->DaemonCount();
00151   }
00152   return 0;
00153 }
00154 
00155 void ippSimpleServer::ProcessLine(const char* commandBuffer)
00156 {
00157   LogMessage(" received :",commandBuffer);
00158   ProcessCommand(commandBuffer);
00159 }
00160 
00161 void ippSimpleServer::ProcessMisformedLine(const char* commandBuffer)
00162 {
00163   
00164   // although the string is malformed it may contain a valid 
00165   // tag. let try to extract it so we can send the ACK packet back
00166 
00167   ippCommandParser parser;
00168   parser.setInput(commandBuffer); // Set the parser input string         
00169         parser.parseTag();                                     // Parse the tag
00170         int parser_tag = parser.getTag();
00171   if(parser.getIsEvent()) {
00172     parser_tag = parser_tag * (-1);
00173   }
00174   // Determining if Event or Command Tag
00175   tagIdType tt = (parser.getIsEvent()) ?  EventTag : CommandTag;
00176 
00177         // Build Ack Response
00178   SendAcknowledge(ippTag(parser.getTag(),tt));
00179 
00180   
00181   // the line contains some illegal characters
00182   ippErrorResponsePtr resp =
00183     new ippErrorResponse(0000, EventTag,IllegalCharacter, commandBuffer);
00184 
00185   SendError(resp,"misformed input ");           
00186   
00187   IPP_ASSERT(_tagBeingExecuted == 0);
00188   _tagBeingExecuted = parser.getTag();
00189   SendComplete(ippTag(parser.getTag(),tt));   
00190 
00191 
00192 }
00193 
00194 
00195 void ippSimpleServer::ProcessCommand(const char* commandBuffer)
00196 {
00197 
00198   ippCommandParser parser1;
00199   parser1.setInput(commandBuffer); // Set the parser input string        
00200         parser1.parseTag();                                    // Parse the tag
00201         int parser1_tag = parser1.getTag();
00202   if(parser1.getIsEvent()) {
00203     parser1_tag = parser1_tag * (-1);
00204   }
00205 
00206   // Determining if Event or Command Tag
00207   tagIdType tt = (parser1.getIsEvent()) ?  EventTag : CommandTag;
00208 
00209         ippParserCmdErrorId  parser1_code = parser1.getParserErr();
00210 
00211         // If parser error (i.e. bad tag), produce error Response
00212         if(parser1_code != OK)
00213         {
00214     char errorCauseMethod[IPPSIZE] = "";
00215                 if(GetLogDetails()) {
00216       std::string errorMessage = parser1.getErrorMessageString();
00217                         sprintf(errorCauseMethod,"%s : %s",commandBuffer, errorMessage.c_str());
00218                 }
00219     else{
00220       sprintf(errorCauseMethod,"%s",commandBuffer);
00221     }
00222     ippErrorResponsePtr resp =
00223         new ippErrorResponse(0000, EventTag,IllegalTag, errorCauseMethod);
00224     
00225     std::string errorMessage = parser1.getErrorMessageString();
00226     SendError(resp,errorMessage.c_str());               
00227     return; 
00228   }
00229 
00230   // tag is well formed , but it might be already in use !
00231 
00232         // Build Ack Response
00233   SendAcknowledge(ippTag(parser1.getTag(),tt));
00234 
00235 
00236   if(_serverQueues.tagInList(parser1_tag))  // Check the tag in session list
00237         {
00238                 // If tag in session, produce an IllegalTag Response
00239                 char errorCauseMethod[IPPSIZE]="";
00240     if(GetLogDetails()) {
00241                          sprintf(errorCauseMethod,"%s : TAG NUMBER IN USE",commandBuffer);
00242     } else {
00243        sprintf(errorCauseMethod,"%s",commandBuffer);
00244     }
00245     
00246     ippErrorResponsePtr resp =
00247       new ippErrorResponse(0000, EventTag,IllegalTag, errorCauseMethod);
00248 
00249     SendError(resp,"TAG NUMBER IN USE");                
00250     return; 
00251   }
00252 
00253   
00254   _serverQueues.addTag(parser1_tag);// Add tag # to active tag list
00255                                         
00256         /****************************************************************/
00257         /*                                                              */
00258         /*    If Command tag, place command on "slow queue"             */
00259         /*                                                              */
00260         /*    Else If Event tag, place command on "fast" queue          */
00261         /*                                                              */
00262         /****************************************************************/
00263 
00264   if (tt==CommandTag) {
00265     _serverQueues.EnqueueCommand(commandBuffer);                                                
00266         }       else if (tt==EventTag){                                         
00267     // put on fast queue
00268                 _serverQueues.EnqueueEvent(commandBuffer);
00269         }
00270 
00271                                         
00272 }
00273 
00274 
00275 
00276 void ippSimpleServer::SendAcknowledge(const ippTag& tag)
00277 {
00278   SendResponse(new ippResponse(tag.getTagNumber(), tag.getTagType(), Ack));
00279 }
00280 
00281 
00282 void ippSimpleServer::WriteToSocket(const char* line)
00283 {
00284         LogMessage("  sent : ",line);
00285   int nRet = _socket.Write(line);
00286   if (nRet)  {
00287     OnConnectionLost();
00288   }
00289 }
00290 void ippSimpleServer::SendResponse(ippResponsePtr response)
00291 {
00292   std::string responseStr = response->getResponseString();
00293 
00294   // special treatment for Ack Response, which is not queued,
00295   // we send it directly to the socket stream.
00296   if (response->getResponseName() == Ack) {
00297     // acknowledge the response, this time 
00298     WriteToSocket(response->getResponseString().c_str());
00299 
00300   }  else {
00301     if ( response->getResponseName() == Complete) {
00302       if (response->getTag().getTagType() == CommandTag) { 
00303         IPP_ASSERT(_tagBeingExecuted  == response->getTag().getTagNumber());
00304         _tagBeingExecuted = 0;
00305       }
00306     }
00307           //Log the Response
00308     // LogMessage("     pushing to queue :",responseStr.c_str());
00309           
00310     // send response buffer to the response queue
00311           _serverQueues.EnqueueResponse(responseStr.c_str());
00312     // Send to response queue
00313   }
00314 }
00315 
00316 void ippSimpleServer::SendError(
00317  ippErrorResponsePtr errResponse,
00318  const char* errorMessage
00319 )
00320 {
00321   std::string   responseStr = errResponse->getResponseString();
00322 
00323         if (errResponse->getTheError()->getSeverity() > '1'){
00324     _inErrorState = true;
00325                 //xx _world1.setReadiness(erred);
00326                 //xx _serverQueues.ClearAllQueues();
00327         }  
00328   // If set by user, write detailed parser errors to the log file.
00329         if(GetLogDetails()){
00330       //Log Ipp error response
00331       LogMessage("     pushing to queue :",responseStr.c_str());
00332       LogMessage("   parser :",errorMessage);
00333   }
00334   // send tag syntax error response buffer to the world response queue
00335   _serverQueues.EnqueueResponse(responseStr.c_str()); // Send to response queue
00336 
00337 }
00338 void ippSimpleServer::SendComplete(const ippTag& tag)
00339 {
00340   ippResponsePtr _CompletedResponse = new ippCompleteResponse(tag.getTagNumber(), tag.getTagType());
00341 
00342         //Remove current tag from list
00343   if(tag.getTagType() == EventTag)   {
00344                 _serverQueues.delTag(tag.getTagNumber()*(-1));
00345   }     else {
00346     _serverQueues.delTag(tag.getTagNumber());           
00347   }                     
00348   SendResponse(_CompletedResponse);
00349 }
00350 
00351 
00352 void ippSimpleServer::PerformWrite()
00353 {
00354   // flush pending responses, and write them to the socket
00355   while(_serverQueues.ResponseQueueHasData()){
00356     std::string  resp = _serverQueues.DequeueResponse(); //get msg from response queue  
00357     IPP_ASSERT(resp.length()!=0);
00358     WriteToSocket(resp.c_str());
00359   } // end while
00360 
00361 }
00362 
00363 
00364 void ippSimpleServer::ProcessResponseList(const ippResponseList& responseList)
00365 {
00366                 for (size_t i=0; i<responseList.size(); i++) {
00367                         
00368                         // Get the response name
00369                         ippResponseNameType rnt = responseList[i]->getResponseName();
00370 
00371                         // Cast response to specific response
00372                         switch (rnt) {
00373                           case ErrorError: 
00374           {
00375             ippErrorResponsePtr er= static_cast<ippErrorResponse*>(responseList[i].get());
00376             SendError(er,"");
00377           } break;
00378         case Complete:
00379           {
00380             const ippTag& tag = responseList[i]->getTag();
00381             SendComplete(tag);
00382           } break;                      
00383                           default:
00384         {
00385           SendResponse(responseList[i]);                                                                                          
00386         }
00387                         }
00388     }
00389 }
00390 
00391 
00392 void ippSimpleServer::ExecuteCommand(ippCommandPtr aCommand)
00393 {
00394  
00395   if (aCommand->getTag().getTagType()== CommandTag ) {
00396     IPP_ASSERT_MSG( _tagBeingExecuted ==0,
00397        " Should not be already executing a command, except a fast queue command");
00398     _tagBeingExecuted = aCommand->getTag().getTagNumber();
00399   }
00400 
00401   // two special commands are specifically handler by the 
00402   // simple server  start session / end session ....
00403 
00404   // 6.3.1 Server Methods
00405   // If no session is active, the server will accept only StartSession()
00406   // and EndSession() commands.
00407 
00408   if (aCommand->getCommandName() == StartSession)
00409   {
00410     if (!_inSession) { 
00411      
00412      _inSession = true;
00413      if (_executor) { 
00414        // delegate to the executor
00415        _executor->executeCommand(aCommand);
00416        ProcessResponseList(_executor->checkStatus());
00417 
00418      } else {
00419        // in absence of a dedicated executor , we simply generate a complete command
00420        // ( useful for testing ) 
00421        SendComplete(aCommand->getTag());
00422      }
00423      
00424      // 6.3.1.1 the client can be sure that no event nor daemon are pending
00425      //         from the session before.
00426      IPP_ASSERT(DaemonCount() == 0);
00427 
00428      // 6.3.1.1 : StartSession() implicitly executes ClearAllErrors()
00429      ClearAllErrors();
00430 
00431    
00432     } else {
00433       // already in session 
00434       // 6.3.1.1 : The client should not send a StartSession() command while a session is in progress.
00435       ippErrorResponsePtr resp =
00436         new ippErrorResponse(aCommand->getTag(),ProtocolError, "StartSession already called");
00437 
00438       SendError(resp,"");       
00439       SendComplete(aCommand->getTag());
00440       
00441     }
00442 
00443     return ;
00444 
00445   } else if (aCommand->getCommandName() == EndSession) {
00446     if (!_inSession) { 
00447        // 6.3.1: If an EndSession is received while no session is active, this command will do nothing.
00448       //        This handling will guarantee that sending an EndSession() followed by a 
00449       //        StartSession will start a new session in any case.
00450       SendComplete(aCommand->getTag());   
00451       return ;
00452     } else {
00453 
00454        // stop all daemon etc...      
00455        // 6.3.1.1 The method must make sure that all daemons are stopped and no events are sent
00456        //         after it completes.
00457        StopAllDaemons();
00458        IPP_ASSERT(DaemonCount() == 0);
00459     
00460        // delegate to the executor
00461        if (_executor) { 
00462 
00463          // delegate to the executor
00464          _executor->executeCommand(aCommand);
00465          ProcessResponseList(_executor->checkStatus());
00466 
00467        } else {
00468          // in absence of a dedicated executor , we simply generate a complete command
00469          // ( useful for testing ) 
00470          SendComplete(aCommand->getTag());
00471        }       
00472 
00473        _inSession =false;
00474     }
00475     return ;
00476   }
00477 
00478 
00479   if (!_inSession) {
00480     ippErrorResponsePtr resp =
00481         new ippErrorResponse(aCommand->getTag(),IllegalCommand, "StartSession not received");
00482     SendError(resp,"StartSession not received");
00483     SendComplete(aCommand->getTag());
00484     return;
00485   }
00486 
00487 
00488 
00489   if (_checker) {
00490     _checker->checkCommand(aCommand);   // Test command via the checker
00491         ippCheckerErrorId checker_code = _checker->getCheckerErr();
00492     
00493     if (checker_code != CHECKER_OK) {
00494 
00495                           char errorCauseMethod[IPPSIZE]="";
00496 
00497         std::string errorMessage = _checker->getErrorMessageString();
00498         std::string cmd = aCommand->getCommandString();
00499                           if(GetLogDetails()){
00500                                   sprintf(errorCauseMethod,"%s : %s",cmd.c_str(), errorMessage.c_str());
00501         }       else {
00502           sprintf(errorCauseMethod,"%s",cmd.c_str());
00503         }
00504        // the checker has failed
00505                  ippErrorNameType errType =  _checker->getIppErr(checker_code);
00506 
00507         SendError(
00508           new ippErrorResponse(aCommand->getTag(),errType,errorCauseMethod),errorMessage.c_str());        
00509         SendComplete(aCommand->getTag());                       
00510        return ;
00511     }
00512   }
00513 
00514   if (aCommand->getCommandName() == AbortE) {
00515     ExecuteAbortE(aCommand->getTag());
00516     return; // 
00517   }
00518 
00519   if (_inErrorState) { 
00520     // only ClearAllErrors / GetErrStatusE(), GetXtdErrStatus() can be called 
00521     // when the server is in error State
00522     if (aCommand->getCommandName() != ipp::ClearAllErrors && 
00523         aCommand->getCommandName() != ipp::GetErrStatusE && 
00524         aCommand->getCommandName() != ipp::GetXtdErrStatus 
00525       ) { 
00526 
00527         SendError(
00528           new ippErrorResponse(
00529           aCommand->getTag().getTagNumber(),aCommand->getTag().getTagType(),
00530           UseClearAllErrorsToCont,aCommand->getCommandString().c_str()),"");        
00531         SendComplete(aCommand->getTag());                       
00532         return;
00533 
00534     } 
00535   }
00536 
00537   if (aCommand->getCommandName() == ipp::ClearAllErrors) { 
00538     ClearAllErrors();
00539   }
00540 
00541   if (_executor) { 
00542 
00543     _executor->executeCommand(aCommand);
00544     ProcessResponseList(_executor->checkStatus());
00545 
00546   } else {
00547 
00548     // in absence of a dedicated executor , we simply generate a complete command
00549     // ( useful for testing ) 
00550     SendComplete(aCommand->getTag());
00551   }
00552 }
00553 
00554 void ippSimpleServer::ExecuteAbortE(const ippTag& tag)
00555 {
00556   // we must complete all pending command first
00557   if (_executor) { 
00558      // delegate to the executor
00559      _executor->AbortCurrentCommand();
00560      ProcessResponseList(_executor->checkStatus());
00561   } else {
00562     IPP_ASSERT(_tagBeingExecuted==0);
00563     //xx SendError(new ippErrorResponse(aCommand->getTag(),TransactionAborted,""),"");        
00564     //xx SendComplete(aCommand->getTag());                      
00565 
00566   }
00567   // flush all pending command in the slow queue
00568   AbortPendingCommands();
00569   SendComplete(tag);
00570   
00571 }
00572 void ippSimpleServer::AbortPendingCommands()
00573 {
00574   IPP_ASSERT(!IsProcessingSlowCommand());
00575   ippCommandParser parser;
00576   while(_serverQueues.CommandQueueHasData() ) { 
00577     std::string cmd = _serverQueues.DequeueCommand(); // get cmd from slow queue
00578     parser.setInput(cmd.c_str());
00579     parser.parseTag();// parse the tag
00580                 ippParserCmdErrorId     parser_code = parser.getParserErr();
00581     if (parser_code == OK) {
00582                                 _tagBeingExecuted = parser.getTag();
00583         ippErrorResponsePtr _ErrorResponse= 
00584           new ippErrorResponse(parser.getTag(),CommandTag,TransactionAborted,"");
00585                         SendError(_ErrorResponse,"some error");
00586         SendComplete(ippTag(parser.getTag(),CommandTag));
00587     }
00588   }
00589 }
00590 //
00591 //
00592 // return true if the server is still processing a slow command
00593 // i.e the completion of the command being run has not yet been sent
00594 //
00595 bool ippSimpleServer::IsProcessingSlowCommand() const
00596 {
00597    if (_tagBeingExecuted) { 
00598      return true;
00599    } 
00600    if(_executor) {
00601      return !_executor->readyToProcessSlowQueueCommand();
00602    } 
00603    return  (_tagBeingExecuted != 0);
00604 }
00605 
00606 void ippSimpleServer::PerformExecute()
00607 {
00608 
00609   if (this->_executor) {
00610     // purge the executor from any pending responses
00611     ProcessResponseList(_executor->checkStatus());
00612   }
00613 
00614 
00615   bool command_exists = false;
00616 
00617   ippCommandParser parser;
00618   std::string cmd;
00619         /*******************************************************************************/
00620         /*                                                                             */
00621         /*                          Check for data on fast queue first                 */
00622         /*                                                                             */
00623         /*******************************************************************************/
00624         if(_serverQueues.EventQueueHasData()) { 
00625 
00626     command_exists = true;
00627                 cmd = _serverQueues.DequeueEvent(); //get cmd from fast queue
00628                 parser.setInput(cmd.c_str());      // feed the cmd to the parser        
00629 
00630   } 
00631         /*******************************************************************************/
00632         /*                                                                             */
00633         /*      If no fast queue data and there is no multi cycle command currently    */
00634         /*      running then check for data on the slow queue                          */
00635         /*                                                                             */
00636         /*******************************************************************************/
00637   else  if(_serverQueues.CommandQueueHasData() && !IsProcessingSlowCommand()) { 
00638 
00639     command_exists = true;
00640                 cmd = _serverQueues.DequeueCommand(); // get cmd from slow queue
00641                 parser.setInput(cmd.c_str());        // feed the cmd to the parser
00642 
00643   }
00644 
00645   /********************************************/
00646         /*                                          */
00647         /*  if a command was successfully dequeued  */
00648         /*                                          */
00649         /********************************************/
00650         if(command_exists) {
00651     
00652     parser.parseTag();// parse the tag
00653 
00654     //Check and record if event or command
00655     tagIdType tt = (parser.getIsEvent()) ?  EventTag : CommandTag;
00656 
00657           const ippCommandPtr aCommand = parser.parseCommand();// parse the command
00658 
00659                 ippParserCmdErrorId     parser_code = parser.getParserErr();
00660 
00661                 if (parser_code == OK) {// If the command parses OK
00662       ExecuteCommand(aCommand);
00663     }
00664                 /************************************************************************/
00665                 /*                                                                      */
00666                 /*   The command  failed the parser              :                      */
00667                 /*                                                                      */
00668                 /*   1. Get the error code from the parser                              */
00669                 /*   2. Generate an error response                                      */
00670                 /*   3. Check error severity and update world if required               */
00671                 /*   4. Put error response on the response queue                        */
00672                 /*                                                                      */
00673                 /************************************************************************/
00674     else { 
00675 
00676                                 char errorCauseMethod[IPPSIZE]="";
00677 
00678                                 if(GetLogDetails()){
00679           std::string errorMessage = parser.getErrorMessageString();
00680                                   sprintf(errorCauseMethod,"%s : %s",cmd.c_str(), errorMessage.c_str());
00681         }       else {
00682           sprintf(errorCauseMethod,"%s",cmd.c_str());
00683         }
00684 
00685                                 ippErrorResponsePtr _ErrorResponse= 
00686           new ippErrorResponse(parser.getTag(),tt, 
00687                                                          getIppErr(parser_code),errorCauseMethod);
00688                         SendError(_ErrorResponse,"some error");
00689         
00690         IPP_ASSERT(_tagBeingExecuted ==0);
00691         _tagBeingExecuted = parser.getTag();
00692         SendComplete(ippTag(parser.getTag(),tt));
00693 
00694                         }
00695     }
00696 }
00697 
00698 //
00699 //
00700 //
00701 //
00702 void ippSimpleServer::PerformListening()
00703 {
00704   IPP_ASSERT(_state == listening);
00705   IPP_ASSERT(!_socket.IsValid());
00706   IPP_ASSERT(_listenSocket.IsValid());
00707  
00708   ippSocket::SERROR nRet = _listenSocket.Accept(_socket);
00709   
00710   switch(nRet) {
00711   case ippSocket::SOCKET_WOULD_BLOCK:
00712                 // xx PRINTSTATUS("Waiting for connection ...");
00713     break;
00714   case ippSocket::SOCKET_OK:
00715     // we don't want to accept new connection 
00716     _listenSocket.Close();
00717     _state = connected;
00718     OnClientConnected();
00719     break;
00720   default:
00721     // a major problem has occur ...
00722     _listenSocket.Close();
00723     _state = uninitialized;
00724     break;
00725   }
00726 }
00727 
00728 void ippSimpleServer::ClearAllErrors()
00729 {
00730   _inErrorState = false;
00731 }
00732 
00733 

Generated on Wed Nov 8 00:20:06 2006 for IPPDME by  doxygen 1.4.1