diff -r 000000000000 -r f5a58ecadc66 upnp/upnpstack/serviceframework/src/upnpserviceimplementation.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/upnp/upnpstack/serviceframework/src/upnpserviceimplementation.cpp Tue Feb 02 01:12:20 2010 +0200 @@ -0,0 +1,517 @@ +/** @file +* Copyright (c) 2005-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: CUpnpServiceImplementation +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include +#include "upnpserviceimplementation.h" +#include "upnphttpmessage.h" +#include "upnpsoapmessage.h" +#include "upnpsoapmessagefactory.h" +#include "upnpgenamessage.h" +#include "upnpgenamessagefactory.h" +#include "upnpstring.h" +#include "upnpcommonupnplits.h" +#include "upnphttpmessagefactory.h" +#include "upnpdevice.h" +#include "upnpdeviceimplementationbase.h" +#include "upnpcommonstructs.h" +#include "upnplist.h" +#include "upnpfileutils.h" +#include "upnpdispatcher.h" +#include "upnpcontenthandlerscontroller.h" +#include "upnpeventcontroller.h" +#include "upnpsoapparser.h" + +#define KLogFile _L("UPnPStack.txt") +#include "upnpcustomlog.h" + +// ----------------------------------------------------------------------------- +// CUpnpService::SetDispatcher +// ----------------------------------------------------------------------------- +// +EXPORT_C void CUpnpServiceImplementation::SetDispatcher( CUpnpDispatcher* aDispatcher ) + { + if(iDispatcher) + { + iDispatcher->RemoveCustomer(*this, EFalse); + } + + iDispatcher = aDispatcher; + } + +// ----------------------------------------------------------------------------- +// CUpnpService::SendL +// ----------------------------------------------------------------------------- +// +EXPORT_C void CUpnpServiceImplementation::SendL( CUpnpHttpMessage *aMessage ) + { + if ( iDispatcher ) + { + iDispatcher->SendMessageL( aMessage, *this ); + } + } + +// ----------------------------------------------------------------------------- +// CUpnpService::Path +// ----------------------------------------------------------------------------- +// +EXPORT_C const TDesC8& CUpnpServiceImplementation::Path() + { + return *iPath; + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::CUpnpServiceImplementation +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +EXPORT_C CUpnpServiceImplementation::CUpnpServiceImplementation( CUpnpDevice& aDevice ) +: CUpnpService(aDevice) + { + } + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::~CUpnpServiceImplementation +// Destructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CUpnpServiceImplementation::~CUpnpServiceImplementation() + { + DeviceImpl().DetachService( this ); + iEventedVariables.Reset(); + delete iEventController; + delete iSaxController; + delete iSoapParser; + } + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::BaseConstructL +// ----------------------------------------------------------------------------- +// +EXPORT_C void CUpnpServiceImplementation::BaseConstructL( const TDesC& aFileName, + const TDesC8& aServiceType ) + { + //subscriber library initialization + LOGS("CUpnpServiceImplementation::BaseConstructL"); + + HBufC8* descr = UpnpFileUtil::ReadFileL( aFileName ); + CleanupStack::PushL(descr); + // File ready + + this->ConstructL( *descr, aServiceType ); + + CleanupStack::PopAndDestroy(descr); + + iEventController = CUpnpEventController::NewL( *this ); + + // from device + DeviceImpl().AttachServiceL( this ); + iComplete = ETrue; + iDispatcher->AddCustomerL( *this, EFalse ); + + iSaxController = CUpnpContentHandlersController::NewL(); + iSoapParser = new (ELeave) TUpnpSoapParser( *iSaxController ); + } + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::MessageReceivedLD +// ----------------------------------------------------------------------------- +// +EXPORT_C void CUpnpServiceImplementation::MessageReceivedLD( CUpnpHttpMessage* aMessage ) + { + LOGS("CUpnpServiceImplementation::MessageReceivedL(CUpnpHttpMessage*)"); + + if ( !aMessage ) + { + return; + } + + CleanupStack::PushL( aMessage ); + if ( aMessage->IsSoap() ) + { + // checking content type of action. Checking that content type exists. + TPtrC8 tempHeaderValue = aMessage->GetHeaderValue( UpnpGENA::KContentType() ); + TPtrC8 headerValue; + TInt posOfSemicolon = tempHeaderValue.Find( UpnpString::KSemiColon() ); + + // checking if content type contains semicolon + if ( posOfSemicolon != KErrNotFound ) + { + tempHeaderValue.Set( tempHeaderValue.Left( posOfSemicolon ) ); + TPtrC8 trimmed( UpnpString::Trim( tempHeaderValue, EFalse ) ); + headerValue.Set( trimmed ); + } + else + { + headerValue.Set( tempHeaderValue ); + } + + if ( headerValue.CompareC( UpnpGENA::KDefaultContentType ) != 0 ) + { + // content type of action is not text/xml. Invalid action. + CUpnpHttpMessage* messageOut + = RUpnpHttpMessageFactory::HttpResponseErrorL(aMessage, + EHttpUnsupportedMediaType + ); + CleanupStack::PushL( messageOut ); + SendL( messageOut ); + CleanupStack::PopAndDestroy( messageOut ); + CleanupStack::PopAndDestroy( aMessage ); + return; + } + + TRAPD( err, HandleActionL( reinterpret_cast( aMessage ) ) ); + if ( err ) + { + SendL( reinterpret_cast( aMessage ), + MapGenericErrorToUpnp( err ) ); + } + } + else if ( aMessage->IsGena() ) + { + TRAPD( err, HandleActionL( reinterpret_cast( aMessage ) ) ); + if ( err ) + { + // send proper errormessage + CUpnpHttpMessage* messageOut + = RUpnpHttpMessageFactory::UpnpResponseErrorL(aMessage, + EActionFailed + ); + CleanupStack::PushL( messageOut ); + SendL( messageOut ); + CleanupStack::PopAndDestroy( messageOut ); + } + } + else + { + //should never happen + LOGS1( "CUpnpServiceImplementation::MessageReceivedLD msg type %d", aMessage->Type() ); + ASSERT( EFalse ); + } + CleanupStack::PopAndDestroy( aMessage ); + } + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::MapGenericErrorToUpnp +// ----------------------------------------------------------------------------- +// +TUpnpErrorCode CUpnpServiceImplementation::MapGenericErrorToUpnp( TInt aError ) + { + if ( aError == KErrArgument ) + { + return EInvalidArgs; + } + else + { + return EActionFailed; + } + } + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::HandleActionL +// ----------------------------------------------------------------------------- +// +void CUpnpServiceImplementation::HandleActionL(CUpnpGenaMessage* aMessage) + { + LOGS("CUpnpServiceImplementation::HandleActionL(CUpnpGenaMessage*)"); + + if ( !aMessage ) + { + return; + } + + TPtrC8 method = aMessage->Method(); + + if (method.Compare(UpnpGENA::KGenaSubscribe) == 0) + { + // Subscription or renewing: + iEventController->SubscribeL( aMessage ); + } + else if (method.Compare(UpnpGENA::KGenaUnSubscribe) == 0) + { + // UnSubscription: + iEventController->UnSubscribeL( aMessage ); + } + } + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::HandleActionL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CUpnpServiceImplementation::HandleActionL( CUpnpSoapMessage* aMessage ) + { + LOGS("CUpnpServiceImplementation::HandleActionL(CUpnpSoapMessage*)"); + if ( !aMessage ) + { + return; + } + + // parse SOAP to CUpnpAction + CUpnpAction* action = CreateActionLC( aMessage->ActionName() ); + + if ( !action ) + { + // send errormessage + SendL( aMessage, EInvalidAction ); + } + else + { + iSoapParser->UpdateActionWithRequestL( aMessage, action ); + TInt actionError( action->Error() ); + if ( ( EUpnpOk == actionError ) || ( EHttp200Ok == actionError ) ) + { + CleanupStack::Pop( action ); + // a valid action received + ActionReceivedLD( action ); + } + else + { + TUpnpErrorCode upnpError; + // error + if ( actionError < 0 ) //is generic symbian error + + { + upnpError = MapGenericErrorToUpnp( actionError ); + } + else + { + upnpError = (TUpnpErrorCode) actionError; + } + SendL( aMessage, upnpError ); + CleanupStack::PopAndDestroy( action ); + } + } + } + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::SendL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C void CUpnpServiceImplementation::SendL( CUpnpAction* aAction, + TUpnpErrorCode aError) + { + LOGS1("CUpnpServiceImplementation::SendL(CUpnpAction*, TUpnpErrorCode: %d)", aError); + + CUpnpHttpMessage* msg( NULL ); + if ( EHttpOk == aError ) + { + msg = reinterpret_cast + (RUpnpSoapMessageFactory::SoapResponseL( aAction )); + } + else + { + LOGS1("Error: %i", aError); + msg = reinterpret_cast + (RUpnpSoapMessageFactory::SoapResponseL( aAction, aError )); + } + CleanupStack::PushL( msg ); + SendL( msg ); + CleanupStack::PopAndDestroy( msg ); + } + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::SendL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C void CUpnpServiceImplementation::SendL(CUpnpSoapMessage* aMessage, + TUpnpErrorCode aError) + { + LOGS1("CUpnpServiceImplementation::SendL(CUpnpSoapMessage*, TUpnpErrorCode: %d)", aError); + + CUpnpHttpMessage* msg = reinterpret_cast( + RUpnpSoapMessageFactory::SoapResponseL(aMessage, aError)); + CleanupStack::PushL(msg); + SendL(msg); + CleanupStack::PopAndDestroy(msg); + } + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::SetStateVariableL +// ----------------------------------------------------------------------------- +// +EXPORT_C void CUpnpServiceImplementation::SetStateVariableL( const TDesC8& aName, + const TDesC8& aValue, + TBool aIsModerated ) + { + LOGS("CUpnpServiceImplementation::SetStateVariableL"); + TInt totalDesLength(0); + totalDesLength = KGenaXml().Length() + KGenaPropertysetStart().Length()+ + KGenaPropertysetEnd().Length(); + for ( TInt i(0);iEventable().CompareF(KYes) == 0 ) + { + totalDesLength+=KGenaPropertyStart().Length(); + totalDesLength+=iStateVariables[i]->Name().Length(); + totalDesLength+=KCloseBracket().Length(); + if ( aName.Compare( iStateVariables[i]->Name() ) == 0 ) + { + totalDesLength+=aValue.Length(); + } + else + { + totalDesLength+=iStateVariables[i]->Value().Length(); + } + totalDesLength+=KOpenBracket().Length(); + totalDesLength+=( UpnpString::KSlash )().Length(); + totalDesLength+=iStateVariables[i]->Name().Length(); + totalDesLength+=KGenaPropertyEnd().Length(); + } + } + if (totalDesLengthSetValueL( aValue, aIsModerated ); + } + else + { + iEventController->SendModeratedNotification(); + } + } + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::StateVariableValue +// ----------------------------------------------------------------------------- +// +EXPORT_C const TPtrC8 CUpnpServiceImplementation::StateVariableValue( + const TDesC8& aVariableName ) + { + CUpnpStateVariable* variable = StateVariable(aVariableName); + if (variable) + { + return variable->Value(); + } + return KNullDesC8(); + } + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::StateVariable +// ----------------------------------------------------------------------------- +// +EXPORT_C CUpnpStateVariable* CUpnpServiceImplementation::StateVariable( + const TDesC8& aVariableName ) + { + CUpnpStateVariable* variable = NULL; + variable = CUpnpService::StateVariable(aVariableName); + if (variable) + { + variable->SetParentImplementation(*this); + } + return variable; + } + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::AddEventVariable +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C void CUpnpServiceImplementation::AddEventVariable +(const CUpnpStateVariable& aVariable, + TBool aIsModerated ) + { + LOGS("CUpnpServiceImplementation::AddEventVariable"); + + if (iEventedVariables.Find(&aVariable) == KErrNotFound) + { + iEventedVariables.Append(&aVariable); + } + if (aIsModerated) + { + iEventController->SendModeratedNotification(); + } + else + { + iEventController->SendNonModeratedNotification(); + } + + } + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::SetVariableMaxEventRate +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C void CUpnpServiceImplementation::SetVariableMaxEventRate +(const TDesC8& aVariable, TInt aMaxRate) + + { + LOGS("CUpnpServiceImplementation::SetVariableMaxEventRate"); + + for(TInt i = 0; i < iEventedVariables.Count(); i++) + { + if(iEventedVariables[i]->Name().Compare(aVariable)==0) + { + iEventedVariables[i]->SetMaxEventRate(aMaxRate, KMaxEventRate); + } + } + + } + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::StateVariableEvented +// ----------------------------------------------------------------------------- +// +EXPORT_C void CUpnpServiceImplementation::StateVariableEvented( + const TDesC8& /*aVariableName*/) + { + } + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::SubcribersAmount +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CUpnpServiceImplementation::SubcribersAmount() + { + return iEventController->SubscribersAmount(); + } + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::DeviceImpl +// ----------------------------------------------------------------------------- +// +CUpnpDeviceImplementationBase& CUpnpServiceImplementation::DeviceImpl() + { + return (CUpnpDeviceImplementationBase&) Device(); + } + +// ----------------------------------------------------------------------------- +// CUpnpServiceImplementation::EventedStateVariables +// ----------------------------------------------------------------------------- +// +EXPORT_C RPointerArray& +CUpnpServiceImplementation::EventedStateVariables() + { + return iEventedVariables; + } + +// End of File