00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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);
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
00079
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
00108
00109
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
00122 _serverQueues.ClearAllQueues();
00123
00124 if(_executor) {
00125 _executor->resetExecutor();
00126 }
00127
00128 IPP_ASSERT(!_inSession);
00129 }
00130 void ippSimpleServer::OnClientDisconnected()
00131 {
00132
00133 _serverQueues.ClearAllQueues();
00134
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
00165
00166
00167 ippCommandParser parser;
00168 parser.setInput(commandBuffer);
00169 parser.parseTag();
00170 int parser_tag = parser.getTag();
00171 if(parser.getIsEvent()) {
00172 parser_tag = parser_tag * (-1);
00173 }
00174
00175 tagIdType tt = (parser.getIsEvent()) ? EventTag : CommandTag;
00176
00177
00178 SendAcknowledge(ippTag(parser.getTag(),tt));
00179
00180
00181
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);
00200 parser1.parseTag();
00201 int parser1_tag = parser1.getTag();
00202 if(parser1.getIsEvent()) {
00203 parser1_tag = parser1_tag * (-1);
00204 }
00205
00206
00207 tagIdType tt = (parser1.getIsEvent()) ? EventTag : CommandTag;
00208
00209 ippParserCmdErrorId parser1_code = parser1.getParserErr();
00210
00211
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
00231
00232
00233 SendAcknowledge(ippTag(parser1.getTag(),tt));
00234
00235
00236 if(_serverQueues.tagInList(parser1_tag))
00237 {
00238
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);
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 if (tt==CommandTag) {
00265 _serverQueues.EnqueueCommand(commandBuffer);
00266 } else if (tt==EventTag){
00267
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
00295
00296 if (response->getResponseName() == Ack) {
00297
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
00308
00309
00310
00311 _serverQueues.EnqueueResponse(responseStr.c_str());
00312
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
00326
00327 }
00328
00329 if(GetLogDetails()){
00330
00331 LogMessage(" pushing to queue :",responseStr.c_str());
00332 LogMessage(" parser :",errorMessage);
00333 }
00334
00335 _serverQueues.EnqueueResponse(responseStr.c_str());
00336
00337 }
00338 void ippSimpleServer::SendComplete(const ippTag& tag)
00339 {
00340 ippResponsePtr _CompletedResponse = new ippCompleteResponse(tag.getTagNumber(), tag.getTagType());
00341
00342
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
00355 while(_serverQueues.ResponseQueueHasData()){
00356 std::string resp = _serverQueues.DequeueResponse();
00357 IPP_ASSERT(resp.length()!=0);
00358 WriteToSocket(resp.c_str());
00359 }
00360
00361 }
00362
00363
00364 void ippSimpleServer::ProcessResponseList(const ippResponseList& responseList)
00365 {
00366 for (size_t i=0; i<responseList.size(); i++) {
00367
00368
00369 ippResponseNameType rnt = responseList[i]->getResponseName();
00370
00371
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
00402
00403
00404
00405
00406
00407
00408 if (aCommand->getCommandName() == StartSession)
00409 {
00410 if (!_inSession) {
00411
00412 _inSession = true;
00413 if (_executor) {
00414
00415 _executor->executeCommand(aCommand);
00416 ProcessResponseList(_executor->checkStatus());
00417
00418 } else {
00419
00420
00421 SendComplete(aCommand->getTag());
00422 }
00423
00424
00425
00426 IPP_ASSERT(DaemonCount() == 0);
00427
00428
00429 ClearAllErrors();
00430
00431
00432 } else {
00433
00434
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
00448
00449
00450 SendComplete(aCommand->getTag());
00451 return ;
00452 } else {
00453
00454
00455
00456
00457 StopAllDaemons();
00458 IPP_ASSERT(DaemonCount() == 0);
00459
00460
00461 if (_executor) {
00462
00463
00464 _executor->executeCommand(aCommand);
00465 ProcessResponseList(_executor->checkStatus());
00466
00467 } else {
00468
00469
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);
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
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
00521
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
00549
00550 SendComplete(aCommand->getTag());
00551 }
00552 }
00553
00554 void ippSimpleServer::ExecuteAbortE(const ippTag& tag)
00555 {
00556
00557 if (_executor) {
00558
00559 _executor->AbortCurrentCommand();
00560 ProcessResponseList(_executor->checkStatus());
00561 } else {
00562 IPP_ASSERT(_tagBeingExecuted==0);
00563
00564
00565
00566 }
00567
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();
00578 parser.setInput(cmd.c_str());
00579 parser.parseTag();
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
00593
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
00611 ProcessResponseList(_executor->checkStatus());
00612 }
00613
00614
00615 bool command_exists = false;
00616
00617 ippCommandParser parser;
00618 std::string cmd;
00619
00620
00621
00622
00623
00624 if(_serverQueues.EventQueueHasData()) {
00625
00626 command_exists = true;
00627 cmd = _serverQueues.DequeueEvent();
00628 parser.setInput(cmd.c_str());
00629
00630 }
00631
00632
00633
00634
00635
00636
00637 else if(_serverQueues.CommandQueueHasData() && !IsProcessingSlowCommand()) {
00638
00639 command_exists = true;
00640 cmd = _serverQueues.DequeueCommand();
00641 parser.setInput(cmd.c_str());
00642
00643 }
00644
00645
00646
00647
00648
00649
00650 if(command_exists) {
00651
00652 parser.parseTag();
00653
00654
00655 tagIdType tt = (parser.getIsEvent()) ? EventTag : CommandTag;
00656
00657 const ippCommandPtr aCommand = parser.parseCommand();
00658
00659 ippParserCmdErrorId parser_code = parser.getParserErr();
00660
00661 if (parser_code == OK) {
00662 ExecuteCommand(aCommand);
00663 }
00664
00665
00666
00667
00668
00669
00670
00671
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
00713 break;
00714 case ippSocket::SOCKET_OK:
00715
00716 _listenSocket.Close();
00717 _state = connected;
00718 OnClientConnected();
00719 break;
00720 default:
00721
00722 _listenSocket.Close();
00723 _state = uninitialized;
00724 break;
00725 }
00726 }
00727
00728 void ippSimpleServer::ClearAllErrors()
00729 {
00730 _inErrorState = false;
00731 }
00732
00733