diff -r 000000000000 -r f5a58ecadc66 upnp/upnpstack/serviceframework/src/upnpsoapmessagefactory.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/upnp/upnpstack/serviceframework/src/upnpsoapmessagefactory.cpp Tue Feb 02 01:12:20 2010 +0200 @@ -0,0 +1,497 @@ +/** @file +* Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Produces SOAP messages +* +*/ + + + +// INCLUDE FILES +#include "upnpsoapmessagefactory.h" +#include "upnphttpmessagefactory.h" +#include "upnpsoapmessage.h" +#include "upnpaction.h" +#include "upnpargument.h" +#include "upnperrors.h" +#include "upnpserviceimplementation.h" +#include "upnpdevice.h" +#include "upnpstring.h" +#include "upnpcommonupnplits.h" +#define KLogFile _L("UPnPStack.txt") +#include "upnpcustomlog.h" +#include "upnplist.h" +#include "upnpcons.h" + +// CONSTANTS +_LIT8(KSoapEnvelopeStart, "\n\n\n\n"); +_LIT8(KActionNameEnd, "\n\n"); +_LIT8(KSoapActionStart, "\"urn:schemas-upnp-org:service:"); +_LIT8(KCrash, "#"); +_LIT8(KOpenBracket, "<"); +_LIT8(KCloseBracket, ">"); +_LIT8(KLinefeed, "\n"); +_LIT8(KResponse, "Response"); + +_LIT(KSoapErrorStart, + "\n\n\n\ns:Client\nUPnPError\n\n\n"); + +_LIT(KSoapErrorBetween, + "\n"); +_LIT(KSoapErrorEnd, + "\n\n\n\n\n"); + +static const TInt KTagCharsLength = 7; +static const TInt KExtraCharsLength = 2; +static const TInt KMaxErrorCodeLength = 20; + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// RUpnpSoapMessageFactory::SoapRequest +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C CUpnpSoapMessage* RUpnpSoapMessageFactory::SoapRequestL(CUpnpAction* aAction) + { + LOGS("RUpnpSoapMessageFactory::SoapRequest(CUpnpAction*)"); + + if (aAction == NULL) + { + return NULL; + } + const TDesC8& actName = aAction->Name(); + HBufC8* servTypeB = NULL; + TInt posS(KErrNotFound); + TInt posD(KErrNotFound); + + const TDesC8& servType = aAction->ServiceType(); + TInt serviceVersion(KErrNotFound); + if(servType.Length()) + { + posS = servType.LocateReverse(':'); + if (posS != KErrNotFound) + { + TLex8 number(servType.Right(servType.Length() - posS - 1)); + if(number.Val(serviceVersion) != KErrNone) + { + serviceVersion = KErrNotFound; + } + } + } + + const TDesC8& devType = aAction->Service().Device().DeviceType(); + TInt deviceVersion(KErrNotFound); + + if(devType.Length()) + { + posD = devType.LocateReverse(':'); + if (posD != KErrNotFound) + { + TLex8 number(devType.Right(devType.Length() - posD - 1)); + if(number.Val(deviceVersion) != KErrNone) + { + deviceVersion = KErrNotFound; + } + } + } + + if(deviceVersion != KErrNotFound && serviceVersion != KErrNotFound) + { + if(deviceVersion < serviceVersion) + { + servTypeB = HBufC8::NewLC(servType.Length() + devType.Length() - posD); + TPtr8 buf = servTypeB->Des(); + buf.Append(servType.Left(posS + 1)); + buf.Append(devType.Right(devType.Length() - posD - 1)); + } + else + { + servTypeB = servType.AllocLC(); + } + } + else + { + servTypeB = servType.AllocLC(); + } + + RPointerArray& args = aAction->ArgumentList(); + + TInt argLength = 0; + + TInt i=0; + for(i=0; iName().Length() * 2; + argLength += args[i]->Value().Length(); + } + + argLength += KSoapEnvelopeStart().Length(); + argLength += KSoapServiceNsStart().Length(); + argLength += KSoapServiceNsEnd().Length(); + argLength += KActionNameEnd().Length(); + argLength += KSoapEnvelopeEnd().Length(); + + argLength += actName.Length()*2; + argLength += servTypeB->Length(); + + HBufC8* buffer = HBufC8::NewLC(argLength); + TPtr8 ptr = buffer->Des(); + + ptr.Append(KSoapEnvelopeStart()); + ptr.Append(actName); + ptr.Append(KSoapServiceNsStart()); + ptr.Append(*servTypeB); + ptr.Append(KSoapServiceNsEnd()); + + for (i=0; iDirection() == EIn) + { + const TDesC8& name = args[i]->Name(); + const TDesC8& value = args[i]->Value(); + + ptr.Append(KOpenBracket()); + ptr.Append(name); + ptr.Append(KCloseBracket()); + ptr.Append(value); + ptr.Append(KOpenBracket()); + ptr.Append(UpnpString::KSlash()); + ptr.Append(name); + ptr.Append(KCloseBracket()); + ptr.Append(KLinefeed()); + + } + } + ptr.Append(KActionNameEnd()); + ptr.Append(actName); + ptr.Append(KSoapEnvelopeEnd()); + + + CUpnpSoapMessage* self = NULL; + + TInetAddr dest = aAction->DestinationAddr(); + dest.SetFamily(KAfInet); + + TPtrC8 destPath = aAction->DestinationPath(); + if (destPath.Length() > KHttp().Length() && + destPath.Left( KHttp().Length() ) == KHttp()) + { + self = static_cast(RUpnpHttpMessageFactory::HttpPostL( + destPath)); + } + else if (destPath.Find(UpnpString::KSlash()) != 0) + { + HBufC8* longPath = HBufC8::NewLC(destPath.Length() +1); + longPath->Des().Append(UpnpString::KSlash()); + longPath->Des().Append(destPath); + self = static_cast(RUpnpHttpMessageFactory::HttpPostL( + dest, *longPath)); + + CleanupStack::PopAndDestroy( longPath ); + } + else + { + self = static_cast(RUpnpHttpMessageFactory::HttpPostL( + dest, destPath)); + } + + CleanupStack::PushL(self); + CUpnpHttpHeaderList* hdrList=self->HeaderList(); + + CUpnpHttpHeader* hdr = hdrList->First(); + + + while ( hdr ) + { + TBool flag = EFalse; + if(hdr->Name().Length() == UpnpSSDP::KHdrHost().Length()) + { + if (hdr->Name().FindC(UpnpSSDP::KHdrHost()) == 0) + { + CUpnpHttpHeader* temp = hdr; + hdr = hdrList->Next(hdr); + flag = ETrue; + hdrList->Remove(temp); + delete temp; + + } + } + if(!flag) + hdr = hdrList->Next(hdr); + } + + HBufC8* host = UpnpString::InetToStringL( self->Sender() ); + CleanupStack::PushL( host ); + self->AddPairL( UpnpSSDP::KHdrHost(), *host ); + CleanupStack::PopAndDestroy( host ); + + self->SetSessionId(aAction->SessionId()); + self->SetBodyL(*buffer); + self->AddPairL(UpnpHTTP::KHdrContentType(), UpnpGENA::KTextXmlUtf8()); + + + HBufC8* soapAction = HBufC8::NewLC( + KSoapActionStart().Length() + + aAction->Name().Length() + + servTypeB->Length() + + KExtraCharsLength); + + TPtr8 soapPtr = soapAction->Des(); + + // soapPtr = "urn:schemas-upnp-org:service: + soapPtr.Append(KSoapActionStart()); + // soapPtr = "urn:schemas-upnp-org:service:serviceType:v + soapPtr.Append(*servTypeB); + // soapPtr = "urn:schemas-upnp-org:service:serviceType:v# + soapPtr.Append(KCrash()); + // soapPtr = "urn:schemas-upnp-org:service:serviceType:v#actionName + soapPtr.Append(aAction->Name()); + // soapPtr = "urn:schemas-upnp-org:service:serviceType:v#actionName" + soapPtr.Append(UpnpString::KInvComma()); + + self->AddPairL(KSoapAction(), soapPtr); + + self->SetLocal(aAction->Local()); + CleanupStack::PopAndDestroy(soapAction); + CleanupStack::Pop(self); + CleanupStack::PopAndDestroy(buffer); + + CleanupStack::PopAndDestroy(servTypeB); + + return self; +} + +// ----------------------------------------------------------------------------- +// RUpnpSoapMessageFactory::SoapResponseL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C CUpnpSoapMessage* RUpnpSoapMessageFactory::SoapResponseL(CUpnpAction* aAction) +{ + LOGS("RUpnpSoapMessageFactory::SoapResponseL(CUpnpAction*)"); + if (aAction == NULL) + { + return NULL; + } + const TDesC8& actName = aAction->Name(); + const TDesC8& servType = aAction->ServiceType(); + + RPointerArray& args = aAction->ArgumentList(); + + TInt argLength = 0; + + TInt i=0; + for(i=0; iName().Length() * 2; + argLength += args[i]->Value().Length(); + } + + argLength += (2 * KResponse().Length()); + + argLength += KSoapEnvelopeStart().Length(); + argLength += KSoapServiceNsStart().Length(); + argLength += KSoapServiceNsEnd().Length(); + argLength += KActionNameEnd().Length(); + argLength += KSoapEnvelopeEnd().Length(); + + argLength += actName.Length() * 2; + argLength += servType.Length(); + + HBufC8* buffer = HBufC8::NewLC(argLength); + TPtr8 ptr = buffer->Des(); + + ptr.Append(KSoapEnvelopeStart()); + ptr.Append(actName); + ptr.Append(KResponse()); + ptr.Append(KSoapServiceNsStart()); + ptr.Append(servType); + ptr.Append(KSoapServiceNsEnd()); + + for (i=0; iDirection() == EOut) + { + TDesC8& name = args[i]->Name(); + TDesC8& value = args[i]->Value(); + + ptr.Append(KOpenBracket()); + ptr.Append(name); + ptr.Append(KCloseBracket()); + ptr.Append(value); + ptr.Append(KOpenBracket()); + ptr.Append(UpnpString::KSlash()); + ptr.Append(name); + ptr.Append(KCloseBracket()); + ptr.Append(KLinefeed()); + + } + } + ptr.Append(KActionNameEnd()); + ptr.Append(actName); + ptr.Append(KResponse()); + ptr.Append(KSoapEnvelopeEnd()); + + CUpnpSoapMessage* self = static_cast( + RUpnpHttpMessageFactory::HttpResponseOkL(aAction->Sender())); + CleanupStack::PushL(self); + + self->SetSessionId(aAction->SessionId()); + + self->SetBodyL(*buffer); + + self->AddPairL(UpnpHTTP::KHdrContentType(), UpnpGENA::KTextXmlUtf8()); + + self->AddPairL(UpnpHTTP::KHdrExtWithoutColon(), KNullDesC8); + + self->SetLocal(aAction->Local()); + + CleanupStack::Pop(self); + CleanupStack::PopAndDestroy(buffer); + + return self; +} + +// ----------------------------------------------------------------------------- +// RUpnpSoapMessageFactory::SoapResponseL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C CUpnpSoapMessage* RUpnpSoapMessageFactory::SoapResponseL( CUpnpAction* aAction, TUpnpErrorCode aCode) +{ + LOGS("RUpnpSoapMessageFactory::SoapResponseL(CUpnpAction*, TUpnpErrorCode)"); + + HBufC8* errorString = CUpnpSoapMessage::UpnpErrorL(aCode); + CleanupStack::PushL(errorString); + CUpnpSoapMessage* self = RUpnpSoapMessageFactory::SoapResponseL(aAction, aCode, *errorString); + CleanupStack::PopAndDestroy(errorString); + return self; +} + +EXPORT_C CUpnpSoapMessage* RUpnpSoapMessageFactory::SoapResponseL( CUpnpAction* aAction, + TUpnpErrorCode aCode, + const TDesC8& aDescription) +{ + LOGS("RUpnpSoapMessageFactory::SoapResponseL(CUpnpAction*, TUpnpErrorCode,TDesC8&)"); + + if (aAction == NULL) + { + return NULL; + } + TBuf8 errorCode; + TInt code = aCode; + errorCode.Num(code); + + TInt length = 0; + length += KSoapErrorStart().Length(); + length += KSoapErrorBetween().Length(); + length += KSoapErrorEnd().Length(); + length += errorCode.Length(); + + length += aDescription.Length(); + + HBufC8* buffer = HBufC8::NewL(length); + TPtr8 ptr = buffer->Des(); + + ptr.Append(KSoapErrorStart()); + ptr.Append(errorCode); + ptr.Append(KSoapErrorBetween()); + ptr.Append(aDescription); + ptr.Append(KSoapErrorEnd()); + + CleanupStack::PushL(buffer); + + CUpnpSoapMessage* self = static_cast( + RUpnpHttpMessageFactory::HttpResponseErrorL(aAction->Sender(), 500)); + + CleanupStack::PushL(self); + self->SetSessionId(aAction->SessionId()); + + self->SetBodyL(*buffer); + self->AddPairL(UpnpHTTP::KHdrContentType(), UpnpGENA::KTextXmlUtf8()); + self->AddPairL(UpnpHTTP::KHdrExtWithoutColon(), KNullDesC8); + + self->SetLocal(aAction->Local()); + + CleanupStack::Pop(self); + CleanupStack::PopAndDestroy(buffer); + + return self; +} + +// ----------------------------------------------------------------------------- +// RUpnpSoapMessageFactory::SoapResponseL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C CUpnpSoapMessage* RUpnpSoapMessageFactory::SoapResponseL( + CUpnpSoapMessage* aMessage, + TUpnpErrorCode aCode ) +{ + if (aMessage == NULL) + { + return NULL; + } + TBuf8 errorCode; + TInt code = aCode; + errorCode.Num(code); + + TInt length = 0; + length += KSoapErrorStart().Length(); + length += KSoapErrorBetween().Length(); + length += KSoapErrorEnd().Length(); + length += errorCode.Length(); + + HBufC8* errorString = CUpnpSoapMessage::UpnpErrorL(aCode); + CleanupStack::PushL(errorString); + + length += errorString->Length(); + + HBufC8* buffer = HBufC8::NewLC(length); + TPtr8 ptr = buffer->Des(); + + ptr.Append(KSoapErrorStart()); + ptr.Append(errorCode); + ptr.Append(KSoapErrorBetween()); + ptr.Append(*errorString); + ptr.Append(KSoapErrorEnd()); + + CUpnpSoapMessage* self = static_cast( + RUpnpHttpMessageFactory::HttpResponseErrorL(aMessage->Sender(), 500)); + + self->SetSessionId(aMessage->SessionId()); + + self->SetBodyL(*buffer); + self->AddPairL(UpnpHTTP::KHdrContentType(), UpnpGENA::KTextXmlUtf8()); + self->AddPairL(UpnpHTTP::KHdrExtWithoutColon(), KNullDesC8); + + self->SetLocal(aMessage->Local()); + + CleanupStack::PopAndDestroy(2); + + return self; +} + +// End of File