upnp/upnpstack/ssdpserver/src/upnpssdpserver.cpp
changeset 0 f5a58ecadc66
child 31 b51a6f4f15ba
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:  CUpnpSsdpServer
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <in_sock.h>
       
    21 #include <upnpsettings.h>
       
    22 #include "upnpssdpserver.h"
       
    23 #include "upnpcons.h"
       
    24 #define KLogFile _L("DLNAWebServer.txt")
       
    25 #include "upnpcustomlog.h"
       
    26 #include "upnplist.h"
       
    27 
       
    28 
       
    29 using namespace UpnpSSDP;
       
    30 using namespace UpnpString;
       
    31 
       
    32 
       
    33 // ============================ MEMBER FUNCTIONS ===============================
       
    34 
       
    35 // -----------------------------------------------------------------------------
       
    36 // CUpnpSsdpServer::CUpnpSsdpServer
       
    37 // C++ default constructor can NOT contain any code, that
       
    38 // might leave.
       
    39 // -----------------------------------------------------------------------------
       
    40 //
       
    41 CUpnpSsdpServer::CUpnpSsdpServer( MUpnpSsdpServerObserver* aSsdpServerObserver,
       
    42                           RSocketServ* aSocketServ,
       
    43                           TInt aListeningPort,
       
    44                           CUpnpSsdpServer* aMasterServer )
       
    45    : CUpnpUdpServer( aSocketServ, this, aListeningPort )
       
    46     {
       
    47     iMasterServer=aMasterServer;
       
    48 
       
    49     iSsdpServerObserver = aSsdpServerObserver;
       
    50     }
       
    51 
       
    52 // -----------------------------------------------------------------------------
       
    53 // CUpnpSsdpServer::CUpnpSsdpServer
       
    54 // C++ default constructor can NOT contain any code, that
       
    55 // might leave.
       
    56 // -----------------------------------------------------------------------------
       
    57 //
       
    58 CUpnpSsdpServer::CUpnpSsdpServer( MUpnpSsdpServerObserver* aSsdpServerObserver,
       
    59                           RSocketServ* aSocketServ,
       
    60                           TInt aListeningPort )
       
    61         : CUpnpUdpServer( aSocketServ, this, aListeningPort )
       
    62     {
       
    63     iMasterServer = NULL;
       
    64 
       
    65     iSsdpServerObserver = aSsdpServerObserver;
       
    66     }
       
    67 
       
    68 // -----------------------------------------------------------------------------
       
    69 // CUpnpSsdpServer::ConstructL
       
    70 // Symbian 2nd phase constructor can leave.
       
    71 // -----------------------------------------------------------------------------
       
    72 //
       
    73 void CUpnpSsdpServer::ConstructL()
       
    74     {
       
    75     UdpConstructL();    
       
    76     iServerDescription =  CUpnpSettings::GetServerHeaderL();    
       
    77     }
       
    78 
       
    79 // -----------------------------------------------------------------------------
       
    80 // CUpnpSsdpServer::NewL
       
    81 // Two-phased constructor.
       
    82 // -----------------------------------------------------------------------------
       
    83 //
       
    84 EXPORT_C CUpnpSsdpServer* CUpnpSsdpServer::NewL( MUpnpSsdpServerObserver*
       
    85                                                          aSsdpServerObserver,
       
    86                                          RSocketServ* aSocketServ,
       
    87                                          TInt aListeningPort )
       
    88     {
       
    89     CUpnpSsdpServer* self = new (ELeave) CUpnpSsdpServer( aSsdpServerObserver,
       
    90                                                   aSocketServ,
       
    91                                                   aListeningPort );
       
    92     
       
    93     CleanupStack::PushL(self);
       
    94     self->ConstructL();
       
    95     CleanupStack::Pop(self);
       
    96     
       
    97     return self;
       
    98     }
       
    99 
       
   100 // -----------------------------------------------------------------------------
       
   101 // CUpnpSsdpServer::NewL
       
   102 // Two-phased constructor.
       
   103 // -----------------------------------------------------------------------------
       
   104 //
       
   105 EXPORT_C CUpnpSsdpServer* CUpnpSsdpServer::NewL( MUpnpSsdpServerObserver* 
       
   106                                                         aSsdpServerObserver,
       
   107                                          RSocketServ* aSocketServ,
       
   108                                          TInt aListeningPort,
       
   109                                          CUpnpSsdpServer* aMasterServer )
       
   110     {
       
   111     CUpnpSsdpServer* self = new (ELeave) CUpnpSsdpServer( aSsdpServerObserver,
       
   112                                                   aSocketServ,
       
   113                                                   aListeningPort,
       
   114                                                   aMasterServer );
       
   115     
       
   116     CleanupStack::PushL(self);
       
   117     self->ConstructL();
       
   118     CleanupStack::Pop(self);
       
   119     
       
   120     return self;
       
   121     }
       
   122 
       
   123 // -----------------------------------------------------------------------------
       
   124 // Destructor
       
   125 // -----------------------------------------------------------------------------
       
   126 // 
       
   127 EXPORT_C CUpnpSsdpServer::~CUpnpSsdpServer()
       
   128     {
       
   129     delete iServerDescription;
       
   130     }
       
   131 
       
   132 // -----------------------------------------------------------------------------
       
   133 // CUpnpSsdpServer::MessageFromMulticastL
       
   134 // Message from multicast.
       
   135 // -----------------------------------------------------------------------------
       
   136 //
       
   137 void CUpnpSsdpServer::MessageFromMulticastL( CUpnpSsdpMessage* aMessage )
       
   138     {
       
   139     UdpMessageReceivedL( aMessage );
       
   140     }
       
   141 
       
   142 // -----------------------------------------------------------------------------
       
   143 // CUpnpSsdpServer::UdpMessageReceivedL
       
   144 // UDP message received.
       
   145 // -----------------------------------------------------------------------------
       
   146 //
       
   147 void CUpnpSsdpServer::UdpMessageReceivedL( CUdpMessage* aMessage )
       
   148     {
       
   149     if ( !aMessage )
       
   150         {
       
   151         return;
       
   152         }
       
   153     CUpnpSsdpMessage* message = ( CUpnpSsdpMessage* ) aMessage;
       
   154    
       
   155        // Unless it's response, check if HOST header has explicitly specified port number - 1900
       
   156        // If not, then add this port
       
   157        if ( !message->IsSsdpResponse() )
       
   158            {
       
   159            TPtrC8 host = message->GetHeaderValue( KHdrHost );
       
   160            
       
   161            // : Not found so port is not specified
       
   162            if( host.Find( UpnpString::KColon() ) == KErrNotFound )
       
   163             {
       
   164             TBuf8<KMaxIntegerLength> defaultPort;
       
   165                defaultPort.Num( KMulticastPort );
       
   166                
       
   167                HBufC8* newHost = HBufC8::NewLC( host.Length() +
       
   168                                        UpnpString::KColon().Length() +
       
   169                                        defaultPort.Length() );
       
   170                
       
   171                newHost->Des().Zero();
       
   172                newHost->Des().Append( host );
       
   173                newHost->Des().Append( UpnpString::KColon() );
       
   174                newHost->Des().Append( defaultPort );
       
   175                    
       
   176                message->AddHostL( *newHost );
       
   177                CleanupStack::PopAndDestroy(newHost);
       
   178             }
       
   179            }
       
   180    
       
   181     if ( iMasterServer )
       
   182         {
       
   183         iMasterServer->MessageFromMulticastL( message );
       
   184         }
       
   185     else
       
   186         {
       
   187         if ( message->IsSsdpMSearch() )
       
   188             {
       
   189             LOGS( "SSDP *** Search received");
       
   190             ResponseL( message );
       
   191             // add additional notification to upper-layer 
       
   192             // used for detection IP address change
       
   193             iSsdpServerObserver->SsdpEventL( message );
       
   194             }
       
   195         else if (message->IsSsdpNotify())
       
   196             {
       
   197             LOGS( "SSDP *** Notify received");
       
   198             iSsdpServerObserver->SsdpEventL( message );
       
   199             }
       
   200         else if (message->IsSsdpResponse())
       
   201             {
       
   202             LOGS( "SSDP *** Response received");
       
   203             iSsdpServerObserver->SsdpEventL( message );
       
   204             }
       
   205         else
       
   206             {
       
   207             LOGS( "SSDP *** UNKNOWN MESSAGE RECEIVED");
       
   208             }
       
   209         }
       
   210     }
       
   211 
       
   212 // -----------------------------------------------------------------------------
       
   213 // CUpnpSsdpServer::StartL
       
   214 // Start.
       
   215 // -----------------------------------------------------------------------------
       
   216 //
       
   217 EXPORT_C void CUpnpSsdpServer::StartL()
       
   218     {
       
   219     LOGS( "SSDP *** StartL");
       
   220     OpenL();    
       
   221     }
       
   222 
       
   223 // -----------------------------------------------------------------------------
       
   224 // CUpnpSsdpServer::StopL
       
   225 // Stop.
       
   226 // -----------------------------------------------------------------------------
       
   227 //
       
   228 EXPORT_C void CUpnpSsdpServer::Stop()
       
   229     {
       
   230     LOGS( "SSDP *** Stop");
       
   231     Close();
       
   232     }
       
   233 
       
   234 // -----------------------------------------------------------------------------
       
   235 // CUpnpSsdpServer::AdvertiseAliveL
       
   236 // 
       
   237 // -----------------------------------------------------------------------------
       
   238 //
       
   239 EXPORT_C void CUpnpSsdpServer::AdvertiseAliveL( CUpnpDeviceLibraryElement& aDev )
       
   240     {
       
   241     LOGS( "SSDP *** AdvertiseAliveL");
       
   242     // advertise this device
       
   243     SingleDeviceAdvertiseAliveL( aDev );
       
   244     SingleDeviceAdvertiseAliveL( aDev );
       
   245     }
       
   246 
       
   247 // -----------------------------------------------------------------------------
       
   248 // CUpnpSsdpServer::AdvertiseByebyeL
       
   249 // 
       
   250 // -----------------------------------------------------------------------------
       
   251 //
       
   252 EXPORT_C void CUpnpSsdpServer::AdvertiseByebyeL( CUpnpDeviceLibraryElement& aDev )
       
   253     {
       
   254     SingleDeviceAdvertiseByebyeL( aDev );
       
   255     }
       
   256 
       
   257 // -----------------------------------------------------------------------------
       
   258 // CUpnpSsdpServer::SearchL
       
   259 // 
       
   260 // -----------------------------------------------------------------------------
       
   261 //
       
   262 EXPORT_C void CUpnpSsdpServer::SearchL( TDesC8& aTarget )
       
   263     {
       
   264     SearchL(aTarget, (TDesC8&)UpnpSSDP::KDefaultResponseDelay());
       
   265     }
       
   266 
       
   267 // -----------------------------------------------------------------------------
       
   268 // CUpnpSsdpServer::SearchL
       
   269 // 
       
   270 // -----------------------------------------------------------------------------
       
   271 //
       
   272 EXPORT_C void CUpnpSsdpServer::SearchL( TDesC8& aTarget, TDesC8& aMaximumWaitTime )
       
   273     {
       
   274     CUpnpSsdpMessage* msg = RUpnpSsdpMessageFactory::SearchL( aTarget );
       
   275     CleanupStack::PushL( msg );
       
   276     msg->AddMxL(aMaximumWaitTime);
       
   277     
       
   278     HBufC8* str = HBufC8::NewLC( KMaxSsdpMessageLength );
       
   279     
       
   280     HBufC8* msgStr = ( ( CUpnpSsdpMessage* ) msg )->ToStringL();
       
   281     CleanupStack::PushL( msgStr );
       
   282     
       
   283     str->Des().Append( *msgStr );
       
   284     
       
   285     CleanupStack::PopAndDestroy( msgStr );
       
   286     
       
   287     TInetAddr addr( KDefaultMulticastAddress, KDefaultMulticastPort );
       
   288     
       
   289     SendL( *str, addr );
       
   290     
       
   291     CleanupStack::PopAndDestroy( str );
       
   292     CleanupStack::PopAndDestroy( msg );
       
   293     }
       
   294 
       
   295 // -----------------------------------------------------------------------------
       
   296 // CUpnpSsdpServer::SendAdvertiseAliveL
       
   297 //
       
   298 // -----------------------------------------------------------------------------
       
   299 //
       
   300 void CUpnpSsdpServer::SendAdvertiseAliveL( TDesC8& aNt, TDesC8& aUsn, TDesC8& aLoc )
       
   301     {
       
   302     TInetAddr addr( KDefaultMulticastAddress, KDefaultMulticastPort );
       
   303     
       
   304     CUpnpSsdpMessage* msg = RUpnpSsdpMessageFactory::AdvertiseAliveL( 
       
   305                                             aLoc, aNt, aUsn, *iServerDescription);
       
   306     CleanupStack::PushL( msg );
       
   307     HBufC8* str = msg->ToStringL();
       
   308     CleanupStack::PushL( str );
       
   309     
       
   310     SendL( *str, addr );
       
   311     
       
   312     CleanupStack::PopAndDestroy( str );
       
   313     str=NULL;
       
   314     
       
   315     CleanupStack::PopAndDestroy( msg );
       
   316     msg=NULL;    
       
   317     }
       
   318 
       
   319 // -----------------------------------------------------------------------------
       
   320 // CUpnpSsdpServer::SendAdvertiseByebyeL
       
   321 //
       
   322 // -----------------------------------------------------------------------------
       
   323 //
       
   324 void CUpnpSsdpServer::SendAdvertiseByebyeL( TDesC8& aNt, TDesC8& aUsn )
       
   325     {
       
   326     TInetAddr addr( KDefaultMulticastAddress, KDefaultMulticastPort );
       
   327     
       
   328     CUpnpSsdpMessage* msg = RUpnpSsdpMessageFactory::AdvertiseByebyeL( aNt, aUsn );
       
   329     CleanupStack::PushL( msg );
       
   330     HBufC8* str = msg->ToStringL();
       
   331     CleanupStack::PushL( str );    
       
   332     
       
   333     SendL( *str, addr );
       
   334     
       
   335     CleanupStack::PopAndDestroy( str );
       
   336     str=NULL;
       
   337     
       
   338     CleanupStack::PopAndDestroy( msg );
       
   339     msg=NULL;
       
   340     }
       
   341 
       
   342 // -----------------------------------------------------------------------------
       
   343 // CUpnpSsdpServer::SendResponseL
       
   344 //
       
   345 // -----------------------------------------------------------------------------
       
   346 //
       
   347 void CUpnpSsdpServer::SendResponseL( TInetAddr& aDest, 
       
   348                                  TDesC8& aSt, 
       
   349                                  TDesC8& aUsn, 
       
   350                                  TDesC8& aLoc )
       
   351     {
       
   352     CUpnpSsdpMessage* msg = RUpnpSsdpMessageFactory::ResponseL( 
       
   353                                         aSt, aUsn, aLoc, *iServerDescription );
       
   354     CleanupStack::PushL( msg );
       
   355     HBufC8* str = msg->ToStringL();
       
   356     CleanupStack::PushL( str );
       
   357     
       
   358     SendL( *str, aDest );
       
   359     
       
   360     CleanupStack::PopAndDestroy( str );
       
   361     str=NULL;
       
   362     
       
   363     CleanupStack::PopAndDestroy( msg );
       
   364     msg=NULL;    
       
   365     }
       
   366 
       
   367 // -----------------------------------------------------------------------------
       
   368 // CUpnpSsdpServer::SingleDeviceAdvertiseAliveL
       
   369 //
       
   370 // -----------------------------------------------------------------------------
       
   371 //
       
   372 void CUpnpSsdpServer::SingleDeviceAdvertiseAliveL( CUpnpDeviceLibraryElement& aDev )
       
   373     {
       
   374     HBufC8* nt=NULL;
       
   375     HBufC8* usn=NULL;
       
   376     HBufC8* loc=NULL;
       
   377     
       
   378     loc=HBufC8::NewLC( aDev.DescriptionUrl().Length() );
       
   379     loc->Des().Zero();
       
   380     loc->Des().Append( aDev.DescriptionUrl() );
       
   381     
       
   382     CDesC8Array* services = &aDev.ServiceList();
       
   383     
       
   384     if ( aDev.IsRootDevice() )
       
   385         {
       
   386         
       
   387         nt = HBufC8::NewLC( KUPnPRootDevice().Length() );
       
   388         nt->Des().Zero();
       
   389         nt->Des().Append( KUPnPRootDevice() );
       
   390         
       
   391         usn = HBufC8::NewLC( KUPnPUuid().Length()
       
   392             + aDev.UUID().Length()
       
   393             + KDblColon().Length()
       
   394             + KUPnPRootDevice().Length() );
       
   395 
       
   396         usn->Des().Zero();
       
   397         usn->Des().Append( KUPnPUuid() );
       
   398         usn->Des().Append( aDev.UUID() );
       
   399         usn->Des().Append( KDblColon() );
       
   400         usn->Des().Append( KUPnPRootDevice() );
       
   401         
       
   402         SendAdvertiseAliveL( *nt, *usn, *loc );
       
   403         
       
   404         CleanupStack::PopAndDestroy( usn );
       
   405         usn = NULL;
       
   406         
       
   407         CleanupStack::PopAndDestroy( nt );
       
   408         nt = NULL;
       
   409         }
       
   410     
       
   411     nt=HBufC8::NewLC( KUPnPUuid().Length() + aDev.UUID().Length() );
       
   412     nt->Des().Zero();
       
   413     nt->Des().Append( KUPnPUuid() );
       
   414     nt->Des().Append( aDev.UUID() );
       
   415     
       
   416     usn=HBufC8::NewLC( KUPnPUuid().Length() + aDev.UUID().Length() );
       
   417     usn->Des().Zero();
       
   418     usn->Des().Append( KUPnPUuid() );
       
   419     usn->Des().Append( aDev.UUID() );
       
   420     
       
   421     SendAdvertiseAliveL( *nt, *usn, *loc );
       
   422     
       
   423     CleanupStack::PopAndDestroy( usn );
       
   424     usn = NULL;
       
   425     
       
   426     CleanupStack::PopAndDestroy( nt );
       
   427     nt = NULL;
       
   428     
       
   429     nt = HBufC8::NewLC( aDev.DeviceType().Length() );
       
   430 
       
   431     nt->Des().Zero();
       
   432     nt->Des().Append( aDev.DeviceType() );
       
   433     
       
   434     usn = HBufC8::NewLC( KUPnPUuid().Length()
       
   435         + aDev.UUID().Length()
       
   436         + KDblColon().Length()
       
   437         + aDev.DeviceType().Length() );
       
   438 
       
   439     usn->Des().Zero();
       
   440     usn->Des().Append( KUPnPUuid() );
       
   441     usn->Des().Append( aDev.UUID() );
       
   442     usn->Des().Append( KDblColon() );
       
   443     usn->Des().Append( aDev.DeviceType() );
       
   444     
       
   445     SendAdvertiseAliveL( *nt, *usn, *loc );
       
   446     
       
   447     CleanupStack::PopAndDestroy( usn );
       
   448     usn = NULL;
       
   449     
       
   450     CleanupStack::PopAndDestroy( nt );
       
   451     nt = NULL;
       
   452     
       
   453     if(!services)
       
   454         {
       
   455         return;
       
   456         }
       
   457     
       
   458     TInt NumOfServices = services->Count();
       
   459     
       
   460     TInt i = 0;
       
   461     
       
   462     for( i = 0; i < NumOfServices; i++ )
       
   463         {
       
   464         
       
   465         nt = HBufC8::NewLC( KUPnPServiceSchema().Length()
       
   466             + (*services)[i].Length() );
       
   467 
       
   468         nt->Des().Zero();
       
   469         nt->Des().Append( KUPnPServiceSchema() );
       
   470         nt->Des().Append( (*services)[i] );
       
   471         
       
   472         usn=HBufC8::NewLC( KUPnPUuid().Length()
       
   473             + aDev.UUID().Length()
       
   474             + KDblColon().Length()
       
   475             + KUPnPServiceSchema().Length()
       
   476             + (*services)[i].Length() );
       
   477 
       
   478         usn->Des().Zero();
       
   479         usn->Des().Append( KUPnPUuid() );
       
   480         usn->Des().Append( aDev.UUID() );
       
   481         usn->Des().Append( KDblColon() );
       
   482         usn->Des().Append( KUPnPServiceSchema() );
       
   483         usn->Des().Append( (*services)[i] );
       
   484         
       
   485         SendAdvertiseAliveL( *nt, *usn, *loc );
       
   486         
       
   487         CleanupStack::PopAndDestroy( usn );
       
   488         usn = NULL;
       
   489         
       
   490         CleanupStack::PopAndDestroy( nt );
       
   491         nt = NULL;
       
   492         }
       
   493     
       
   494     CleanupStack::PopAndDestroy( loc );
       
   495     loc = NULL;
       
   496     }
       
   497 
       
   498 // -----------------------------------------------------------------------------
       
   499 // CUpnpSsdpServer::SingleDeviceAdvertiseByebyeL
       
   500 //
       
   501 // -----------------------------------------------------------------------------
       
   502 //
       
   503 void CUpnpSsdpServer::SingleDeviceAdvertiseByebyeL(CUpnpDeviceLibraryElement& aDev)
       
   504     {
       
   505     HBufC8* nt=NULL;
       
   506     HBufC8* usn=NULL;
       
   507     
       
   508     CDesC8Array* services = &aDev.ServiceList();
       
   509     
       
   510     if (aDev.IsRootDevice())
       
   511         {
       
   512         nt=HBufC8::NewLC(KUPnPRootDevice().Length());
       
   513         nt->Des().Copy(KUPnPRootDevice());
       
   514         
       
   515         usn=HBufC8::NewLC(KUPnPUuid().Length()
       
   516             +aDev.UUID().Length()
       
   517             +UpnpString::KDblColon().Length()
       
   518             +KUPnPRootDevice().Length());
       
   519 
       
   520         usn->Des().Zero();
       
   521         usn->Des().Append(KUPnPUuid());
       
   522         usn->Des().Append(aDev.UUID());
       
   523         usn->Des().Append(UpnpString::KDblColon());
       
   524         usn->Des().Append(KUPnPRootDevice());
       
   525         
       
   526         SendAdvertiseByebyeL(*nt, *usn);
       
   527         
       
   528         CleanupStack::PopAndDestroy(usn); 
       
   529         usn=NULL;
       
   530         
       
   531         CleanupStack::PopAndDestroy(nt);
       
   532         nt=NULL;
       
   533         }
       
   534     
       
   535     nt=HBufC8::NewLC(KUPnPUuid().Length()+aDev.UUID().Length());
       
   536     nt->Des().Zero();
       
   537     nt->Des().Append(KUPnPUuid());
       
   538     nt->Des().Append(aDev.UUID());
       
   539     
       
   540     usn=HBufC8::NewLC(KUPnPUuid().Length()+aDev.UUID().Length());
       
   541     usn->Des().Zero();
       
   542     usn->Des().Append(KUPnPUuid());
       
   543     usn->Des().Append(aDev.UUID());
       
   544     
       
   545     
       
   546     SendAdvertiseByebyeL(*nt, *usn);
       
   547     
       
   548     
       
   549     CleanupStack::PopAndDestroy(usn);
       
   550     usn=NULL;
       
   551     
       
   552     CleanupStack::PopAndDestroy(nt);
       
   553     nt=NULL;
       
   554     
       
   555     nt=HBufC8::NewLC(aDev.DeviceType().Length());
       
   556 
       
   557     nt->Des().Zero();
       
   558     nt->Des().Append(aDev.DeviceType());    
       
   559     
       
   560     usn=HBufC8::NewLC(KUPnPUuid().Length()
       
   561         +aDev.UUID().Length()
       
   562         +UpnpString::KDblColon().Length()
       
   563         +aDev.DeviceType().Length());
       
   564 
       
   565     usn->Des().Zero();
       
   566     usn->Des().Append(KUPnPUuid());
       
   567     usn->Des().Append(aDev.UUID());
       
   568     usn->Des().Append(UpnpString::KDblColon());
       
   569     usn->Des().Append(aDev.DeviceType());
       
   570     
       
   571     
       
   572     SendAdvertiseByebyeL(*nt, *usn);
       
   573     
       
   574     
       
   575     CleanupStack::PopAndDestroy(usn);
       
   576     usn=NULL;
       
   577     
       
   578     CleanupStack::PopAndDestroy(nt); 
       
   579     nt=NULL;
       
   580     
       
   581     TInt i=0;
       
   582     
       
   583     if(!services)
       
   584         {
       
   585         return;
       
   586         }
       
   587     
       
   588     TInt NumOfServices=services->Count();
       
   589     
       
   590     for(i=0; i<NumOfServices; i++)
       
   591         {
       
   592         
       
   593         nt=HBufC8::NewLC(KUPnPServiceSchema().Length()
       
   594             +(*services)[i].Length());
       
   595 
       
   596         nt->Des().Zero();
       
   597         nt->Des().Append(KUPnPServiceSchema());
       
   598         nt->Des().Append((*services)[i]);
       
   599         
       
   600         usn=HBufC8::NewLC(KUPnPUuid().Length()
       
   601             +aDev.UUID().Length()
       
   602             +UpnpString::KDblColon().Length()
       
   603             +KUPnPServiceSchema().Length()
       
   604             +(*services)[i].Length());
       
   605 
       
   606         usn->Des().Zero();
       
   607         usn->Des().Append(KUPnPUuid());
       
   608         usn->Des().Append(aDev.UUID());
       
   609         usn->Des().Append(UpnpString::KDblColon());
       
   610         usn->Des().Append(KUPnPServiceSchema());
       
   611         usn->Des().Append((*services)[i]);
       
   612         
       
   613         
       
   614         SendAdvertiseByebyeL(*nt, *usn);
       
   615         
       
   616         
       
   617         CleanupStack::PopAndDestroy(usn);
       
   618         usn=NULL;
       
   619         
       
   620         CleanupStack::PopAndDestroy(nt);
       
   621         nt=NULL;
       
   622         }
       
   623     }
       
   624 
       
   625 // -----------------------------------------------------------------------------
       
   626 // CUpnpSsdpServer::SingleServiceResponseL
       
   627 //
       
   628 // -----------------------------------------------------------------------------
       
   629 //
       
   630 void CUpnpSsdpServer::SingleServiceResponseL( CUpnpDeviceLibraryElement* aDevice, 
       
   631                                           const TDesC8& aServiceType, 
       
   632                                           CUpnpSsdpMessage* aMsg )
       
   633     {
       
   634     if ( !aDevice || !aMsg  )
       
   635         {
       
   636         return;
       
   637         }
       
   638     // name buffers
       
   639     HBufC8* nt=NULL;
       
   640     HBufC8* usn=NULL;
       
   641     HBufC8* loc=NULL;
       
   642     
       
   643     // set location buffer to point to the 
       
   644     // service description file of this service
       
   645     // e.g. loc = 192.168.100.2/mediaserver/desc.xml
       
   646     
       
   647     loc=HBufC8::NewLC(aDevice->DescriptionUrl().Length());
       
   648     loc->Des().Zero();
       
   649     loc->Des().Append(aDevice->DescriptionUrl());
       
   650     
       
   651 
       
   652     // separate different search targets
       
   653     switch(aMsg->SearchTarget())
       
   654         {
       
   655         case CUpnpSsdpMessage::ESsdpNone:
       
   656             
       
   657             break;
       
   658             
       
   659         case CUpnpSsdpMessage::ESsdpAll:
       
   660             // In case of Ssdp:all search, 
       
   661             // every service should send a device uuid response
       
   662             
       
   663             // 1. service type response
       
   664             /*
       
   665             NT:     urn:schemas-upnp-org:service:serviceType:v
       
   666             USN:     uuid:device-UUID::urn:schemas-upnp-org:service:serviceType:v
       
   667             */
       
   668             
       
   669             // nt = urn:schemas-upnp-org:service:serviceType:v
       
   670              nt = HBufC8::NewLC( KUPnPServiceSchema().Length() +
       
   671                                  aServiceType.Length() );
       
   672             nt->Des().Zero();
       
   673             nt->Des().Append(KUPnPServiceSchema());
       
   674             nt->Des().Append(aServiceType);
       
   675             
       
   676             // usn = uuid:device-UUID::urn:schemas-upnp
       
   677             // -org:service:serviceType:v
       
   678             
       
   679             usn=HBufC8::NewLC(KUPnPUuid().Length()
       
   680                 +aDevice->UUID().Length()
       
   681                 +UpnpString::KDblColon().Length()
       
   682                 +KUPnPServiceSchema().Length()
       
   683                 +aServiceType.Length());
       
   684 
       
   685             usn->Des().Zero();
       
   686             usn->Des().Append(KUPnPUuid());
       
   687             usn->Des().Append(aDevice->UUID());
       
   688             usn->Des().Append(UpnpString::KDblColon());
       
   689             usn->Des().Append(KUPnPServiceSchema());
       
   690             usn->Des().Append(aServiceType);    
       
   691             
       
   692             // send response to sender
       
   693             SendResponseL(aMsg->Sender() ,*nt, *usn, *loc);
       
   694             
       
   695             CleanupStack::PopAndDestroy(usn);
       
   696             usn=NULL;
       
   697             
       
   698             CleanupStack::PopAndDestroy(nt);
       
   699             nt=NULL;
       
   700             
       
   701             break;
       
   702             
       
   703         case CUpnpSsdpMessage::EUPnPRootDevice:
       
   704             
       
   705             break;
       
   706             
       
   707         case CUpnpSsdpMessage::EDeviceUid:
       
   708             
       
   709             break;
       
   710             
       
   711         case CUpnpSsdpMessage::EDeviceType:
       
   712             
       
   713             break;
       
   714             
       
   715         case CUpnpSsdpMessage::EServiceType:
       
   716             {
       
   717             /*
       
   718             NT:     urn:schemas-upnp-org:service:serviceType:v
       
   719             USN:     uuid:device-UUID::urn:schemas-upnp-
       
   720                          org:service:serviceType:v
       
   721             */
       
   722                 
       
   723              // nt = urn:schemas-upnp-org:service:serviceType:v
       
   724              nt = HBufC8::NewLC( KUPnPServiceSchema().Length() + 
       
   725                                     aServiceType.Length());
       
   726 
       
   727              nt->Des().Zero();
       
   728              nt->Des().Append(KUPnPServiceSchema());
       
   729              nt->Des().Append(aServiceType);
       
   730             
       
   731             if (aMsg->St().Compare(*nt) == 0)
       
   732                 {
       
   733                 
       
   734                 // usn = uuid:device-UUID::urn:schemas-upnp
       
   735                 //       -org:service:serviceType:v
       
   736                 usn=HBufC8::NewLC(KUPnPUuid().Length()
       
   737                     +aDevice->UUID().Length()
       
   738                     +UpnpString::KDblColon().Length()
       
   739                     +KUPnPServiceSchema().Length()
       
   740                     +aServiceType.Length());
       
   741 
       
   742                 usn->Des().Zero();
       
   743                 usn->Des().Append(KUPnPUuid());
       
   744                 usn->Des().Append(aDevice->UUID());
       
   745                 usn->Des().Append(UpnpString::KDblColon());
       
   746                 usn->Des().Append(KUPnPServiceSchema());
       
   747                 usn->Des().Append(aServiceType);    
       
   748                 
       
   749                 
       
   750                 // send response to sender
       
   751                 SendResponseL(aMsg->Sender() ,*nt, *usn, *loc);
       
   752                 
       
   753                 
       
   754                 CleanupStack::PopAndDestroy(usn);
       
   755                 usn=NULL;
       
   756                 
       
   757                 
       
   758                 }        
       
   759             
       
   760             CleanupStack::PopAndDestroy(nt);
       
   761             nt=NULL;
       
   762             }
       
   763             break;
       
   764         default:
       
   765             
       
   766             break;
       
   767         }
       
   768         
       
   769         CleanupStack::PopAndDestroy(loc);
       
   770         loc=NULL;
       
   771     }
       
   772 
       
   773 // -----------------------------------------------------------------------------
       
   774 // CUpnpSsdpServer::SingleDeviceResponseL
       
   775 //
       
   776 // -----------------------------------------------------------------------------
       
   777 //
       
   778 void CUpnpSsdpServer::SingleDeviceResponseL( CUpnpDeviceLibraryElement* aDevice, 
       
   779                                          CUpnpSsdpMessage* aMsg )
       
   780     {
       
   781     if ( !aDevice || !aMsg )
       
   782         {
       
   783         return;
       
   784         }
       
   785     
       
   786     // name buffers
       
   787     HBufC8* nt=NULL;
       
   788     HBufC8* usn=NULL;
       
   789     HBufC8* loc=NULL;
       
   790     
       
   791     // format location buffer to point 
       
   792     // to the device description file of this device
       
   793     
       
   794     loc=HBufC8::NewLC(aDevice->DescriptionUrl().Length());
       
   795     loc->Des().Zero();
       
   796     loc->Des().Append(aDevice->DescriptionUrl());
       
   797     
       
   798     // separate different search targets
       
   799     switch( aMsg->SearchTarget() )
       
   800         {
       
   801         case CUpnpSsdpMessage::ESsdpNone:
       
   802             
       
   803             
       
   804             break;
       
   805             
       
   806         case CUpnpSsdpMessage::ESsdpAll:
       
   807             // In case of Ssdp:all search, every device should 
       
   808             // send following responses:
       
   809             // 1. if a root device, a root device response
       
   810             // 2. a device uuid response
       
   811             // 3. a device type response
       
   812             
       
   813             //************************
       
   814             // 1. root device response        
       
   815             /*
       
   816             NT:     upnp:rootdevice
       
   817             USN:     uuid:device-UUID::upnp:rootdevice
       
   818             */
       
   819             // if a root device
       
   820             if (aDevice->IsRootDevice())
       
   821                 {
       
   822                 
       
   823                 
       
   824                 nt=HBufC8::NewLC(KUPnPRootDevice().Length());
       
   825                 nt->Des().Zero();
       
   826                 nt->Des().Append(KUPnPRootDevice());
       
   827                 
       
   828                 // nt = upnp:rootdevice
       
   829                 
       
   830                 // usn = uuid:device-UUID::upnp:rootdevice
       
   831                 
       
   832                 usn=HBufC8::NewLC(KUPnPUuid().Length()
       
   833                     +aDevice->UUID().Length()
       
   834                     +UpnpString::KDblColon().Length()
       
   835                     +KUPnPRootDevice().Length());
       
   836 
       
   837                 usn->Des().Zero();
       
   838                 usn->Des().Append(KUPnPUuid());
       
   839                 usn->Des().Append(aDevice->UUID());
       
   840                 usn->Des().Append(UpnpString::KDblColon());
       
   841                 usn->Des().Append(KUPnPRootDevice());
       
   842                 
       
   843                 // send response to sender
       
   844                 SendResponseL(aMsg->Sender(), *nt, *usn, *loc);
       
   845                 
       
   846                 CleanupStack::PopAndDestroy(usn);
       
   847                 usn=NULL;
       
   848                 
       
   849                 CleanupStack::PopAndDestroy(nt);
       
   850                 nt=NULL;
       
   851                 }
       
   852             
       
   853             
       
   854             //************************
       
   855             // 2. device uuid response
       
   856             /*
       
   857             NT:     uuid:device-UUID
       
   858             USN:     uuid:device-UUID
       
   859             */
       
   860             
       
   861             nt=HBufC8::NewLC(KUPnPUuid().Length()+aDevice->UUID().Length());
       
   862             nt->Des().Zero();
       
   863             nt->Des().Append(KUPnPUuid());
       
   864             nt->Des().Append(aDevice->UUID());
       
   865             
       
   866             // nt = uuid:device-UUID
       
   867             
       
   868             // usn = uuid:device-UUID
       
   869             
       
   870             usn=HBufC8::NewLC(KUPnPUuid().Length()+aDevice->UUID().Length());
       
   871             usn->Des().Zero();
       
   872             usn->Des().Append(KUPnPUuid());
       
   873             usn->Des().Append(aDevice->UUID());
       
   874             
       
   875             // send response to sender
       
   876             SendResponseL(aMsg->Sender(), *nt, *usn, *loc);
       
   877             
       
   878             CleanupStack::PopAndDestroy(usn);
       
   879             usn=NULL;
       
   880             
       
   881             CleanupStack::PopAndDestroy(nt);
       
   882             nt=NULL;
       
   883             
       
   884             
       
   885             //************************
       
   886             // 3. device type response
       
   887             /*
       
   888             NT:     urn:schemas-upnp-org:device:deviceType:v
       
   889             USN:     uuid:device-UUID::urn:schemas-upnp-org:device:deviceType:v
       
   890             */
       
   891             
       
   892             nt=HBufC8::NewLC(aDevice->DeviceType().Length());
       
   893 
       
   894             nt->Des().Zero();
       
   895             nt->Des().Append(aDevice->DeviceType());
       
   896             
       
   897             // nt = urn:schemas-upnp-org:device:deviceType:v
       
   898             
       
   899             // usn = uuid:device-UUID::urn:schemas-upnp-org:device:deviceType:v
       
   900             
       
   901             usn=HBufC8::NewLC(KUPnPUuid().Length()
       
   902                 +aDevice->UUID().Length()
       
   903                 +UpnpString::KDblColon().Length()
       
   904                 +aDevice->DeviceType().Length());
       
   905 
       
   906             usn->Des().Zero();
       
   907             usn->Des().Append(KUPnPUuid());
       
   908             usn->Des().Append(aDevice->UUID());
       
   909             usn->Des().Append(UpnpString::KDblColon());
       
   910             usn->Des().Append(aDevice->DeviceType());
       
   911             
       
   912             // send response to sender
       
   913             SendResponseL(aMsg->Sender(), *nt, *usn, *loc);
       
   914             
       
   915             
       
   916             CleanupStack::PopAndDestroy(usn);
       
   917             usn=NULL;
       
   918             
       
   919             CleanupStack::PopAndDestroy(nt);
       
   920             nt=NULL;
       
   921             
       
   922             
       
   923             break;
       
   924             
       
   925         case CUpnpSsdpMessage::EUPnPRootDevice:
       
   926             // if the search is done for only root devices, 
       
   927             // every root device should answer with a root device response
       
   928             
       
   929             //************************
       
   930             // 1. root device response        
       
   931             /*
       
   932             NT:     upnp:rootdevice
       
   933             USN:     uuid:device-UUID::upnp:rootdevice
       
   934             */
       
   935             // if device is a root device
       
   936             if (aDevice->IsRootDevice())
       
   937                 {
       
   938                 
       
   939                 nt=HBufC8::NewLC(KUPnPRootDevice().Length());
       
   940                 nt->Des().Zero();
       
   941                 nt->Des().Append(KUPnPRootDevice());
       
   942                 
       
   943                 usn=HBufC8::NewLC(KUPnPUuid().Length()
       
   944                     +aDevice->UUID().Length()
       
   945                     +UpnpString::KDblColon().Length()
       
   946                     +KUPnPRootDevice().Length());
       
   947 
       
   948                 usn->Des().Zero();
       
   949                 usn->Des().Append(KUPnPUuid());
       
   950                 usn->Des().Append(aDevice->UUID());
       
   951                 usn->Des().Append(UpnpString::KDblColon());
       
   952                 usn->Des().Append(KUPnPRootDevice());
       
   953                 
       
   954                 // send response to sender
       
   955                 SendResponseL(aMsg->Sender(), *nt, *usn, *loc);
       
   956                 
       
   957                 CleanupStack::PopAndDestroy(usn);
       
   958                 usn=NULL;
       
   959                 
       
   960                 CleanupStack::PopAndDestroy(nt); 
       
   961                 nt=NULL;
       
   962                 }
       
   963             
       
   964             
       
   965             break;
       
   966             
       
   967         case CUpnpSsdpMessage::EDeviceUid:
       
   968             {
       
   969             // if the search is done for only devices with specific uuid,
       
   970             // response if the uuids match
       
   971             
       
   972             //************************
       
   973             // 2. device uuid response
       
   974             /*
       
   975             NT:     uuid:device-UUID
       
   976             USN:     uuid:device-UUID
       
   977             */
       
   978             
       
   979             // nt = uuid:device-UUID
       
   980             nt=HBufC8::NewLC(KUPnPUuid().Length()
       
   981                     +aDevice->UUID().Length());
       
   982 
       
   983             nt->Des().Zero();
       
   984             nt->Des().Append(KUPnPUuid());
       
   985             nt->Des().Append(aDevice->UUID());
       
   986             
       
   987             
       
   988             // if device uuids match
       
   989             if (aMsg->St().Compare(*nt) == 0)
       
   990                 {
       
   991 
       
   992                 usn=HBufC8::NewLC(KUPnPUuid().Length()
       
   993                     +aDevice->UUID().Length());
       
   994 
       
   995                 usn->Des().Zero();
       
   996                 usn->Des().Append(KUPnPUuid());
       
   997                 usn->Des().Append(aDevice->UUID());
       
   998                 
       
   999                 // send response to sender
       
  1000                 SendResponseL(aMsg->Sender(), *nt, *usn, *loc);
       
  1001                 
       
  1002                 CleanupStack::PopAndDestroy(usn);
       
  1003                 usn=NULL;
       
  1004                 
       
  1005                 
       
  1006                 }
       
  1007                 CleanupStack::PopAndDestroy(nt);
       
  1008                 nt=NULL;
       
  1009             
       
  1010             }
       
  1011             break;
       
  1012             
       
  1013         case CUpnpSsdpMessage::EDeviceType:
       
  1014             {
       
  1015             // if the search is done for only devices of specific type,
       
  1016             // response if types match
       
  1017             
       
  1018             //************************
       
  1019             // 3. device type response
       
  1020             /*
       
  1021             NT:     urn:schemas-upnp-org:device:deviceType:v
       
  1022             USN:     uuid:device-UUID::urn:schemas-upnp-org:device:deviceType:v
       
  1023             */
       
  1024                         
       
  1025             // nt = urn:schemas-upnp-org:device:deviceType:v                
       
  1026              nt=HBufC8::NewLC(aDevice->DeviceType().Length());
       
  1027 
       
  1028              nt->Des().Zero();
       
  1029              nt->Des().Append(aDevice->DeviceType());
       
  1030             
       
  1031             // if device types match
       
  1032             if (aMsg->St().Compare(*nt) == 0)
       
  1033                 {         
       
  1034                 
       
  1035                 // usn = uuid:device-UUID::urn:schemas-upnp-org:device:deviceType:v                
       
  1036                 usn=HBufC8::NewLC(KUPnPUuid().Length()
       
  1037                     +aDevice->UUID().Length()
       
  1038                     +KDblColon().Length()
       
  1039                     +aDevice->DeviceType().Length());
       
  1040 
       
  1041                 usn->Des().Zero();
       
  1042                 usn->Des().Append(KUPnPUuid());
       
  1043                 usn->Des().Append(aDevice->UUID());
       
  1044                 usn->Des().Append(KDblColon());
       
  1045                 usn->Des().Append(aDevice->DeviceType());
       
  1046                 
       
  1047                 // send response to sender
       
  1048                 SendResponseL(aMsg->Sender(), *nt, *usn, *loc);
       
  1049                 
       
  1050                 CleanupStack::PopAndDestroy(usn);
       
  1051                 usn=NULL;
       
  1052                 
       
  1053                 
       
  1054                 }
       
  1055                 CleanupStack::PopAndDestroy(nt);
       
  1056                 nt=NULL;
       
  1057 
       
  1058             
       
  1059             }
       
  1060             break;
       
  1061             
       
  1062         case CUpnpSsdpMessage::EServiceType:
       
  1063             // devices do not answer if searching services
       
  1064             
       
  1065             break;
       
  1066         default:
       
  1067             
       
  1068             break;
       
  1069         }
       
  1070         
       
  1071     CleanupStack::PopAndDestroy( loc );
       
  1072     loc = NULL;
       
  1073     }
       
  1074 
       
  1075 // -----------------------------------------------------------------------------
       
  1076 // CUpnpSsdpServer::ResponseL
       
  1077 //
       
  1078 // -----------------------------------------------------------------------------
       
  1079 //
       
  1080 void CUpnpSsdpServer::ResponseL(CUpnpSsdpMessage* aMsg)
       
  1081     {
       
  1082     if ( !aMsg )
       
  1083         {
       
  1084         return;
       
  1085         }
       
  1086     
       
  1087     // a search message is received
       
  1088     // seek for devices and services matching to the search
       
  1089     
       
  1090     // get device list from message handler
       
  1091     RPointerArray<CUpnpDeviceLibraryElement>& devs 
       
  1092         = iSsdpServerObserver->DeviceList();
       
  1093    
       
  1094 
       
  1095     TInt devCount=0;
       
  1096      // get number of devices
       
  1097     devCount=devs.Count();
       
  1098     
       
  1099     TInt j=0;
       
  1100     
       
  1101     for(j=0;j<devCount;j++)
       
  1102         {
       
  1103         CUpnpDeviceLibraryElement* dev = (CUpnpDeviceLibraryElement*) devs[j];
       
  1104         
       
  1105         if (dev->Local())
       
  1106             {
       
  1107             // for every device
       
  1108             // make this device respond if needed
       
  1109             SingleDeviceResponseL(dev, aMsg);
       
  1110             // get the service list of this device
       
  1111             CDesC8Array* services = &dev->ServiceList();
       
  1112             // get the first service
       
  1113             
       
  1114             for(TInt i=0; i<services->Count(); i++)
       
  1115                 {
       
  1116                 TPtrC8 serviceType = (*services)[i];
       
  1117                 SingleServiceResponseL(dev, serviceType, aMsg);
       
  1118                 }
       
  1119             }
       
  1120         }
       
  1121     }
       
  1122 
       
  1123 //  End of File