diff -r 000000000000 -r ff3b6d0fd310 cbs/CbsServer/ServerSrc/CCbsMcnSession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cbs/CbsServer/ServerSrc/CCbsMcnSession.cpp Tue Feb 02 01:11:09 2010 +0200 @@ -0,0 +1,377 @@ +/* +* Copyright (c) 2003 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: MCN server-side subsession implementation. +* +* Implementation of MCN topic subscription commits changes (reception +* state, subscribed topics, etc) immediately after every request. +* +*/ + + + +// INCLUDE FILES + +#include "CbsCommon.h" +#include "CbsServerPanic.h" +#include "CbsServerConstants.h" +#include "CCbsMcnSession.h" +#include "CCbsRecMessage.h" +#include "CCbsReceiverHelper.h" +#include "CCbsDbImpSettings.H" +#include "CCbsRecEtel.h" +#include "CCbsSession.h" +#include "CCbsServer.h" +#include "CbsLogger.h" + +// CONSTANTS + +/// Initial size of the array holding numbers of subscribed topics. +const TInt KInitialSpaceForSubscribedTopics = 1; + +// ================= MEMBER FUNCTIONS ======================= + +// ----------------------------------------------------------------------------- +// CCbsMcnSession::CCbsMcnSession +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CCbsMcnSession::CCbsMcnSession( + CCbsSession& aSession, + CCbsRecEtel& aReceiver ) + : CCbsObject( aSession ), + iReceiver( aReceiver ), + iMcnPckg( iMcnMessage ) + { + // Do nothing + } + +// ----------------------------------------------------------------------------- +// CCbsEtelMessaging::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CCbsMcnSession::ConstructL() + { + CBSLOGSTRING("CBSSERVER: >>> CCbsMcnSession::ConstructL()"); + + iSubscribedTopics = new (ELeave) CArrayFixFlat + ( KInitialSpaceForSubscribedTopics ); + iReceiver.AddSubscriptionProviderL( this ); + + CBSLOGSTRING("CBSSERVER: <<< CCbsMcnSession::ConstructL()"); + } + +// ----------------------------------------------------------------------------- +// CCbsEtelMessaging::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CCbsMcnSession* CCbsMcnSession::NewL( + CCbsSession& aSession, + CCbsRecEtel& aReceiver ) + { + CBSLOGSTRING("CBSSERVER: >>> CCbsMcnSession::NewL()"); + + CCbsMcnSession* self = + new (ELeave) CCbsMcnSession( aSession, aReceiver ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + + CBSLOGSTRING("CBSSERVER: <<< CCbsMcnSession::NewL()"); + return self; + } + +// Destructor + +CCbsMcnSession::~CCbsMcnSession() + { + CBSLOGSTRING("CBSSERVER: >>> CCbsMcnSession::~CCbsMcnSession()"); + TRAP_IGNORE( iReceiver.RemoveSubscriptionProviderL( this ) ); + delete iSubscribedTopics; + CBSLOGSTRING("CBSSERVER: <<< CCbsMcnSession::~CCbsMcnSession()"); + } + +// ----------------------------------------------------------------------------- +// CCbsMcnSession::HandleRequestsL +// Handles MCN client requests. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCbsMcnSession::HandleRequestsL( + const RMessage2& aMessage ) + { + CBSLOGSTRING("CBSSERVER: >>> CCbsMcnSession::HandleRequestsL()"); + + TBool requestHandled( ETrue ); + + switch( aMessage.Function() ) + { + case EMcnNotifyOnChange: + CBSLOGSTRING("CBSSERVER: CCbsMcnSession::HandleRequestsL(): EMcnNotifyOnChange"); + NotifyOnChange(); + break; + + case EMcnCloseSubsession: + CBSLOGSTRING("CBSSERVER: CCbsMcnSession::HandleRequestsL(): EMcnCloseSubsession"); + CloseMcnSession(); + aMessage.Complete( KErrNone ); + break; + + case EMcnNotifyOnChangeCancel: + CBSLOGSTRING("CBSSERVER: CCbsMcnSession::HandleRequestsL(): EMcnNotifyOnChangeCancel"); + NotifyOnChangeCancel(); + break; + + case EMcnSubscribeTopic: + CBSLOGSTRING("CBSSERVER: CCbsMcnSession::HandleRequestsL(): EMcnSubscribeTopic"); + SubscribeTopicL(); + break; + + case EMcnClearSubscriptions: + CBSLOGSTRING("CBSSERVER: CCbsMcnSession::HandleRequestsL(): EMcnClearSubscriptions"); + ClearSubscriptionsL(); + break; + + case EMcnNoMoreSubscriptions: + CBSLOGSTRING("CBSSERVER: CCbsMcnSession::HandleRequestsL(): EMcnNoMoreSubscriptions"); + ApplySubscriptionsL(); + break; + + default: + CBSLOGSTRING("CBSSERVER: CCbsMcnSession::HandleRequestsL(): default"); + requestHandled = EFalse; + break; + } + CBSLOGSTRING("CBSSERVER: <<< CCbsMcnSession::HandleRequestsL()"); + + return requestHandled; + } + +// ----------------------------------------------------------------------------- +// CCbsMcnSession::NumberOfSubscriptions +// Returns the number of topic subscriptions of this MCN client. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TUint CCbsMcnSession::NumberOfSubscriptions() const + { + return iSubscribedTopics->Count(); + } + +// ----------------------------------------------------------------------------- +// CCbsMcnSession::RouteMessageL +// Routes messages to the subscribed Mcnclients. +// If the topic of the message is subscribed by the client, +// aMessage is copied to client-side. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMcnSession::RouteMessageL( + const CCbsMessage& aMessage ) + { + CBSLOGSTRING("CBSSERVER: >>> CCbsMcnSession::RouteMessageL()"); + + TKeyArrayFix key(0, ECmpTUint16); + TInt index; + TUint16 topicNumber( aMessage.TopicNumber() ); + TInt result( iSubscribedTopics->FindIsq( topicNumber, key, index ) ); + + + TBool isLC( aMessage.IsLivecastMessage() ); + + if ( isLC ) + { + iMcnMessage.iBuffer8 = aMessage.Contents8(); + iMcnMessage.iBuffer = KNullDesC; + } + else + { + iMcnMessage.iBuffer = aMessage.Contents(); + iMcnMessage.iBuffer8 = KNullDesC8; + } + + iMcnMessage.iNetworkMode = aMessage.NetworkMode(); + iMcnMessage.iTopicNumber = aMessage.TopicNumber(); + + CBSLOGSTRING2("CBSSERVER: CCbsMcnSession::RouteMessageL(): topicNumber: %d", iMcnMessage.iTopicNumber ); + CBSLOGSTRING2("CBSSERVER: CCbsMcnSession::RouteMessageL(): networkMode: %d (0=GSM, 1=WCDMA, 2=Not defined).", iMcnMessage.iNetworkMode ); + + if ( result == KErrNone ) + { + CBSLOGSTRING("CBSSERVER: CCbsMcnSession::RouteMessageL(): Notifying client..."); + NotifyClientL( iMcnPckg ); + CBSLOGSTRING("CBSSERVER: CCbsMcnSession::RouteMessageL(): Client notified."); + } + CBSLOGSTRING("CBSSERVER: <<< CCbsMcnSession::RouteMessageL()"); + } + +// ----------------------------------------------------------------------------- +// CCbsMcnSession::CloseMcnSession +// Close the subsession. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMcnSession::CloseMcnSession() + { + CBSLOGSTRING("CBSSERVER: >>> CCbsMcnSession::CloseMcnSession()"); + + // Removes the object. + Session().Server().DeleteObjectByHandle( Message().Int3() ); + + CBSLOGSTRING("CBSSERVER: <<< CCbsMcnSession::CloseMcnSession()"); + } + +// ----------------------------------------------------------------------------- +// CCbsMcnSession::NotifyOnChange +// Handles client request for message routing. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMcnSession::NotifyOnChange() + { + CBSLOGSTRING("CBSSERVER: >>> CCbsMcnSession::NotifyOnChange()"); + + if ( iIsMessage ) + { + NotifyOnChangeCancel(); + } + + iMessage = Message(); + iIsMessage = ETrue; + + CBSLOGSTRING("CBSSERVER: <<< CCbsMcnSession::NotifyOnChange()"); + } + +// ----------------------------------------------------------------------------- +// CCbsMcnSession::NotifyOnChangeCancel +// Handles client request to cancel an outstanding routing request. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMcnSession::NotifyOnChangeCancel() + { + CBSLOGSTRING("CBSSERVER: >>> CCbsMcnSession::NotifyOnChangeCancel()"); + + if ( iIsMessage ) + { + iMessage.Complete( KErrCancel ); + } + + iIsMessage = EFalse; + Message().Complete( KErrNone ); + + CBSLOGSTRING("CBSSERVER: <<< CCbsMcnSession::NotifyOnChangeCancel()"); + } + +// ----------------------------------------------------------------------------- +// CCbsMcnSession::SubscribeTopicL +// Handles client-side request to subscribe a single topic. +// An attempt to subscribe the same topic twice does not +// cause any error - the topic remains subscribed. +// Note: ApplySubscriptionL has to be called in order to +// apply receiver changes. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMcnSession::SubscribeTopicL() + { + CBSLOGSTRING("CBSSERVER: >>> CCbsMcnSession::SubscribeTopicL()"); + + // Read topic number from client. + TUint16 topicNumber( 0 ); + topicNumber = static_cast ( Message().Int0() ); + + // Store the topic number and notify receiver. + TKeyArrayFix key(0, ECmpTUint16); + TRAPD( err, iSubscribedTopics->InsertIsqL( topicNumber, key ) ); + if( err != KErrAlreadyExists ) + { + CBSLOGSTRING2("CBSSERVER: CCbsMcnSession::SubscribeTopicL(), leaving if error != 0: %d", err); + User::LeaveIfError( err ); + } + + // Complete the request. + Message().Complete( KErrNone ); + + CBSLOGSTRING("CBSSERVER: <<< CCbsMcnSession::SubscribeTopicL()"); + } + +// ----------------------------------------------------------------------------- +// CCbsMcnSession::NotifyClientL +// Called by RouteMessageL() to actually copy the message content +// to client side. +// If the client has a CB message routing request pending, +// the message and topicnumber of the message are given to client side. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMcnSession::NotifyClientL( + const TPckg& aMcnPckg ) + { + CBSLOGSTRING("CBSSERVER: >>> CCbsMcnSession::NotifyClientL()"); + + if ( iIsMessage ) + { + CBSLOGSTRING("CBSSERVER: CCbsMcnSession::NotifyClientL(): Writing msg pckg to client..."); + // Write the message package to client + iMessage.WriteL( 0, aMcnPckg ); + CBSLOGSTRING("CBSSERVER: CCbsMcnSession::NotifyClientL(): Writing msg pckg to client OK."); + + // Complete the request + iMessage.Complete( KErrNone ); + iIsMessage = EFalse; + } + CBSLOGSTRING("CBSSERVER: <<< CCbsMcnSession::NotifyClientL()"); + } + +// ----------------------------------------------------------------------------- +// CCbsMcnSession::ClearSubscriptionsL +// Clears all topic subscriptions of this MCN session. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMcnSession::ClearSubscriptionsL() + { + CBSLOGSTRING("CBSSERVER: >>> CCbsMcnSession::ClearSubscriptionsL()"); + + iSubscribedTopics->Reset(); + iReceiver.ApplyStateChangesL(); + Message().Complete( KErrNone ); + + CBSLOGSTRING("CBSSERVER: <<< CCbsMcnSession::ClearSubscriptionsL()"); + } + +// ----------------------------------------------------------------------------- +// CCbsMcnSession::ApplySubscriptionsL +// Forces receiver to reload CB topic subscriptions. +// This function has to be called after MCN client has subscribed +// topics with SubscribeTopicL(). +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsMcnSession::ApplySubscriptionsL() + { + CBSLOGSTRING("CBSSERVER: >>> CCbsMcnSession::ApplySubscriptionsL()"); + + iReceiver.ApplyStateChangesL(); + Message().Complete( KErrNone ); + + CBSLOGSTRING("CBSSERVER: <<< CCbsMcnSession::ApplySubscriptionsL()"); + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// End of File