00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "ECHOENG.H"
00033
00034
00035 const TInt KTimeOut = 50000000;
00036
00037
00038
00039
00040 EXPORT_C CEchoEngine::CEchoEngine() : CActive(EPriorityStandard)
00041 {
00042 }
00043
00044 EXPORT_C CEchoEngine* CEchoEngine::NewL(MUINotify* aConsole)
00045 {
00046 CEchoEngine* self = NewLC(aConsole);
00047 CleanupStack::Pop();
00048 return self;
00049 }
00050
00051 EXPORT_C CEchoEngine* CEchoEngine::NewLC(MUINotify* aConsole)
00052 {
00053 CEchoEngine* self = new(ELeave) CEchoEngine;
00054 CleanupStack::PushL(self);
00055 self->ConstructL(aConsole);
00056 return self;
00057 }
00058
00059
00060
00061 EXPORT_C void CEchoEngine::ConstructL(MUINotify* aConsole)
00062 {
00063 iConsole = aConsole;
00064 iEngineStatus = EComplete;
00065
00066 iTimeOut = KTimeOut;
00067 iTimer = CTimeOutTimer::NewL(EPriorityHigh, *this);
00068 CActiveScheduler::Add(this);
00069
00070
00071 User::LeaveIfError(iSocketServ.Connect());
00072
00073 User::LeaveIfError(iEchoSocket.Open(iSocketServ, KAfInet, KSockStream, KProtocolInetTcp));
00074
00075 iEchoRead = new CEchoRead(&iEchoSocket, aConsole);
00076 iEchoWrite = CEchoWrite::NewL(&iEchoSocket, aConsole);
00077 }
00078
00079 void CEchoEngine::DoCancel()
00080
00081 {
00082 iTimer->Cancel();
00083
00084
00085 switch (iEngineStatus)
00086 {
00087 case EConnecting:
00088 iEchoSocket.CancelConnect();
00089 break;
00090 case ELookingUp:
00091
00092 iResolver.Cancel();
00093 iResolver.Close();
00094 break;
00095 default:;
00096 }
00097 }
00098
00099
00100
00101 EXPORT_C void CEchoEngine::ConnectTo(TUint32 aAddr)
00102 {
00103
00104 iAddress.SetPort(7);
00105 iAddress.SetAddress(aAddr);
00106 iEchoSocket.Connect(iAddress, iStatus);
00107 iEngineStatus = EConnecting;
00108 SetActive();
00109 iTimer->After(iTimeOut);
00110 }
00111
00112 EXPORT_C void CEchoEngine::ConnectL(const TDesC& aServerName)
00113
00114 {
00115
00116 User::LeaveIfError(iResolver.Open(iSocketServ, KAfInet, KProtocolInetUdp));
00117
00118 iResolver.GetByName(aServerName, iNameEntry, iStatus);
00119
00120 iEngineStatus=ELookingUp;
00121
00122 iTimer->After(iTimeOut);
00123 SetActive();
00124 }
00125
00126 EXPORT_C void CEchoEngine::TestGetByAddrL(TUint32 aAddr)
00127
00128 {
00129
00130 User::LeaveIfError(iResolver.Open(iSocketServ, KAfInet, KProtocolInetUdp));
00131
00132 iAddress.SetAddress(aAddr);
00133 iResolver.GetByAddress(iAddress, iNameEntry, iStatus);
00134
00135 iEngineStatus=ELookingUp;
00136
00137 iTimer->After(iTimeOut);
00138 SetActive();
00139 }
00140
00141
00142
00143 EXPORT_C void CEchoEngine::Write(TChar aChar)
00144 {
00145
00146
00147
00148
00149 if ((iEngineStatus == EConnected) && !iEchoWrite->IsActive())
00150 iEchoWrite->IssueWrite(aChar);
00151 }
00152
00153
00154
00155 EXPORT_C void CEchoEngine::Read()
00156 {
00157 if ((iEngineStatus == EConnected)&&(!iEchoRead->IsActive()))
00158 iEchoRead->IssueRead();
00159 }
00160
00161
00162
00163
00164
00165
00166 void CEchoEngine::RunL()
00167 {
00168
00169 iTimer->Cancel();
00170 _LIT(KConnecting,"\n<CEchoEngine> Connecting\n");
00171 _LIT(KConnectionFailed,"\n<CEchoEngine> Connection failed");
00172 _LIT(KDNSFailed,"\n<CEchoEngine> DNS lookup failed");
00173 _LIT(KTimedOut,"\n<CEchoEngine> Timed out\n");
00174 _LIT(KDomainName,"\nDomain name = ");
00175 _LIT(KIPAddress,"\nIP address = ");
00176
00177 TBuf<15> ipAddr;
00178
00179 switch(iEngineStatus)
00180 {
00181 case EConnecting:
00182
00183 if (iStatus == KErrNone)
00184
00185 {
00186 iConsole->PrintNotify(KConnecting);
00187 iEngineStatus = EConnected;
00188
00189 Read();
00190 }
00191 else
00192 {
00193 iEngineStatus = EConnectFailed;
00194 iConsole->ErrorNotifyL(KConnectionFailed, iStatus.Int());
00195 }
00196 break;
00197 case ETimedOut:
00198
00199 iConsole->ErrorNotifyL(KTimedOut, KErrTimedOut);
00200 break;
00201 case ELookingUp:
00202 iResolver.Close();
00203 if (iStatus == KErrNone)
00204
00205 {
00206 iNameRecord = iNameEntry();
00207
00208 iConsole->PrintNotify(KDomainName);
00209 iConsole->PrintNotify(iNameRecord.iName);
00210 TInetAddr::Cast(iNameRecord.iAddr).Output(ipAddr);
00211 iConsole->PrintNotify(KIPAddress);
00212 iConsole->PrintNotify(ipAddr);
00213
00214 ConnectTo(TInetAddr::Cast(iNameRecord.iAddr).Address());
00215 }
00216 else
00217 {
00218 iStatus = ELookUpFailed;
00219 iConsole->ErrorNotifyL(KDNSFailed, iStatus.Int());
00220 }
00221 break;
00222
00223 default:;
00224 };
00225 }
00226
00227 CEchoEngine::~CEchoEngine()
00228 {
00229 delete iEchoRead;
00230 delete iEchoWrite;
00231 delete iTimer;
00232 iEchoSocket.Close();
00233 iSocketServ.Close();
00234 }
00235
00236
00237
00238
00239 void CEchoEngine::TimerExpired()
00240 {
00241 Cancel();
00242 iEngineStatus = ETimedOut;
00243 TRequestStatus* p=&iStatus;
00244 SetActive();
00245 User::RequestComplete(p, ETimedOut);
00246 }
00247
00248
00249
00250
00251 EXPORT_C void CEchoEngine::Stop()
00252 {
00253 _LIT(KETerminate,"\n<CEchoEngine> Terminating\n");
00254
00255 iConsole->PrintNotify(KETerminate);
00256
00257 switch (iEngineStatus)
00258 {
00259 case EConnected:
00260
00261 iEchoRead->Cancel();
00262 iEchoWrite->Cancel();
00263 break;
00264 case EConnecting:
00265 case ELookingUp:
00266
00267 Cancel();
00268 break;
00269 default:;
00270 }
00271 }
00272
00273
00274 CEchoRead::CEchoRead(RSocket* aSocket, MUINotify* aConsole)
00275 :CActive(EPriorityStandard), iEchoSocket(aSocket), iConsole(aConsole)
00276 {
00277 CActiveScheduler::Add(this);
00278 }
00279
00280
00281
00282
00283
00284 void CEchoRead::DoCancel()
00285 {
00286 iEchoSocket->CancelRead();
00287 }
00288
00289
00290
00291 void CEchoRead::RunL()
00292 {
00293 if (iStatus == KErrNone)
00294
00295 {
00296 _LIT(KDot,".");
00297 iConsole->PrintNotify(KDot);
00298 TBuf16<1> Buffer;
00299 Buffer.Copy(iBuffer);
00300 iConsole->PrintNotify(Buffer);
00301 IssueRead();
00302 }
00303 else
00304 {
00305
00306 _LIT(KCEchoReadError,"\nCEchoRead error");
00307 iConsole->ErrorNotifyL(KCEchoReadError, iStatus.Int());
00308 }
00309 }
00310
00311
00312
00313 void CEchoRead::IssueRead()
00314 {
00315 if (!IsActive())
00316 {
00317 iEchoSocket->Recv(iBuffer, 0, iStatus);
00318 SetActive();
00319 }
00320 }
00321
00322
00323
00324
00325 void CEchoRead::IssueRecvFrom(TInetAddr &aAddr)
00326
00327 {
00328 iEchoSocket->RecvFrom(iBuffer,aAddr,NULL,iStatus);
00329 SetActive();
00330 };
00331
00332
00333
00334
00335 CEchoWrite::CEchoWrite() : CActive(EPriorityStandard)
00336 {
00337
00338 };
00339
00340 CEchoWrite* CEchoWrite::NewL(RSocket* aSocket, MUINotify* aConsole)
00341 {
00342 CEchoWrite* self = NewLC(aSocket, aConsole);
00343 CleanupStack::Pop();
00344 return self;
00345 };
00346
00347 CEchoWrite* CEchoWrite::NewLC(RSocket* aSocket, MUINotify* aConsole)
00348 {
00349 CEchoWrite* self = new(ELeave) CEchoWrite;
00350 CleanupStack::PushL(self);
00351 self->ConstructL(aSocket, aConsole);
00352 return self;
00353 };
00354
00355
00356
00357
00358 void CEchoWrite::ConstructL(RSocket* aSocket, MUINotify* aConsole)
00359 {
00360 iEchoSocket = aSocket;
00361 iConsole = aConsole;
00362 CActiveScheduler::Add(this);
00363
00364 iTimeOut = KTimeOut;
00365 iTimer = CTimeOutTimer::NewL(10, *this);
00366 iWriteStatus = EWaiting;
00367 };
00368
00369 CEchoWrite::~CEchoWrite()
00370 {
00371 delete iTimer;
00372 }
00373
00374
00375
00376 void CEchoWrite::DoCancel()
00377 {
00378 iEchoSocket->CancelWrite();
00379 };
00380
00381
00382
00383 void CEchoWrite::TimerExpired()
00384 {
00385 Cancel();
00386 iWriteStatus = ETimedOut;
00387 TRequestStatus* p=&iStatus;
00388 SetActive();
00389 User::RequestComplete(p, ETimedOut);
00390 }
00391
00392
00393
00394 void CEchoWrite::RunL()
00395 {
00396 if (iStatus == KErrNone)
00397 {
00398 _LIT(KWriteOperationTimedOut,"\nWrite operation timed out");
00399 switch(iWriteStatus)
00400 {
00401
00402 case ESending:
00403
00404 iTimer->Cancel();
00405 iWriteStatus = EWaiting;
00406 break;
00407
00408 case ETimedOut:
00409 iConsole->ErrorNotifyL(KWriteOperationTimedOut, KErrTimedOut);
00410 break;
00411 default:;
00412 };
00413 }
00414 else
00415 {
00416
00417 _LIT(KCEchoWriteError,"\nCEchoWrite error");
00418 iConsole->ErrorNotifyL(KCEchoWriteError, iStatus.Int());
00419 }
00420 }
00421
00422
00423
00424 void CEchoWrite::IssueWrite(const TChar &aChar)
00425 {
00426
00427 iBuffer.SetLength(0);
00428 iBuffer.Append(aChar);
00429 iEchoSocket->Write(iBuffer, iStatus);
00430
00431 iTimer->After(iTimeOut);
00432 SetActive();
00433 iWriteStatus = ESending;
00434 };
00435
00436 void CEchoWrite::IssueSendTo(TInetAddr &aAddr, const TChar &aChar)
00437
00438
00439 {
00440
00441 iBuffer.SetLength(0);
00442 iBuffer.Append(aChar);
00443 iEchoSocket->SendTo(iBuffer,aAddr,NULL,iStatus);
00444 iTimer->After(iTimeOut);
00445 SetActive();
00446 iWriteStatus = ESending;
00447 };
00448
00449
00450
00451
00452 CTimeOutTimer::CTimeOutTimer(const TInt aPriority)
00453 : CTimer(aPriority)
00454 {
00455 }
00456
00457 CTimeOutTimer::~CTimeOutTimer()
00458 {
00459 Cancel();
00460 }
00461
00462 CTimeOutTimer* CTimeOutTimer::NewL(const TInt aPriority, MTimeOutNotify& aTimeOutNotify)
00463 {
00464 CTimeOutTimer *p = new (ELeave) CTimeOutTimer(aPriority);
00465 CleanupStack::PushL(p);
00466 p->ConstructL(aTimeOutNotify);
00467 CleanupStack::Pop();
00468 return p;
00469 }
00473 void CTimeOutTimer::ConstructL(MTimeOutNotify &aTimeOutNotify)
00474 {
00475 iNotify=&aTimeOutNotify;
00476 CTimer::ConstructL();
00477 CActiveScheduler::Add(this);
00478 }
00482 void CTimeOutTimer::RunL()
00483
00484 {
00485 iNotify->TimerExpired();
00486 }
00487