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