--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/upnp/upnpstack/controlpointbase/src/upnpcpbcurrenthttpclient.cpp Tue Feb 02 01:12:20 2010 +0200
@@ -0,0 +1,503 @@
+/** @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: CUpnpCpbCurrentHttpClient
+ *
+*/
+
+#include <e32base.h>
+#include <e32cons.h>
+#include <e32std.h>
+#include <upnpsettings.h>
+#include <charconv.h>
+#include <utf.h>
+
+#include "upnpcpstackrequestor.h"
+#include "upnphttpmessage.h"
+#include "upnpsoapmessage.h"
+#include "upnpicon.h"
+#include "upnpdevice.h"
+#include "upnpstring.h"
+#include "upnphttpmessagefactory.h"
+#include "upnpsoapmessagefactory.h"
+#include "upnpgenamessagefactory.h"
+#include "upnpserviceinfo.h"
+#include "upnpcpbhttpmessagecontroller.h"
+#include "upnpcpbcurrenthttpclient.h"
+#include "upnpcontrolpoint.h"
+#include "upnpcommonupnplits.h"
+#include "upnpcpbdevicedescription.h"
+#include "upnpdevicedescriptionhttptransaction.h"
+#include "upnpservicedescriptionhttptransaction.h"
+#include "upnpsoapactionhttptransaction.h"
+#include "upnpservicesubscriptionhttptransaction.h"
+#include "upnpserviceunsubscriptionhttptransaction.h"
+#include "upnpcphttprequestorimpl.h"
+#include "upnpcpstackrequestorimpl.h"
+#include "upnpfilesender.h"
+
+#define KLogFile _L("UPnPControlPoint.txt")
+#include <upnpcustomlog.h>
+
+using namespace UpnpHTTP;
+
+static const TInt KMessageTimeout( 10000000 );
+static const TInt KActionTimeout( 35000000 );
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::CUpnpCurrentHttpClient
+// C++ default constructor
+// -----------------------------------------------------------------------------
+//
+CUpnpCpbCurrentHttpClient::CUpnpCpbCurrentHttpClient( CUpnpControlPoint& aControlPoint,
+ MUpnpCpHttpRequestor* aHttpRequestor, MUpnpCpStackRequestor* aStackRequestor )
+ : iControlPoint( aControlPoint ),
+ iHttpRequestor( aHttpRequestor ), iStackRequestor( aStackRequestor )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::~CUpnpCpbCurrentHttpClient
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CUpnpCpbCurrentHttpClient::~CUpnpCpbCurrentHttpClient()
+ {
+ if ( iStackRequestor )
+ {
+ iStackRequestor->RemoveCustomer( *this );
+ }
+ iPendingHttpMessages.ResetAndDestroy();
+ iPendingTransactions.ResetAndDestroy();
+ delete iUserAgent;
+ delete iHttpRequestorDefaultImpl;
+ delete iStackRequestorDefaultImpl;
+ delete iFileSender;
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::NewL
+//
+// -----------------------------------------------------------------------------
+//
+CUpnpCpbCurrentHttpClient* CUpnpCpbCurrentHttpClient::NewL(
+ CUpnpControlPoint& aControlPoint,
+ MUpnpCpHttpRequestor* aHttpRequestor, MUpnpCpStackRequestor* aStackRequestor)
+ {
+ LOG_FUNC_NAME;
+ CUpnpCpbCurrentHttpClient* self =
+ new (ELeave) CUpnpCpbCurrentHttpClient( aControlPoint, aHttpRequestor, aStackRequestor );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::ConstructL
+//
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::ConstructL()
+ {
+ iFileSender = CUpnpFileSender::NewL( iControlPoint );
+
+ if ( !iHttpRequestor )
+ {
+ iHttpRequestorDefaultImpl = CUpnpCpHttpRequestorImpl::NewL();
+ iHttpRequestor = iHttpRequestorDefaultImpl;
+ }
+ iHttpRequestor->InitialiseL( *this, CUpnpSettings::GetIapL() );
+
+ if ( !iStackRequestor )
+ {
+ iStackRequestorDefaultImpl = CUpnpCpStackRequestorImpl::NewL( iControlPoint );
+ iStackRequestor = iStackRequestorDefaultImpl;
+ }
+ iStackRequestor->AddCustomerL( *this );
+ ASSERT( iHttpRequestor && iStackRequestor ); //ensure correct initialisation
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::SendActionL
+//
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::SendActionL( CUpnpAction* aAction )
+ {
+ if( !aAction )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ CUpnpHttpMessage* msg = RUpnpSoapMessageFactory::SoapRequestL( aAction );
+ CleanupStack::PushL( msg );
+
+ // 7.2.32.1 UPnP action requests (sent by a control point) must include a
+ // DLNA-CP-version in a USER-AGENT HTTP header value.
+ if ( !iUserAgent )
+ {
+ HBufC8* userAgent = CUpnpSettings::GetUserAgentL();
+ CleanupStack::PushL( userAgent );
+
+ iUserAgent = HBufC8::NewL( userAgent->Length() );
+ iUserAgent->Des().Append( *userAgent );
+
+ CleanupStack::PopAndDestroy( userAgent );
+ }
+
+ msg->AddPairL( UpnpHTTP::KHdrUserAgent, *iUserAgent );
+
+ msg->SetTcpTimeout( KActionTimeout );
+
+ CleanupStack::Pop( msg );//ownership passed to Transaction and is safe
+ CUpnpHttpTransaction* soapTransaction =
+ CUpnpSoapActionHttpTransaction::NewLC( msg, aAction->SessionId(), iControlPoint );
+
+ iPendingTransactions.AppendL( soapTransaction );
+ CleanupStack::Pop( soapTransaction );
+ iHttpRequestor->SendL( *soapTransaction );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::SendSubscribeL
+//
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::SendSubscribeL( CUpnpServiceInfo* aServiceInfo )
+ {
+ const TDesC8& path = Path();
+
+ TInetAddr addr = iStackRequestor->HttpServerAddress();
+ HBufC8* longPath = aServiceInfo->ConstructSubscribtionPathLC( path , addr );
+ CUpnpGenaMessage* gena = aServiceInfo->CreateSubscriptionMessageL(
+ *longPath,
+ ESubscription );
+
+ gena->SetTcpTimeout( KMessageTimeout );
+ CUpnpServiceSubscriptionHttpTransaction* transaction =
+ CUpnpServiceSubscriptionHttpTransaction::NewLC( gena, iControlPoint );
+ iPendingTransactions.AppendL( transaction );
+ CleanupStack::Pop( transaction );
+ iHttpRequestor->SendL( *transaction );
+ CleanupStack::PopAndDestroy( longPath );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::SendUnsubscribeL
+//
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::SendUnsubscribeL( CUpnpServiceInfo* aServiceInfo )
+ {
+ if ( aServiceInfo->Sid() != KNullDesC8 )
+ {
+ CUpnpGenaMessage* gena = aServiceInfo->CreateSubscriptionMessageL( EUnSubscription );
+ gena->SetTcpTimeout( KMessageTimeout );
+ CUpnpServiceUnsubscriptionHttpTransaction* transaction =
+ CUpnpServiceUnsubscriptionHttpTransaction::NewLC( gena, iControlPoint) ;
+ iPendingTransactions.AppendL( transaction );
+ CleanupStack::Pop( transaction );
+ iHttpRequestor->SendL( *transaction );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::SendResubscribeL
+//
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::SendResubscribeL( CUpnpServiceInfo* aServiceInfo )
+ {
+ CUpnpGenaMessage* gena = aServiceInfo->CreateSubscriptionMessageL( EResubscription );
+ gena->SetTcpTimeout( KMessageTimeout );
+ CUpnpServiceSubscriptionHttpTransaction* transaction =
+ CUpnpServiceSubscriptionHttpTransaction::NewLC( gena, iControlPoint );
+ iPendingTransactions.AppendL( transaction );
+ CleanupStack::Pop( transaction );
+ iHttpRequestor->SendL( *transaction );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::GetServiceDescriptionL
+//
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpCpbCurrentHttpClient::GetServiceDescriptionL( CUpnpDevice* aDevice,
+ const TDesC8& aUrl )
+ {
+ CUpnpHttpMessage* result( NULL );
+ TPtrC8 urlBase( aDevice->UrlBase() );
+
+ if ( aUrl.Find( KHttp ) == 0 )
+ {
+ result = RUpnpHttpMessageFactory::HttpGetL( aUrl );
+ }
+ else
+ {
+ TInetAddr addr = aDevice->Address();
+ if ( urlBase.Length() > 0 )
+ {
+ HBufC8* url = aDevice->ConcatWithUrlBaseL( aUrl );
+ CleanupStack::PushL( url );
+
+ if ( url->Find( KHttp ) )
+ {
+ result = RUpnpHttpMessageFactory::HttpGetL( addr, *url,
+ KNullDesC8 );
+ }
+ else
+ {
+ result = RUpnpHttpMessageFactory::HttpGetL( *url );
+ }
+
+ CleanupStack::PopAndDestroy( url );
+ }
+ else
+ {
+ result = RUpnpHttpMessageFactory::HttpGetL( addr,
+ aDevice->DescriptionUrlPath(), aUrl );
+ }
+ }
+ result->SetTcpTimeout( KMessageTimeout );
+
+ CUpnpServiceDescriptionHttpTransaction* transaction =
+ CUpnpServiceDescriptionHttpTransaction::NewLC( result, iControlPoint );
+
+ iPendingTransactions.AppendL( transaction );
+ CleanupStack::Pop( transaction );
+ iHttpRequestor->SendL( *transaction );
+ return result->SessionId();
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::GetDeviceDescriptionL
+//
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpCpbCurrentHttpClient::GetDeviceDescriptionL( CUpnpDevice* aDevice )
+ {
+ TInetAddr addr = aDevice->DescriptionUrlAddressL();
+ addr.SetPort( aDevice->DescriptionUrlPort() );
+
+ CUpnpHttpMessage* message = RUpnpHttpMessageFactory::HttpGetL( addr,
+ aDevice->DescriptionUrlPath() );
+ message->SetTcpTimeout( KMessageTimeout );
+
+ CUpnpDeviceDescriptionHttpTransaction* transaction =
+ CUpnpDeviceDescriptionHttpTransaction::NewLC( message, iControlPoint );
+
+ iPendingTransactions.AppendL( transaction );
+ CleanupStack::Pop( transaction );
+ iHttpRequestor->SendL( *transaction );
+
+ return message->SessionId();
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::MessageReceivedLD
+//
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::MessageReceivedLD( CUpnpHttpMessage* aHttpMessage )
+ {
+ if ( !aHttpMessage )
+ {
+ User::Leave( KErrArgument );
+ }
+ // match arrived response to pending request
+
+ TIdentityRelation<CUpnpHttpMessage> matcher( CUpnpHttpMessage::SessionIdMatch );
+ TInt idx = iPendingHttpMessages.Find ( aHttpMessage, matcher );
+
+ CleanupStack::PushL( aHttpMessage );
+
+ if ( aHttpMessage->IsGena() )
+ {
+ CleanupStack::Pop( aHttpMessage );
+ iControlPoint.NotifyReceivedL( *aHttpMessage );
+ }
+ else
+ {
+ iControlPoint.MessageReceived( aHttpMessage );
+ iPendingHttpMessages.Compress();
+ CleanupStack::PopAndDestroy( aHttpMessage );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::Path
+//
+// -----------------------------------------------------------------------------
+//
+const TDesC8& CUpnpCpbCurrentHttpClient::Path()
+ {
+ return KPath();
+ }
+
+// ----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::StopIgnoringL
+//
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::StopIgnoringL( CUpnpDevice* aDevice )
+ {
+ iStackRequestor->StopIgnoringL( aDevice->Uuid() );
+ StopIgnoringEmbeddedL( aDevice );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::StopIgnoringEmbeddedL
+//
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::StopIgnoringEmbeddedL( CUpnpDevice* aRoot )
+ {
+ RPointerArray<CUpnpDevice> devicesAll;
+ aRoot->GetAllDevices( devicesAll );
+ CleanupClosePushL( devicesAll );
+ for ( TInt k = 0; k < devicesAll.Count(); k++ )
+ {
+ iStackRequestor->StopIgnoringL( devicesAll[k]->Uuid() );
+ }
+ CleanupStack::PopAndDestroy( &devicesAll );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::StopIgnoringUuidL
+// Send stop ignoring message to MH
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::StopIgnoringUuidL( const TDesC8& aUuids )
+ {
+ iStackRequestor->StopIgnoringL( aUuids );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::StartIPFilteringL
+//
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::StartIPFilteringL()
+ {
+ iStackRequestor->StartIPFilteringL();
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::StopIPFiltering
+//
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::StopIPFiltering()
+ {
+ iStackRequestor->StopIPFiltering();
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::SendL
+// Send response HTTP message
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::SendL( CUpnpHttpMessage* aHttpMessage )
+ {
+ const TInt KUnused(0);
+ iStackRequestor->SendMessageL( aHttpMessage, *this, KUnused );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::SendFileByPostL
+// Send HTTP message
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::SendFileByPostL( CUpnpHttpMessage* aHttpMessage )
+ {
+ if ( !aHttpMessage )
+ {
+ User::Leave( KErrArgument );
+ }
+ iFileSender->SendL( *aHttpMessage );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::SearchL
+// Sends a SSDP Search with 8-bit search string.
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::SearchL( const TDesC8& aSearchString )
+ {
+ iStackRequestor->SearchL( aSearchString );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::ClientResponseRecivedLD
+// Callback indicating that response was received within transaction.
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::ClientResponseRecivedLD(
+ CUpnpHttpTransaction& aCompletedTrasaction )
+ {
+ TInt idx( iPendingTransactions.Find( &aCompletedTrasaction ) );
+ //it should never happen that we received transaction that wasn't sent by us
+ ASSERT( idx >= 0 );
+ aCompletedTrasaction.ProcessResponseL();
+ iPendingTransactions.Remove( idx );
+ delete ( &aCompletedTrasaction );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::WlanLostOccurs
+//
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::WlanLostOccurs()
+ {
+ iStackRequestor->StopHttpServer();
+ TRAP_IGNORE( SetNullRequestorsL() );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::AddressChanged
+//
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::AddressChangedL()
+ {
+ iStackRequestor->StopHttpServer();
+ iStackRequestor->StartHttpServerL();
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpCpbCurrentHttpClient::SetNullRequestorsL
+//
+// -----------------------------------------------------------------------------
+//
+void CUpnpCpbCurrentHttpClient::SetNullRequestorsL()
+ {
+ CUpnpCpHttpRequestorImplBase* httpReq = new ( ELeave ) CUpnpCpHttpRequestorImplBase();
+ delete iHttpRequestorDefaultImpl;
+ iHttpRequestorDefaultImpl = NULL;
+ iHttpRequestorDefaultImpl = httpReq;
+ iHttpRequestor = iHttpRequestorDefaultImpl;
+
+ CUpnpCpStackRequestorImplBase* stackReq = new ( ELeave ) CUpnpCpStackRequestorImplBase();
+ delete iStackRequestorDefaultImpl;
+ iStackRequestorDefaultImpl = NULL;
+ iStackRequestorDefaultImpl = stackReq;
+ iStackRequestor = iStackRequestorDefaultImpl;
+ }
+
+// End of File
+