upnp/upnpstack/serviceframework/src/upnpdispatcherengine.cpp
changeset 0 f5a58ecadc66
child 9 5c72fd91570d
equal deleted inserted replaced
-1:000000000000 0:f5a58ecadc66
       
     1 /** @file
       
     2 * Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies  this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Message dispacher engine
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 
       
    21 #include "upnpdispatcherengine.h"
       
    22 #include "upnphttpmessagefactory.h"
       
    23 #include "upnphttpfileaccess.h"
       
    24 #include "upnpdispatcherrequest.h"
       
    25 #include "upnpdispatcherengineobserver.h"
       
    26 #include "upnpcustomlog.h"
       
    27 #include "upnphttpserversession.h"
       
    28 #include "upnphttpserverruntime.h"
       
    29 #include "upnpsettings.h"
       
    30 
       
    31 #ifdef _DEBUG
       
    32 #define KLogFile _L("UPnPStack.txt")
       
    33 #endif
       
    34 
       
    35 // CONSTANTS
       
    36 const TInt KPortBufferLength = 10;
       
    37 _LIT8(KMSearchConfig,"1,1,5,5,10");
       
    38 
       
    39 // ============================ MEMBER FUNCTIONS ===============================
       
    40 
       
    41 // -----------------------------------------------------------------------------
       
    42 // CUpnpDispatcherEngine::CUpnpDispatcherEngine
       
    43 // C++ default constructor can NOT contain any code, that
       
    44 // might leave.
       
    45 // -----------------------------------------------------------------------------
       
    46 //
       
    47 CUpnpDispatcherEngine::CUpnpDispatcherEngine(
       
    48                                       MDispatcherEngineObserver& aObserver )
       
    49     : CActive( EPriorityStandard ),
       
    50       iAddLocalPtr( NULL, 0 ),
       
    51       iObserver( aObserver ),
       
    52       iGetDevPtr( NULL, 0 ),
       
    53       iGetServPtr( NULL, 0 ),
       
    54       iRemoveUuidPtr( NULL, 0 ),
       
    55       iIsSessionOpen( EFalse )
       
    56     {
       
    57     CActiveScheduler::Add( this );
       
    58     iDeviceGetState = ENoOperation;
       
    59     iAddLocalBuffer = NULL;
       
    60     iRemoveUuid = NULL;
       
    61     }
       
    62 
       
    63 // -----------------------------------------------------------------------------
       
    64 // CUpnpDispatcherEngine::ConstructL
       
    65 // Symbian 2nd phase constructor can leave.
       
    66 // -----------------------------------------------------------------------------
       
    67 //
       
    68 void CUpnpDispatcherEngine::ConstructL()
       
    69     {
       
    70 #ifdef _DEBUG
       
    71     iReqsInStart = RThread().RequestCount();
       
    72     RThread().HandleCount( iProcessHandlesInStart, iThreadHandlesInStart );
       
    73 #endif // _DEBUG
       
    74 
       
    75     User::LeaveIfError( iSession.Connect() );
       
    76     iIsSessionOpen = ETrue;
       
    77     iSession.RequestStartSsdpL();
       
    78 
       
    79     iActiveRequest = NULL;
       
    80     iSearch = NULL;
       
    81 
       
    82     ConstructHttpL();
       
    83 
       
    84     iDeviceGetState = ENoOperation;
       
    85     }
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // CUpnpDispatcherEngine::ConstructHttpL
       
    89 // -----------------------------------------------------------------------------
       
    90 //
       
    91 void CUpnpDispatcherEngine::ConstructHttpL()
       
    92     {
       
    93     TInt iapId = CUpnpSettings::GetIapL();
       
    94     iHttpServerSession = CUpnpHttpServerSession::NewL( iapId, *this );    
       
    95     }
       
    96     
       
    97 // -----------------------------------------------------------------------------
       
    98 // CUpnpDispatcherEngine::NewL
       
    99 // Two-phased constructor.
       
   100 // -----------------------------------------------------------------------------
       
   101 //
       
   102 CUpnpDispatcherEngine* CUpnpDispatcherEngine::NewL(
       
   103         MDispatcherEngineObserver& aObserver )
       
   104     {
       
   105     CUpnpDispatcherEngine* self = NewLC( aObserver );
       
   106     CleanupStack::Pop( self );
       
   107     return self;
       
   108     }
       
   109 
       
   110 // -----------------------------------------------------------------------------
       
   111 // CUpnpDispatcherEngine::NewLC
       
   112 // Two-phased constructor.
       
   113 // -----------------------------------------------------------------------------
       
   114 //
       
   115 CUpnpDispatcherEngine* CUpnpDispatcherEngine::NewLC(
       
   116         MDispatcherEngineObserver& aObserver )
       
   117     {
       
   118     CUpnpDispatcherEngine* self =
       
   119         new ( ELeave ) CUpnpDispatcherEngine( aObserver );
       
   120     CleanupStack::PushL( self );
       
   121     self->ConstructL();
       
   122     return self;
       
   123     }
       
   124 
       
   125 // -----------------------------------------------------------------------------
       
   126 // CUpnpDispatcherEngine::~CUpnpDispatcherEngine
       
   127 // -----------------------------------------------------------------------------
       
   128 //
       
   129 CUpnpDispatcherEngine::~CUpnpDispatcherEngine()
       
   130     {
       
   131     // If active, calls DoCancel
       
   132     Cancel();
       
   133 
       
   134     delete iRemoveUuid;
       
   135     iRemoveUuid = NULL;
       
   136 
       
   137     delete iAddLocalBuffer;
       
   138     iAddLocalBuffer = NULL;
       
   139 
       
   140     delete iSearch;
       
   141     iSearch = NULL;
       
   142 
       
   143     delete iUuids;
       
   144     iUuids = NULL;
       
   145 
       
   146     delete [] iDevs;
       
   147     delete [] iServs;
       
   148     
       
   149     iSession.Close();
       
   150     iIsSessionOpen = EFalse;
       
   151     iCustomers.Reset();
       
   152 
       
   153     if ( iHttpServerSession )
       
   154         {
       
   155         iHttpServerSession->Stop();
       
   156         delete iHttpServerSession;
       
   157         }
       
   158 
       
   159     iPendingRequests.ResetAndDestroy();
       
   160 
       
   161     iNewDevices.ResetAndDestroy();
       
   162 
       
   163     RemoveHandledRequest();
       
   164 
       
   165     delete iMXString;
       
   166     }
       
   167 
       
   168 // -----------------------------------------------------------------------------
       
   169 // CUpnpDispatcherEngine::AddCustomer
       
   170 // -----------------------------------------------------------------------------
       
   171 //
       
   172 void CUpnpDispatcherEngine::AddCustomer( const MUpnpDispatcherCustomer& aCustomer )
       
   173     {
       
   174     // adds a new customer for CUpnpDispatcherEngine
       
   175     if ( iCustomers.Find( &aCustomer ) == KErrNotFound )
       
   176         {
       
   177         iCustomers.Append( &aCustomer );
       
   178         }
       
   179     }
       
   180 // -----------------------------------------------------------------------------
       
   181 // CUpnpDispatcherEngine::RemoveCustomer
       
   182 // -----------------------------------------------------------------------------
       
   183 //
       
   184 void CUpnpDispatcherEngine::RemoveCustomer( const MUpnpDispatcherCustomer& aCustomer )
       
   185     {
       
   186     TInt pos = iCustomers.Find( &aCustomer );
       
   187     if ( pos != KErrNotFound )
       
   188         {
       
   189         LOGS2("CUpnpDispatcherEngine::RemoveCustomer, removing customer 0x%x from position %d", &aCustomer, pos);
       
   190         iCustomers.Remove( pos );
       
   191         iCustomers.Compress();
       
   192         LOGS("CUpnpDispatcherEngine::RemoveCustomer done");
       
   193         }
       
   194     else
       
   195         LOGS1("CUpnpDispatcherEngine::RemoveCustomer, customer 0x%x not found", &aCustomer);
       
   196     }
       
   197 
       
   198 // -----------------------------------------------------------------------------
       
   199 // CUpnpDispatcherEngine::SendMessageL
       
   200 // -----------------------------------------------------------------------------
       
   201 //
       
   202 void CUpnpDispatcherEngine::SendMessageL( CUpnpHttpMessage* aMessage )
       
   203     {
       
   204     // Sends a Http message
       
   205     iHttpServerSession->SendMessageL( aMessage );
       
   206     }
       
   207 
       
   208 // -----------------------------------------------------------------------------
       
   209 // CUpnpDispatcherEngine::UpdateDevicesL
       
   210 // -----------------------------------------------------------------------------
       
   211 //
       
   212 void CUpnpDispatcherEngine::UpdateDevicesL( TInt aUpdateId )
       
   213     {
       
   214     // checking if new list size is called.
       
   215     if ( iDeviceGetState != EGetListSize )
       
   216         {
       
   217         if ( IsActive() )
       
   218             {
       
   219             return;
       
   220             }
       
   221 
       
   222         // setting information for message handler
       
   223         // iSize contains information about last known
       
   224         // update id. On return, it will contain also
       
   225         // number of new devices and servises.
       
   226 
       
   227         if( iSize.iUpdateId > iOldUpdateId )
       
   228             {
       
   229             iDeviceGetState = EGetList;
       
   230             SetActive();
       
   231             iStatus = KRequestPending;
       
   232             TRequestStatus* stat = &iStatus;
       
   233             User::RequestComplete( stat, KErrNone );
       
   234             }
       
   235         else
       
   236             {
       
   237             iSize.iUpdateId = aUpdateId;
       
   238             iOldUpdateId = aUpdateId;
       
   239 
       
   240             iStatus = KRequestPending;
       
   241             // connection restoring
       
   242             if(!iIsSessionOpen)
       
   243                 {
       
   244                 User::LeaveIfError( iSession.Connect() );
       
   245                 iIsSessionOpen = ETrue;
       
   246                 }
       
   247 
       
   248             iSession.RequestGetDeviceListSize( iStatus, iSize );
       
   249             if( !IsActive() )
       
   250                 {
       
   251                 SetActive();
       
   252                 }
       
   253                 iDeviceGetState = EGetList;
       
   254             }
       
   255         }
       
   256     }
       
   257 
       
   258 // -----------------------------------------------------------------------------
       
   259 // CUpnpDispatcherEngine::GetDevicesL
       
   260 //
       
   261 // (other items were commented in a header).
       
   262 // -----------------------------------------------------------------------------
       
   263 //
       
   264 CUpnpDispatcherEngine::TDispatcherRequest CUpnpDispatcherEngine::GetDevicesL()
       
   265     {
       
   266     LOG_FUNC_NAME;
       
   267 
       
   268     TDispatcherRequest status( ENewDevices );
       
   269     if ( iDevs )
       
   270         {
       
   271         delete [] iDevs;
       
   272         iDevs = NULL;
       
   273         }
       
   274 
       
   275     if ( iServs )
       
   276         {
       
   277         delete [] iServs;
       
   278         iServs = NULL;
       
   279         }
       
   280 
       
   281     // checking if new devices or services has been found.
       
   282     if ( iSize.iUpdateId > iOldUpdateId )
       
   283         {
       
   284         if( IsActive() )
       
   285             {
       
   286             Cancel();
       
   287             }
       
   288 
       
   289         // constructing buffers for getting the information
       
   290         // for new devices and services.
       
   291         // iDevs is an array, that will have number of
       
   292         // devices as we have just received from Message Handler
       
   293         // Same with iServs for services.
       
   294 
       
   295         iDevs = new (ELeave) TUpnpDevice[iSize.iDeviceCount];
       
   296         iServs = new (ELeave) TUpnpService[iSize.iServiceCount];
       
   297 
       
   298         TPtr8 devPtr( reinterpret_cast<TUint8*>( iDevs ),
       
   299             iSize.iDeviceCount*sizeof( TUpnpDevice ),
       
   300             iSize.iDeviceCount*sizeof( TUpnpDevice ) );
       
   301         TPtr8 servPtr( reinterpret_cast<TUint8*>( iServs ),
       
   302             iSize.iServiceCount*sizeof( TUpnpService ),
       
   303             iSize.iServiceCount*sizeof( TUpnpService ) );
       
   304 
       
   305         // setting member pointers to point to strictures that will be
       
   306         // filled with device and service information as call returns.
       
   307         iGetDevPtr.Set(devPtr);
       
   308         iGetServPtr.Set(servPtr);
       
   309 
       
   310         // connection restoring
       
   311         if(!iIsSessionOpen)
       
   312             {
       
   313             User::LeaveIfError( iSession.Connect() );
       
   314             iIsSessionOpen = ETrue;
       
   315             }
       
   316 
       
   317         iStatus = KRequestPending;
       
   318         iSession.RequestGetDeviceList( iStatus, iGetDevPtr, iGetServPtr );
       
   319         if( !IsActive() )
       
   320             {
       
   321             SetActive();
       
   322             }
       
   323 
       
   324         status = ENewDevices;
       
   325         }
       
   326     else
       
   327         {
       
   328         // if no new devices, return the request for Message Handler,
       
   329         // so it can complete message when there will be new devices.
       
   330         UpdateDevicesL(iSize.iUpdateId);
       
   331 
       
   332         status = EDeviceList;
       
   333         }
       
   334 
       
   335     return status;
       
   336     }
       
   337 
       
   338 // -----------------------------------------------------------------------------
       
   339 // CUpnpDispatcherEngine::DevicesReceivedL
       
   340 // -----------------------------------------------------------------------------
       
   341 //
       
   342 TInt CUpnpDispatcherEngine::DevicesReceivedL()
       
   343     {
       
   344     if( iDevs && iServs)
       
   345         {
       
   346         TInt servIndex = 0;
       
   347 
       
   348         // parsing data to devices and services.
       
   349         for ( TInt i = 0; i < iSize.iDeviceCount; i++ )
       
   350             {
       
   351             RPointerArray<TUpnpService> currServs;
       
   352             CleanupClosePushL( currServs );
       
   353             for ( TInt j = 0; j < iDevs[i].iServiceCount; j++ )
       
   354                 {
       
   355                 currServs.Append( (const TUpnpService*)&iServs[servIndex+j] );
       
   356                 }
       
   357             CleanupStack::Check(&currServs);
       
   358             servIndex += iDevs[i].iServiceCount;
       
   359 
       
   360             // creating CUpnpDevice objects from this information.
       
   361 
       
   362             CUpnpDevice* device = CUpnpDevice::NewL( &iDevs[i], currServs );
       
   363             CleanupStack::Check(&currServs);
       
   364             device->SetAlive( iDevs[i].iAlive );
       
   365             CleanupStack::Check(&currServs);
       
   366             currServs.Reset();
       
   367             CleanupStack::Pop( &currServs );
       
   368 
       
   369             iNewDevices.Append( device );
       
   370             }
       
   371 
       
   372         delete[] iDevs;
       
   373         iDevs = NULL;
       
   374 
       
   375         delete[] iServs;
       
   376         iServs = NULL;
       
   377 
       
   378         iOldUpdateId = iSize.iUpdateId;
       
   379 
       
   380         // inform CUpnpDispatcher that new devices and services has been found.
       
   381         iObserver.DeviceListReceivedL(iOldUpdateId);
       
   382         }
       
   383     //The UpdateId should be passed back to the DispatcherEngine
       
   384     //(Through Observer)
       
   385     return iOldUpdateId;
       
   386     }
       
   387 
       
   388 // -----------------------------------------------------------------------------
       
   389 // CUpnpDispatcherEngine::NewDevices
       
   390 // -----------------------------------------------------------------------------
       
   391 //
       
   392 const RPointerArray<CUpnpDevice>& CUpnpDispatcherEngine::NewDevices() const
       
   393     {
       
   394     return iNewDevices;
       
   395     }
       
   396 
       
   397 // -----------------------------------------------------------------------------
       
   398 // CUpnpDispatcherEngine::RemoveDevices
       
   399 // -----------------------------------------------------------------------------
       
   400 //
       
   401 void CUpnpDispatcherEngine::RemoveDevices()
       
   402     {
       
   403     iNewDevices.ResetAndDestroy();
       
   404     }
       
   405 
       
   406 // -----------------------------------------------------------------------------
       
   407 // CUpnpDispatcherEngine::AddLocalDeviceL
       
   408 // -----------------------------------------------------------------------------
       
   409 //
       
   410 void CUpnpDispatcherEngine::AddLocalDeviceL( const TDesC8& aUuid,
       
   411                                              const TDesC8& aDeviceType,
       
   412                                              const TDesC8& aDescriptionPath,
       
   413                                              const CDesC8Array& aServices,
       
   414                                              const TBool aIsRootDevice )
       
   415     {
       
   416     // checking if client is busy.
       
   417     if ( iDeviceGetState != EOtherOperation &&
       
   418         iDeviceGetState != EListReceived)
       
   419         {
       
   420         if ( IsActive() )
       
   421             {
       
   422             Cancel();
       
   423             }
       
   424 
       
   425         TBuf8<KPortBufferLength> port;
       
   426         port.Num( HttpServerAddress().Port() );
       
   427 
       
   428         _LIT8( KRootDevice, "r" );
       
   429 
       
   430         TInt bufLen = aUuid.Length() +
       
   431             aDeviceType.Length() +
       
   432             aDescriptionPath.Length() +
       
   433             port.Length() + KRootDevice().Length();
       
   434 
       
   435         TInt i=0;
       
   436         for ( i = 0; i < aServices.Count(); i++ )
       
   437             {
       
   438             bufLen += aServices[i].Length();
       
   439             }
       
   440 
       
   441         if(iAddLocalBuffer)
       
   442             {
       
   443             delete iAddLocalBuffer;
       
   444             iAddLocalBuffer = NULL;
       
   445             }
       
   446 
       
   447         // creating a buffer that will hold information about device
       
   448         // that is to be added.
       
   449 
       
   450         iAddLocalBuffer = HBufC8::NewL( bufLen );
       
   451         iAddLocalPtr.Set( iAddLocalBuffer->Des() );
       
   452 
       
   453         // iAddLocalDevice is a struct, that will hold length of each
       
   454         // data in the buffer. When we have length of each data and
       
   455         // the data buffer, we can parse the data back to separate
       
   456         // buffers on server side.
       
   457 
       
   458         iAddLocalDevice.iUuidLength = aUuid.Length();
       
   459         iAddLocalDevice.iDeviceTypeLength = aDeviceType.Length();
       
   460         iAddLocalDevice.iDescriptionUrlLength = aDescriptionPath.Length();
       
   461         iAddLocalDevice.iDomainLength = 0;
       
   462         iAddLocalDevice.iPortNumberLength = port.Length();
       
   463         iAddLocalDevice.iRootDeviceLength = 0;
       
   464 
       
   465         iAddLocalPtr.Append( aUuid );
       
   466         iAddLocalPtr.Append( aDeviceType );
       
   467         iAddLocalPtr.Append( aDescriptionPath );
       
   468         iAddLocalPtr.Append( port );
       
   469 
       
   470                 if ( aIsRootDevice )
       
   471                     {
       
   472                     iAddLocalPtr.Append( KRootDevice() );
       
   473                     iAddLocalDevice.iRootDeviceLength = KRootDevice().Length();
       
   474                     }
       
   475 
       
   476         for ( i = 0; i < aServices.Count(); i++ )
       
   477             {
       
   478             iAddLocalDevice.iServiceLength[i] = aServices[i].Length();
       
   479             iAddLocalPtr.Append( aServices[i] );
       
   480             }
       
   481 
       
   482         for ( ; i < KMaxServiceCount; i++ )
       
   483             {
       
   484             iAddLocalDevice.iServiceLength[i] = 0;
       
   485             }
       
   486 
       
   487         iAddLocalDevice.iBufferLength = iAddLocalPtr.Length();
       
   488 
       
   489         // connection restoring
       
   490         if(!iIsSessionOpen)
       
   491             {
       
   492             User::LeaveIfError( iSession.Connect() );
       
   493             iIsSessionOpen = ETrue;
       
   494             }
       
   495 
       
   496         iStatus = KRequestPending;
       
   497         iSession.RequestAddLocalDevice( iStatus, iAddLocalDevice,
       
   498             iAddLocalPtr );
       
   499         if( !IsActive() )
       
   500             {
       
   501             SetActive();
       
   502             }
       
   503 
       
   504         iDeviceGetState = EOtherOperation;
       
   505         }
       
   506     else
       
   507         {
       
   508         // if client is busy, making a request to request queue.
       
   509         CUpnpDispatcherRequest* request = CUpnpDispatcherRequest::NewLC(
       
   510             EAddLocalDevice );
       
   511 
       
   512         request->AddArgumentL( aUuid );
       
   513         request->AddArgumentL( aDeviceType );
       
   514         request->AddArgumentL( aDescriptionPath );
       
   515 
       
   516         _LIT8( KRootDevice, "r" );
       
   517 
       
   518         if ( aIsRootDevice )
       
   519             {
       
   520             request->AddArgumentL( KRootDevice );
       
   521             }
       
   522         else
       
   523             {
       
   524             request->AddArgumentL( KNullDesC8 );
       
   525             }
       
   526 
       
   527         TInt granularity = aServices.Count();
       
   528         if( 0 == granularity )
       
   529             {
       
   530             granularity = 1;
       
   531             }
       
   532         CDesC8ArrayFlat* array = new (ELeave) CDesC8ArrayFlat( granularity );
       
   533 
       
   534         CleanupStack::PushL(array);
       
   535 
       
   536         for ( TInt k = 0; k < aServices.Count(); k++ )
       
   537             {
       
   538             array->AppendL( aServices[k] );
       
   539             }
       
   540 
       
   541         CleanupStack::Pop(array);
       
   542         request->AddServices(array);
       
   543 
       
   544         CleanupStack::Pop(request);
       
   545         iPendingRequests.Append(request);
       
   546         }
       
   547     }
       
   548 
       
   549 // -----------------------------------------------------------------------------
       
   550 // CUpnpDispatcherEngine::AddControlPointClientL
       
   551 // -----------------------------------------------------------------------------
       
   552 //
       
   553 void CUpnpDispatcherEngine::AddControlPointClientL()
       
   554     {
       
   555     // checking if client is busy.
       
   556     if ( iDeviceGetState != EOtherOperation &&
       
   557         iDeviceGetState != EListReceived )
       
   558         {
       
   559         if ( IsActive() )
       
   560             {
       
   561             Cancel();
       
   562             }
       
   563 
       
   564         // connection restoring
       
   565         if ( !iIsSessionOpen )
       
   566             {
       
   567             User::LeaveIfError( iSession.Connect() );
       
   568             iIsSessionOpen = ETrue;
       
   569             }
       
   570 
       
   571         iStatus = KRequestPending;
       
   572         iSession.RequestAddControlPoint( iStatus );
       
   573 
       
   574         if ( !IsActive() )
       
   575             {
       
   576             SetActive();
       
   577             }
       
   578         iDeviceGetState = EOtherOperation;
       
   579         }
       
   580     else
       
   581         {
       
   582         // client is busy, making a request and adding it to queue.
       
   583         CUpnpDispatcherRequest* request =
       
   584             CUpnpDispatcherRequest::NewLC( EAddControlPointClient );
       
   585         iPendingRequests.AppendL( request );
       
   586         CleanupStack::Pop( request );
       
   587         }
       
   588     }
       
   589 
       
   590 void CUpnpDispatcherEngine::RemoveControlPointClientL()
       
   591     {
       
   592     // checking if client is busy.
       
   593     if ( iDeviceGetState != EOtherOperation &&
       
   594         iDeviceGetState != EListReceived )
       
   595         {
       
   596         if ( IsActive() )
       
   597             {
       
   598             Cancel();
       
   599             }
       
   600 
       
   601         // connection restoring
       
   602         if ( !iIsSessionOpen )
       
   603             {
       
   604             User::LeaveIfError( iSession.Connect() );
       
   605             iIsSessionOpen = ETrue;
       
   606             }
       
   607 
       
   608         iStatus = KRequestPending;
       
   609         iSession.RequestRemoveControlPoint( iStatus );
       
   610 
       
   611         if ( !IsActive() )
       
   612             {
       
   613             SetActive();
       
   614             }
       
   615         iDeviceGetState = EOtherOperation;
       
   616         }
       
   617     else
       
   618         {
       
   619         // client is busy, making a request and adding it to queue.
       
   620         CUpnpDispatcherRequest* request =
       
   621                 CUpnpDispatcherRequest::NewLC( ERemoveControlPointClient );
       
   622         iPendingRequests.AppendL( request );
       
   623         CleanupStack::Pop( request );
       
   624         }
       
   625     }
       
   626 
       
   627 // -----------------------------------------------------------------------------
       
   628 // CUpnpDispatcherEngine::SsdpSearchL
       
   629 //
       
   630 // (other items were commented in a header).
       
   631 // -----------------------------------------------------------------------------
       
   632 //
       
   633 void CUpnpDispatcherEngine::SsdpSearchL( const TDesC8& aString )
       
   634     {
       
   635     if(!iMXString)
       
   636         {
       
   637         TRAPD(err,iMXString = CUpnpSettings::GetMSearchConfigurationL());
       
   638         if(err == KErrNotFound)
       
   639             {
       
   640             iMXString = KMSearchConfig().AllocL();
       
   641             }
       
   642         else
       
   643             {
       
   644             User::LeaveIfError(err);
       
   645             }
       
   646         }
       
   647 
       
   648     if( aString.Length() <= 0 )
       
   649         {
       
   650         return;
       
   651         }
       
   652 
       
   653     // checking if client is busy.
       
   654     if ( iDeviceGetState != EOtherOperation &&
       
   655         iDeviceGetState != EListReceived )
       
   656         {
       
   657         if ( IsActive() )
       
   658             {
       
   659             Cancel();
       
   660             }
       
   661 
       
   662         if( iSearch )
       
   663             {
       
   664             delete iSearch;
       
   665             iSearch = NULL;
       
   666             }
       
   667 
       
   668         iSearch = HBufC8::NewL( aString.Length() );
       
   669         iSearch->Des().Zero();
       
   670         iSearch->Des().Append( aString );
       
   671         // connection restoring
       
   672         if(!iIsSessionOpen)
       
   673             {
       
   674             User::LeaveIfError( iSession.Connect() );
       
   675             iIsSessionOpen = ETrue;
       
   676             }
       
   677 
       
   678         iStatus = KRequestPending;
       
   679         iSession.RequestSsdpSearch( iStatus, *iSearch, *iMXString );
       
   680 
       
   681         if( !IsActive() )
       
   682             {
       
   683             SetActive();
       
   684             }
       
   685 
       
   686         iDeviceGetState = EOtherOperation;
       
   687         }
       
   688     else
       
   689         {
       
   690         // client is busy, making a request and adding it to queue.
       
   691         CUpnpDispatcherRequest* request = CUpnpDispatcherRequest::NewLC( ESsdpSearch );
       
   692 
       
   693         request->AddArgumentL( aString );
       
   694 
       
   695         CleanupStack::Pop(request);
       
   696         iPendingRequests.Append(request);
       
   697         }
       
   698     }
       
   699 
       
   700 // -----------------------------------------------------------------------------
       
   701 // CUpnpDispatcherEngine::SsdpStopFilteringL
       
   702 //
       
   703 // (other items were commented in a header).
       
   704 // -----------------------------------------------------------------------------
       
   705 //
       
   706 void CUpnpDispatcherEngine::SsdpStopFilteringL( const TDesC8& aString )
       
   707     {
       
   708     if( aString.Length() <= 0 )
       
   709         {
       
   710         return;
       
   711         }
       
   712     if( iUuids )
       
   713         {
       
   714         delete iUuids;
       
   715         iUuids = NULL;
       
   716         }
       
   717     iUuids = HBufC8::NewL( aString.Length() );
       
   718     iUuids->Des().Zero();
       
   719     iUuids->Des().Append( aString );
       
   720     // connection restoring
       
   721     if(!iIsSessionOpen)
       
   722         {
       
   723         User::LeaveIfError( iSession.Connect() );
       
   724         iIsSessionOpen = ETrue;
       
   725         }
       
   726     iSession.RequestStopFiltering( *iUuids );
       
   727     }
       
   728 
       
   729 // -----------------------------------------------------------------------------
       
   730 // CUpnpDispatcherEngine::HttpEventLD
       
   731 // -----------------------------------------------------------------------------
       
   732 //
       
   733 void CUpnpDispatcherEngine::HttpEventLD( CUpnpHttpMessage* aMessage )
       
   734     {
       
   735     if( !aMessage )
       
   736         {
       
   737         return;
       
   738         }
       
   739     CleanupStack::PushL( aMessage );
       
   740 
       
   741     HBufC8* customerPath = aMessage->ServicePath().AllocLC();
       
   742     for ( TInt i = 0; i < iCustomers.Count(); i++ )
       
   743         {
       
   744         MUpnpDispatcherCustomer* customer = iCustomers[i];
       
   745         if ( customerPath->CompareF( customer->Path() ) == 0 )
       
   746             {
       
   747             CleanupStack::PopAndDestroy(customerPath);
       
   748             CleanupStack::Pop( aMessage );
       
   749             customer->MessageReceivedLD( aMessage );
       
   750             return;
       
   751             }
       
   752         }
       
   753     CleanupStack::PopAndDestroy(customerPath);
       
   754     
       
   755     if ( aMessage->Type() <= ETransferStart )
       
   756         {
       
   757         CUpnpHttpMessage* reply = RUpnpHttpMessageFactory::HttpResponseErrorL(
       
   758                                                         aMessage->Sender(), EHttpBadRequest );
       
   759         CleanupStack::PushL( reply );
       
   760         reply->SetSessionId( aMessage->SessionId() );
       
   761         SendMessageL( reply );
       
   762         CleanupStack::PopAndDestroy( reply );
       
   763         }
       
   764     CleanupStack::PopAndDestroy( aMessage );
       
   765     }
       
   766 
       
   767 // -----------------------------------------------------------------------------
       
   768 // CUpnpDispatcherEngine::HttpServerAddressL
       
   769 // -----------------------------------------------------------------------------
       
   770 //
       
   771 TInetAddr CUpnpDispatcherEngine::HttpServerAddress()
       
   772     {
       
   773     TInetAddr addr;
       
   774     iHttpServerSession->GetAddress( addr );
       
   775     return addr;
       
   776     }
       
   777 
       
   778 // CUpnpDispatcherEngine::RemoveLocalDeviceL
       
   779 // -----------------------------------------------------------------------------
       
   780 //
       
   781 void CUpnpDispatcherEngine::RemoveLocalDeviceL( const TDesC8& aUuid, TBool aSilent )
       
   782     {
       
   783     // checking if client is busy.
       
   784     if ( iDeviceGetState != EOtherOperation &&
       
   785          iDeviceGetState != EListReceived )
       
   786         {
       
   787         if ( IsActive() )
       
   788             {
       
   789             Cancel();
       
   790             }
       
   791 
       
   792         if(iRemoveUuid)
       
   793             {
       
   794             delete iRemoveUuid;
       
   795             iRemoveUuid = NULL;
       
   796             }
       
   797 
       
   798         iRemoveUuid = aUuid.AllocL();
       
   799         iRemoveUuidPtr.Set(iRemoveUuid->Des());
       
   800 
       
   801         // connection restoring
       
   802         if(!iIsSessionOpen)
       
   803             {
       
   804             User::LeaveIfError( iSession.Connect() );
       
   805             iIsSessionOpen = ETrue;
       
   806             }
       
   807 
       
   808         iStatus = KRequestPending;
       
   809 
       
   810         if (!aSilent)
       
   811             {
       
   812             iSession.RequestRemoveLocalDevice( iStatus, iRemoveUuidPtr );
       
   813             }
       
   814         else
       
   815             {
       
   816             iSession.RequestRemoveSilentLocalDevice( iStatus, iRemoveUuidPtr );
       
   817             }
       
   818         iDeviceGetState = EOtherOperation;
       
   819 
       
   820         if( !IsActive() )
       
   821             {
       
   822             SetActive();
       
   823             }
       
   824         }
       
   825     else
       
   826         {
       
   827         // client is busy, making a request and adding it to queue.
       
   828         CUpnpDispatcherRequest* request = CUpnpDispatcherRequest::NewLC(
       
   829             ERemoveLocalDevice );
       
   830 
       
   831         request->AddArgumentL( aUuid );
       
   832 
       
   833         // we need to store information if the removal should be silent
       
   834         if ( aSilent )
       
   835             {
       
   836             request->AddArgumentL( KNullDesC8 );
       
   837             }
       
   838 
       
   839         CleanupStack::Pop(request);
       
   840         iPendingRequests.Append(request);
       
   841         }
       
   842     }
       
   843 
       
   844 // -----------------------------------------------------------------------------
       
   845 // CUpnpDispatcherEngine::MacAddressL
       
   846 // -----------------------------------------------------------------------------
       
   847 //
       
   848 const HBufC8* CUpnpDispatcherEngine::MacAddressL()
       
   849     {
       
   850     TSockAddr* addr;
       
   851     addr = iHttpServerSession->HWAddressL();
       
   852     CleanupStack::PushL( addr);
       
   853     TInt i = 0;
       
   854     HBufC8* hwAddr = NULL;
       
   855     hwAddr = HBufC8::NewL( 2 * addr->GetUserLen() );
       
   856     hwAddr->Des().Zero();
       
   857 
       
   858     for ( i = sizeof(SSockAddr); i < sizeof(SSockAddr) + addr->GetUserLen(); i++ )
       
   859         {
       
   860         hwAddr->Des().AppendNumFixedWidth((*addr)[i], EHex, 2);
       
   861         }
       
   862 
       
   863     CleanupStack::PopAndDestroy( addr);
       
   864 
       
   865     hwAddr->Des().UpperCase();
       
   866 
       
   867     return hwAddr;
       
   868     }
       
   869 
       
   870 // -----------------------------------------------------------------------------
       
   871 // CUpnpDispatcherEngine::RunL
       
   872 // -----------------------------------------------------------------------------
       
   873 //
       
   874 void CUpnpDispatcherEngine::RunL()
       
   875     {
       
   876     if ( iStatus.Int() == KErrServerTerminated || iStatus.Int() == KErrCancel )
       
   877         {
       
   878         LOGS("CUpnpDispatcherEngine::RunL, Server terminated or canceled, trying to restart");
       
   879         iSession.Close();
       
   880         iIsSessionOpen = EFalse;
       
   881         return;
       
   882         }
       
   883 
       
   884     switch( iDeviceGetState )
       
   885         {
       
   886         case EOtherOperation:
       
   887             if ( iPendingRequests.Count() > 0 )
       
   888                 {
       
   889                 HandlePendingRequestL();
       
   890                 }
       
   891             else
       
   892                 {
       
   893                 UpdateDevicesL(iOldUpdateId);
       
   894                 }
       
   895             break;
       
   896         case EGetListSize:
       
   897             UpdateDevicesL(iOldUpdateId);
       
   898             break;
       
   899         case EGetList:
       
   900             if( GetDevicesL() == EDeviceList)
       
   901                 {
       
   902                 iDeviceGetState = EGetList;
       
   903                 }
       
   904             else
       
   905                 {
       
   906                 iDeviceGetState = EListReceived;
       
   907                 }
       
   908 
       
   909             break;
       
   910         case EListReceived:
       
   911             if( iSize.iUpdateId >= iOldUpdateId )
       
   912                 {
       
   913                 DevicesReceivedL();
       
   914                 }
       
   915             if( iPendingRequests.Count() > 0 && !IsActive())
       
   916                 {
       
   917                 iDeviceGetState = EOtherOperation;
       
   918                 //Re-execute RunL to launch HandlePendingRequest
       
   919                 SetActive();
       
   920                 iStatus = KRequestPending;
       
   921                 TRequestStatus* stat = &iStatus;
       
   922                 User::RequestComplete( stat, KErrNone );
       
   923                 break;
       
   924                 }
       
   925             UpdateDevicesL(iOldUpdateId);
       
   926 
       
   927             break;
       
   928         default: //NoOperation
       
   929             break;
       
   930         }
       
   931     }
       
   932 
       
   933 // -----------------------------------------------------------------------------
       
   934 // CUpnpDispatcherEngine::RunError
       
   935 // RunError in case RunL leaves.
       
   936 // -----------------------------------------------------------------------------
       
   937 //
       
   938 TInt CUpnpDispatcherEngine::RunError( TInt /*aError*/ )
       
   939     {
       
   940     return KErrNone;
       
   941     }
       
   942 
       
   943 // -----------------------------------------------------------------------------
       
   944 // CUpnpDispatcherEngine::DoCancel
       
   945 // -----------------------------------------------------------------------------
       
   946 //
       
   947 void CUpnpDispatcherEngine::DoCancel()
       
   948     {
       
   949     TRAP_IGNORE( StopRequestL() );
       
   950 
       
   951     if(iDevs)
       
   952         {
       
   953         delete [] iDevs;
       
   954         iDevs = NULL;
       
   955         }
       
   956     if(iServs)
       
   957         {
       
   958         delete [] iServs;
       
   959         iServs = NULL;
       
   960         }
       
   961 
       
   962     iDeviceGetState = ENoOperation;
       
   963     }
       
   964 
       
   965 // -----------------------------------------------------------------------------
       
   966 // CUpnpDispatcherEngine::HandlePendingRequestL
       
   967 // -----------------------------------------------------------------------------
       
   968 //
       
   969 void CUpnpDispatcherEngine::HandlePendingRequestL()
       
   970     {
       
   971     ASSERT( iPendingRequests.Count() > 0 );
       
   972     RemoveHandledRequest();
       
   973     iActiveRequest = iPendingRequests[0];
       
   974     CDesC8ArrayFlat& arguments = iActiveRequest->Arguments();
       
   975     switch( iActiveRequest->Request() )
       
   976         {
       
   977         case EAddLocalDevice:
       
   978             {
       
   979             if( iDeviceGetState == EOtherOperation )
       
   980                 {
       
   981                 iDeviceGetState = ENoOperation;
       
   982                 }
       
   983 
       
   984             if ( arguments[3].Length() > 0 )
       
   985                 {
       
   986                 AddLocalDeviceL(
       
   987                                 arguments[0],
       
   988                                 arguments[1],
       
   989                                 arguments[2],
       
   990                                 iActiveRequest->Services(),
       
   991                         ETrue );
       
   992                 }
       
   993             else
       
   994                 {
       
   995                 AddLocalDeviceL(
       
   996                                 arguments[0],
       
   997                                 arguments[1],
       
   998                                 arguments[2],
       
   999                                 iActiveRequest->Services(),
       
  1000                                 EFalse );
       
  1001                 }
       
  1002 
       
  1003             }
       
  1004             break;
       
  1005 
       
  1006         case ERemoveLocalDevice:
       
  1007             {
       
  1008 
       
  1009             if( iDeviceGetState == EOtherOperation )
       
  1010                 {
       
  1011                 iDeviceGetState = ENoOperation;
       
  1012                 }
       
  1013 
       
  1014             // the presence of 2nd argument means the removal should be silent
       
  1015             TBool silent = EFalse;
       
  1016             if ( arguments.Count() == 2 )
       
  1017                 {
       
  1018                 silent = ETrue;
       
  1019                 }
       
  1020             RemoveLocalDeviceL( arguments[0], silent );
       
  1021             }
       
  1022             break;
       
  1023 
       
  1024         case EAddControlPointClient:
       
  1025             {
       
  1026             if( iDeviceGetState == EOtherOperation )
       
  1027                 {
       
  1028                 iDeviceGetState = ENoOperation;
       
  1029                 }
       
  1030                 AddControlPointClientL();
       
  1031             }
       
  1032             break;
       
  1033 
       
  1034         case ERemoveControlPointClient:
       
  1035             {
       
  1036             if( iDeviceGetState == EOtherOperation )
       
  1037                 {
       
  1038                 iDeviceGetState = ENoOperation;
       
  1039                 }
       
  1040 
       
  1041             RemoveControlPointClientL();
       
  1042             }
       
  1043             break;
       
  1044 
       
  1045         case ESsdpSearch:
       
  1046             {
       
  1047 
       
  1048             if( iDeviceGetState == EOtherOperation )
       
  1049                 {
       
  1050                 iDeviceGetState = ENoOperation;
       
  1051                 }
       
  1052 
       
  1053             SsdpSearchL( arguments[0] );
       
  1054 
       
  1055             }
       
  1056         default:
       
  1057             break;
       
  1058         }
       
  1059     iPendingRequests.Remove( 0 );
       
  1060     iPendingRequests.Compress();
       
  1061     iDeviceGetState = EOtherOperation;
       
  1062     }
       
  1063 
       
  1064 // -----------------------------------------------------------------------------
       
  1065 // CUpnpDispatcherEngine::RemoveHandledRequest
       
  1066 // -----------------------------------------------------------------------------
       
  1067 //
       
  1068 TInt CUpnpDispatcherEngine::RemoveHandledRequest()
       
  1069     {
       
  1070     if(iActiveRequest)
       
  1071         {
       
  1072         // If last message was ssdp search, now it is safe
       
  1073         // to delete iSearch also.
       
  1074         if( iActiveRequest->Request() == ESsdpSearch )
       
  1075             {
       
  1076             if( iSearch )
       
  1077                 {
       
  1078                 delete iSearch;
       
  1079                 iSearch = NULL;
       
  1080                 }
       
  1081             }
       
  1082         delete iActiveRequest;
       
  1083         iActiveRequest = NULL;
       
  1084         return KErrNone;
       
  1085         }
       
  1086     return KErrNotFound;
       
  1087     }
       
  1088 
       
  1089 // -----------------------------------------------------------------------------
       
  1090 // CUpnpDispatcherEngine::StopRequestL
       
  1091 // -----------------------------------------------------------------------------
       
  1092 //
       
  1093 void CUpnpDispatcherEngine::StopRequestL()
       
  1094     {
       
  1095     //LOGSH( iHandle, "Disp Request Cancelled");
       
  1096 
       
  1097     if( iDeviceGetState == EGetList )
       
  1098         {
       
  1099         // connection restoring
       
  1100         if(!iIsSessionOpen)
       
  1101             {
       
  1102             User::LeaveIfError( iSession.Connect() );
       
  1103             iIsSessionOpen = ETrue;
       
  1104             }
       
  1105 
       
  1106         iDeviceGetState = ENoOperation;
       
  1107         iSession.RequestStop();
       
  1108         }
       
  1109     }
       
  1110 
       
  1111 // -----------------------------------------------------------------------------
       
  1112 // CUpnpDispatcherEngine::SetTransactionCreator
       
  1113 // -----------------------------------------------------------------------------
       
  1114 //
       
  1115 void CUpnpDispatcherEngine::SetTransactionCreator( 
       
  1116           MUpnpHttpServerTransactionCreator* aTransactionCreator )
       
  1117     {
       
  1118     iHttpServerSession->DefaultRuntime().SetCreator( *aTransactionCreator );
       
  1119     }
       
  1120 
       
  1121 // -----------------------------------------------------------------------------
       
  1122 // CUpnpDispatcher::StartHttpServerL
       
  1123 // -----------------------------------------------------------------------------
       
  1124 //
       
  1125 void CUpnpDispatcherEngine::StartHttpServerL( TBool aRegister , const TInt aPort )
       
  1126     {
       
  1127     iHttpServerSession->StartL( aPort );    
       
  1128     CheckErrorL( aRegister );
       
  1129     }
       
  1130 
       
  1131 // -----------------------------------------------------------------------------
       
  1132 // CUpnpDispatcher::CheckErrorL
       
  1133 // -----------------------------------------------------------------------------
       
  1134 //
       
  1135 void CUpnpDispatcherEngine::CheckErrorL( TBool /*aRegister*/ )
       
  1136     {
       
  1137     TInt error = KErrNone;
       
  1138     iSession.RequestCheckError(error);
       
  1139     User::LeaveIfError(error);
       
  1140     }
       
  1141 
       
  1142 // -----------------------------------------------------------------------------
       
  1143 // CUpnpDispatcher::StopHttpServer
       
  1144 // -----------------------------------------------------------------------------
       
  1145 //
       
  1146 void CUpnpDispatcherEngine::StopHttpServer()
       
  1147     {
       
  1148     iHttpServerSession->Stop();
       
  1149     }
       
  1150 
       
  1151 //  End of File