00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <nifman.h>
00010 #include <eikenv.h>
00011 #include <aknglobalnote.h>
00012 #include <es_enum.h>
00013 #include <TextResolver.h>
00014 #include <aknquerydialog.h>
00015 #include <txtetext.h>
00016 #include <cmapplicationsettingsui.h>
00017
00018 #include "MobilityEngine.h"
00019 #include "LogContainer.h"
00020
00021
00022 _LIT(KInitialText, "Select Options->Connect to start");
00023 _LIT(KStarting, "Starting connection...");
00024 _LIT(KSuccessful, "Successful connection.");
00025 _LIT(KRegisteredWithMobilityExt, "Registered with Mobility Ext");
00026 _LIT(KResolvingUrlFmt,"Resolving URL: %S");
00027 _LIT(KSocketConnecting,"Socket connecting...");
00028 _LIT(KSocketConnected,"Socket connected.");
00029 _LIT(KDisconnected,"Disconnected.");
00030 _LIT(KPreferredCarrierAvailableFmt,"PreferredCarrierAvailable: #%u->#%u, upgrade: %S, seamless: %S");
00031 _LIT(KMigrating, "Migrating...");
00032 _LIT(KNewCarrierActive, "New Carrier Active");
00033 _LIT(KErrorFmt,"Error: %S");
00034 _LIT(KAddressFmt,"Address: %S:%u");
00035 _LIT(KFallBackToPreviousCarrier,"Falling back to previous carrier.");
00036 _LIT(KTrueStr,"true");
00037 _LIT(KFalseStr,"false");
00038
00039 _LIT(KPanicCategory,"MobilityEngine");
00040 enum TPanicCodes
00041 {
00042 EPanicUnreachable = 0,
00043 EPanicBadAddressFamily = 1
00044 };
00045
00046 _LIT(KDefaultHost,"www.google.com");
00047
00048
00049
00050
00052 CMobilityEngine::CMobilityEngine(CLogContainer* aLogView) :
00053 CActive(EPriorityStandard),
00054 iLogView(aLogView)
00055 {
00056 }
00057
00061 CMobilityEngine* CMobilityEngine::NewLC(CLogContainer* aLogView)
00062 {
00063 CMobilityEngine* self = new (ELeave) CMobilityEngine(aLogView);
00064 CleanupStack::PushL(self);
00065 self->ConstructL();
00066 return self;
00067 }
00068
00072 CMobilityEngine* CMobilityEngine::NewL(CLogContainer* aLogView)
00073 {
00074 CMobilityEngine* self = CMobilityEngine::NewLC(aLogView);
00075 CleanupStack::Pop(self);
00076 return self;
00077 }
00078
00080 void CMobilityEngine::ConstructL()
00081 {
00082 User::LeaveIfError(iSocketServ.Connect());
00083 User::LeaveIfError(iConnection.Open(iSocketServ));
00084
00085 iTextResolver = CTextResolver::NewL();
00086
00087 CActiveScheduler::Add(this);
00088
00089 iHostAndPort = KDefaultHost().AllocL();
00090
00091 iLogView->LogEntryL(KInitialText);
00092 }
00093
00095 CMobilityEngine::~CMobilityEngine()
00096 {
00097 Disconnect();
00098 delete iTextResolver;
00099 iConnection.Close();
00100 iSocketServ.Close();
00101 delete iHostAndPort;
00102 }
00103
00105 void CMobilityEngine::DoCancel()
00106 {
00107 switch(iState)
00108 {
00109 case EStartingConnection:
00110 iConnection.Stop();
00111 break;
00112 case EResolvingAddress:
00113 iResolver.Cancel();
00114 break;
00115 case ESocketConnecting:
00116 iRoamingSocket.CancelConnect();
00117 break;
00118 case EAsyncDisconnect:
00119 break;
00120 default:
00121 User::Panic(KPanicCategory,EPanicUnreachable);
00122 break;
00123 }
00124 }
00125
00127 void CMobilityEngine::RunL()
00128 {
00129 if(iStatus!=KErrNone)
00130 {
00131 iLogView->LogEntryL(KErrorFmt,&iTextResolver->ResolveErrorString(iStatus.Int()));
00132 if(iAcceptOnConnect)
00133 {
00134 iAcceptOnConnect = EFalse;
00135
00136 iRoamingSocket.Close();
00137 iResolver.Close();
00138 iMobility->NewCarrierRejected();
00139 iLogView->LogEntryL(KFallBackToPreviousCarrier);
00140 ConnectSocketL();
00141 return;
00142 }
00143 Disconnect();
00144 return;
00145 }
00146 switch(iState)
00147 {
00148 case EStartingConnection:
00149 {
00150 iLogView->LogEntryL(KSuccessful);
00151
00152 iMobility = CActiveCommsMobilityApiExt::NewL(iConnection, *this);
00153 iLogView->LogEntryL(KRegisteredWithMobilityExt);
00154 ConnectSocketL();
00155 break;
00156 }
00157 case EResolvingAddress:
00158 {
00159 TNameRecord& record = iNameEntry();
00160 if(record.iFlags&TNameRecord::EAlias)
00161 {
00162 iResolver.Next(iNameEntry,iStatus);
00163 SetActive();
00164 break;
00165 }
00166 iResolver.Close();
00167 record.iAddr.SetPort(GetPort());
00168 LogAddressL(record.iAddr);
00169 iAddrResolved = ETrue;
00170 ConnectSocketL();
00171 break;
00172 }
00173 case ESocketConnecting:
00174 {
00175 iState = ESocketConnected;
00176 if(iAcceptOnConnect)
00177 {
00178 iAcceptOnConnect = EFalse;
00179 iMobility->NewCarrierAccepted();
00180 }
00181
00182 iLogView->LogEntryL(KSocketConnected);
00183 break;
00184 }
00185 case EAsyncDisconnect:
00186 Disconnect();
00187 break;
00188 default:
00189 {
00190 User::Panic(KPanicCategory,EPanicUnreachable);
00191 break;
00192 }
00193 }
00194 }
00195
00196
00198 TInt CMobilityEngine::RunError(TInt aError)
00199 {
00200 TRAP_IGNORE(iLogView->LogEntryL(KErrorFmt,&iTextResolver->ResolveErrorString(aError)));
00201 Disconnect();
00202 return KErrNone;
00203 }
00204
00206 void CMobilityEngine::ConnectL()
00207 {
00208 if(iState!=EIdle)
00209 {
00210 User::Leave(KErrInUse);
00211 }
00212
00213 TCmSettingSelection userSelection;
00214
00215 CCmApplicationSettingsUi* settings = CCmApplicationSettingsUi::NewL();
00216 CleanupStack::PushL(settings);
00217
00218 TUint listedItems = CMManager::EShowAlwaysAsk |
00219 CMManager::EShowDefaultConnection |
00220 CMManager::EShowDestinations |
00221 CMManager::EShowConnectionMethods;
00222
00223 TBearerFilterArray filter;
00224
00225 TBool selected = settings->RunApplicationSettingsL(userSelection,
00226 listedItems,
00227 filter);
00228
00229 CleanupStack::PopAndDestroy(settings);
00230
00231 if (selected) {
00232 switch (userSelection.iResult)
00233 {
00234 case CMManager::EDestination:
00235 {
00236 TConnSnapPref prefs;
00237 prefs.SetSnap(userSelection.iId);
00238
00239 iConnection.Start(prefs, iStatus);
00240 break;
00241 }
00242 case CMManager::EConnectionMethod:
00243 {
00244 TCommDbConnPref prefs;
00245 prefs.SetIapId(userSelection.iId);
00246 prefs.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
00247
00248 iConnection.Start(prefs, iStatus);
00249 break;
00250 }
00251 case CMManager::EDefaultConnection:
00252 {
00253 iConnection.Start(iStatus);
00254 break;
00255 }
00256 default:
00257 {
00258 TCommDbConnPref prefs;
00259 prefs.SetDialogPreference(ECommDbDialogPrefPrompt);
00260
00261 iConnection.Start(prefs, iStatus);
00262 }
00263 }
00264
00265 iState = EStartingConnection;
00266 SetActive();
00267 iLogView->LogEntryL(KStarting);
00268 }
00269 }
00270
00272 void CMobilityEngine::Disconnect()
00273 {
00274 Cancel();
00275
00276 iRoamingSocket.Close();
00277 iAddrResolved = EFalse;
00278 iResolver.Close();
00279 delete iMobility;
00280 iMobility = NULL;
00281 iConnection.Stop();
00282 iState = EIdle;
00283 TRAP_IGNORE(iLogView->LogEntryL(KDisconnected));
00284 }
00285
00287 TBool CMobilityEngine::IsIdle()
00288 {
00289 return iState==EIdle;
00290 }
00291
00300 void CMobilityEngine::PreferredCarrierAvailable(TAccessPointInfo aOldAPInfo,
00301 TAccessPointInfo aNewAPInfo,
00302 TBool aIsUpgrade,
00303 TBool aIsSeamless)
00304 {
00305 TRAP_IGNORE(iLogView->LogEntryL(KPreferredCarrierAvailableFmt,
00306 aOldAPInfo.AccessPoint(),aNewAPInfo.AccessPoint(),
00307 &(aIsUpgrade ? KTrueStr() : KFalseStr()),&(aIsSeamless ? KTrueStr() : KFalseStr())));
00308
00309 if (aIsSeamless)
00310 {
00311
00312 }
00313 else
00314 {
00315 Cancel();
00316
00317
00318
00319
00320
00321
00322 iRoamingSocket.Close();
00323 iResolver.Close();
00324 iMobility->MigrateToPreferredCarrier();
00325 iState = EChangingCarrier;
00326 TRAP_IGNORE(iLogView->LogEntryL(KMigrating));
00327 }
00328 }
00329
00333 void CMobilityEngine::NewCarrierActive(TAccessPointInfo , TBool )
00334 {
00335 TRAPD(err,HandleNewCarrierActiveL());
00336 if(err!=KErrNone)
00337 {
00338 iMobility->NewCarrierRejected();
00339 TRAP_IGNORE(iLogView->LogEntryL(KErrorFmt,&iTextResolver->ResolveErrorString(err)));
00340
00341 AsyncDisconnect();
00342 }
00343 }
00344
00348 void CMobilityEngine::Error(TInt aError)
00349 {
00350
00351 if(aError!=KErrCancel)
00352 {
00353 TRAP_IGNORE(iLogView->LogEntryL(KErrorFmt,&iTextResolver->ResolveErrorString(aError)));
00354
00355 AsyncDisconnect();
00356 }
00357 }
00358
00362 void CMobilityEngine::HandleNewCarrierActiveL()
00363 {
00364 iLogView->LogEntryL(KNewCarrierActive);
00365 ConnectSocketL();
00366 iAcceptOnConnect = ETrue;
00367 }
00368
00372 void CMobilityEngine::ConnectSocketL()
00373 {
00374 if(!iAddrResolved)
00375 {
00376 User::LeaveIfError(iResolver.Open(iSocketServ,KAfInet,KProtocolInetTcp,iConnection));
00377 iResolver.GetByName(GetHost(),iNameEntry,iStatus);
00378 iState = EResolvingAddress;
00379 SetActive();
00380 iLogView->LogEntryL(KResolvingUrlFmt,iHostAndPort);
00381 return;
00382 }
00383 User::LeaveIfError(iRoamingSocket.Open(iSocketServ,KAfInet,KSockStream,KProtocolInetTcp,iConnection));
00384 iRoamingSocket.Connect(iNameEntry().iAddr,iStatus);
00385 iState = ESocketConnecting;
00386 SetActive();
00387 iLogView->LogEntryL(KSocketConnecting);
00388 }
00389
00393 void CMobilityEngine::AsyncDisconnect()
00394 {
00395 iState = EAsyncDisconnect;
00396 iStatus = KRequestPending;
00397 SetActive();
00398 TRequestStatus* status = &iStatus;
00399 User::RequestComplete(status,KErrNone);
00400 }
00401
00405 void CMobilityEngine::LogAddressL(const TSockAddr& aAddr)
00406 {
00407 __ASSERT_DEBUG(aAddr.Family()==KAfInet,User::Panic(KPanicCategory,EPanicBadAddressFamily));
00408 TBuf<16> buf;
00409 static_cast<const TInetAddr&>(aAddr).Output(buf);
00410 iLogView->LogEntryL(KAddressFmt,&buf,aAddr.Port());
00411 }
00412
00416 TPtrC CMobilityEngine::GetHost() const
00417 {
00418 TInt pos = iHostAndPort->Locate(':');
00419 if(pos==KErrNotFound)
00420 {
00421 return *iHostAndPort;
00422 }
00423 return (pos==KErrNotFound) ? *iHostAndPort : iHostAndPort->Left(pos);
00424 }
00425
00429 TUint CMobilityEngine::GetPort() const
00430 {
00431 TInt pos = iHostAndPort->Locate(':');
00432 if(pos==KErrNotFound)
00433 {
00434 return 80u;
00435 }
00436 TPtrC portStr = iHostAndPort->Right(pos+1);
00437 TLex lex(portStr);
00438 TUint port;
00439 if(lex.Val(port)!=KErrNone || port==0u)
00440 {
00441 port = 80u;
00442 }
00443 return port;
00444 }
00445
00446