diff -r 4096754ee773 -r 52a167391590 localconnectivityservice/obexserviceman/obexservicemanserver/src/SrcsSession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/localconnectivityservice/obexserviceman/obexservicemanserver/src/SrcsSession.cpp Wed Sep 01 12:20:40 2010 +0100 @@ -0,0 +1,502 @@ +/* +* Copyright (c) 2002-2007 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: SRCS session handler. Dispatchs requests from +* clients and serves them. +* +*/ + + + +// INCLUDE FILES + +#include "SrcsSession.h" +#include "obexsm.h" +#include "SrcsMessage.h" +#include "debug.h" +#include + + +// CONSTANTS + +// The granularity of the array used to hold CSrcsMessage objects +static const TInt KMessageArrayGranularity = 4; + + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// C++ default constructor can NOT contain any code, that +// might leave. +// constructor - must pass client to CSession2 +// --------------------------------------------------------- +// +CSrcsSession::CSrcsSession(CObexSM* aServer) : CSession2(), + iServer(aServer), + iCanceling(EFalse) + { + if(iServer) + { + iServer->IncSessionCount(); + } + } +// --------------------------------------------------------- +// destructor +// --------------------------------------------------------- +// +CSrcsSession::~CSrcsSession() + { + FLOG(_L("[SRCS]\tserver\tCSrcsSession closed.")); + if ( iMessageArray ) + { + // Cleanup the array + iMessageArray->ResetAndDestroy(); + } + delete iMessageArray; + if(iServer) + { + iServer->DecSessionCount(); + } + } +// --------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------- +// +CSrcsSession* CSrcsSession::NewL(CObexSM* aServer) + { + return new(ELeave) CSrcsSession(aServer); + } + +// --------------------------------------------------------- +// Server +// Return a reference to CSrcs +// --------------------------------------------------------- +CObexSM& CSrcsSession::Server() + { + return *iServer; + } + +// --------------------------------------------------------- +// CreateL +// 2nd phase construct for sessions +// - called by the CServer framework +// --------------------------------------------------------- +void CSrcsSession::CreateL() + { + // Add session to server first. + // If anything leaves, it will be removed by the destructor + ConstructL(); + } + +// --------------------------------------------------------- +// ConstructL +// 2nd phase construct for sessions +// - called by the CServer framework +// +// --------------------------------------------------------- +void CSrcsSession::ConstructL() + { + iMessageArray = new(ELeave) CArrayPtrFlat(KMessageArrayGranularity); + } + +// --------------------------------------------------------- +// HandleError +// Handle an error from ServiceL() +// A bad descriptor error implies a badly programmed client, so panic it; +// otherwise report the error to the client +// +// --------------------------------------------------------- +void CSrcsSession::HandleError(TInt aError, const RMessage2& aMessage) + { + FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession::HandleError(): %d"), aError)); + if (aError==KErrBadDescriptor) + { + PanicClient( aMessage, ESrcsBadDescriptor); + } + else + { + CompleteMessage( aMessage, aError); + } + } + + +// --------------------------------------------------------- +// ServiceL +// Calls DispatchMessage under trap harness +// +// --------------------------------------------------------- +void CSrcsSession::ServiceL(const RMessage2& aMessage) + { + // First make our own message from RMessage2 + // TRAP because message needs to be completed + // in case of Leave. + TRAPD( err, CreateSrcsMessageL( aMessage )); + if ( err ) + { + FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession: ServiceL. Error %d when creating message."), err)); + aMessage.Complete( err ); + } + else + { + err = KErrNone; + TRAP( err ,DispatchMessageL( aMessage )); + + // If we have an error, try to handle it with handle-error. + if ( err ) + { + HandleError( err, aMessage ); + } + } + } + +// --------------------------------------------------------- +// CreateSrcsMessageL +// Creates a CSrcsMessage and appends it to iMessageArray. +// --------------------------------------------------------- +// +void CSrcsSession::CreateSrcsMessageL(const RMessage2& aMessage) + { + __ASSERT_DEBUG(iMessageArray!=NULL, PanicServer(ESrcsClassMemberVariableIsNull)); + CSrcsMessage* message = CSrcsMessage::NewL(aMessage); + CleanupStack::PushL( message ); + iMessageArray->AppendL( message ); + CleanupStack::Pop(); + FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession: MessageArray count: %d"), iMessageArray->Count())); + } + +// --------------------------------------------------------- +// CompleteMessage +// Finds a message based on aMessage and completes it. +// --------------------------------------------------------- +// +void CSrcsSession::CompleteMessage(const RMessage2& aMessage, TInt aReason) + { + FLOG(_L("[SRCS]\tserver\tCSrcsSession: CompleteMessage.")); + CSrcsMessage* message = FindMessage(aMessage); + __ASSERT_DEBUG(message!=NULL, PanicServer(ESrcsBadMessage)); + message->Complete(aReason); + DeleteMessage( message ); + } + +// --------------------------------------------------------- +// CompleteMessage +// Completes given message. +// --------------------------------------------------------- +// +void CSrcsSession::CompleteMessage(CSrcsMessage* aMessage, TInt aReason) + { + __ASSERT_DEBUG(aMessage!=NULL, PanicServer(ESrcsBadMessage)); + FLOG(_L("[SRCS]\tserver\tCSrcsSession: CompleteMessage.")); + aMessage->Complete(aReason); + DeleteMessage(aMessage); + } + +// --------------------------------------------------------- +// CompletePendingMessages +// Completes any messages pending in the CBTManMessage array. +// --------------------------------------------------------- +void CSrcsSession::CompletePendingMessages() + { + __ASSERT_DEBUG(iMessageArray!=NULL, PanicServer(ESrcsClassMemberVariableIsNull)); + CSrcsMessage* messagePtr = NULL; + TInt count = iMessageArray->Count(); + FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession::CompletePendingMessages. Message count: %d"), count)); + + // Messages can be completed from array + // and deleted after that. + for ( TInt index = ( count-1 ) ; index >= 0 ; index-- ) + { + messagePtr = iMessageArray->At(index); + messagePtr->Complete(KErrDied); + iMessageArray->Delete(index); + delete messagePtr; + messagePtr = NULL; + } + } + +// --------------------------------------------------------- +// FindMessage +// Searches the array of CBTManMessages for the one dealing with aMessage. +// --------------------------------------------------------- +// +CSrcsMessage* CSrcsSession::FindMessage(const RMessage2& aMessage) + { + __ASSERT_DEBUG(iMessageArray!=NULL, PanicServer(ESrcsClassMemberVariableIsNull)); + FLOG(_L("[SRCS]\tserver\tCSrcsSession: FindMessage.")); + RMessagePtr2 messagePtr = aMessage; + CSrcsMessage* ptr = NULL; + + for ( TInt index = 0 ; index < iMessageArray->Count() ; index++ ) + { + ptr = iMessageArray->At( index ); + if( ptr->MessagePtr() == messagePtr ) + { + FLOG(_L("[SRCS]\tserver\tCSrcsSession: FindMessage. Message found")); + return ptr; + } + } + return NULL; + } + +// --------------------------------------------------------- +// FindMessage +// Searches the array for the 1st message with the function. +// --------------------------------------------------------- +// +CSrcsMessage* CSrcsSession::FindMessage(TInt aFunction) + { + __ASSERT_DEBUG(iMessageArray!=NULL, PanicServer(ESrcsClassMemberVariableIsNull)); + FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession: FindMessage aFunction %d"), aFunction)); + CSrcsMessage* ptr = NULL; + for ( TInt index = 0 ; index < iMessageArray->Count() ; index++ ) + { + ptr = iMessageArray->At( index ); + if ( ptr->MessagePtr().Function() == aFunction ) + { + FLOG(_L("[SRCS]\tserver\tCSrcsSession: FindMessage. Message found")); + return ptr; + } + } + FLOG(_L("[SRCS]\tserver\tCSrcsSession: FindMessage. Message not found")); + return NULL; + } + +// --------------------------------------------------------- +// DeleteMessage +// Find the CSrcsMessage in the message array and delete it. +// --------------------------------------------------------- +// +void CSrcsSession::DeleteMessage(CSrcsMessage* aMessage) + { + __ASSERT_DEBUG(iMessageArray!=NULL, PanicServer(ESrcsClassMemberVariableIsNull)); + FLOG(_L("[SRCS]\tserver\tCSrcsSession: DeleteMessage. ")); + CSrcsMessage* ptr = NULL; + TInt count = iMessageArray->Count(); + for ( TInt index = ( count-1 ) ; index >= 0 ; index-- ) + { + ptr = iMessageArray->At( index ); + if( ptr == aMessage ) + { + FLOG(_L("[SRCS]\tserver\tCSrcsSession: Message deleting. ")); + //Delete the message first before removing from the array since a helper associated + //with the message will try to find the message by parsing the array as part of the + //destruction the message. + delete ptr; + iMessageArray->Delete( index ); + ptr = NULL; + break; + } + } + FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession: MessageArray count: %d"), iMessageArray->Count())); + //compress the array if the count is less than the length - granularity AND if the count != 0 + if ( iMessageArray->Count() ) + { + if (iMessageArray->Length() - iMessageArray->Count() >= KMessageArrayGranularity) + iMessageArray->Compress(); + } + } + + +// --------------------------------------------------------- +// DispatchMessageL +// service a client request; test the opcode and then do +// appropriate servicing +// --------------------------------------------------------- +// +void CSrcsSession::DispatchMessageL(const RMessage2 &aMessage) + { + FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession: DispatchMessageL function %d"), aMessage.Function())); + iCanceling=EFalse; + switch (aMessage.Function()) + { + // Turn BT services ON (with service handler). + case ESrcsBTServicesON: + { + if ( BluetoothFeatures::EnterpriseEnablementL() != BluetoothFeatures::EEnabled ) + { + CompleteMessage(aMessage, KErrNotSupported); + } + else + { + ManageServices(ESrcsTransportBT, ETrue, aMessage); + } + break; + } + // Turn BT services OFF. + case ESrcsBTServicesOFF: + { + ManageServices(ESrcsTransportBT, EFalse, aMessage); + break; + } + + // Turn IrDA services ON (with service handler). + case ESrcsIrDAServicesON: + { + ManageServices(ESrcsTransportIrDA, ETrue, aMessage); + break; + } + // Turn IrDA services OFF. + case ESrcsIrDAServicesOFF: + { + ManageServices(ESrcsTransportIrDA, EFalse, aMessage); + break; + } + + case ESrcsStartUSB: + { + ManageServices(ESrcsTransportUSB, ETrue, aMessage); + break; + } + case ESrcsStopUSB: + { + ManageServices(ESrcsTransportUSB, EFalse, aMessage); + break; + } + case ESrcsCancelRequest: + { + FLOG(_L("[SRCS]\tserver\tCSrcsSession: DispatchMessageL: ESrcsCancelRequest")); + CancelingRequest(aMessage); + break; + } + default: + { + PanicClient( aMessage, ESrcsBadRequest); + break; + } + } + } + +// --------------------------------------------------------- +// ManageServicesL +// OpCode function; Manages Services. +// --------------------------------------------------------- +// +void CSrcsSession::ManageServices(TSrcsTransport aTransport, TBool aState, + const RMessage2& aMessage) + { + FLOG(_L("[SRCS]\tserver\tCSrcsSession: ManageServicesL")); + TInt retVal = Server().ManageServices(aTransport, aState, this, aMessage); + FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession: ManageServicesL return %d"), retVal)); + } + +// --------------------------------------------------------- +// CancelingRequest +// Canceling the ongoing request. +// --------------------------------------------------------- +// +void CSrcsSession::CancelingRequest(const RMessage2& aMessage) + { + FLOG(_L("[SRCS]\tserver\tCSrcsSession: CancelingRequest")); + iCanceling=ETrue; + if (iMessageArray->Count() == 1) + { + FLOG(_L("[SRCS]\tserver\tCSrcsSession: CancelingRequest completing")); + CompleteMessage(aMessage, KErrGeneral); + } + else + { + //The cancel handling continues, when another request completes. + } + } + +// --------------------------------------------------------- +// RequestCompleted +// --------------------------------------------------------- +// +void CSrcsSession::RequestCompleted(const RMessage2 &aMessage, TInt aError) + { + FLOG(_L("[SRCS]\tserver\tCSrcsSession: RequestCompleted")); + TBool postponeCompletion = EFalse; + if ( !iCanceling ) + { + FLOG(_L("[SRCS]\tserver\tCSrcsSession: RequestCompleted completing")); + CompleteMessage( aMessage, aError ); + } + else + { + CompleteCanceling(aMessage, aError, postponeCompletion); + } + if ( !postponeCompletion && iMessageArray->Count() > 0 ) + { + FLOG(_L("[SRCS]\tserver\tCSrcsSession: RequestCompleted dispatching")); + CSrcsMessage* messagePtr = NULL; + messagePtr=iMessageArray->At( 0 ); + RMessage2 message=messagePtr->MessagePtr(); + TRAP_IGNORE( DispatchMessageL( message ) ); + } + FLOG(_L("[SRCS]\tserver\tCSrcsSession: RequestCompleted exit")); + } + +// --------------------------------------------------------- +// CompleteCanceling +// Only USB service cancel is handled, since Locod Service +// Plugin API does not allow cancel for BT or IrDA. +// --------------------------------------------------------- +// +void CSrcsSession::CompleteCanceling(const RMessage2& aMessage, TInt aError, + TBool& aPostponeCompletion) + { + FLOG(_L("[SRCS]\tserver\tCSrcsSession: CompleteCanceling")); + TBool cancelMsgFound = EFalse; + CSrcsMessage* messagePtr = NULL; + FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession: CompleteCanceling function %d"), + aMessage.Function())); + switch ( aMessage.Function() ) + { + case ESrcsStartUSB: + messagePtr = FindMessage(ESrcsCancelRequest); + if ( messagePtr ) + { + FLOG(_L("[SRCS]\tserver\tCSrcsSession: CompleteCanceling ESrcsStartUSB found cancel req")); + RMessage2 message=messagePtr->MessagePtr(); + ManageServices(ESrcsTransportUSB, EFalse, message); + aPostponeCompletion = ETrue; + cancelMsgFound = ETrue; + } + break; + case ESrcsStopUSB: + messagePtr = FindMessage(ESrcsCancelRequest); + if ( messagePtr ) + { + CompleteMessage(aMessage, KErrCancel); + CompleteMessage(messagePtr, aError); + cancelMsgFound = ETrue; + } + break; + case ESrcsCancelRequest: + //either start or stop USB + messagePtr = FindMessage(ESrcsStartUSB); + if ( !messagePtr ) + { + messagePtr = FindMessage(ESrcsStopUSB); + } + if ( messagePtr ) + { + CompleteMessage(messagePtr, KErrCancel); + CompleteMessage(aMessage, aError); + cancelMsgFound = ETrue; + } + break; + default: + FLOG(_L("[SRCS]\tserver\tCSrcsSession: CompleteCanceling ESrcsCancelRequest unhandled msg")); + break; + } + if ( !cancelMsgFound ) + { + FLOG(_L("[SRCS]\tserver\tCSrcsSession: CompleteCanceling no message")); + CompleteMessage(aMessage, KErrGeneral); + } + FLOG(_L("[SRCS]\tserver\tCSrcsSession: CompleteCanceling exit")); + } +// End of File