engine/src/ConnectionEngine.cpp
author Sebastian Brannstrom <sebastianb@symbian.org>
Sun, 31 Oct 2010 14:15:37 +0000
branchRCL_3
changeset 321 7a0fb290f9c6
parent 310 2e0299e13cbf
child 368 b131f7696342
permissions -rw-r--r--
Re-enabled max items parsed, because disabling this causes shows to turn up as new multiple times. This again breaks feeds that add new shows at the bottom, so we need to solve this properly.

/*
 * Copyright (c) 2007-2010 Sebastian Brannstrom, Lars Persson, EmbedDev AB
 *
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
 * which accompanies this distribution, and is available
 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
 *
 * Initial Contributors:
 * EmbedDev AB - initial contribution.
 *
 * Contributors:
 *
 * Description:
 *
 */

#include "connectionengine.h"
#include "settingsengine.h"
#include "podcastmodel.h"

CConnectionEngine* CConnectionEngine::NewL(CPodcastModel& aPodcastModel)
	{
	CConnectionEngine* self = new (ELeave) CConnectionEngine(aPodcastModel);
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop(self);
	return self;
	}

CConnectionEngine::~CConnectionEngine()
	{
	delete iMobility;

	Cancel();
	
	iConnection.Close();

	iSocketServer.Close();
	
	iObserverArray.Close();
	}

CConnectionEngine::CConnectionEngine(CPodcastModel& aPodcastModel):
					CActive(CActive::EPriorityStandard),iPodcastModel(aPodcastModel)
	{
	CActiveScheduler::Add(this);	
	}

void CConnectionEngine::ConstructL()
	{
	User::LeaveIfError(iSocketServer.Connect());
	User::LeaveIfError( iConnection.Open( iSocketServer ) );
	}

void CConnectionEngine::RunL()
	{
	DP2("CConnectionEngine::RunL BEGIN, iStatus.Int()=%d, iConnectionState=%d", iStatus.Int(), iConnectionState);
	if ( iStatus.Int() == KErrNone && iMobility == NULL && iConnectionState == EConnected)
		{
		TRAPD(err, iMobility = CActiveCommsMobilityApiExt::NewL( iConnection, *this ));
		
		if (err != KErrNone)
			{
			DP1("Leave in CActiveCommsMobilityApiExt::NewL, err=%d", err);
			}
		}
	
	iConnectionState = iStatus.Int() == KErrNone?CConnectionEngine::EConnected:CConnectionEngine::ENotConnected;
	ReportConnectionL( iStatus.Int() );
	DP("CConnectionEngine::RunL END");
	}

void CConnectionEngine::DoCancel()
	{
	}

TInt CConnectionEngine::RunError( TInt /*aError*/ )
	{
	return KErrNone;
	}

void CConnectionEngine::PreferredCarrierAvailable( TAccessPointInfo /*aOldAPInfo*/,
		TAccessPointInfo /*aNewAPInfo*/,
		TBool aIsUpgrade,
		TBool aIsSeamless )
	{
	DP("CConnectionEngine::PreferredCarrierAvailable");
	if ( aIsUpgrade )
		{        
		}
	else
		{       
		}

	if ( aIsSeamless )
		{
		// in S60 3.2, this situation cannot occur.        
		}
	else
		{       
		// Sockets have to be closed at this point.        

		iMobility->MigrateToPreferredCarrier();
		}

	}

void CConnectionEngine::NewCarrierActive( TAccessPointInfo /*aNewAPInfo*/, TBool aIsSeamless )
	{    
	DP("CConnectionEngine::NewCarrierActive");
	if ( aIsSeamless )
		{
		// in S60 3.2, this situation cannot occur.

		}
	else
		{        
		// Sockets have to be re-opened and check they can connect
		// to their server at this point.        

		iMobility->NewCarrierAccepted();
		}
	}

void CConnectionEngine::Error( TInt /*aError*/ )
	{

	}

TBool CConnectionEngine::ConnectionSettingL()
	{
	DP("CConnectionEngine::ConnectionSettingL");
	TBool selected( EFalse );

	CCmApplicationSettingsUi* settings = CCmApplicationSettingsUi::NewL();
	CleanupStack::PushL( settings );

	TUint listedItems = 
	CMManager::EShowDefaultConnection |
	CMManager::EShowDestinations;

	TBearerFilterArray filter;
	ReportConnectionSelectionStart();
	selected = settings->RunApplicationSettingsL( iUserSelection,
			listedItems,
			filter );

	CleanupStack::PopAndDestroy( settings );
	ReportConnectionSelectionEnd();
	return selected;
	}


void CConnectionEngine::StartL(TConnectionType aConnectionType)
	{
	DP1("CConnectionEngine::StartL BEGIN, aConnectionType=%d", aConnectionType);
	
	iConnection.Close();
	User::LeaveIfError( iConnection.Open( iSocketServer ) );
	// Connect using UI Setting
	if(aConnectionType == EDefaultConnection)
		{
		iConnection.Start( iStatus );
		SetActive();
		}
	else if(aConnectionType == EUserSelectConnection)
		{				
		TBool selected = ConnectionSettingL();

		if ( selected )
			{
			switch ( iUserSelection.iResult )
				{
				case CMManager::EDestination:
					{					
					iSnapPreference.SetSnap( iUserSelection.iId );
					iConnection.Start( iSnapPreference, iStatus );
					aConnectionType = ESNAPConnection;
					break;
					}				
				default: // CMManager::EAlwaysAsk
				case CMManager::EDefaultConnection:
					{					
					iConnection.Start( iStatus );
					break;
					}									
				}						
			}
		else
			{
			TRequestStatus* status = &iStatus;
			User::RequestComplete(status, KErrCancel);
			}
		
			SetActive();
		}	
	else if (aConnectionType == EIAPConnection)
		{
		iCommdbPreference.SetIapId((iPodcastModel.SettingsEngine().SpecificIAP()& KUseIAPMask));
		iCommdbPreference.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
		iCommdbPreference.SetDirection(ECommDbConnectionDirectionOutgoing);
		iConnection.Start( iCommdbPreference, iStatus );
		SetActive();
		}
	// Connect using SNAP 
	else
		{
		iSnapPreference.SetSnap(iPodcastModel.SettingsEngine().SpecificIAP());
		iConnection.Start( iSnapPreference, iStatus );
		SetActive();	
		}		
	
	iConnectionType = aConnectionType;
	iConnectionState = CConnectionEngine::EConnecting;
	DP1("CConnectionEngine::StartL END, iConnectionState=%d", iConnectionState);	
	}

void CConnectionEngine::Stop()
	{
	DP("CConnectionEngine::Stop");
	iConnection.Stop();
	iConnectionState = CConnectionEngine::ENotConnected;
	}


RConnection& CConnectionEngine::Connection()
	{
	return iConnection;	
	}

CConnectionEngine::TConnectionState CConnectionEngine::ConnectionState()
	{
	DP("CConnectionEngine::ConnectionState BEGIN");
	TInt selectedConn = (TInt) iSnapPreference.Snap();
	TInt specIAPSNAP = iPodcastModel.SettingsEngine().SpecificIAP();
	// If we have IAP preference then get that from our current connection and mask out the selected iap
	if((specIAPSNAP&KUseIAPFlag))
		{
		selectedConn = iCommdbPreference.IapId();
		specIAPSNAP = specIAPSNAP&KUseIAPMask;
		}
	
	// IAPSNAP must be > 0 and then  if the IAP/Sel conn IAP differs
	if(specIAPSNAP >0 && specIAPSNAP !=  selectedConn )
		{
		if(iConnection.SubSessionHandle() != 0)
			{
			iConnection.Stop();
			}
		
		iConnectionState = CConnectionEngine::ENotConnected;
		}
	else
		{
		// We have a user selection or default selction, check our current connection state.
		TNifProgress progress;
		if(iConnection.Progress(progress) == KErrNone)
			{
			if(progress.iError == KErrNone && progress.iStage != 0)
				{
				if(progress.iStage == KLinkLayerOpen)
					{
					iConnectionState = CConnectionEngine::EConnected;
					}				
				}
			else if(iConnectionState != CConnectionEngine::EConnecting)
				{
				iConnectionState = CConnectionEngine::ENotConnected;
				}
			}
		else
			{
			iConnectionState = CConnectionEngine::ENotConnected;
			}
		}
	
	DP("CConnectionEngine::ConnectionState END");
	return iConnectionState;
	}

EXPORT_C void CConnectionEngine::AddObserver(MConnectionObserver* aObserver)
	{
	DP("CConnectionEngine::AddObserver");
	iObserverArray.Append(aObserver);
	}

EXPORT_C void CConnectionEngine::RemoveObserver(MConnectionObserver* aObserver)
	{
	DP("CConnectionEngine::RemoveObserver");
	for (int i=0;i<iObserverArray.Count();i++)
		{
		if (iObserverArray[i] == aObserver)
			{
			iObserverArray.Remove(i);
			}
			
		}
	}

RSocketServ& CConnectionEngine::SockServ()
	{
	return iSocketServer;
	}


void CConnectionEngine::ReportConnectionL(TInt aError)
	{
	DP1("CConnectionEngine::ReportConnectionL, aError=%d", aError);
	TInt noObservers = iObserverArray.Count();
	DP1("    noObservers=%d", noObservers);
	while(noObservers)
		{
		noObservers--;
		DP("    calling callback");
		iObserverArray[noObservers]->ConnectCompleteL(aError);
		}
	}


void CConnectionEngine::ReportConnectionSelectionStart()
	{
	TInt noObservers = iObserverArray.Count();
	while(noObservers)
		{
		noObservers--;
		iObserverArray[noObservers]->ConnectionSelectionStart();
		}
	}


void CConnectionEngine::ReportConnectionSelectionEnd()
	{
	TInt noObservers = iObserverArray.Count();
	while(noObservers)
		{
		noObservers--;
		iObserverArray[noObservers]->ConnectionSelectionEnd();
		}
	}