--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/servicediscoveryandcontrol/pnp/test/upnp/Client/upnpplugin/src/cupnpsearch.cpp Tue Feb 02 01:12:20 2010 +0200
@@ -0,0 +1,293 @@
+// Copyright (c) 2008-2009 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:
+//
+
+#include "cupnpsearch.h"
+
+CUPnPSearch::CUPnPSearch( RSubConnection& aSubConnection )
+ :iSubConnection( aSubConnection )
+ {
+ }
+
+CUPnPSearch* CUPnPSearch::NewL(RSubConnection& aSubConnection)
+ {
+ CUPnPSearch* search = new (ELeave) CUPnPSearch( aSubConnection );
+ CleanupStack::PushL( search );
+ search->ConstructL();
+ CleanupStack::Pop( search );
+ return search;
+ }
+
+void CUPnPSearch::ConstructL()
+ {
+ // Create a delta timer with the given priority
+ iDeltaTimer=CDeltaTimer::NewL(EPriorityLow);
+ }
+
+CUPnPSearch::~CUPnPSearch()
+ {
+ iDeltaTimer->Cancel();
+ delete iDeltaTimer;
+ iTimerMappedArray.ResetAndDestroy();
+ iCallbackArray.ResetAndDestroy();
+ iMappedUri=NULL;
+ }
+
+/* Used to send a discover request to the network
+ @param aServiceInfo Bundle of uri's which have to be searched for
+ */
+void CUPnPSearch::SubmitRequestL(const RPnPParameterBundle& aServiceInfo)
+ {
+ const TInt KMaxMXValue = 120;
+ _LIT8(KSsdpAll,"ssdp:all");
+ iObserver = aServiceInfo.PnPObserver();
+
+ RParameterFamily family = const_cast<RPnPParameterBundle&>(aServiceInfo).FindFamily( EUPnPDiscoverRequestParamSet );
+ // Iterate through all the param sets in the passed bundle
+
+ CUPnPDiscoverRequestParamSet* paramSet = NULL;
+ TUint count = family.CountParameterSets ( RParameterFamily::ERequested ) ;
+
+ for ( TInt paramIndex = count - 1; paramIndex >= 0; paramIndex-- )
+ {
+ paramSet = static_cast<CUPnPDiscoverRequestParamSet*> ( family.GetParameterSetAtIndex ( paramIndex, RParameterFamily::ERequested ) );
+
+ //Extract the MX value and the uri
+ TInt delayResp=paramSet->ResponseTime();
+ const TDesC8& uri = paramSet->Uri();
+ __ASSERT_DEBUG( uri != KNullDesC8, User::Panic( KUPnPInvalidUserInput, KUPnPErrInvalidInput ) );
+ __ASSERT_DEBUG( delayResp>=0, User::Panic( KUPnPInvalidUserInput, KUPnPErrInvalidInput ) );
+ if ( delayResp > KMaxMXValue )
+ {
+ paramSet->SetResponseTime(KMaxMXValue);
+ delayResp = KMaxMXValue;
+ }
+ /* If one of the uris being discovered is ssdp:all then no other uri
+ needs to be discovered and hence no more traversal through the param
+ bundle is required */
+ if ( paramSet->Uri().CompareF(KSsdpAll) == NULL)
+ {
+ CreateTimerEntryL(uri);
+ iTimerMappedArray.ResetAndDestroy();
+ iMappedUri = CTimerMappedUri::NewL(uri,iEntry,delayResp);
+ iTimerMappedArray.AppendL(iMappedUri);
+ if ( family.CountParameterSets(RParameterFamily::ERequested) > 1 )
+ {
+ for ( TInt i = family.CountParameterSets(RParameterFamily::ERequested)-1; i >= 0; i-- )
+ {
+ if ( i != paramIndex )
+ reinterpret_cast<RUPnPParameterFamily*>(&family)->DeleteParamSetL ( i );
+
+ }
+ }
+
+ break;
+ }
+ // Check for validity of the uri
+ User::LeaveIfError(CUPnPUtils::GenericUriValidity( uri, CUPnPUtils::EAny ));
+
+
+ // If uri has already been indexed into iTimerMappedArray that means its a
+ // duplicate entry and the index of this param set is appended to
+ // tempDuplicateArray
+ TInt err = KErrNone;
+ for (TInt i=0;i<iTimerMappedArray.Count();i++)
+ {
+ if(iTimerMappedArray[i]->UriExists(uri))
+ {
+ reinterpret_cast<RUPnPParameterFamily*>(&family)->DeleteParamSetL(paramIndex);
+ err = KErrAlreadyExists;
+ break;
+ }
+ }
+ if (err == KErrAlreadyExists)
+ continue;
+
+ // CreateTimerEntry sets iEntry to the new timer entry
+ CreateTimerEntryL(uri);
+ iMappedUri = CTimerMappedUri::NewL(uri,iEntry,delayResp);
+ iTimerMappedArray.AppendL(iMappedUri);
+
+ }
+
+ /* Transfer ownvership of all CTimerMappedUri objects from tempMappedArray to
+ iTimerMappedArray
+ */
+ for(TInt i=0;i<iTimerMappedArray.Count();i++)
+ {
+ // queue up in deltatimer
+ TInt time = AdjustedDelay(iTimerMappedArray[i]->Delay());
+ TTimeIntervalMicroSeconds32 delay(time);
+ iDeltaTimer->Queue(delay,iTimerMappedArray[i]->GetTimerEntry());
+ }
+ /* if SetParameters fails should it be communicated to client
+ * so that he may take corrective measures */
+ User::LeaveIfError(iSubConnection.SetParameters(aServiceInfo));
+ SetDiscoverProgress(ETrue);
+ }
+
+/* Static method which is called on timer expiry and which removes the uri entry
+ * from the array.
+ */
+TInt CUPnPSearch::StopSearch(TAny* aPtr)
+ {
+ CCallbackArgument* pointerData= static_cast<CCallbackArgument*> (aPtr);
+ CUPnPSearch* thisObject= static_cast < CUPnPSearch*> (pointerData->GetThisPointer());
+ RPointerArray<CTimerMappedUri>& rArray=thisObject->GetTimerArray();
+ RPointerArray<CCallbackArgument>& argArray = thisObject->GetArgumentArray();
+ const TDesC8& uri = pointerData->GetUri();
+ TInt index;
+ for(index=0;index<rArray.Count();index++)
+ {
+ if(rArray[index]->UriExists(uri))
+ {
+ // Removes the uri entry from the array
+ CTimerMappedUri* timerUri = rArray[index];
+ rArray.Remove(index);
+ delete timerUri;
+ break;
+ }
+ }
+ for( index=0;index<argArray.Count();index++)
+ {
+ if(uri.CompareF(argArray[index]->GetUri()) == NULL)
+ {
+ argArray.Remove(index);
+ break;
+ }
+ }
+ // Requests the subconnection to cancel ongoing search
+ TRAPD( error , thisObject->CancelSearchL( uri ));
+
+ // Reset Discover In progress
+ if(rArray.Count() <= 0)
+ thisObject->SetDiscoverProgress(EFalse);
+
+ // Notifies the client that timer has expired
+ TRAP(error,thisObject->MakeBundleAndNotifyL(pointerData));
+ delete pointerData;
+ return error;
+ }
+
+/* Used to notify results back to the client application */
+void CUPnPSearch::NotifyResultsL(RPnPParameterBundleBase& aBundle)
+ {
+ RParameterFamily family = aBundle.FindFamily(EUPnPDiscoverResponseParamSet);
+ __ASSERT_DEBUG(!family.IsNull (), User::Panic(KUPnPInvalidFamily,KUPnPErrInvalidFamily));
+ __ASSERT_DEBUG(family.CountParameterSets(RParameterFamily::ERequested) > 0, User::Panic(KUPnPNoParamSet,KUPnPErrNoParamSet));
+ iObserver->OnPnPEventL(aBundle) ;
+ }
+
+/* Is used to notify the timeout expired result back to the control point */
+void CUPnPSearch::MakeBundleAndNotifyL(CCallbackArgument* aCallArgument)
+ {
+ RPnPParameterBundleBase pnpBundle ;
+ pnpBundle.Open();
+ CleanupClosePushL( pnpBundle );
+
+ // Create the family on the bundle
+ RParameterFamily family = pnpBundle.CreateFamilyL(EUPnPDiscoverResponseParamSet);
+ //Set the values in the parameter set
+ CUPnPDiscoverResponseParamSet* searchParamSet = CUPnPDiscoverResponseParamSet::NewL(family );
+
+ TUPnPEvent event;
+ const TDesC8& uri = aCallArgument->GetUri();
+ event.iStatus=TUPnPEvent::EDiscoveryTimeout;
+ event.iErrorCode = KErrTimedOut;
+ searchParamSet->SetUPnPEvent(event);
+ searchParamSet->SetUriL ( uri );
+ CleanupStack::Pop(&pnpBundle);
+ iObserver->OnPnPEventL( pnpBundle );
+ }
+
+/* Used to send a Cancel discover request to the network in case of timer expiry
+ Sent automatically by CUPnPSearch::StopSearch */
+void CUPnPSearch::CancelSearchL(const TDesC8& aUri)
+ {
+ RPnPParameterBundleBase rBundle;
+ rBundle.Open();
+ CleanupClosePushL( rBundle );
+ RParameterFamily family = rBundle.CreateFamilyL(EUPnPCancelDiscoverParamSet);
+
+ //Allocate the param set on the family
+ CUPnPCancelDiscoverParamSet* paramSet = CUPnPCancelDiscoverParamSet::NewL(family );
+
+ // Set the values in the parameter set
+ paramSet->SetUriL( aUri );
+ // Finally send cancel request to the subconnection
+ User::LeaveIfError( iSubConnection.SetParameters(rBundle ));
+ CleanupStack::PopAndDestroy( &rBundle );
+ }
+
+/* Used to send a Cancel discover request to the network. This is called on client
+ invocation
+ @param aServiceInfo Bundle containing list of uri's whose discovery has to be cancelled
+ */
+void CUPnPSearch::CancelSearchL( const RPnPParameterBundle& aServiceInfo )
+ {
+ RParameterFamily family = const_cast<RPnPParameterBundle&>(aServiceInfo).FindFamily(EUPnPCancelDiscoverParamSet);
+
+ /* The uris passed in the bundle are looked up in iTimerMappedUri.If they
+ exist, then its entry is removed from DeltaTimer and iTimerMappedUri as well
+ */
+ TInt err = 0;
+ // Iterate through all the param sets in the passed bundle
+
+ TUint count = family.CountParameterSets ( RParameterFamily::ERequested ) ;
+ CUPnPCancelDiscoverParamSet* paramSet = NULL;
+ for ( TInt paramIndex = count - 1; paramIndex >= 0; paramIndex-- )
+ {
+ paramSet = static_cast<CUPnPCancelDiscoverParamSet*> ( family.GetParameterSetAtIndex ( paramIndex, RParameterFamily::ERequested) );
+
+ //Extract the uri
+ const TDesC8& uri = paramSet->Uri();
+ __ASSERT_DEBUG( paramSet->Uri() != KNullDesC8, User::Panic( KUPnPInvalidUserInput, KUPnPErrInvalidInput ) );
+ // Removes the uri entry from the array if exists
+ err=KErrNotFound;
+ for(TInt i=0;i<iTimerMappedArray.Count();i++)
+ {
+ if(iTimerMappedArray[i]->UriExists(uri))
+ {
+ err = KErrNone;
+ CTimerMappedUri* timerUri = iTimerMappedArray[i];
+ iDeltaTimer->Remove(timerUri->GetTimerEntry());
+ iTimerMappedArray.Remove(i);
+ if(iTimerMappedArray.Count()<= 0)
+ SetDiscoverProgress(EFalse);
+ delete timerUri;
+ break;
+ }
+ }
+ if ( err != KErrNone )
+ {
+ reinterpret_cast<RUPnPParameterFamily*>(&family)->DeleteParamSetL ( paramIndex );
+ continue;
+ }
+ }
+ if ( family.CountParameterSets(RParameterFamily::ERequested)>= 1)
+ User::LeaveIfError(iSubConnection.SetParameters(aServiceInfo));
+ }
+
+/* CreateTimerEntry : creates the deltatimer entry and sets it to iEntry
+ @param aUri The uri whose timer entry has to be created
+ */
+void CUPnPSearch::CreateTimerEntryL(const TDesC8& aUri )
+ {
+ CCallbackArgument* callArgument =CCallbackArgument::NewL(this,aUri);
+ CleanupStack::PushL(callArgument);
+ iCallbackArray.AppendL(callArgument);
+ TCallBack callBack(StopSearch,callArgument);
+ iEntry = new (ELeave) TDeltaTimerEntry ( callBack );
+ CleanupStack::Pop();
+ }