/*
* Copyright (c) 2002-2006 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "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:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: Implementation of HotSpot Server Session
*
*/
// INCLUDE FILES
#include "hotspotserver.h"
#include "hotspotsession.h"
#include "hssnotif.h"
#include "hsslogintimer.h"
#include "hsslogouttimer.h"
#include <internetconnectivitycrkeys.h>
#include <WlanCdbCols.h>
#include <starterclient.h>
#include "e32std.h"
#include "am_debug.h"
#include <ecom.h>
#include "hssclientinterface.h"
#include <f32file.h>
#include <apgcli.h>
// Forward declarations
class CWlanMgmtClient;
class MWlanMgmtNotifications;
// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// CHotSpotPluginSession
// -----------------------------------------------------------------------------
//
CHotSpotSession::CHotSpotSession( CHotSpotServer& aServer ) :
iServer( aServer ), iClient( NULL ), iSrvNotifications ( NULL ),
iNotificationHandle( NULL ), iAllowNotifications( ETrue ), iHotspotExtension( ETrue )
{
}
// -----------------------------------------------------------------------------
// ConstructL
// -----------------------------------------------------------------------------
//
void CHotSpotSession::ConstructL()
{
DEBUG( "CHotSpotSession::ConstructL()" );
iIapSettingsHandler = CHssIapSettingsHandler::NewL();
iLoginTimer = CHssLoginTimer::NewL( *this );
iLogoutTimer = CHssLogoutTimer::NewL( *this );
iMgtClient = CWlanMgmtClient::NewL();
iRepository = CRepository::NewL( KCRUidInternetConnectivitySettings );
}
// -----------------------------------------------------------------------------
// NewL
// -----------------------------------------------------------------------------
//
CHotSpotSession* CHotSpotSession::NewL( CHotSpotServer& aServer )
{
CHotSpotSession* self = new( ELeave ) CHotSpotSession( aServer );
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop( self ); // Should this class have a 2-way constructor?
return self;
}
// ----------------------------------------------------------------------------------------
// ~CHotSpotSession
// ----------------------------------------------------------------------------------------
//
CHotSpotSession::~CHotSpotSession()
{
DEBUG( "CHotSpotSession::~CHotSpotSession()" );
iPendingNotifications.Close();
if ( iMgtClient != NULL )
{
iMgtClient->CancelNotifications();
delete iMgtClient;
}
iMgtClient = NULL;
if ( iIapSettingsHandler != NULL )
{
delete iIapSettingsHandler;
}
iIapSettingsHandler = NULL;
if ( iClient != NULL )
{
delete iClient;
}
iClient = NULL;
if ( iNotifications != NULL )
{
delete iNotifications;
}
iNotifications = NULL;
if ( iLoginTimer != NULL )
{
iLoginTimer->Cancel();
delete iLoginTimer;
}
iLoginTimer = NULL;
if ( iLogoutTimer != NULL )
{
iLogoutTimer->Cancel();
delete iLogoutTimer;
}
iLogoutTimer = NULL;
if ( iRepository != NULL )
{
delete iRepository;
}
iRepository = NULL;
if ( iIcts != NULL )
{
delete iIcts;
}
iIcts = NULL;
DEBUG( "CHotSpotSession::~CHotSpotSession() Done" );
}
// ----------------------------------------------------------------------------------------
// ServiceL
// ----------------------------------------------------------------------------------------
//
void CHotSpotSession::ServiceL( const RMessage2& aMessage )
{
DEBUG1( "CHotSpotSession::ServiceL message: %d", aMessage.Function() );
TRAPD( err, DispatchMessageL( aMessage) );
if (err != KErrNone)
{
// Something went wrong. Complete message to let
// the client to continue
aMessage.Complete(err);
}
}
// ----------------------------------------------------------------------------------------
// ServiceL
// ----------------------------------------------------------------------------------------
//
void CHotSpotSession::DispatchMessageL( const RMessage2& aMessage )
{
DEBUG( "CHotSpotSession::DispatchMessageL()" );
TUint value1(NULL);
TInt value2(NULL);
TInt err(KErrNone);
TInt indx(KErrNone);
TPckgBuf<TInt> iapPackage( iIapId );
switch ( aMessage.Function() )
{
case EHssActivateNotifications :
iAllowNotifications = EFalse;
DEBUG( "CHotSpotSession::ActivateNotificationsL" );
if ( iNotifications == NULL )
{
DEBUG( "CHotSpotSession::DispatchMessageL activated !!!" );
iNotifications = new (ELeave) HssNotifications(*this);
iMgtClient->ActivateNotificationsL( *iNotifications );
}
HandleOrderNotifications( aMessage );
break;
case EHssCancelNotifications :
iAllowNotifications = EFalse;
DEBUG( "CHotSpotSession::CancelNotifications" );
iMgtClient->CancelNotifications( );
if ( iNotifications != NULL )
{
delete iNotifications;
}
iNotifications = NULL;
HandleCancelNotifications( aMessage );
break;
case EHssGetScanResults :
// Handled now in client side. Left here for future use.
break;
case EHssRegister :
ProcessRegisterL( aMessage );
break;
case EHssUnRegister :
ProcessUnRegisterL( aMessage );
break;
case EHssJoin :
iAllowNotifications = EFalse;
// IAP id
value1 = ( TInt )aMessage.Int0();
iIapId = value1;
indx = iServer.FindMessage(value1, EHssStart );
if ( indx >= 0 )
{
iServer.CompleteMessage( indx , KErrNone );
}
else
{
indx = iServer.FindMessage(value1, EHssStartAgain );
if ( indx >= 0 )
{
iServer.CompleteMessage( indx , KErrNone );
}
}
aMessage.Complete( KErrNone );
break;
case EHssCancelStart :
iServer.SetLogoutFlag( ETrue );
// Do not send association status to client
iServer.SetAssociationFlag( EFalse );
// IAP id
iIapId = ( TInt )aMessage.Int0();
indx = iServer.FindMessage(iIapId, EHssStart );
if ( indx >= 0 )
{
iServer.CompleteMessage( indx , KErrAbort);
}
else
{
indx = iServer.FindMessage(iIapId, EHssStartAgain );
if ( indx >= 0 )
{
iServer.CompleteMessage( indx , KErrAbort );
}
}
aMessage.Complete( KErrNone );
break;
case EHssStop :
iAllowNotifications = EFalse;
iServer.SetLogoutFlag( ETrue );
iLoginTimer->Cancel();
iLogoutTimer->Cancel();
// IAP id
value1 = ( TInt )aMessage.Int0();
for (TInt counter = EHssGetScanResults; counter <EHssServerShutdown ;counter++)
{
indx = iServer.FindMessage(value1, THotSpotCommands(counter ));
if ( indx >= 0 )
{
iServer.CompleteMessage( indx , KErrCancel);
}
}
aMessage.Complete( KErrNone );
break;
case EHssLoginComplete :
iAllowNotifications = EFalse;
// IAP id
value1 = ( TInt )aMessage.Int0();
// ret value
value2 = ( TInt )aMessage.Int1();
iLoginTimer->Cancel();
DEBUG1( "EHssLoginComplete value2: %d", value2 );
indx = iServer.FindMessage( value1, EHssStartLogin );
if ( KErrNotFound != indx )
{
if (value2 == KErrNone)
{
DEBUG( "EHssLoginComplete1" );
iServer.CompleteMessage( indx, KErrNone );
}
else
{
DEBUG( "EHssLoginComplete2" );
iServer.CompleteMessage( indx, KErrCancel );
iServer.SetLogoutFlag( ETrue );
}
}
aMessage.Complete( KErrNone );
break;
case EHssLogoutComplete :
iAllowNotifications = EFalse;
iLogoutTimer->Cancel();
// IAP id
value1 = ( TInt )aMessage.Int0();
indx = iServer.FindMessage( value1, EHssCloseConnection );
if ( KErrNotFound != indx )
{
iServer.CompleteMessage( indx, KErrNone );
}
aMessage.Complete( KErrNone );
break;
case EHssStartLogin :
// Do not send association status, since it's already done.
iServer.SetAssociationFlag( EFalse );
// IAP id
iIapId = ( TInt )aMessage.Int0();
// Network id
iNetId = ( TInt )aMessage.Int1();
err = iServer.SaveMessage( iIapId, aMessage, EHssStartLogin );
if ( KErrNone != err )
{
aMessage.Complete( err );
}
else
{
err = ProcessStartLoginL( iIapId, iNetId );
// If client not found, an error was returned.
// Otherwise message completed elsewhere.
if ( KErrNone != err )
{
indx = iServer.FindMessage(iIapId, EHssStartLogin );
if ( indx >= 0 )
{
iServer.CompleteMessage( indx , KErrNone );
}
else
{
aMessage.Complete( KErrNone );
}
}
}
break;
case EHssCancelLogin :
iLoginTimer->Cancel();
// if client doesn't exist (is NULL), Login(.) has not been
// called to client -> that is CancelLogin() not needed to call
if ( iClient != NULL )
{
iClient->CancelLogin( iIapId );
}
indx = iServer.FindMessage(iIapId, EHssStartLogin );
if ( indx >= 0 )
{
iServer.CompleteMessage( indx , err );
}
aMessage.Complete( KErrNone );
break;
case EHssStart:
// IAP id
iServer.SetLoginFlag( ETrue );
iIapId = ( TInt )aMessage.Int0();
err = iServer.SaveMessage( iIapId, aMessage, EHssStart );
if ( err != KErrNone)
{
aMessage.Complete( err );
}
else
{
TRAPD( startLeaved, err = ProcessStartL( iIapId ) );
if ( startLeaved != KErrNone)
{
indx = iServer.FindMessage(iIapId, EHssStart );
if ( indx >= 0 )
{
iServer.CompleteMessage( indx , KErrNotSupported );
}
else
{
aMessage.Complete( KErrNotSupported );
}
}
else if ( err != KErrNone)
{
indx = iServer.FindMessage(iIapId, EHssStart );
if ( indx >= 0 )
{
iServer.CompleteMessage( indx , KErrNotSupported );
}
else
{
aMessage.Complete( KErrNotSupported );
}
}
// else -> client is created and called
// WLAN agent waits for 30 seconds before continuing connection setup.
}
break;
case EHssStartAgain:
// IAP id
iServer.SetLoginFlag( ETrue );
iIapId = ( TInt )aMessage.Int0();
err = iServer.SaveMessage( iIapId, aMessage, EHssStartAgain );
if ( err != KErrNone)
{
aMessage.Complete( err );
}
else
{
err = ProcessStartAgain( iIapId );
if ( err != KErrNone)
{
indx = iServer.FindMessage(iIapId, EHssStartAgain );
if ( indx >= 0 )
{
iServer.CompleteMessage( indx , err );
}
else
{
aMessage.Complete( err );
}
}
}
break;
case EHssCancel:
iLoginTimer->Cancel();
iLogoutTimer->Cancel();
// IAP id
iIapId = ( TInt )aMessage.Int0();
if ( iServer.GetAssociationFlagValue() )
{
// We are in association phase and Agent failed it for some reason
ProcessAssociationStatus( iIapId, EFalse );
}
indx = iServer.FindMessage(iIapId, EHssStart );
if ( indx >= 0 )
{
iServer.CompleteMessage( indx , KErrCancel );
}
indx = iServer.FindMessage(iIapId, EHssStartAgain );
if ( indx >= 0 )
{
iServer.CompleteMessage( indx , KErrCancel );
}
indx = iServer.FindMessage(iIapId, EHssCloseConnection );
if ( indx >= 0 )
{
iServer.CompleteMessage( indx , KErrCancel );
}
//Not needed to send Logout()
//iServer.SetLogoutFlag( ETrue )
//ProcessCloseL( iIapId )
aMessage.Complete( KErrNone );
break;
case EHssCloseConnection:
iLoginTimer->Cancel();
iLogoutTimer->Cancel();
// IAP id
iIapId = ( TInt )aMessage.Int0();
if ( iServer.GetAssociationFlagValue() )
{
// We are in association phase and Agent failed it for some reason
ProcessAssociationStatus( iIapId, EFalse );
}
err = iServer.SaveMessage( iIapId, aMessage, EHssCloseConnection );
if ( KErrNone != err )
{
aMessage.Complete( err );
}
else
{
err = ProcessCloseL( iIapId );
// If client not found, an error was returned.
// Otherwise message completed elsewhere.
if ( KErrNone != err )
{
indx = iServer.FindMessage(iIapId, EHssCloseConnection );
if ( indx >= 0 )
{
iServer.CompleteMessage( indx , KErrNone );
}
else
{
aMessage.Complete( KErrNone );
}
}
}
break;
case EHssServerShutdown:
ProcessServerShutdown( aMessage );
break;
case EHssGetIAP:
aMessage.WriteL( 0, iapPackage );
aMessage.Complete( KErrNone );
break;
case EHssUiState:
ProcessUiState( aMessage );
break;
case EHssStartBrowser:
{
TInt len = aMessage.GetDesLength( 0 );
iIapId = ( TInt )aMessage.Int1();
iNetId = ( TInt )aMessage.Int2();
err = iServer.SaveMessage( iIapId, aMessage, EHssStartBrowser );
HBufC* buf = HBufC::NewLC( len );
TPtr ptr( buf->Des() );
User::LeaveIfError( aMessage.Read( 0, ptr ) );
AuthenticateL( ptr );
CleanupStack::PopAndDestroy(buf);
}
break;
case EHssSetTimerValues:
{
TUid clientUid( TUid::Uid( aMessage.Int0() ) );
TUint loginTimerValue = aMessage.Int1();
TUint logoutTimerValue = aMessage.Int2();
iServer.SetTimerValues( clientUid, loginTimerValue, logoutTimerValue );
aMessage.Complete( KErrNone );
}
break;
default:
aMessage.Complete( KErrNotSupported );
//PanicClient( aMessage, EBadRequest )
break;
}
iAllowNotifications = TRUE;
}
// ---------------------------------------------------------
// HandleOrderNotifications
// ---------------------------------------------------------
//
void CHotSpotSession::HandleOrderNotifications( const RMessage2& aMessage )
{
iPendingNotificationRequest = aMessage;
iIsNotificationRequestPending = ETrue;
if( !iNotificationHandle ) // == NULL i.e. is not activated
{
TRAPD( err, iNotificationHandle = CSessionNotification::NewL( *this ) );
if ( err == KErrNone )
{
iServer.NotifyAdd( *iNotificationHandle );
}
else
{
iIsNotificationRequestPending = EFalse;
aMessage.Complete( err );
return;
}
}
HandleNotification(); // check is there any unsent notifications
}
// ---------------------------------------------------------
// HandleCancelNotifications
// ---------------------------------------------------------
//
void CHotSpotSession::HandleCancelNotifications( const RMessage2& aMessage )
{
if( iIsNotificationRequestPending )
{
iPendingNotificationRequest.Complete( KErrNone /*EWLMNotificationsCancelled*/ );
iIsNotificationRequestPending = EFalse;
iPendingNotifications.Reset();
}
if( iNotificationHandle )
{
iServer.NotifyRemove( *iNotificationHandle );
delete iNotificationHandle;
iNotificationHandle = NULL;
}
aMessage.Complete( KErrNone );
}
// ---------------------------------------------------------
// AddNotification
// ---------------------------------------------------------
//
void CHotSpotSession::AddNotification( TInt aNotification, TDes8& aData )
{
DEBUG( "CHotSpotSession::AddNotification" );
TNotification notif;
notif.id = aNotification;
notif.data = aData;
if ( iIsNotificationRequestPending )
{
DEBUG( "CHotSpotSession::AddNotification added to array. Request found..." );
iPendingNotifications.Append( notif );
HandleNotification(); // check is there client waiting for notification
}
}
// ---------------------------------------------------------
// HandleNotification
// ---------------------------------------------------------
//
void CHotSpotSession::HandleNotification()
{
DEBUG( "CHotSpotSession::HandleNotification" );
// Check if we allow notifications
if (iAllowNotifications == TRUE)
{
// Check is there message to wait notification and
// notification that is not sent.
if ( iIsNotificationRequestPending && iPendingNotifications.Count() != 0 )
{
DEBUG( "CHotSpotSession::HandleNotification - sending response..." );
iIsNotificationRequestPending = EFalse;
THssPckgData data;
TPckg<THssPckgData> pckg( data );
data.data = iPendingNotifications[0].data;
TInt ret( iPendingNotificationRequest.Write( 0, pckg ) );
if ( ret != KErrNone )
{
iPendingNotificationRequest.Complete( ret );
return;
}
iPendingNotificationRequest.Complete( iPendingNotifications[0].id );
iPendingNotifications.Reset();
}
}
}
// -----------------------------------------------------------------------------
// TestInternetConnectivityL
// -----------------------------------------------------------------------------
//
void CHotSpotSession::TestInternetConnectivityL()
{
DEBUG("CHotSpotSession::TestInternetConnectivityL");
if ( iIcts != NULL )
{
delete iIcts;
}
TInt connectivityTestAllowed( EIctsRunAutomatically );
iRepository->Get( KIctsTestPermission, connectivityTestAllowed );
DEBUG1("CHotSpotSession::TestInternetConnectivityL: %d", connectivityTestAllowed);
if ( connectivityTestAllowed == EIctsNeverRun )
{
TInt indx = iServer.FindMessage( iIapId, EHssStartLogin );
if ( KErrNotFound != indx )
{
iServer.CompleteMessage( indx, KErrNone );
}
}
else
{
iIcts = CIctsClientInterface::NewL( iIapId, iNetId, *this );
iIcts->StartL();
}
}
// -----------------------------------------------------------------------------
// ConnectivityObserver
// -----------------------------------------------------------------------------
//
void CHotSpotSession::ConnectivityObserver( TIctsTestResult aResult,
const TDesC& aString )
{
DEBUG1("CHotSpotSession::ConnectivityObserver result: %d", aResult);
TInt indx( KErrNone );
switch ( aResult )
{
case EConnectionOk :
indx = iServer.FindMessage( iIapId, EHssStartLogin );
if ( KErrNotFound != indx )
{
iServer.CompleteMessage( indx, KErrNone );
}
TRAP_IGNORE( iIapSettingsHandler->CreateIapL() );
break;
case EHttpAuthenticationNeeded :
// Start browser for authentication
TRAP_IGNORE( AuthenticateL( aString ) );
break;
case EConnectionNotOk :
indx = iServer.FindMessage( iIapId, EHssStartLogin );
if ( KErrNotFound != indx )
{
iServer.CompleteMessage( indx, KErrNone );
}
break;
case ETimeout :
indx = iServer.FindMessage( iIapId, EHssStartLogin );
if ( KErrNotFound != indx )
{
iServer.CompleteMessage( indx, KErrNone );
}
break;
default:
break;
}
}
// -----------------------------------------------------------------------------
// LoginTimeout
// -----------------------------------------------------------------------------
//
void CHotSpotSession::LoginTimeout()
{
DEBUG1("CHotSpotSession::LoginTimeout iIapId :%d", iIapId );
iServer.SetLogoutFlag( ETrue );
// if message is not found, client has not completed it (LoginComplete(..))
TInt indx = iServer.FindMessage( iIapId, EHssStartLogin );
if ( KErrNotFound != indx )
{
iServer.CompleteMessage( indx, KErrCancel );
}
TUid clientUid;
TBuf8<KExtensionAPILength> extAPI;
TRAP_IGNORE( iIapSettingsHandler->FindClientL( iIapId, clientUid, extAPI ) );
// 3rd party client was found
if ( clientUid != TUid::Null() )
{
DEBUG("CHotSpotSession::LoginTimeout clientUid = CLIENT");
TBuf8<KExtensionAPILength> nullBuf;
TInt ret = CreateClient( clientUid, nullBuf );
DEBUG1("CHotSpotSession::LoginTimeout CreateClient ret: %d", ret);
if ( KErrNone == ret )
{
iClient->CancelLogin( iIapId );
}
}
DEBUG("CHotSpotSession::LoginTimeout Done");
}
// -----------------------------------------------------------------------------
// LogoutTimeout
// -----------------------------------------------------------------------------
//
void CHotSpotSession::LogoutTimeout()
{
DEBUG("CHotSpotSession::LogoutTimeout");
// if message is not found, client has not completed it (LogoutComplete(..))
TInt indx = iServer.FindMessage( iIapId, EHssCloseConnection );
if ( KErrNotFound != indx )
{
iServer.CompleteMessage( indx, KErrNone );
}
}
// ---------------------------------------------------------
// ProcessRegisterL
// ---------------------------------------------------------
//
void CHotSpotSession::ProcessRegisterL( const RMessage2& aMessage )
{
DEBUG("CHotSpotSession::ProcessRegisterL");
iAllowNotifications = EFalse;
TBufC< KIapNameLength > iapName;
TPckgBuf< TIapName > iapPckg;
TUid clientUid;
TPckgBuf< TClientUid > uidPckg;
TPckgBuf<TInt> iapPackage( iIapId );
// Read message
aMessage.ReadL( 0, uidPckg );
clientUid = uidPckg().ClientUid();
aMessage.ReadL( 1, iapPckg );
iapName = iapPckg().IapName();
TUint32 iapId( 0 );
// TRAPD needed here so that 0 can be returned if DeleteIapL leaves
TInt ret( KErrNone );
TRAP( ret, iIapSettingsHandler->CreateClientIapL( iapName, iapId, clientUid ));
DEBUG1( "CHotSpotSession::EHssRegister iapId: %d", iapId );
DEBUG1( "CHotSpotSession::EHssRegister ret: %d", ret );
if ( KErrNone == ret )
{
aMessage.Complete( iapId );
}
else
{
// TRAP needed here so that 0 can be returned if DeleteIapL leaves
//TRAP(err, iIapSettingsHandler->DeleteIapL( iapId ))
// Error, we are returning 0 to client
// and no IAP is created
aMessage.Complete( KErrNone );
}
}
// ---------------------------------------------------------
// ProcessUnRegisterL
// ---------------------------------------------------------
//
void CHotSpotSession::ProcessUnRegisterL( const RMessage2& aMessage )
{
DEBUG("CHotSpotSession::ProcessUnRegisterL");
iAllowNotifications = EFalse;
// Read message
TInt iapId = ( TInt )aMessage.Int0();
TInt ret( KErrNone );
// Check that this is not Easy WLAN
if ( iServer.GetEasyWlanId() != iapId )
{
TRAPD( err, iIapSettingsHandler->DeleteIapL( iapId ) );
// return KErrGeneral if IAP removal is not successful
if ( err != KErrNone )
{
ret = KErrGeneral;
}
}
else
{
ret = KErrPermissionDenied;
}
aMessage.Complete( ret );
}
// -----------------------------------------------------------------------------
// ProcessStartLogin
// -----------------------------------------------------------------------------
//
TInt CHotSpotSession::ProcessStartLoginL( const TUint aIapId, const TUint aNetId )
{
DEBUG("CHotSpotSession::ProcessStartLogin");
TInt ret( KErrNotFound );
TUid clientUid;
TBuf8<KExtensionAPILength> extAPI;
iIapId = aIapId;
// This is Easy WLAN.
if ( iServer.GetEasyWlanId() == aIapId )
{
DEBUG("CHotSpotSession::ProcessStartLogin Easy WLAN detected");
// Just test internet connectivity and complete message later
TestInternetConnectivityL();
ret = KErrNone;
return ret;
}
iIapSettingsHandler->FindClientL( aIapId, clientUid, extAPI );
// 3rd party client was found
if ( clientUid != TUid::Null() )
{
DEBUG("CHotSpotSession::ProcessStartLogin clientUid = CLIENT");
TBuf8<KExtensionAPILength> nullBuf;
ret = CreateClient( clientUid, nullBuf );
if ( KErrNone == ret && iServer.GetLoginFlagValue() )
{
iLoginTimer->After( iServer.GetLoginTimeMicroSecs( clientUid ) );
DEBUG("CHotSpotSession::ProcessStartLogin iClient->Login( iIapId, iNetId );");
iClient->Login( aIapId, aNetId );
iServer.SetLogoutFlag( EFalse );
}
else
{
ret = KErrNotFound;
}
}
DEBUG("CHotSpotSession::ProcessStartLogin DONE");
return ret;
}
// -----------------------------------------------------------------------------
// ProcessStart
// -----------------------------------------------------------------------------
//
TInt CHotSpotSession::ProcessStartL( const TUint aIapId )
{
DEBUG("CHotSpotSession::ProcessStart");
TInt ret( KErrNone );
TBuf8<KExtensionAPILength> extAPI;
iIapSettingsHandler->FindClientL( aIapId, iClientUid, extAPI );
if ( iClientUid == TUid::Null() )
{
DEBUG("CHotSpotSession::ProcessStartL clientUid = EMPTY");
ret = KErrNotSupported;
}
else
{
DEBUG("CHotSpotSession::ProcessStartL clientUid = CLIENT");
// Try first with API extension defined
ret = CreateClient( iClientUid, extAPI );
if ( ret != KErrNone )
{
// Client exists, but hasn't implemented API extension
// Let's try again without API extension definition
TBuf8<KExtensionAPILength> nullBuf;
ret = CreateClient( iClientUid, nullBuf );
}
if ( ret == KErrNone )
{
iServer.SetAssociationFlag( ETrue );
iMgtClient->ActivateNotificationsL( *this );
iClient->Start( aIapId );
}
}
DEBUG1("CHotSpotSession::ProcessStartL DONE ret%d", ret);
return ret;
}
// -----------------------------------------------------------------------------
// ProcessStartAgain
// -----------------------------------------------------------------------------
//
TInt CHotSpotSession::ProcessStartAgain( const TUint aIapId )
{
DEBUG("CHotSpotSession::ProcessStartAgain");
TInt ret( KErrNone );
// Client exists if StartAgain is called.
if ( iClient == NULL )
{
TBuf8<KExtensionAPILength> nullBuf;
ret = CreateClient( iClientUid, nullBuf );
}
if ( ret == KErrNone )
{
iServer.SetAssociationFlag( ETrue ); // Send association status
iClient->Update( aIapId );
}
return ret;
}
// -----------------------------------------------------------------------------
// ProcessAssociationStatus
// -----------------------------------------------------------------------------
//
TInt CHotSpotSession::ProcessAssociationStatus( const TUint aIapId, TBool aResult )
{
DEBUG("CHotSpotSession::ProcessAssociationStatus");
TInt ret( KErrNone );
iServer.SetAssociationFlag( EFalse );
if ( iHotspotExtension )
{
iHotspotExtension = EFalse;
if ( iClient != NULL )
{
DEBUG("CHotSpotSession::ProcessAssociationStatus sent to client");
iClient->WlanAssociationStatus( aIapId, aResult );
}
}
DEBUG("CHotSpotSession::ProcessAssociationStatus Done");
return ret;
}
// -----------------------------------------------------------------------------
// CreateClient
// -----------------------------------------------------------------------------
//
TInt CHotSpotSession::CreateClient( const TUid aUid, TDesC8& aUidText )
{
DEBUG("CHotSpotSession::CreateClient");
TInt err( KErrNone );
if ( aUidText == KNullDesC8 )
{
DEBUG("CHotSpotSession::CreateClient iHotspotExtension = EFalse;");
iHotspotExtension = EFalse;
TRAP( err, iClient = CHssClientPlugin::NewL( aUid, aUidText ) );
DEBUG1("CHotSpotSession::CreateClient err: %d", err );
}
else
{
DEBUG("CHotSpotSession::CreateClient iHotspotExtension = ETrue;");
iHotspotExtension = ETrue;
TRAP( err, iClient = CHssClientPlugin::NewL( aUid, aUidText ) );
DEBUG1("CHotSpotSession::CreateClient err: %d", err );
}
return err;
}
// -----------------------------------------------------------------------------
// ProcessClose
// -----------------------------------------------------------------------------
//
TInt CHotSpotSession::ProcessCloseL( const TUint aIapId )
{
DEBUG("CHotSpotSession::ProcessCloseL");
TInt ret( KErrNone );
TUid clientUid;
TBuf8<KExtensionAPILength> extAPI;
iIapSettingsHandler->FindClientL( aIapId, clientUid, extAPI );
if ( clientUid == TUid::Null() )
{
DEBUG("CHotSpotSession::ProcessCloseL clientUid = EMPTY");
// do nothing
ret = KErrNotSupported;
}
else
{
DEBUG("CHotSpotSession::ProcessCloseL clientUid = CLIENT");
if ( iClient == NULL )
{
TBuf8<KExtensionAPILength> nullBuf;
ret = CreateClient( clientUid, nullBuf );
}
else
{
ret = KErrNone;
}
iLogoutTimer->After( iServer.GetLogoutTimeMicroSecs( clientUid ) );
if ( ret == KErrNone && !iServer.GetLogoutFlagValue() )
{
DEBUG("CHotSpotSession::ProcessCloseL send Logout()");
iClient->Logout( aIapId );
iServer.SetLogoutFlag( ETrue );
iServer.SetLoginFlag( EFalse );
}
else
{
ret = KErrNotFound;
}
}
return ret;
}
// -----------------------------------------------------------------------------
// ProcessServerShutdown
// -----------------------------------------------------------------------------
//
void CHotSpotSession::ProcessServerShutdown( const RMessage2& aMessage )
{
DEBUG("CHotSpotSession::ProcessServerShutdown");
TInt shutdown;
shutdown = ( TInt )aMessage.Int0();
if ( KHssShutdown == shutdown )
{
DEBUG("CHotSpotSession::ProcessServerShutdown shutdown ");
aMessage.Complete( KErrNone );
RProcess server; // Sets the handle-number to the KCurrentProcessHandle
server.Kill( KErrNone );
}
else
{
DEBUG("CHotSpotSession::ProcessServerShutdown else ");
aMessage.Complete( KErrNone );
}
}
// -----------------------------------------------------------------------------
// ProcessUiState
// -----------------------------------------------------------------------------
//
void CHotSpotSession::ProcessUiState( const RMessage2& aMessage )
{
DEBUG( "CHotSpotSession::ProcessUiState()" );
TBool completeMsg = EFalse;
TInt indx( KErrNone );
TInt indxBrowser( KErrNone );
TInt ret( KErrNone );
iIapId = ( TInt )aMessage.Int0();
indx = iServer.FindMessage( iIapId, EHssStartLogin );
indxBrowser = iServer.FindMessage( iIapId, EHssStartBrowser );
THsBrowserUiStates uiState = ( THsBrowserUiStates ) aMessage.Int1(); // UI state
switch ( uiState )
{
case EHsBrowserUiRunning:
{
DEBUG( "CHotSpotSession::ProcessUiState() EHsBrowserUiRunning" );
break;
}
case EHsBrowserUiAuthenticatedOk:
{
DEBUG( "CHotSpotSession::ProcessUiState() EHsBrowserUiAuthenticatedOk" );
completeMsg = ETrue;
break;
}
case EHsBrowserUiAuthenticatedNok:
{
DEBUG( "CHotSpotSession::ProcessUiState() EHsBrowserUiAuthenticatedNok" );
completeMsg = ETrue;
break;
}
case EHsBrowserUiClosed:
{
DEBUG( "CHotSpotSession::ProcessUiState() EHsBrowserUiClosed" );
completeMsg = ETrue;
break;
}
default:
{
DEBUG( "CHotSpotSession::ProcessUiState() default" );
completeMsg = ETrue;
}
}
if ( completeMsg )
{
// complete messages EHssStartLogin/EHssStartBrowser
if ( indx >= 0 )
{
DEBUG( "CHotSpotSession::ProcessUiState() completing EHssStartLogin" );
iServer.CompleteMessage( indx , KErrNone );
aMessage.Complete( KErrNone );
}
else if ( indxBrowser >= 0 )
{
DEBUG( "CHotSpotSession::ProcessUiState() completing EHssStartBrowser" );
iServer.CompleteMessage( indxBrowser, ret );
aMessage.Complete( KErrNone );
}
else
{
DEBUG( "CHotSpotSession::ProcessUiState() completing EHssUiState" );
aMessage.Complete( KErrNotFound );
}
}
}
// -----------------------------------------------------------------------------
// Authenticate()
// -----------------------------------------------------------------------------
//
void CHotSpotSession::AuthenticateL( const TDesC& aString )
{
DEBUG("CHotSpotSession::AuthenticateL()");
const TInt KBrowserUid = 0x2000AFCC; // hotspot browser application
HBufC* param = HBufC::NewLC( KMaxFileName );
_LIT(tmpString, "%d, %d, %S");
param->Des().Format( tmpString, iIapId, iNetId, &aString );
TUid uid( TUid::Uid( KBrowserUid ) );
RApaLsSession appArcSession;
User::LeaveIfError( appArcSession.Connect() ); // connect to AppArc server
CleanupClosePushL( appArcSession );
TThreadId id;
TInt err = appArcSession.StartDocument( *param, TUid::Uid( KBrowserUid ), id );
if ( err != KErrNone )
{
DEBUG1( "CHotSpotSession::AuthenticateL() StartDocument: %d", err );
}
CleanupStack::PopAndDestroy( &appArcSession );
CleanupStack::PopAndDestroy( param );
DEBUG("CHotSpotSession::AuthenticateLC() done");
}
// -----------------------------------------------------------------------------
// ConnectionStateChanged
// -----------------------------------------------------------------------------
//
void CHotSpotSession::ConnectionStateChanged( TWlanConnectionMode aNewState )
{
DEBUG1( "CHotSpotSession::ConnectionStateChanged() aNewState=%d", aNewState );
switch ( aNewState )
{
case EWlanConnectionModeSearching:
{
break;
}
case EWlanConnectionModeInfrastructure:
case EWlanConnectionModeSecureInfra:
{
iMgtClient->CancelNotifications();
ProcessAssociationStatus( iIapId, ETrue );
break;
}
case EWlanConnectionModeAdhoc:
case EWlanConnectionModeNotConnected:
{
iMgtClient->CancelNotifications();
iServer.SetAssociationFlag( EFalse );
break;
}
default:
{
iMgtClient->CancelNotifications();
iServer.SetAssociationFlag( EFalse );
}
}
}
// end of file