upnp/upnpstack/serviceframework/src/upnpsoapmessagefactory.cpp
changeset 0 f5a58ecadc66
child 9 e84a4b44b2e8
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:  Produces SOAP messages
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include "upnpsoapmessagefactory.h"
       
    22 #include "upnphttpmessagefactory.h"
       
    23 #include "upnpsoapmessage.h"
       
    24 #include "upnpaction.h"
       
    25 #include "upnpargument.h"
       
    26 #include "upnperrors.h"
       
    27 #include "upnpserviceimplementation.h"
       
    28 #include "upnpdevice.h"
       
    29 #include "upnpstring.h"
       
    30 #include "upnpcommonupnplits.h"
       
    31 #define KLogFile _L("UPnPStack.txt")
       
    32 #include "upnpcustomlog.h"
       
    33 #include "upnplist.h"
       
    34 #include "upnpcons.h"
       
    35 
       
    36 // CONSTANTS
       
    37 _LIT8(KSoapEnvelopeStart, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n<s:Body>\n<u:");
       
    38 _LIT8(KSoapServiceNsStart, " xmlns:u=\"urn:schemas-upnp-org:service:");
       
    39 _LIT8(KSoapServiceNsEnd, "\">\n");
       
    40 _LIT8(KActionNameEnd, "</u:");
       
    41 _LIT8(KSoapEnvelopeEnd, ">\n</s:Body>\n</s:Envelope>");
       
    42 _LIT8(KSoapActionStart, "\"urn:schemas-upnp-org:service:");
       
    43 _LIT8(KCrash, "#");
       
    44 _LIT8(KOpenBracket, "<");
       
    45 _LIT8(KCloseBracket, ">");
       
    46 _LIT8(KLinefeed, "\n");
       
    47 _LIT8(KResponse, "Response");
       
    48 
       
    49 _LIT(KSoapErrorStart, 
       
    50      "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n<s:Body>\n<s:Fault>\n<faultcode>s:Client</faultcode>\n<faultstring>UPnPError</faultstring>\n<detail>\n<UPnPError xmlns=\"urn:schemas-upnp-org:control-1-0\">\n<errorCode>");
       
    51 
       
    52 _LIT(KSoapErrorBetween,
       
    53      "</errorCode>\n<errorDescription>");
       
    54 _LIT(KSoapErrorEnd,
       
    55      "</errorDescription>\n</UPnPError>\n</detail>\n</s:Fault>\n</s:Body>\n</s:Envelope>");
       
    56 
       
    57 static const TInt KTagCharsLength = 7;
       
    58 static const TInt KExtraCharsLength = 2;
       
    59 static const TInt KMaxErrorCodeLength = 20;
       
    60 
       
    61 
       
    62 // ============================ MEMBER FUNCTIONS ===============================
       
    63 
       
    64 // -----------------------------------------------------------------------------
       
    65 // RUpnpSoapMessageFactory::SoapRequest
       
    66 //
       
    67 // (other items were commented in a header).
       
    68 // -----------------------------------------------------------------------------
       
    69 //
       
    70 EXPORT_C CUpnpSoapMessage* RUpnpSoapMessageFactory::SoapRequestL(CUpnpAction* aAction)
       
    71     {
       
    72     LOGS("RUpnpSoapMessageFactory::SoapRequest(CUpnpAction*)");
       
    73     
       
    74     if (aAction == NULL)
       
    75     {
       
    76         return NULL;
       
    77     }
       
    78     const TDesC8& actName = aAction->Name();
       
    79     HBufC8* servTypeB = NULL;
       
    80     TInt posS(KErrNotFound);
       
    81     TInt posD(KErrNotFound);
       
    82     
       
    83     const TDesC8& servType = aAction->ServiceType();
       
    84     TInt serviceVersion(KErrNotFound);
       
    85     if(servType.Length())
       
    86         {
       
    87         posS = servType.LocateReverse(':');
       
    88         if (posS != KErrNotFound)
       
    89             {
       
    90             TLex8 number(servType.Right(servType.Length() - posS - 1));
       
    91             if(number.Val(serviceVersion) != KErrNone)
       
    92                 {
       
    93                 serviceVersion = KErrNotFound;
       
    94                 }
       
    95             }
       
    96         }
       
    97     
       
    98     const TDesC8& devType = aAction->Service().Device().DeviceType();
       
    99     TInt deviceVersion(KErrNotFound);
       
   100     
       
   101     if(devType.Length())
       
   102         {
       
   103         posD = devType.LocateReverse(':');
       
   104         if (posD != KErrNotFound)
       
   105             {
       
   106             TLex8 number(devType.Right(devType.Length() - posD - 1));
       
   107             if(number.Val(deviceVersion) != KErrNone)
       
   108                 {
       
   109                 deviceVersion = KErrNotFound;
       
   110                 }
       
   111             }
       
   112         }    
       
   113     
       
   114     if(deviceVersion != KErrNotFound && serviceVersion != KErrNotFound)
       
   115         {
       
   116         if(deviceVersion < serviceVersion)
       
   117             {
       
   118             servTypeB = HBufC8::NewLC(servType.Length() + devType.Length() - posD);
       
   119             TPtr8 buf = servTypeB->Des();
       
   120             buf.Append(servType.Left(posS + 1));
       
   121             buf.Append(devType.Right(devType.Length() - posD - 1));
       
   122             }
       
   123         else
       
   124             {
       
   125             servTypeB = servType.AllocLC();
       
   126             }           
       
   127         }
       
   128     else
       
   129         {
       
   130         servTypeB = servType.AllocLC();
       
   131         }
       
   132     
       
   133     RPointerArray<CUpnpArgument>& args = aAction->ArgumentList();
       
   134     
       
   135     TInt argLength = 0;
       
   136     
       
   137     TInt i=0;
       
   138     for(i=0; i<args.Count(); i++)
       
   139     {
       
   140         argLength += KTagCharsLength; 
       
   141         argLength += args[i]->Name().Length() * 2;
       
   142         argLength += args[i]->Value().Length();
       
   143     }
       
   144     
       
   145     argLength += KSoapEnvelopeStart().Length();
       
   146     argLength += KSoapServiceNsStart().Length();
       
   147     argLength += KSoapServiceNsEnd().Length();
       
   148     argLength += KActionNameEnd().Length();
       
   149     argLength += KSoapEnvelopeEnd().Length();
       
   150     
       
   151     argLength += actName.Length()*2;
       
   152     argLength += servTypeB->Length();
       
   153     
       
   154     HBufC8* buffer = HBufC8::NewLC(argLength);
       
   155     TPtr8 ptr = buffer->Des();
       
   156     
       
   157     ptr.Append(KSoapEnvelopeStart());
       
   158     ptr.Append(actName);
       
   159     ptr.Append(KSoapServiceNsStart());
       
   160     ptr.Append(*servTypeB);
       
   161     ptr.Append(KSoapServiceNsEnd());
       
   162     
       
   163     for (i=0; i<args.Count(); i++)
       
   164     {
       
   165         if (args[i]->Direction() == EIn)
       
   166         {
       
   167             const TDesC8& name = args[i]->Name();
       
   168             const TDesC8& value = args[i]->Value();
       
   169             
       
   170             ptr.Append(KOpenBracket());
       
   171             ptr.Append(name);
       
   172             ptr.Append(KCloseBracket());
       
   173             ptr.Append(value);
       
   174             ptr.Append(KOpenBracket());
       
   175             ptr.Append(UpnpString::KSlash());
       
   176             ptr.Append(name);
       
   177             ptr.Append(KCloseBracket());
       
   178             ptr.Append(KLinefeed());
       
   179             
       
   180         }
       
   181     }
       
   182     ptr.Append(KActionNameEnd());
       
   183     ptr.Append(actName);
       
   184     ptr.Append(KSoapEnvelopeEnd());
       
   185     
       
   186     
       
   187     CUpnpSoapMessage* self = NULL;
       
   188     
       
   189     TInetAddr dest = aAction->DestinationAddr();
       
   190     dest.SetFamily(KAfInet);
       
   191     
       
   192     TPtrC8 destPath = aAction->DestinationPath();
       
   193     if (destPath.Length() > KHttp().Length() && 
       
   194         destPath.Left( KHttp().Length() ) == KHttp())
       
   195     {
       
   196         self = static_cast<CUpnpSoapMessage*>(RUpnpHttpMessageFactory::HttpPostL(
       
   197             destPath));
       
   198     }
       
   199     else if (destPath.Find(UpnpString::KSlash()) != 0)
       
   200     {
       
   201         HBufC8* longPath = HBufC8::NewLC(destPath.Length() +1);
       
   202         longPath->Des().Append(UpnpString::KSlash());
       
   203         longPath->Des().Append(destPath);
       
   204         self = static_cast<CUpnpSoapMessage*>(RUpnpHttpMessageFactory::HttpPostL(
       
   205                                                         dest, *longPath));
       
   206         
       
   207         CleanupStack::PopAndDestroy( longPath );
       
   208     }
       
   209     else
       
   210     {
       
   211         self = static_cast<CUpnpSoapMessage*>(RUpnpHttpMessageFactory::HttpPostL(
       
   212                                                         dest, destPath));
       
   213     }
       
   214     
       
   215     CleanupStack::PushL(self);
       
   216     CUpnpHttpHeaderList* hdrList=self->HeaderList();
       
   217     
       
   218     CUpnpHttpHeader* hdr = hdrList->First();
       
   219     
       
   220     
       
   221     while ( hdr )
       
   222     {
       
   223      TBool flag = EFalse;
       
   224         if(hdr->Name().Length() == UpnpSSDP::KHdrHost().Length())
       
   225         {
       
   226             if (hdr->Name().FindC(UpnpSSDP::KHdrHost()) == 0)
       
   227             {
       
   228 				CUpnpHttpHeader* temp = hdr;
       
   229 				hdr = hdrList->Next(hdr);
       
   230 				flag = ETrue;
       
   231 				hdrList->Remove(temp);
       
   232                 delete temp;
       
   233 				
       
   234             }
       
   235         }
       
   236 		if(!flag)
       
   237 			hdr = hdrList->Next(hdr);
       
   238     }
       
   239     
       
   240     HBufC8* host = UpnpString::InetToStringL( self->Sender() );
       
   241     CleanupStack::PushL( host );
       
   242     self->AddPairL( UpnpSSDP::KHdrHost(), *host );
       
   243     CleanupStack::PopAndDestroy( host );
       
   244     
       
   245     self->SetSessionId(aAction->SessionId());
       
   246     self->SetBodyL(*buffer);
       
   247     self->AddPairL(UpnpHTTP::KHdrContentType(), UpnpGENA::KTextXmlUtf8());
       
   248     
       
   249     
       
   250     HBufC8* soapAction = HBufC8::NewLC(
       
   251                    KSoapActionStart().Length() + 
       
   252                    aAction->Name().Length() + 
       
   253                    servTypeB->Length() + 
       
   254                    KExtraCharsLength);
       
   255     
       
   256     TPtr8 soapPtr = soapAction->Des();
       
   257     
       
   258     // soapPtr = "urn:schemas-upnp-org:service:
       
   259     soapPtr.Append(KSoapActionStart());
       
   260     // soapPtr = "urn:schemas-upnp-org:service:serviceType:v
       
   261     soapPtr.Append(*servTypeB);
       
   262     // soapPtr = "urn:schemas-upnp-org:service:serviceType:v#
       
   263     soapPtr.Append(KCrash());
       
   264     // soapPtr = "urn:schemas-upnp-org:service:serviceType:v#actionName
       
   265     soapPtr.Append(aAction->Name());
       
   266     // soapPtr = "urn:schemas-upnp-org:service:serviceType:v#actionName"
       
   267     soapPtr.Append(UpnpString::KInvComma());
       
   268     
       
   269     self->AddPairL(KSoapAction(), soapPtr);
       
   270     
       
   271     self->SetLocal(aAction->Local());
       
   272     CleanupStack::PopAndDestroy(soapAction);
       
   273     CleanupStack::Pop(self);
       
   274     CleanupStack::PopAndDestroy(buffer);
       
   275     
       
   276     CleanupStack::PopAndDestroy(servTypeB);
       
   277     
       
   278     return self;
       
   279 }
       
   280 
       
   281 // -----------------------------------------------------------------------------
       
   282 // RUpnpSoapMessageFactory::SoapResponseL
       
   283 //
       
   284 // (other items were commented in a header).
       
   285 // -----------------------------------------------------------------------------
       
   286 //
       
   287 EXPORT_C CUpnpSoapMessage* RUpnpSoapMessageFactory::SoapResponseL(CUpnpAction* aAction)
       
   288 {
       
   289     LOGS("RUpnpSoapMessageFactory::SoapResponseL(CUpnpAction*)");
       
   290     if (aAction == NULL)
       
   291     {
       
   292         return NULL;
       
   293     }
       
   294     const TDesC8& actName = aAction->Name();
       
   295     const TDesC8& servType = aAction->ServiceType();
       
   296     
       
   297     RPointerArray<CUpnpArgument>& args = aAction->ArgumentList();
       
   298     
       
   299     TInt argLength = 0;
       
   300     
       
   301     TInt i=0;
       
   302     for(i=0; i<args.Count(); i++)
       
   303     {
       
   304         argLength += KTagCharsLength;
       
   305         
       
   306         argLength += args[i]->Name().Length() * 2;
       
   307         argLength += args[i]->Value().Length();
       
   308     }
       
   309     
       
   310     argLength += (2 * KResponse().Length()); 
       
   311     
       
   312     argLength += KSoapEnvelopeStart().Length();
       
   313     argLength += KSoapServiceNsStart().Length();
       
   314     argLength += KSoapServiceNsEnd().Length();
       
   315     argLength += KActionNameEnd().Length();
       
   316     argLength += KSoapEnvelopeEnd().Length();
       
   317     
       
   318     argLength += actName.Length() * 2;
       
   319     argLength += servType.Length();
       
   320     
       
   321     HBufC8* buffer = HBufC8::NewLC(argLength);
       
   322     TPtr8 ptr = buffer->Des();
       
   323     
       
   324     ptr.Append(KSoapEnvelopeStart());
       
   325     ptr.Append(actName);
       
   326     ptr.Append(KResponse());
       
   327     ptr.Append(KSoapServiceNsStart());
       
   328     ptr.Append(servType);
       
   329     ptr.Append(KSoapServiceNsEnd());
       
   330     
       
   331     for (i=0; i<args.Count(); i++)
       
   332     {
       
   333         if (args[i]->Direction() == EOut)
       
   334         {
       
   335             TDesC8& name = args[i]->Name();
       
   336             TDesC8& value = args[i]->Value();
       
   337             
       
   338             ptr.Append(KOpenBracket());
       
   339             ptr.Append(name);
       
   340             ptr.Append(KCloseBracket());
       
   341             ptr.Append(value);
       
   342             ptr.Append(KOpenBracket());
       
   343             ptr.Append(UpnpString::KSlash());
       
   344             ptr.Append(name);
       
   345             ptr.Append(KCloseBracket());
       
   346             ptr.Append(KLinefeed());
       
   347             
       
   348         }
       
   349     }
       
   350     ptr.Append(KActionNameEnd());
       
   351     ptr.Append(actName);
       
   352     ptr.Append(KResponse());
       
   353     ptr.Append(KSoapEnvelopeEnd());
       
   354     
       
   355     CUpnpSoapMessage* self = static_cast<CUpnpSoapMessage*>(
       
   356                     RUpnpHttpMessageFactory::HttpResponseOkL(aAction->Sender()));
       
   357     CleanupStack::PushL(self);
       
   358     
       
   359     self->SetSessionId(aAction->SessionId());
       
   360     
       
   361     self->SetBodyL(*buffer);
       
   362     
       
   363     self->AddPairL(UpnpHTTP::KHdrContentType(), UpnpGENA::KTextXmlUtf8());
       
   364 
       
   365     self->AddPairL(UpnpHTTP::KHdrExtWithoutColon(), KNullDesC8);
       
   366     
       
   367     self->SetLocal(aAction->Local());
       
   368       
       
   369     CleanupStack::Pop(self);
       
   370     CleanupStack::PopAndDestroy(buffer);
       
   371     
       
   372     return self;
       
   373 }
       
   374 
       
   375 // -----------------------------------------------------------------------------
       
   376 // RUpnpSoapMessageFactory::SoapResponseL
       
   377 //
       
   378 // (other items were commented in a header).
       
   379 // -----------------------------------------------------------------------------
       
   380 //
       
   381 EXPORT_C CUpnpSoapMessage* RUpnpSoapMessageFactory::SoapResponseL( CUpnpAction* aAction, TUpnpErrorCode aCode)
       
   382 {
       
   383     LOGS("RUpnpSoapMessageFactory::SoapResponseL(CUpnpAction*, TUpnpErrorCode)");
       
   384     
       
   385     HBufC8* errorString = CUpnpSoapMessage::UpnpErrorL(aCode);
       
   386     CleanupStack::PushL(errorString);
       
   387     CUpnpSoapMessage* self = RUpnpSoapMessageFactory::SoapResponseL(aAction, aCode, *errorString);       
       
   388     CleanupStack::PopAndDestroy(errorString);    
       
   389     return self;   
       
   390 }
       
   391 
       
   392 EXPORT_C CUpnpSoapMessage* RUpnpSoapMessageFactory::SoapResponseL( CUpnpAction* aAction, 
       
   393                                                                    TUpnpErrorCode aCode, 
       
   394                                                                    const TDesC8& aDescription)
       
   395 {
       
   396     LOGS("RUpnpSoapMessageFactory::SoapResponseL(CUpnpAction*, TUpnpErrorCode,TDesC8&)");
       
   397     
       
   398     if (aAction == NULL)
       
   399     {
       
   400         return NULL;
       
   401     }
       
   402     TBuf8<KMaxErrorCodeLength> errorCode;
       
   403     TInt code = aCode;
       
   404     errorCode.Num(code);
       
   405     
       
   406     TInt length = 0;
       
   407     length += KSoapErrorStart().Length();
       
   408     length += KSoapErrorBetween().Length();
       
   409     length += KSoapErrorEnd().Length();
       
   410     length += errorCode.Length();
       
   411     
       
   412     length += aDescription.Length();
       
   413     
       
   414     HBufC8* buffer = HBufC8::NewL(length);
       
   415     TPtr8 ptr = buffer->Des();
       
   416     
       
   417     ptr.Append(KSoapErrorStart());
       
   418     ptr.Append(errorCode);
       
   419     ptr.Append(KSoapErrorBetween());
       
   420     ptr.Append(aDescription);
       
   421     ptr.Append(KSoapErrorEnd());
       
   422     
       
   423     CleanupStack::PushL(buffer);
       
   424     
       
   425     CUpnpSoapMessage* self = static_cast<CUpnpSoapMessage*>(
       
   426         RUpnpHttpMessageFactory::HttpResponseErrorL(aAction->Sender(), 500));
       
   427     
       
   428     CleanupStack::PushL(self);
       
   429     self->SetSessionId(aAction->SessionId());
       
   430     
       
   431     self->SetBodyL(*buffer);
       
   432     self->AddPairL(UpnpHTTP::KHdrContentType(), UpnpGENA::KTextXmlUtf8());
       
   433     self->AddPairL(UpnpHTTP::KHdrExtWithoutColon(), KNullDesC8);
       
   434     
       
   435     self->SetLocal(aAction->Local());
       
   436 
       
   437         CleanupStack::Pop(self);
       
   438     CleanupStack::PopAndDestroy(buffer);
       
   439     
       
   440     return self;
       
   441 }
       
   442                                                            
       
   443 // -----------------------------------------------------------------------------
       
   444 // RUpnpSoapMessageFactory::SoapResponseL
       
   445 //
       
   446 // (other items were commented in a header).
       
   447 // -----------------------------------------------------------------------------
       
   448 //
       
   449 EXPORT_C CUpnpSoapMessage* RUpnpSoapMessageFactory::SoapResponseL( 
       
   450                                             CUpnpSoapMessage* aMessage,
       
   451                                             TUpnpErrorCode aCode )
       
   452 {
       
   453     if (aMessage == NULL)
       
   454     {
       
   455         return NULL;
       
   456     }
       
   457     TBuf8<KMaxErrorCodeLength> errorCode;
       
   458     TInt code = aCode;
       
   459     errorCode.Num(code);
       
   460     
       
   461     TInt length = 0;
       
   462     length += KSoapErrorStart().Length();
       
   463     length += KSoapErrorBetween().Length();
       
   464     length += KSoapErrorEnd().Length();
       
   465     length += errorCode.Length();
       
   466     
       
   467     HBufC8* errorString = CUpnpSoapMessage::UpnpErrorL(aCode);
       
   468     CleanupStack::PushL(errorString);
       
   469     
       
   470     length += errorString->Length();
       
   471     
       
   472     HBufC8* buffer = HBufC8::NewLC(length);
       
   473     TPtr8 ptr = buffer->Des();
       
   474     
       
   475     ptr.Append(KSoapErrorStart());
       
   476     ptr.Append(errorCode);
       
   477     ptr.Append(KSoapErrorBetween());
       
   478     ptr.Append(*errorString);
       
   479     ptr.Append(KSoapErrorEnd());
       
   480     
       
   481     CUpnpSoapMessage* self = static_cast<CUpnpSoapMessage*>(
       
   482             RUpnpHttpMessageFactory::HttpResponseErrorL(aMessage->Sender(), 500));
       
   483     
       
   484     self->SetSessionId(aMessage->SessionId());
       
   485     
       
   486     self->SetBodyL(*buffer);
       
   487     self->AddPairL(UpnpHTTP::KHdrContentType(), UpnpGENA::KTextXmlUtf8());
       
   488     self->AddPairL(UpnpHTTP::KHdrExtWithoutColon(), KNullDesC8);
       
   489 
       
   490     self->SetLocal(aMessage->Local());
       
   491   
       
   492     CleanupStack::PopAndDestroy(2);
       
   493     
       
   494     return self;
       
   495 }
       
   496 
       
   497 //  End of File