upnp/upnpstack/upnputils/src/upnpdevicelibrary.cpp
changeset 0 f5a58ecadc66
child 26 b6b8e90f9863
equal deleted inserted replaced
-1:000000000000 0:f5a58ecadc66
       
     1 /** @file
       
     2 * Copyright (c) 2005-2008 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:  CUpnpDeviceLibrary
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "upnpdevicelibrary.h"
       
    21 #include "upnpssdpmessage.h"
       
    22 #define KLogFile _L("DLNAWebServer.txt")
       
    23 #include "upnpcustomlog.h"
       
    24 
       
    25 static const TInt KIntervalBetweenByeAndAlive = 1;
       
    26 static const TInt KIntervalBeforeFirstAlive = 1;
       
    27 // prevents treating SSDP alive messages sent by local device
       
    28 // as an external device messages in case of quick local device restarting
       
    29 // heuristic value 
       
    30 static const TInt KLocalDeviceHysteresisWindow  = 20;
       
    31 // used for IPC communication 2 phase request
       
    32 // heuristic value 
       
    33 static const TInt KIpcCommunicationTimeout = 2;
       
    34 
       
    35 // ============================ MEMBER FUNCTIONS ===============================
       
    36 
       
    37 // -----------------------------------------------------------------------------
       
    38 // CUpnpDeviceLibrary::CUpnpDeviceLibrary
       
    39 // C++ default constructor can NOT contain any code, that
       
    40 // might leave.
       
    41 // -----------------------------------------------------------------------------
       
    42 //
       
    43 CUpnpDeviceLibrary::CUpnpDeviceLibrary( MUpnpDeviceLibraryObserver& aObserver,
       
    44                                 TInt aHandle )
       
    45     : iObserver(aObserver),
       
    46       iHandle( aHandle )
       
    47     {
       
    48     }
       
    49 
       
    50 // -----------------------------------------------------------------------------
       
    51 // CUpnpDeviceLibrary::ConstructL
       
    52 // Symbian 2nd phase constructor can leave.
       
    53 // -----------------------------------------------------------------------------
       
    54 //
       
    55 void CUpnpDeviceLibrary::ConstructL()
       
    56     {
       
    57     }
       
    58 
       
    59 // -----------------------------------------------------------------------------
       
    60 // CUpnpDeviceLibrary::NewL
       
    61 // Two-phased constructor.
       
    62 // -----------------------------------------------------------------------------
       
    63 //
       
    64 EXPORT_C CUpnpDeviceLibrary* CUpnpDeviceLibrary::NewL( 
       
    65                                         MUpnpDeviceLibraryObserver& aObserver,
       
    66                                         TInt aHandle )
       
    67     {
       
    68     CUpnpDeviceLibrary* self = new (ELeave) CUpnpDeviceLibrary( aObserver, aHandle );
       
    69 
       
    70     CleanupStack::PushL( self );
       
    71     self->ConstructL();
       
    72     CleanupStack::Pop( self );
       
    73     
       
    74     return self;
       
    75     }
       
    76 // -----------------------------------------------------------------------------
       
    77 // CUpnpDeviceLibrary::~CUpnpDeviceLibrary
       
    78 // Destructor
       
    79 // -----------------------------------------------------------------------------
       
    80 //
       
    81 EXPORT_C CUpnpDeviceLibrary::~CUpnpDeviceLibrary()
       
    82     {
       
    83     LOGSH( iHandle, "Devicelibrary ~CUpnpDeviceLibrary");
       
    84 
       
    85     iElementArray.ResetAndDestroy();
       
    86     iElementArray.Close();
       
    87     }
       
    88 
       
    89 // -----------------------------------------------------------------------------
       
    90 // CUpnpDeviceLibrary::PrepareShutdown
       
    91 // Prepare devices for shutdown.
       
    92 // -----------------------------------------------------------------------------
       
    93 //
       
    94 EXPORT_C void CUpnpDeviceLibrary::PrepareShutdown()
       
    95     {
       
    96     LOGSH( iHandle, "Devicelibrary PrepareShutdown" );
       
    97 
       
    98     }
       
    99 
       
   100 // -----------------------------------------------------------------------------
       
   101 // CUpnpDeviceLibrary::AddInfoL
       
   102 // Add device info.
       
   103 // -----------------------------------------------------------------------------
       
   104 //
       
   105 EXPORT_C void CUpnpDeviceLibrary::AddInfoL( const TUpnpAddLocalDevice* aIndex, 
       
   106                                         const TDesC8& aBuffer, 
       
   107                                         const TInetAddr& aLocalAddr )
       
   108     {
       
   109     LOGSH( iHandle, "Devicelibrary AddInfoL" );
       
   110     if ( !aIndex )
       
   111         {
       
   112         return;
       
   113         }
       
   114     
       
   115     TPtrC8 uuid = aBuffer.Left(aIndex->iUuidLength);    
       
   116     TInt index = Find( uuid );
       
   117     
       
   118     if ( index != KErrNotFound )
       
   119         {        
       
   120         CUpnpDeviceLibraryElement* elem = iElementArray[index];
       
   121         
       
   122         if ( elem->Local() )
       
   123             {            
       
   124             CUpnpTimeoutElement::TRenew state = elem->Renew();          
       
   125             elem->AddInfoL( aIndex, aBuffer, aLocalAddr );                        
       
   126             elem->SetRenew( CUpnpTimeoutElement::ERenew );
       
   127             elem->SetTimeout( KIntervalBeforeFirstAlive );        
       
   128             elem->SetUpdateId( iUpdateId );
       
   129                  
       
   130             if ( state == CUpnpTimeoutElement::ERemove ) 
       
   131                 {   
       
   132                 elem->SetAlive( ETrue );                
       
   133                 elem->SetUpdateId( ++iUpdateId );
       
   134                 iObserver.DeviceListChangedL();
       
   135                 }        
       
   136             }
       
   137         else
       
   138             {
       
   139             InvalidateNonLocalDevice( *elem );
       
   140             AppendLocalDeviceL( aIndex, aBuffer, aLocalAddr );                            
       
   141             iObserver.DeviceListChangedL();            
       
   142             }                
       
   143         }
       
   144     else
       
   145         {        
       
   146         AppendLocalDeviceL( aIndex, aBuffer, aLocalAddr );                
       
   147         iObserver.DeviceListChangedL();
       
   148         }
       
   149     }
       
   150 
       
   151 // -----------------------------------------------------------------------------
       
   152 // CUpnpDeviceLibrary::InvalidateNonLocalDevice
       
   153 // -----------------------------------------------------------------------------
       
   154 //
       
   155 void CUpnpDeviceLibrary::InvalidateNonLocalDevice( CUpnpDeviceLibraryElement& aElem )
       
   156     {
       
   157     aElem.SetAlive( EFalse );
       
   158     aElem.SetUpdateId( ++iUpdateId );
       
   159     aElem.SetTimeout( KIpcCommunicationTimeout );                            
       
   160     }
       
   161 
       
   162 // -----------------------------------------------------------------------------
       
   163 // CUpnpDeviceLibrary::AppendLocalDeviceL
       
   164 // -----------------------------------------------------------------------------
       
   165 //
       
   166 void CUpnpDeviceLibrary::AppendLocalDeviceL( const TUpnpAddLocalDevice* aIndex, 
       
   167                          const TDesC8& aBuffer, 
       
   168                          const TInetAddr& aLocalAddr )
       
   169     {    
       
   170     CUpnpDeviceLibraryElement* element = CUpnpDeviceLibraryElement::NewL(*this);
       
   171     CleanupStack::PushL( element );
       
   172     element->AddInfoL( aIndex, aBuffer, aLocalAddr );
       
   173     element->SetRenew( CUpnpTimeoutElement::ERenew );
       
   174     element->SetTimeout( KIntervalBeforeFirstAlive );
       
   175     element->SetLocal( ETrue );
       
   176     element->SetUpdateId( ++iUpdateId );
       
   177     iElementArray.AppendL( element );
       
   178     CleanupStack::Pop( element );    
       
   179     }
       
   180 // -----------------------------------------------------------------------------
       
   181 // CUpnpDeviceLibrary::AddInfoL
       
   182 // Add device info.
       
   183 // -----------------------------------------------------------------------------
       
   184 //
       
   185 EXPORT_C void CUpnpDeviceLibrary::AddInfoL( const TUpnpAddLocalDevice* aIndex, 
       
   186                                         const TDesC8& aBuffer )
       
   187     {
       
   188     LOGSH( iHandle, "Devicelibrary AddInfoL");
       
   189 
       
   190     if ( !aIndex )
       
   191         {
       
   192         return;
       
   193         }
       
   194     
       
   195     TPtrC8 uuid = aBuffer.Left(aIndex->iUuidLength);
       
   196     
       
   197     TInt index = Find( uuid );
       
   198     
       
   199     if ( index != KErrNotFound )
       
   200         {
       
   201         CUpnpDeviceLibraryElement* elem = iElementArray[index];
       
   202         
       
   203         CUpnpTimeoutElement::TRenew state = elem->Renew();
       
   204         
       
   205         elem->AddInfoL( aIndex, aBuffer );                        
       
   206         elem->SetRenew( CUpnpTimeoutElement::ERenew );
       
   207         elem->SetTimeout( 1 );        
       
   208         elem->SetUpdateId( iUpdateId );
       
   209              
       
   210         if (state == CUpnpTimeoutElement::ERemove) 
       
   211             {   
       
   212             iUpdateId++; 
       
   213             elem->SetAlive( ETrue );                
       
   214             elem->SetUpdateId( iUpdateId );
       
   215             iObserver.DeviceListChangedL();
       
   216             }        
       
   217         }
       
   218     else
       
   219         {
       
   220         iUpdateId++;
       
   221         
       
   222         CUpnpDeviceLibraryElement* element = CUpnpDeviceLibraryElement::NewL(*this);
       
   223         CleanupStack::PushL( element );
       
   224         element->AddInfoL( aIndex, aBuffer );
       
   225         element->SetRenew( CUpnpTimeoutElement::ERenew );
       
   226         element->SetTimeout( 1 );
       
   227         element->SetLocal( EFalse );
       
   228         element->SetUpdateId( iUpdateId );
       
   229         iElementArray.AppendL( element );
       
   230         CleanupStack::Pop( element );
       
   231         
       
   232         iObserver.DeviceListChangedL();
       
   233         }
       
   234     }
       
   235 // -----------------------------------------------------------------------------
       
   236 // CUpnpDeviceLibrary::AddInfoL
       
   237 // Add device info.
       
   238 // -----------------------------------------------------------------------------
       
   239 //
       
   240 EXPORT_C void CUpnpDeviceLibrary::AddInfoL( CUpnpSsdpMessage* aMessage )
       
   241     {
       
   242     LOGSH( iHandle, "Devicelibrary AddInfoL");
       
   243     if ( aMessage )
       
   244         {
       
   245         if ( aMessage->IsSsdpAlive() )
       
   246             {       
       
   247             if( AddDeviceL(aMessage) )
       
   248                 {  
       
   249                 iObserver.DeviceListChangedL();
       
   250                 }
       
   251             }
       
   252         else
       
   253             {
       
   254             RemoveDeviceL( aMessage );
       
   255             iObserver.DeviceListChangedL();
       
   256             }
       
   257         }
       
   258     }
       
   259 
       
   260 // -----------------------------------------------------------------------------
       
   261 // CUpnpDeviceLibrary::Find
       
   262 // Find device given by UUID.
       
   263 // -----------------------------------------------------------------------------
       
   264 //
       
   265 EXPORT_C TInt CUpnpDeviceLibrary::Find( const TDesC8& aUuid )
       
   266     {
       
   267     LOGSH( iHandle, "Devicelibrary Find");
       
   268 
       
   269     for ( TInt i=0; i<iElementArray.Count(); i++ )
       
   270         {
       
   271         if ( aUuid.FindC( iElementArray[i]->UUID() ) == 0 
       
   272              && aUuid.Length() == iElementArray[i]->UUID().Length() )
       
   273             {
       
   274             return i;
       
   275             }
       
   276         }
       
   277     return KErrNotFound;
       
   278     }
       
   279 
       
   280 // -----------------------------------------------------------------------------
       
   281 // CUpnpDeviceLibrary::RemoveL
       
   282 // Remove device by given UID. Used for local devices only.
       
   283 // -----------------------------------------------------------------------------
       
   284 //
       
   285 EXPORT_C void CUpnpDeviceLibrary::RemoveL( const TDesC8& aUuid )
       
   286     {
       
   287     LOGSH( iHandle, "Devicelibrary RemoveL");
       
   288 
       
   289     TInt result = Find( aUuid );
       
   290     
       
   291     if ( result != KErrNotFound )
       
   292         {
       
   293         CUpnpDeviceLibraryElement* elem = iElementArray[result];
       
   294 
       
   295         iObserver.AdvertiseDeviceL( EFalse, *elem );
       
   296         iObserver.AdvertiseDeviceL( EFalse, *elem );        
       
   297 
       
   298         elem->AdvertisingFinished();
       
   299         
       
   300         elem->SetRenew( CUpnpTimeoutElement::ERemove );
       
   301         elem->SetTimeout( KLocalDeviceHysteresisWindow );
       
   302         elem->SetUpdateId( ++iUpdateId );
       
   303         elem->SetAlive( EFalse );            
       
   304 
       
   305         iObserver.DeviceListChangedL();
       
   306         }
       
   307     }
       
   308 // -----------------------------------------------------------------------------
       
   309 // CUpnpDeviceLibrary::RemoveSilentL
       
   310 // Remove device by given UID. Used for local devices only.
       
   311 // -----------------------------------------------------------------------------
       
   312 //
       
   313 EXPORT_C void CUpnpDeviceLibrary::RemoveSilentL( const TDesC8& aUuid )
       
   314     {
       
   315     //LOGS( iHandle, "Devicelibrary RemoveSilentL");
       
   316     
       
   317    LOGS("CUpnpDeviceLibrary::RemoveSilentL( const TDesC8& aUuid )");
       
   318     TInt result = Find( aUuid );
       
   319     
       
   320     if ( result != KErrNotFound )
       
   321         {
       
   322         CUpnpDeviceLibraryElement* elem = iElementArray[result];
       
   323 
       
   324         
       
   325         elem->SetRenew( CUpnpTimeoutElement::ERemove );
       
   326         elem->SetTimeout( KLocalDeviceHysteresisWindow );
       
   327         elem->SetUpdateId( ++iUpdateId );
       
   328         elem->SetAlive( EFalse );            
       
   329 
       
   330         iObserver.DeviceListChangedL();
       
   331         }
       
   332          LOGS("CUpnpDeviceLibrary::RemoveSilentL( const TDesC8& aUuid ) passed");
       
   333     }
       
   334 
       
   335 // -----------------------------------------------------------------------------
       
   336 // CUpnpDeviceLibrary::TimeoutExpiredL
       
   337 // Timeout expired for advertisement.
       
   338 // -----------------------------------------------------------------------------
       
   339 //
       
   340 void CUpnpDeviceLibrary::TimeoutExpiredL( CUpnpTimeoutElement* anElement )
       
   341     {
       
   342     LOGSH( iHandle, "Devicelibrary TimeoutExpiredL");
       
   343 
       
   344     if ( !anElement )
       
   345         {
       
   346         return;
       
   347         }
       
   348     
       
   349     CUpnpDeviceLibraryElement* elem = 
       
   350         static_cast<CUpnpDeviceLibraryElement*>(anElement);
       
   351     
       
   352     switch ( elem->Renew() )
       
   353         {
       
   354         case CUpnpTimeoutElement::ERenew:
       
   355             {
       
   356             if ( !elem->Advertised() )
       
   357                 {
       
   358                 elem->Advertising();
       
   359                 // whatever happends we don't want to have leave here
       
   360                 TRAP_IGNORE( iObserver.AdvertiseDeviceL( EFalse, *elem ));
       
   361                 TRAP_IGNORE( iObserver.AdvertiseDeviceL( EFalse, *elem ));
       
   362                 elem->SetTimeout( KIntervalBetweenByeAndAlive );
       
   363                 }
       
   364             else 
       
   365                 {
       
   366                 // whatever happends we don't want to have leave here
       
   367                 TRAP_IGNORE( iObserver.AdvertiseDeviceL( ETrue, *elem ));
       
   368                 elem->SetTimeout( KDeviceTimeout );
       
   369                 }
       
   370             }
       
   371             break;
       
   372             
       
   373         case CUpnpTimeoutElement::EOnce: // after cache control expires
       
   374             {    
       
   375             // Set the timeout for the device to be removed
       
   376             iUpdateId++;
       
   377             elem->SetRenew( CUpnpTimeoutElement::ERemove );
       
   378             if( elem->Local() )
       
   379                 {
       
   380                 elem->SetTimeout( KLocalDeviceHysteresisWindow );    
       
   381                 }
       
   382             else
       
   383                 {
       
   384                 elem->SetTimeout( KIpcCommunicationTimeout );
       
   385                 }
       
   386             elem->SetUpdateId( iUpdateId );
       
   387             elem->SetAlive( EFalse );
       
   388             elem->SetExpired( ETrue );
       
   389 
       
   390             iObserver.DeviceListChangedL();
       
   391             }
       
   392             break;
       
   393 
       
   394         case CUpnpTimeoutElement::ERemove:
       
   395             {
       
   396             // Remove device from the element array
       
   397             for ( TInt i=0; i<iElementArray.Count(); i++ )
       
   398                 {
       
   399                 if ( elem == iElementArray[i] )
       
   400                     {
       
   401                     iElementArray.Remove( i );
       
   402                     iElementArray.Compress();
       
   403                     
       
   404                     delete elem;
       
   405                     break;
       
   406                     }
       
   407                 }
       
   408             }
       
   409             break;
       
   410 
       
   411         default:
       
   412             break;
       
   413         }
       
   414     }
       
   415 
       
   416 // -----------------------------------------------------------------------------
       
   417 // CUpnpDeviceLibrary::DeviceList
       
   418 // Return device list.
       
   419 // -----------------------------------------------------------------------------
       
   420 //
       
   421 EXPORT_C RPointerArray<CUpnpDeviceLibraryElement>& CUpnpDeviceLibrary::DeviceList()
       
   422     {
       
   423     LOGSH( iHandle, "Devicelibrary DeviceList");
       
   424 
       
   425     return iElementArray;
       
   426     }
       
   427 
       
   428 // -----------------------------------------------------------------------------
       
   429 // CUpnpDeviceLibrary::GetUpdate
       
   430 // Get update.
       
   431 // -----------------------------------------------------------------------------
       
   432 //
       
   433 EXPORT_C void CUpnpDeviceLibrary::GetUpdate( TInt& aUpdateId, 
       
   434                                          TUpnpDevice *&aDevices, 
       
   435                                          TUpnpService *&aServices,
       
   436                                          TInt& aDeviceCount,
       
   437                                          TInt& aServiceCount )
       
   438     {
       
   439     aDevices = NULL;
       
   440     aServices = NULL;
       
   441     
       
   442     TUpnpDevice* devices = NULL;
       
   443     TUpnpService* services = NULL;
       
   444     
       
   445     aDeviceCount = 0;
       
   446     aServiceCount = 0;
       
   447     
       
   448     for ( TInt i = 0; i < iElementArray.Count(); i++ )
       
   449         {
       
   450         CUpnpDeviceLibraryElement* elem = iElementArray[i];
       
   451         
       
   452         if (elem->UpdateId() > aUpdateId)
       
   453             {
       
   454             TUpnpDevice* temp = new TUpnpDevice[aDeviceCount+1];
       
   455             if ( !temp )
       
   456                 {
       
   457                 continue;
       
   458                 }
       
   459             
       
   460             TPtr8 destPtr(reinterpret_cast<TUint8*>(temp), 
       
   461                 0,
       
   462                 sizeof(TUpnpDevice)*(aDeviceCount+1));
       
   463             TPtr8 srcPtr(reinterpret_cast<TUint8*>(devices),
       
   464                 sizeof(TUpnpDevice)*aDeviceCount,
       
   465                 sizeof(TUpnpDevice)*aDeviceCount);
       
   466             
       
   467             destPtr.Copy(srcPtr);
       
   468             
       
   469             if (devices)
       
   470                 {
       
   471                 delete[] devices;
       
   472                 devices = NULL;
       
   473                 }
       
   474             
       
   475             devices = temp;
       
   476             
       
   477             TUpnpDevice devtemp;
       
   478             destPtr.Set(reinterpret_cast<TUint8*>(&devices[aDeviceCount]),
       
   479                 0,
       
   480                 sizeof(TUpnpDevice));
       
   481             srcPtr.Set(reinterpret_cast<TUint8*>(&devtemp), 
       
   482                 sizeof(TUpnpDevice),
       
   483                 sizeof(TUpnpDevice));
       
   484             destPtr.Copy(srcPtr);
       
   485             
       
   486             devices[aDeviceCount].Set(elem);
       
   487             
       
   488             TInt servs = elem->ServiceList().Count();
       
   489             
       
   490             TUpnpService* tempServ = new TUpnpService[aServiceCount+servs];
       
   491             if ( !tempServ )
       
   492                 {
       
   493                 delete [] temp;
       
   494                 temp = NULL;
       
   495                 devices = NULL;
       
   496                 continue;
       
   497                 }
       
   498             
       
   499             destPtr.Set(reinterpret_cast<TUint8*>(tempServ), 
       
   500                 0,
       
   501                 sizeof(TUpnpService)*(aServiceCount+servs));
       
   502             srcPtr.Set(reinterpret_cast<TUint8*>(services),
       
   503                 sizeof(TUpnpService)*aServiceCount,
       
   504                 sizeof(TUpnpService)*aServiceCount);
       
   505             
       
   506             destPtr.Copy(srcPtr);
       
   507             
       
   508             if (services)
       
   509                 {
       
   510                 delete[] services;
       
   511                 services = NULL;
       
   512                 }
       
   513             
       
   514             services = tempServ;
       
   515             
       
   516             for (TInt j=0; j<servs; j++)
       
   517                 {
       
   518                 TUpnpService service;
       
   519                 destPtr.Set(reinterpret_cast<TUint8*>(&services[aServiceCount]),
       
   520                     0,
       
   521                     sizeof(TUpnpService));
       
   522                 srcPtr.Set(reinterpret_cast<TUint8*>(&service), 
       
   523                     sizeof(TUpnpService),
       
   524                     sizeof(TUpnpService));
       
   525                 destPtr.Copy(srcPtr);
       
   526                 
       
   527                 services[aServiceCount].iServiceType.Zero();
       
   528                 services[aServiceCount].iServiceType.Append(
       
   529                     elem->ServiceList()[j] );
       
   530                 
       
   531                 aServiceCount++;
       
   532                 }
       
   533             
       
   534             aDeviceCount++;
       
   535             }
       
   536         }
       
   537     
       
   538     aUpdateId = iUpdateId;
       
   539     
       
   540     aDevices = devices;
       
   541     aServices = services;
       
   542     }
       
   543     
       
   544 // -----------------------------------------------------------------------------
       
   545 // CUpnpDeviceLibrary::RemoveAllDevicesL
       
   546 // Removes all remote devices from device library.
       
   547 // -----------------------------------------------------------------------------
       
   548 //
       
   549 EXPORT_C void CUpnpDeviceLibrary::RemoveAllDevicesL()
       
   550     {
       
   551     for (TInt i = 0; i < iElementArray.Count(); i++)
       
   552         {
       
   553         CUpnpDeviceLibraryElement* elem = iElementArray[i];
       
   554         if ( elem->Alive() )
       
   555             {
       
   556             iUpdateId++;
       
   557             elem->SetAlive(EFalse);
       
   558             elem->SetUpdateId( iUpdateId );
       
   559             if( elem->Renew() == CUpnpTimeoutElement::EOnce )
       
   560                 {
       
   561                 elem->SetRenew( CUpnpTimeoutElement::ERemove );
       
   562                 elem->SetTimeout( KIpcCommunicationTimeout );
       
   563                 }
       
   564             }
       
   565         }
       
   566     iObserver.DeviceListChangedL();        
       
   567     }    
       
   568 
       
   569 // -----------------------------------------------------------------------------
       
   570 // TUpnpDevice::Set
       
   571 // Set device.
       
   572 // -----------------------------------------------------------------------------
       
   573 //
       
   574 EXPORT_C void TUpnpDevice::Set(CUpnpDeviceLibraryElement* aElem)
       
   575     {
       
   576     LOGS("Devicelibrary Set");
       
   577 
       
   578     if ( !aElem )
       
   579         {
       
   580         return;
       
   581         }
       
   582 
       
   583     iDescriptionURL = aElem->DescriptionUrl().Left( iDescriptionURL.MaxLength() );
       
   584     iUUID = aElem->UUID().Left( iUUID.MaxLength() );
       
   585     iDeviceType = aElem->DeviceType().Left( iDeviceType.MaxLength() );
       
   586     iDomain = aElem->Domain().Left( iDomain.MaxLength() );
       
   587 
       
   588     iServiceCount = aElem->ServiceList().Count();
       
   589     iLocal = aElem->Local();
       
   590     iRemote = EFalse;
       
   591     iAlive = aElem->Alive();
       
   592     iExpired = aElem->Expired();
       
   593     }
       
   594 
       
   595 // -----------------------------------------------------------------------------
       
   596 // CUpnpDeviceLibrary::AddDeviceL
       
   597 // Add a device.
       
   598 // -----------------------------------------------------------------------------
       
   599 //
       
   600 TBool CUpnpDeviceLibrary::AddDeviceL(CUpnpSsdpMessage *aMessage)
       
   601     {
       
   602     TBool update = EFalse;
       
   603 
       
   604     LOGSH( iHandle, "Devicelibrary AddDeviceL");
       
   605 
       
   606     if ( !aMessage )
       
   607         {
       
   608         return update;
       
   609         }
       
   610     
       
   611     TPtr8 uuidPtr = aMessage->Uuid();
       
   612     TInt index = Find( uuidPtr );
       
   613     
       
   614     if (index != KErrNotFound)
       
   615         {
       
   616         CUpnpDeviceLibraryElement* elem = iElementArray[index];
       
   617         if ( !elem->Local() )
       
   618         {
       
   619             if( elem->Renew() == CUpnpTimeoutElement::ERemove )
       
   620                 {
       
   621                 iElementArray.Remove( index );
       
   622                 iElementArray.Compress();
       
   623                 
       
   624                 delete elem;
       
   625                 
       
   626                 CUpnpDeviceLibraryElement* element = CUpnpDeviceLibraryElement::NewL(*this);
       
   627                 CleanupStack::PushL(element);
       
   628                 
       
   629                 update = element->AddInfoL(aMessage, iUpdateId);
       
   630                 
       
   631                 element->SetRenew(CUpnpTimeoutElement::EOnce);
       
   632                 element->SetTimeout(aMessage->CacheControl());
       
   633                 element->SetLocal(EFalse);
       
   634                 iElementArray.Append(element);
       
   635                 
       
   636                 CleanupStack::Pop(); // element
       
   637                 }
       
   638             
       
   639             else 
       
   640                 {
       
   641                 if(elem->Filter())
       
   642                     {
       
   643                     //Alive message from 
       
   644                     if(elem->AddInfoL(aMessage, iUpdateId))
       
   645                         {
       
   646                         update=ETrue;
       
   647                         }
       
   648                     elem->SetTimeout(aMessage->CacheControl());    
       
   649                     }
       
   650                 else
       
   651                     {
       
   652                     iElementArray.Remove( index );
       
   653                     iElementArray.Compress();
       
   654                 
       
   655                     delete elem;
       
   656                 
       
   657                     CUpnpDeviceLibraryElement* element = CUpnpDeviceLibraryElement::NewL(*this);
       
   658                     CleanupStack::PushL(element);
       
   659                 
       
   660                     update = element->AddInfoL(aMessage, iUpdateId);
       
   661                 
       
   662                     element->SetRenew(CUpnpTimeoutElement::EOnce);
       
   663                     element->SetTimeout(aMessage->CacheControl());
       
   664                     element->SetLocal(EFalse);
       
   665                     iElementArray.Append(element);
       
   666                 
       
   667                     CleanupStack::Pop(); // element
       
   668                     }
       
   669                 }
       
   670             }
       
   671         }
       
   672     else
       
   673         {    
       
   674         CUpnpDeviceLibraryElement* element = CUpnpDeviceLibraryElement::NewL(*this);
       
   675         CleanupStack::PushL(element);
       
   676         
       
   677         update = element->AddInfoL(aMessage, iUpdateId);
       
   678         
       
   679         element->SetRenew(CUpnpTimeoutElement::EOnce);
       
   680         element->SetTimeout(aMessage->CacheControl());
       
   681         element->SetLocal(EFalse);
       
   682         iElementArray.Append(element);
       
   683         
       
   684         CleanupStack::Pop(); // element
       
   685         }
       
   686     return update;
       
   687     }
       
   688 
       
   689 // -----------------------------------------------------------------------------
       
   690 // CUpnpDeviceLibrary::RemoveDevice
       
   691 // Remove a device.
       
   692 // -----------------------------------------------------------------------------
       
   693 //
       
   694 void CUpnpDeviceLibrary::RemoveDeviceL( CUpnpSsdpMessage *aMessage )
       
   695     {
       
   696     LOGSH( iHandle, "Devicelibrary RemoveDevice" );
       
   697 
       
   698     if ( !aMessage )
       
   699         {
       
   700         return;
       
   701         }
       
   702     
       
   703     TPtr8 uuidPtr = aMessage->Uuid();
       
   704     TInt index = Find( uuidPtr );
       
   705     
       
   706     if ( index != KErrNotFound )
       
   707         {
       
   708         CUpnpDeviceLibraryElement* elem = iElementArray[index];
       
   709         if ( !elem->Local() )
       
   710             {
       
   711             if ( elem->Alive() )
       
   712                 {
       
   713                 iUpdateId++;
       
   714                 elem->SetAlive(EFalse);
       
   715                 elem->SetUpdateId( iUpdateId );
       
   716                 if( elem->Renew() == CUpnpTimeoutElement::EOnce )
       
   717                     {
       
   718                     elem->SetRenew( CUpnpTimeoutElement::ERemove );
       
   719                     elem->SetTimeout( KIpcCommunicationTimeout );
       
   720                     }
       
   721                 }
       
   722             iObserver.DeviceListChangedL();
       
   723             }
       
   724         }
       
   725     else
       
   726         {        
       
   727         CUpnpDeviceLibraryElement* element = CUpnpDeviceLibraryElement::NewL( *this );
       
   728         CleanupStack::PushL( element );
       
   729 
       
   730         element->AddInfoL( aMessage, iUpdateId );
       
   731 
       
   732         iUpdateId++;
       
   733         element->SetAlive( EFalse );
       
   734         element->SetUpdateId( iUpdateId );
       
   735         element->SetRenew( CUpnpTimeoutElement::ERemove );
       
   736         element->SetTimeout( KIpcCommunicationTimeout );
       
   737         element->SetLocal( EFalse );
       
   738         iElementArray.AppendL( element );
       
   739         
       
   740         CleanupStack::Pop( element );
       
   741         
       
   742         iObserver.DeviceListChangedL();
       
   743         }
       
   744     }
       
   745 
       
   746 // -----------------------------------------------------------------------------
       
   747 // CUpnpDeviceLibrary::StopFilteringDeviceL
       
   748 // -----------------------------------------------------------------------------
       
   749 //
       
   750 EXPORT_C void CUpnpDeviceLibrary::StopFilteringDeviceL( const TDesC8& aUuid )
       
   751     {
       
   752     LOGSH( iHandle, "Devicelibrary RemoveDevice" );
       
   753 
       
   754     TInt index = Find( aUuid );
       
   755     
       
   756     if ( index != KErrNotFound )
       
   757         {
       
   758         CUpnpDeviceLibraryElement* elem = iElementArray[index];
       
   759         elem->SetFilter(EFalse);
       
   760         }
       
   761     }
       
   762 
       
   763 //  End of File