upnp/upnpstack/serviceframework/src/upnpdeviceimplementationbase.cpp
changeset 0 f5a58ecadc66
child 12 78fbd574edf4
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:  Defines the CUpnpDeviceImplementationBase class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 
       
    21 #include <e32math.h>
       
    22 #include <xmlengdom.h> 
       
    23 
       
    24 #include "upnpfileutils.h"
       
    25 #include "upnpicon.h"
       
    26 #include "upnpdeviceimplementationbase.h"
       
    27 #include "upnpcommonstructs.h"
       
    28 #include "upnpstring.h"
       
    29 #include "upnpdispatcher.h"
       
    30 #include "upnpcons.h"
       
    31 #include "upnpcommonupnplits.h"
       
    32 #include "upnpcustomlog.h"
       
    33 #include "upnpserviceimplementation.h"
       
    34 #include <upnpdevicedescriptionstore.h>
       
    35 #include "upnphttpservertransactionhandler.h"
       
    36 
       
    37 
       
    38 #ifdef _DEBUG
       
    39 #define KLogFile _L("UPnPStack.txt")
       
    40 #endif
       
    41 
       
    42 // ============================= LOCAL FUNCTIONS ===============================
       
    43 
       
    44 // -----------------------------------------------------------------------------
       
    45 // CUpnpDeviceImplementationBase::ConstructL
       
    46 // -----------------------------------------------------------------------------
       
    47 //
       
    48 void CUpnpDeviceImplementationBase::BaseConstructL( const TDesC8& aDeviceDescriptioUri,
       
    49                                             CUpnpDeviceDescriptionStore& aDescriptionStore,
       
    50                                             MUpnpDeviceDescriptionProvider& aProvider )
       
    51     {
       
    52     iDescriptionProvider = &aProvider;
       
    53     iDescriptionStore = &aDescriptionStore;
       
    54     
       
    55     iPath = DeviceType().AllocL();
       
    56 
       
    57     SetDescriptionUrlL( aDeviceDescriptioUri );
       
    58 
       
    59     CreateDispatcherL();
       
    60     RegisterEmbeddedDevices();
       
    61 
       
    62     iIsRootDevice = ETrue;
       
    63 
       
    64     Init();
       
    65     
       
    66     iServerTransactionHandler = CUpnpHttpServerTransactionHandler::NewL( *this );
       
    67     iDispatcher->SetTransactionCreator( iServerTransactionHandler );    
       
    68     }
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 // CUpnpDeviceImplementationBase::RegisterEmbeddedDevices
       
    72 // -----------------------------------------------------------------------------
       
    73 //
       
    74 void CUpnpDeviceImplementationBase::RegisterEmbeddedDevices()
       
    75     {
       
    76     RPointerArray<CUpnpDevice> devices;
       
    77     GetAllDevices(devices);
       
    78     for (TInt i = 0; i < iDeviceList.Count(); i++ )
       
    79     {
       
    80         ((CUpnpDeviceImplementationBase*) iDeviceList[i])->SetDispatcher(iDispatcher);
       
    81     }
       
    82 
       
    83     devices.Reset();
       
    84     devices.Close();
       
    85     }
       
    86 
       
    87 
       
    88 // -----------------------------------------------------------------------------
       
    89 // CUpnpDeviceImplementationBase::~CUpnpDeviceImplementationBase
       
    90 // -----------------------------------------------------------------------------
       
    91 //
       
    92 EXPORT_C CUpnpDeviceImplementationBase::~CUpnpDeviceImplementationBase()
       
    93     {
       
    94     for ( TInt i = ServiceList().Count();  i > 0; i-- )
       
    95         {
       
    96         if ( ServiceList()[i-1]->IsComplete() )
       
    97             {
       
    98             ServiceList().Remove( i-1 );
       
    99             }
       
   100         }
       
   101     if ( iIsRootDevice )
       
   102         {
       
   103         delete iDispatcher;
       
   104         }
       
   105     delete iPath;        
       
   106     delete iServerTransactionHandler;    
       
   107     }
       
   108 
       
   109 // -----------------------------------------------------------------------------
       
   110 // CUpnpDeviceImplementationBase::CUpnpDeviceImplementationBase
       
   111 // C++ default constructor
       
   112 // -----------------------------------------------------------------------------
       
   113 //
       
   114 CUpnpDeviceImplementationBase::CUpnpDeviceImplementationBase()
       
   115     {
       
   116     }
       
   117 
       
   118 // -----------------------------------------------------------------------------
       
   119 // CUpnpDeviceImplementationBase::SetDescriptionPropertyL
       
   120 // -----------------------------------------------------------------------------
       
   121 //
       
   122 EXPORT_C void CUpnpDeviceImplementationBase::SetDescriptionPropertyL( const TDesC8& aPropertyName, 
       
   123                                                                   const TDesC8& aPropertyValue )
       
   124     {
       
   125     TInt index = 0;
       
   126 
       
   127     while ( index < iProperties.Count() )
       
   128         {
       
   129         CUpnpDescriptionProperty* var = iProperties[index];
       
   130 
       
   131         if ( aPropertyName.Compare( var->Name() ) == KErrNone )
       
   132             {
       
   133             var->SetValueL( aPropertyValue );
       
   134             iDescriptionStore->SetPropertyL( aPropertyName, aPropertyValue );
       
   135             return;
       
   136             }
       
   137 
       
   138         index++;
       
   139         }
       
   140     
       
   141     CUpnpDescriptionProperty* newProperty = CUpnpDescriptionProperty::NewL( aPropertyName,
       
   142                                                                             aPropertyValue );
       
   143     CleanupStack::PushL( newProperty );        
       
   144     iProperties.AppendL( newProperty );
       
   145     CleanupStack::Pop( newProperty );
       
   146     iDescriptionStore->SetPropertyL( aPropertyName, aPropertyValue );
       
   147     }
       
   148     
       
   149 // -----------------------------------------------------------------------------
       
   150 // CUpnpDeviceImplementationBase::RemoveDescriptionPropertyL
       
   151 // -----------------------------------------------------------------------------
       
   152 //
       
   153 EXPORT_C void CUpnpDeviceImplementationBase::RemoveDescriptionPropertyL( 
       
   154                                                       const TDesC8& aPropertyName )
       
   155     {
       
   156     TInt index = 0;
       
   157 
       
   158     while ( index < iProperties.Count() )
       
   159         {
       
   160         if ( aPropertyName.Compare( iProperties[index]->Name() ) == KErrNone )
       
   161             {
       
   162             iDescriptionStore->RemoveTagL( aPropertyName );    
       
   163             delete iProperties[index];
       
   164             iProperties.Remove( index );
       
   165             return;
       
   166             }
       
   167         index++;
       
   168         }
       
   169     }
       
   170     
       
   171 // -----------------------------------------------------------------------------
       
   172 // CUpnpDeviceImplementationBase::RemoveIconL
       
   173 // -----------------------------------------------------------------------------
       
   174 //
       
   175 EXPORT_C void CUpnpDeviceImplementationBase::RemoveIconL( const TDesC8& aUrl )
       
   176     {    
       
   177     iDescriptionStore->RemoveIconL( aUrl );
       
   178     
       
   179     TInt amount = iIcons.Count();
       
   180     
       
   181     for(TInt i = 0; i < amount; i++)
       
   182         {
       
   183         if(!aUrl.Compare(iIcons[i]->Url()))
       
   184             {
       
   185             delete iIcons[i];
       
   186             iIcons.Remove(i);
       
   187             break;
       
   188             }
       
   189         }
       
   190     }
       
   191 
       
   192 // -----------------------------------------------------------------------------
       
   193 // CUpnpDeviceImplementationBase::RemoveIconsL
       
   194 // -----------------------------------------------------------------------------
       
   195 //
       
   196 EXPORT_C void CUpnpDeviceImplementationBase::RemoveIconsL()
       
   197     {    
       
   198     iDescriptionStore->RemoveIconsL();
       
   199     TInt amount = iIcons.Count();
       
   200     
       
   201     for(TInt i = amount - 1; i >= 0; i--)
       
   202         {
       
   203         delete iIcons[i];
       
   204         iIcons.Remove(i);
       
   205         }
       
   206     }
       
   207 
       
   208 // -----------------------------------------------------------------------------
       
   209 // CUpnpDeviceImplementationBase::AddIconL
       
   210 // -----------------------------------------------------------------------------
       
   211 //
       
   212 EXPORT_C void CUpnpDeviceImplementationBase::AddIconL( const CUpnpIcon& aIcon )
       
   213     {    
       
   214     iDescriptionStore->AddIconL( aIcon );
       
   215     iIcons.Append( &aIcon );
       
   216     }
       
   217 
       
   218 // -----------------------------------------------------------------------------
       
   219 // CUpnpDeviceImplementationBase::UpdateIconL
       
   220 // -----------------------------------------------------------------------------
       
   221 //
       
   222 EXPORT_C void CUpnpDeviceImplementationBase::UpdateIconL( const CUpnpIcon& aIcon )
       
   223     {    
       
   224     iDescriptionStore->UpdateIconL( aIcon );
       
   225     TInt amount = iIcons.Count();
       
   226     
       
   227     for(TInt i = 0; i < amount; i++)
       
   228         {
       
   229         if(!aIcon.Url().Compare(iIcons[i]->Url()))
       
   230             {
       
   231             delete iIcons[i];
       
   232             iIcons.Remove(i);
       
   233             iIcons.Insert(&aIcon, i);
       
   234             }
       
   235         }
       
   236     }
       
   237 
       
   238 // -----------------------------------------------------------------------------
       
   239 // CUpnpDeviceImplementationBase::SaveDescriptionStoreL
       
   240 // -----------------------------------------------------------------------------
       
   241 //
       
   242 void CUpnpDeviceImplementationBase::SaveDescriptionStoreL()
       
   243     {
       
   244     iDescriptionStore->SaveL();
       
   245     }
       
   246 
       
   247 // -----------------------------------------------------------------------------
       
   248 // CUpnpDeviceImplementationBase::StartHttpServerL
       
   249 // -----------------------------------------------------------------------------
       
   250 //
       
   251 void CUpnpDeviceImplementationBase::StartHttpServerL( const TInt aPort )
       
   252     {
       
   253     if ( iIsRootDevice ) 
       
   254         {
       
   255     	iDispatcher->StartHttpServerL( ETrue , aPort );
       
   256         }   
       
   257     }
       
   258     
       
   259 // -----------------------------------------------------------------------------
       
   260 // CUpnpDeviceImplementationBase::Dispatcher
       
   261 // -----------------------------------------------------------------------------
       
   262 //
       
   263 CUpnpDispatcher* CUpnpDeviceImplementationBase::Dispatcher()
       
   264     {
       
   265     return iDispatcher;
       
   266     }
       
   267 
       
   268 // -----------------------------------------------------------------------------
       
   269 // CUpnpDeviceImplementationBase::StopHttpServer
       
   270 // -----------------------------------------------------------------------------
       
   271 //
       
   272 void CUpnpDeviceImplementationBase::StopHttpServer()
       
   273     {
       
   274     iDispatcher->StopHttpServer();
       
   275     }
       
   276 
       
   277 // -----------------------------------------------------------------------------
       
   278 // CUpnpDeviceImplementationBase::CreateDispatcherL
       
   279 // -----------------------------------------------------------------------------
       
   280 //
       
   281 void CUpnpDeviceImplementationBase::CreateDispatcherL()
       
   282     {
       
   283     iDispatcher = CUpnpDispatcher::NewL( NULL );
       
   284     }
       
   285 
       
   286 // -----------------------------------------------------------------------------
       
   287 //  CUpnpDeviceImplementationBase::GenerateUuidL
       
   288 //  Generates Universally Unique Identifier using good algorithm
       
   289 //
       
   290 //  UUID  =  Universally Unique Identifier
       
   291 //  128 bit UUID (HEX)
       
   292 //  
       
   293 //  01234567   - 0123       - 0123                  - 0123       - 012345678901
       
   294 //  <time_low> - <time_mid> - <time_high & version> - 
       
   295 //  <clock_seq & reserved><clock_seq_low> - <node> 
       
   296 //  8"-"4"-"4"-"4"-"12
       
   297 //  (other items were commented in a header).
       
   298 // -----------------------------------------------------------------------------
       
   299 HBufC8* CUpnpDeviceImplementationBase::GenerateUuidL()
       
   300     {    
       
   301     const TInt smallBlockSize = 4;
       
   302     const TInt largeBlockSize = 8;    
       
   303     
       
   304     //Reserves enough space for the UUID (128bits)
       
   305     HBufC8* uuid = HBufC8::NewLC( UpnpString::KMaxUuidLength );  
       
   306     
       
   307     // setting time
       
   308     TTime timex;
       
   309     timex.UniversalTime();
       
   310     
       
   311     HBufC8* currTime = HBufC8::NewLC( largeBlockSize );
       
   312     
       
   313     TInt timeMaskHi = 0x0FFFFFFF;
       
   314     TInt timeMaskVer = 0x10000000;
       
   315     
       
   316     TInt joinMask = 0x8000;
       
   317     TInt rndTimeMask = 0xBFFF;
       
   318     TInt bitChange = 0x0000FFFF;
       
   319     
       
   320     //Returns a 64bit interpretation of the current time
       
   321     TInt64 timeValue = timex.Int64();
       
   322 
       
   323     TInt32 timeValLow = I64LOW(timeValue);
       
   324     TInt32 timeValHi = I64HIGH(timeValue);
       
   325 
       
   326     //Joining the Time and Version Elements    
       
   327     timeValHi = timeValHi & timeMaskHi;
       
   328     timeValHi = timeValHi | timeMaskVer;
       
   329     
       
   330     currTime->Des().Format( KMask8, timeValHi );
       
   331     
       
   332     // larger buffer required ... +1
       
   333     HBufC8* timeLow = HBufC8::NewLC( largeBlockSize + 1 );
       
   334     HBufC8* timeMid = HBufC8::NewLC( smallBlockSize + 1 );
       
   335     HBufC8* timeHi  = HBufC8::NewLC( smallBlockSize + 1 );
       
   336     
       
   337     //Dividing Time element to the wanted parts. 
       
   338     timeLow->Des().Format( KMask8, timeValLow );
       
   339     
       
   340     timeMid->Des().Append( currTime->Des().Right(smallBlockSize) );
       
   341     timeHi->Des().Append( currTime->Des().Left(smallBlockSize) );
       
   342     
       
   343     if ( iClockSeq == NULL )
       
   344         {
       
   345         //Clock Sequence creation ( random time plus variant )
       
   346         iClockSeq = HBufC8::NewL( smallBlockSize + 1 );
       
   347         iClockSeq->Des().Zero();
       
   348         
       
   349         TInt64 seed = timex.Int64();
       
   350         TUint32 rndTimeTInt = Math::Rand( seed );
       
   351         rndTimeTInt = rndTimeTInt & bitChange;
       
   352         rndTimeTInt = rndTimeTInt >> 2; 
       
   353         rndTimeTInt = rndTimeTInt | joinMask;
       
   354         rndTimeTInt = rndTimeTInt & rndTimeMask;
       
   355         
       
   356         iClockSeq->Des().Num( (TUint16) rndTimeTInt,EHex );
       
   357         HBufC8* buf = iClockSeq->Des().Right( smallBlockSize ).AllocL();
       
   358         
       
   359         delete iClockSeq;
       
   360         iClockSeq = buf;
       
   361         }
       
   362     else if ( iTimeValue>timeValue )
       
   363         {
       
   364         TInt rndTimeTInt;  
       
   365         if ( UpnpString::StringToInt( iClockSeq->Des(),&rndTimeTInt ) == KErrNone )
       
   366             {
       
   367             rndTimeTInt++;
       
   368             iClockSeq->Des().Num( (TUint16) rndTimeTInt,EHex );
       
   369             HBufC8* buf = iClockSeq->Des().Right(smallBlockSize).AllocL();
       
   370             delete iClockSeq;
       
   371             iClockSeq = buf;
       
   372             }
       
   373         }
       
   374     
       
   375     //reading the NodeAddress. 
       
   376     iTimeValue = timeValue;
       
   377     
       
   378     // setting UUID 
       
   379     uuid->Des().Zero();
       
   380     uuid->Des().Append( KUuid() );
       
   381     uuid->Des().Append( timeLow->Des() );
       
   382     uuid->Des().Append( KLine );
       
   383     uuid->Des().Append( timeMid->Des() );
       
   384     uuid->Des().Append( KLine );
       
   385     uuid->Des().Append( timeHi->Des() );
       
   386     uuid->Des().Append( KLine );
       
   387     uuid->Des().Append( iClockSeq->Des() );
       
   388     uuid->Des().Append( KLine );
       
   389     
       
   390     HBufC8* mac=NULL;
       
   391     TRAPD(err, mac = const_cast<HBufC8*>( iDispatcher->MacAddressL() ));
       
   392     if(!err)
       
   393         {    
       
   394         // Calculate remaining lenght, MAC can be corrupted and too long for Append
       
   395         TInt freeLen = UpnpString::KMaxUuidLength - uuid->Length();
       
   396         // If less free lenght than mac lenght, Append only what fits
       
   397         if ( freeLen < mac->Length() )
       
   398             {
       
   399             uuid->Des().Append( mac->Des().Left( freeLen ) );
       
   400             }
       
   401         // Mac fits, Append all
       
   402         else
       
   403             {
       
   404             uuid->Des().Append( mac->Des() );        
       
   405             }
       
   406         }
       
   407     else
       
   408         {
       
   409         TInt freeLen = UpnpString::KMaxUuidLength - uuid->Length();
       
   410         for(TInt i = 0; i < freeLen; i++)
       
   411             {
       
   412             TUint32 r = Math::Random();
       
   413             const TUint32 KOneHexFromInt32Mask = 0x0000000f;
       
   414             r &= KOneHexFromInt32Mask;
       
   415             TBuf<1> d;
       
   416             d.Num(r,EHex);
       
   417             uuid->Des().Append(d);
       
   418             }
       
   419         }
       
   420     
       
   421     delete mac;
       
   422     mac = NULL;
       
   423     
       
   424     // PopAndDestroy: timeLow, timeMid, timeHi, currTime;
       
   425     CleanupStack::PopAndDestroy( 4 );
       
   426     
       
   427     CleanupStack::Pop( uuid );
       
   428     return uuid;
       
   429     }
       
   430     
       
   431 // -----------------------------------------------------------------------------
       
   432 // CUpnpDeviceImplementationBase::GenerateUDNs
       
   433 // -----------------------------------------------------------------------------
       
   434 //
       
   435 void CUpnpDeviceImplementationBase::GenerateUdnsL( CUpnpDeviceImplementationBase* aDevice )
       
   436     {
       
   437     
       
   438     if ( aDevice->Uuid().Length() <= 0 )
       
   439         {
       
   440         HBufC8* udnPtr = aDevice->GenerateUuidL();    
       
   441         CleanupStack::PushL( udnPtr );
       
   442 
       
   443         aDevice->iDescriptionStore->SetPropertyL( KUdn, *udnPtr );
       
   444         
       
   445         TPtrC8 uuid(*udnPtr);    
       
   446         if ( !uuid.Find( UpnpSSDP::KUPnPUuid() ) )
       
   447             {
       
   448             uuid.Set( uuid.Mid( UpnpSSDP::KUPnPUuid().Size() ) );         
       
   449             }                                   
       
   450         aDevice->SetUuidL( uuid );
       
   451         CleanupStack::PopAndDestroy( udnPtr );                        
       
   452         }
       
   453               
       
   454      RPointerArray<CUpnpDevice>& devices = aDevice->DeviceList();
       
   455     
       
   456      for ( TInt i(0); i< devices.Count(); i++ )
       
   457         {
       
   458         GenerateUdnsL( (CUpnpDeviceImplementationBase*) devices[i] );
       
   459         }
       
   460     }
       
   461     
       
   462 
       
   463 // -----------------------------------------------------------------------------
       
   464 // CUpnpDeviceImplementationBase::AttachServiceL
       
   465 // -----------------------------------------------------------------------------
       
   466 //
       
   467 void CUpnpDeviceImplementationBase::AttachServiceL( CUpnpService *aService )
       
   468     {
       
   469     CUpnpDevice::AttachServiceL( aService );
       
   470     if ( iDispatcher )
       
   471         {
       
   472         ((CUpnpServiceImplementation*) aService)->SetDispatcher( iDispatcher );
       
   473         }    
       
   474     }
       
   475 
       
   476 // -----------------------------------------------------------------------------
       
   477 // CUpnpDeviceImplementationBase::Address
       
   478 // -----------------------------------------------------------------------------
       
   479 //
       
   480 EXPORT_C TInetAddr CUpnpDeviceImplementationBase::Address()
       
   481     {
       
   482     iAddress = iDispatcher->HttpServerAddress();
       
   483     return iAddress;
       
   484     }
       
   485     
       
   486 // -----------------------------------------------------------------------------
       
   487 // CUpnpDeviceImplementationBase::SetDispatcher
       
   488 // -----------------------------------------------------------------------------
       
   489 //
       
   490 void CUpnpDeviceImplementationBase::SetDispatcher( CUpnpDispatcher* aDispatcher )
       
   491     {
       
   492     iDispatcher = aDispatcher;    
       
   493     }
       
   494 
       
   495 // -----------------------------------------------------------------------------
       
   496 // CUpnpDeviceImplementationBase::DescritptionProvider
       
   497 // -----------------------------------------------------------------------------
       
   498 //
       
   499 MUpnpDeviceDescriptionProvider& CUpnpDeviceImplementationBase::DescritptionProvider()
       
   500     {
       
   501     return *iDescriptionProvider;
       
   502     }
       
   503 
       
   504 
       
   505 EXPORT_C void CUpnpDeviceImplementationBase::StartIPFilteringL()
       
   506     {
       
   507     #ifdef RD_UPNP_REMOTE_ACCESS
       
   508     iDispatcher->StartIPFilteringL();
       
   509     #endif
       
   510     }
       
   511     
       
   512 EXPORT_C void CUpnpDeviceImplementationBase::StopIPFiltering()
       
   513     {
       
   514     #ifdef RD_UPNP_REMOTE_ACCESS
       
   515     iDispatcher->StopIPFiltering();
       
   516     #endif
       
   517     }
       
   518 // End of File
       
   519 
       
   520 
       
   521