00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "stdafx.h"
00011 #include "ippdme/Server/ippSimpleClient.h"
00012 #include "ippdme/Response/ippErrorResponse.h"
00013 #include "ippdme/assert.h"
00014
00015 ippSimpleClient::ippSimpleClient()
00016 :_state(disconnected)
00017 ,_ready_to_send(false)
00018 ,_in_error_state(false)
00019 ,_next_tag(1)
00020 {
00021 _pending_tag=0;
00022 }
00023
00024 void ippSimpleClient::Connect(
00025 const char* hostname,
00026 int port
00027 )
00028 {
00029 IPP_ASSERT(_state== disconnected);
00030
00031 if(_state != disconnected) {
00032 return;
00033 }
00034
00035
00036 while(!_pending_commands.empty()) {
00037 _pending_commands.pop();
00038 }
00039
00040 bool bSuccess = _socket.Create();
00041 IPP_ASSERT(bSuccess);
00042
00043
00044 ippSocket::SERROR nRet = _socket.Connect(hostname,port);
00045 if (nRet == ippSocket::SOCKET_WOULD_BLOCK) {
00046
00047 _state = trying_to_connect;
00048 } else if (nRet == ippSocket::SOCKET_IS_CONNECTED) {
00049 _state = connected;
00050 _in_error_state = false;
00051 _ready_to_send = true;
00052 } else {
00053 _state = disconnected;
00054 _socket.Close();
00055 }
00056 }
00057
00058 ippSimpleClient::STATE ippSimpleClient::GetState() const
00059 {
00060 return _state;
00061 }
00062
00063 bool ippSimpleClient::ReadyToSend() const
00064 {
00065 return _state == connected && _ready_to_send;
00066 }
00067
00068 bool ippSimpleClient::NeedToSendClearAllErrors() const
00069 {
00070 return _in_error_state;
00071 }
00072
00073 void ippSimpleClient::Disconnect()
00074 {
00075 ProbeConnection();
00076 _state = disconnected;
00077 _socket.Close();
00078 _ready_to_send = false;
00079 _in_error_state = false;
00080
00081 LogMessage(" disconnected","");
00082 }
00083
00084
00085 void ippSimpleClient::HeartBeat()
00086 {
00087 ippSleep(1);
00088 switch(_state){
00089 case trying_to_connect:
00090 {
00091 switch(_socket.CanSendData()){
00092 case ippSocket::SOCKET_OK:
00093 _ready_to_send = true;
00094 _in_error_state = false;
00095 _state = connected;
00096 break;
00097 case ippSocket::SOCKET_WOULD_BLOCK:
00098
00099 Disconnect();
00100 break;
00101 default:
00102 _state = disconnected;
00103 _socket.Close();
00104 }
00105 } break;
00106 case connected:
00107 {
00108 PerformRead();
00109 }
00110 }
00111 }
00112
00113
00114
00115
00116 #include "ippdme/Parser/ippResponseParser.h"
00117
00118 void ippSimpleClient::ProcessLine(const char* inputline)
00119 {
00120
00121 LogMessage("received:",inputline);
00122
00123 ippResponseParser parser;
00124 parser.setInput(inputline);
00125 parser.parseTag();
00126 ipp::parserResErrorId code = parser.getParserErr();
00127
00128 if (code != ipp::OK) {
00129
00130 std::string errorMessage = parser.getErrorMessageString();
00131 char buf[IPPSIZE];
00132 sprintf(buf,"Response Error: %s", errorMessage.c_str());
00133 LogMessage("Response Error:",errorMessage.c_str());
00134 }
00135
00136
00137 if ( parser.getTagType() == EventTag ) {
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 if ( std::string(inputline,7) == "E0000 !") {
00150
00151 ippResponsePtr response = parser.parseResponse();
00152 if(response) {
00153 ippErrorResponsePtr e = static_cast<ippErrorResponse*>(response.get());
00154 ippErrorNameType error= e->getTheError()->getName();
00155 if (BufferFull ==error ||IllegalCharacter==error || IllegalTag==error || NoSpaceAtPos6==error){
00156 _ready_to_send= true;
00157 } else {
00158 OnUnsollicitedEvent(response);
00159 }
00160 } else {
00161 IPP_ASSERT_FAIL("What should we do here ?");
00162 }
00163 }
00164 }
00165 char response_char = inputline[6];
00166
00167 ippResponsePtr response = parser.parseResponse();
00168
00169 int read_tag = parser.getTag();
00170
00171
00172 if (response_char == '&') {
00173
00174 if (_pending_tag == read_tag){
00175
00176 _ready_to_send= true;
00177
00178 _next_tag++;
00179
00180 if (response->getTag().getTagType() == CommandTag) {
00181 _pending_commands.push(_pending_tag);
00182 }
00183 _pending_tag = 0;
00184 } else {
00185 LogMessage("Response Error:","Tags do not match");
00186 }
00187
00188 } else if (response_char == '!') {
00189
00190 if (_pending_tag==read_tag) {
00191
00192 _next_tag++;
00193 }
00194
00195
00196
00197
00198
00199 if (inputline[9] != '1') {
00200
00201 _in_error_state = true;
00202 }
00203 ippResponsePtr response = parser.parseResponse();
00204 OnErrorResponse(response);
00205
00206 } else if (response_char == '%'){
00207
00208
00209 ippResponsePtr response = parser.parseResponse();
00210
00211 if (parser.getTagType() == EventTag) {
00212
00213 OnComnmandCompleted(response->getTag().getTagNumber());
00214 } else {
00215
00216
00217 tagIdType type = response->getTag().getTagType();
00218 if (type == CommandTag) {
00219
00220 if ( _pending_commands.size()>0 && _pending_commands.front()== response->getTag().getTagNumber() ) {
00221 _pending_commands.pop();
00222 OnComnmandCompleted(response->getTag().getTagNumber());
00223 } else {
00224 LogMessage("Unexpected completed command:","Tags do not match");
00225 }
00226 } else {
00227 OnComnmandCompleted(response->getTag().getTagNumber());
00228 }
00229 }
00230
00231 } else if (response_char == '#') {
00232
00233 ippResponsePtr response = parser.parseResponse();
00234
00235 if(response) {
00236
00237 if (response->getTag().getTagType() == CommandTag ) {
00238
00239 if ( _pending_commands.front()== response->getTag().getTagNumber()) {
00240 OnResponse(response);
00241 } else {
00242
00243 LogMessage("unexpected response tag number:","Tags do not match");
00244 }
00245 } else {
00246
00247
00248 IPP_ASSERT_MSG(response->getTag().getTagNumber()!=0," should not be an unsollicited event");
00249 OnDaemonResponse(response);
00250 }
00251 } else {
00252 IPP_ASSERT_FAIL(" to do : be smart here ") ;
00253 }
00254 } else {
00255 IPP_ASSERT_FAIL(" to do : be smart here ") ;
00256
00257 }
00258 }
00259
00260 void ippSimpleClient::ProcessMisformedLine(const char* inputline)
00261 {
00262 LogMessage("received malformed string:",inputline);
00263
00264
00265 Disconnect();
00266 }
00267
00268 bool ippSimpleClient::SendCommand(ippCommandConstPtr command)
00269 {
00270 SendCommand(command->getCommandString().c_str());
00271 return true;
00272 }
00273
00274 void ippSimpleClient::OnConnectionLost()
00275 {
00276 LogMessage(" connection lost","");
00277 Disconnect();
00278 }
00279
00280 void ippSimpleClient::SendCommand(const char* command)
00281 {
00282 IPP_ASSERT(_ready_to_send);
00283 LogMessage(" send :",command);
00284
00285 if(command[0]=='E') {
00286 sscanf(command+1,"%4d",&_pending_tag);
00287 } else {
00288 sscanf(command,"%5d",&_pending_tag);
00289 }
00290
00291 _socket.Write(command);
00292
00293
00294 int l = strlen(command);
00295 if (l > 2 && command[l-1] != '\n' && command[l-2]!='\r') {
00296 _socket.Write("\r\n");
00297 }
00298
00299 _ready_to_send = false;
00300
00301 }
00302
00303 void ippSimpleClient::ClearAllErrors()
00304 {
00305 IPP_ASSERT(NeedToSendClearAllErrors());
00306 _pending_commands.empty();
00307 SendCommand(new ippCommand(_next_tag,ipp::ClearAllErrors));
00308 _in_error_state = false;
00309 }
00310
00311 int ippSimpleClient::NumberOfUncompletedCommandsInQueue()
00312 {
00313 return _pending_commands.size();
00314 }
00315
00316 void ippSimpleClient::OnErrorResponse(ippResponsePtr response)
00317 {
00318
00319 }
00320 void ippSimpleClient::OnDaemonResponse(ippResponsePtr response)
00321 {
00322
00323 }
00325 void ippSimpleClient::OnResponse(ippResponsePtr response)
00326 {
00327
00328 }
00329
00331 void ippSimpleClient::OnUnsollicitedEvent(ippResponsePtr response)
00332 {
00333
00334 }
00336 void ippSimpleClient::OnComnmandCompleted(int tagNumber)
00337 {
00338
00339 }