--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pnpmobileservices/pnpms/PnpPaosFilter/src/PnpPaosXml.cpp Thu Dec 17 08:40:12 2009 +0200
@@ -0,0 +1,960 @@
+/*
+* 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: For parsing PAOS XML documents
+*
+*/
+
+
+
+#include <e32std.h>
+#include <xml/parser.h> // for compact XML parser
+#include <xml/documentparameters.h> // for RDocumentParameters
+#include <sysutil.h>
+#include <PnpToPaosInterface.h>
+#include "HdcToPaosInterface.h"
+
+#include "PnpPaosXml.h"
+#include "PnpPaosLogger.h"
+#include <PnpProvUtil.h>
+
+const TInt KMessageIdLength(12);
+const TInt KInitialResponseLength(512);
+const TInt KInitialReferenceMessageIdLength(32);
+const TInt KInitialUrlLength(128);
+
+_LIT8( KParserDataType, "text/xml" );
+_LIT8( KUriPaosLiberty, "urn:liberty:paos:2003-08" );
+_LIT8( KLocalNameRequest, "Request" );
+_LIT8( KUriSbLiberty, "urn:liberty:sb:2003-08" );
+_LIT8( KLocalNameCorrelation, "Correlation" );
+_LIT8( KAttributeResponseConsumerUrl, "responseConsumerURL" );
+_LIT8( KPnpMsNokiaUri, "http://pnpms.nokia.com/signkey" );
+_LIT8( KAttributeMessageId, "messageID" );
+_LIT8( KElementGetKey, "getkey" );
+_LIT8( KKeyRequest, "Keyrequest" );
+_LIT8( KContentSetOfKeys, "SetOfKeys" );
+_LIT8( KContentHdcSetOfKeys, "HdcSetOfKeys" );
+_LIT8( KContentHdcSetOfKeys2, "HDCSetOfKeys" );
+
+
+enum TElementIds
+ {
+ EElementUnrecognized = 0,
+ EElementKeyRequest,
+ EElementGetKey
+ };
+
+// Panic texts
+_LIT( KResponseEmpty, "PnPMS PAOS Response" );
+
+// PAOS data sent to the PnP MS server
+_LIT8(
+ KPnpPaosResponse,
+ "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
+ "<soap:Header>"
+ "%S" /* Add a KPaosResponseMessageIds here if the request has messageid field */
+ "</soap:Header>"
+ "<soap:Body>"
+ "<pp:Signkey xmlns:pp=\"http://pnpms.nokia.com/signkey\">"
+ "<Keyinfo>%S</Keyinfo>"
+ "<nonce>%S</nonce>"
+ "<mcc>%S</mcc>"
+ "<mnc>%S</mnc>"
+ "<cmcc>%S</cmcc>"
+ "<cmnc>%S</cmnc>"
+ "<cVersion>%S</cVersion>"
+ "<deviceinfo>%S</deviceinfo>"
+ "</pp:Signkey>"
+ "</soap:Body>"
+ "</soap:Envelope>"
+ );
+
+// PAOS data sent to the HelpDeskConnect server
+_LIT8(
+ KHdcPaosResponse,
+ "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
+ "<soap:Header>"
+ "%S" /* Add a KPaosResponseMessageIds here if the request has messageid field */
+ "</soap:Header>"
+ "<soap:Body>"
+ "<pp:Signkey xmlns:pp=\"http://pnpms.nokia.com/signkey\">"
+ "%S" /* Add a list of KHdcKeyInfoElement's here */
+ "<nonce>%S</nonce>"
+ "<hdcVersion>%S</hdcVersion>"
+ "</pp:Signkey>"
+ "</soap:Body>"
+ "</soap:Envelope>"
+ );
+
+_LIT8(
+ KHdcKeyInfoElement,
+ "<Keyinfo>%S</Keyinfo>"
+ );
+const TInt KHdcKeyInfoElementLength( 21 );
+
+_LIT8(
+ KPaosResponseMessageIds,
+ "<sb:Correlation xmlns:sb=\"urn:liberty:paos:2003-08\" "
+ "messageID=\"%S\" "
+ "refToMessageID=\"%S\"/>"
+ );
+
+
+CPnpPaosXml* CPnpPaosXml::NewL()
+ {
+ LOGSTRING("CPnpPaosXml::NewL()");
+ CPnpPaosXml* self = new (ELeave) CPnpPaosXml();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ LOGSTRING("CPnpPaosXml::NewL() - done");
+ return self;
+ }
+
+CPnpPaosXml::CPnpPaosXml() :
+ iPaosStatus( EPaosStatusUnknown ),
+ iResponseConsumerUrlFound( EFalse ),
+ iErrorFound( EFalse ),
+ iCurrentElement( EElementUnrecognized )
+ {
+ LOGSTRING("constructor CPnpPaosXml()");
+ }
+
+void CPnpPaosXml::ConstructL()
+ {
+ LOGSTRING("CPnpPaosXml::ConstructL()");
+
+ iParser = Xml::CParser::NewL( KParserDataType, *this );
+
+ LOGSTRING("CPnpPaosXml::ConstructL() - 2");
+ iPaosPostUrlPath = HBufC8::NewL( KInitialUrlLength );
+
+ iMessageId = HBufC8::NewL( KMessageIdLength );
+ // We do not know the length of refToMessageID until we get it
+ // from the service
+ iReferenceMessageId = HBufC8::NewL( KInitialReferenceMessageIdLength );
+ iPaosResponse = HBufC8::NewL( KInitialResponseLength );
+
+ LOGSTRING("CPnpPaosXml::ConstructL() - done");
+ }
+
+CPnpPaosXml::~CPnpPaosXml()
+ {
+ LOGSTRING("CPnpPaosXml::~CPnpPaosXml()");
+ delete iParser;
+ delete iPaosRequest;
+ delete iPaosResponse;
+ delete iMessageId;
+ delete iReferenceMessageId;
+ delete iPaosPostUrlPath;
+ LOGSTRING("CPnpPaosXml::~CPnpPaosXml() - done");
+ }
+
+void CPnpPaosXml::OnOutOfData()
+ {
+ }
+
+void CPnpPaosXml::ParseL( TPaosStates& aPaosStatus )
+ {
+ LOGSTRING("CPnpPaosXml::ParseL()");
+
+ // Reset possible previous paos response
+ ReleaseData();
+
+ // Reset state variables
+ iPaosStatus = EPaosStatusUnknown;
+ iErrorFound = EFalse;
+ iCurrentElement = EElementUnrecognized;
+ iResponseConsumerUrlFound = EFalse;
+
+ LOGSTRING("ParseBeginL()");
+
+ iParser->ParseBeginL();
+ Xml::ParseL( *iParser, *iPaosRequest );
+
+ aPaosStatus = iPaosStatus; // Store status
+ LOGSTRING("ParseL() - done");
+
+ // There has to be a consumer URL in the document
+ if( !iResponseConsumerUrlFound )
+ {
+ LOGSTRING( "responseCosumerURL not found!" );
+ User::Leave( KErrArgument );
+ }
+
+ // No errors allowed in the XML
+ if( iErrorFound )
+ {
+ LOGSTRING( "Error in the XML!" );
+ User::Leave( KErrArgument );
+ }
+
+ // Only key requests for PnP-MS or HelpDeskConnect
+ // keys (parameters) allowed with this PAOS parser
+ switch( aPaosStatus )
+ {
+ case EPaosStatusRequestingPnPKeys:
+ ConstructPnPPaosResponseL();
+ break;
+ case EPaosStatusRequestingHdcKeys:
+ ConstructHdcPaosResponseL();
+ break;
+ default:
+ LOGSTRING( "Invalid PAOS request!" );
+ User::Leave( KErrArgument );
+ break;
+ }
+
+#ifdef LOGGING_ENABLED
+ for( TInt i(0); i < iPaosResponse->Length(); i += 128 )
+ {
+ TPtrC8 logText = iPaosResponse->Right( iPaosResponse->Length() - i );
+ LOGTEXT( logText );
+ }
+#endif
+
+ // Reset state variables
+ iPaosStatus = EPaosStatusUnknown;
+ iErrorFound = EFalse;
+ iCurrentElement = EElementUnrecognized;
+
+ LOGSTRING("CPnpPaosXml::ParseL - done()");
+ }
+
+TBool CPnpPaosXml::CollectResponseBodyL( MHTTPDataSupplier& aBody )
+ {
+ LOGSTRING( "CPnpPaosXml::CollectResponseBodyL" );
+
+ // Store incoming body part
+ TPtrC8 dataChunk;
+ TBool returnValue = aBody.GetNextDataPart( dataChunk );
+
+#ifdef LOGGING_ENABLED
+ for( TInt i(0); i < dataChunk.Length(); i += 128 )
+ {
+ LOGSTRING( "CPnpPaosXml: MHTTPDataSupplier:" );
+ TPtrC8 logText = dataChunk.Right( dataChunk.Length() - i );
+ LOGTEXT( logText );
+ }
+#endif
+
+ if( !iPaosRequest )
+ {
+ iPaosRequest = HBufC8::NewL( dataChunk.Length() );
+ }
+
+ TPtr8 paosRequestPtr = iPaosRequest->Des();
+ if( paosRequestPtr.MaxLength() < ( iPaosRequest->Length() + dataChunk.Length() ) )
+ {
+ LOGSTRING( "Re-allocate response buffer" );
+ iPaosRequest = iPaosRequest->ReAllocL( iPaosRequest->Length() + dataChunk.Length() );
+ paosRequestPtr.Set( iPaosRequest->Des() );
+ }
+ paosRequestPtr.Append( dataChunk );
+
+ LOGSTRING( "CPnpPaosXml::CollectResponseBodyL - done" );
+ return returnValue;
+ }
+/*
+#ifndef __SERIES60_
+TPtrC8 CPnpPaosXml::ResponseBodyL()
+ {
+ LOGSTRING( "CPnpPaosXml::ResponseBodyL" );
+ if( !iPaosRequest )
+ {
+ User::Leave( KErrNotFound );
+ }
+ return *iPaosRequest;
+ }
+#endif
+*/
+void CPnpPaosXml::ConstructHdcPaosResponseL()
+ {
+ LOGSTRING( "CPnpPaosXml::ConstructHdcPaosResponseL" );
+
+ // give empty parameter values in case there is no DLL for HelpDeskConnect
+ // -> The service may then make the following assumptions:
+ // 1. If there is no PAOS header in the first HTTP GET request -> link: "install HDC"
+ // 2. If there is PAOS headers but PAOS response contains empty parameter values -> link: "install HDC"
+ // 3. PAOS header and a valid PAOS response -> HDC installed OK, proceed to a HDC trigger file
+
+ RLibrary library;
+ const TUidType uid( KNullUid, KNullUid, KHdcUtilDllUid );
+ TInt result = library.Load( KHdcDllFileName, uid );
+ if( result != KErrNone )
+ {
+ // if the dll is not found the response should be empty
+ LOGSTRING2( "err in loading HDC dll: %i", result );
+ ConstructPaosResponseL( KHdcPaosResponse );
+ return;
+ }
+ CleanupClosePushL( library );
+ // Function at ordinal 1 is NewLC
+ TLibraryFunction entry = library.Lookup(1);
+ // Call the function to create new hdc dll object
+ CHdcToPaosInterface* hdcUtil = ( CHdcToPaosInterface* ) entry();
+
+ // HDC-nonce
+ // create new nonce
+ TBuf8<KHdcNonceLength> nonce;
+ hdcUtil->CreateNewNonceL( nonce );
+
+ // HDC-version
+ TBuf8<KMaxHdcVersionStringLength> version;
+ hdcUtil->Version( version );
+
+ // List of key-infos
+ HdcKeyInfoList keyInfoList;
+ hdcUtil->HdcKeyInfos( keyInfoList );
+ TInt keyInfoCount = keyInfoList.Count();
+
+ HBufC8* keyInfos = HBufC8::NewLC(
+ keyInfoCount * KMaxHdcKeyInfoLength + /* space for keyinfos */
+ keyInfoCount * KHdcKeyInfoElement().Length() ); /* space for XML elements */
+ TPtr8 keyInfosPtr = keyInfos->Des();
+ for( TInt i(0); i < keyInfoCount; i++ )
+ {
+ TBuf8<KMaxHdcKeyInfoLength + KHdcKeyInfoElementLength> keyInfoXmlElement;
+ keyInfoXmlElement.Format( KHdcKeyInfoElement, &( keyInfoList[i] ) );
+ keyInfosPtr.Append( keyInfoXmlElement );
+ }
+
+ LOGSTRING( "CPnpPaosXml::ConstructHdcPaosResponseL format response" );
+ // 1. KPaosResponseMessageIds
+ // 2. List of KHdcKeyInfoElement's
+ // 3. HDC nonce
+ // 4. HDC version
+ ConstructPaosResponseL( KHdcPaosResponse, *keyInfos, nonce, version );
+ LOGSTRING( "CPnpPaosXml::ConstructHdcPaosResponseL response formatted" );
+
+ // RArray must be closed before destructing
+ keyInfoList.Close();
+
+ CleanupStack::PopAndDestroy( keyInfos );
+ CleanupStack::PopAndDestroy( hdcUtil );
+ CleanupStack::PopAndDestroy(); // library.Close()
+ }
+
+void CPnpPaosXml::ConstructPnPPaosResponseL()
+ {
+ LOGSTRING( "CPnpPaosXml::ConstructPnPPaosResponseL" );
+
+ // Dynamically load the pnp util DLL,
+ const TUidType uid( KNullUid, KNullUid, KPnpUtilDllUid );
+ RLibrary pnpLibrary;
+ TInt result = pnpLibrary.Load( KPnpUtilDllFileName, uid );
+ if( result != KErrNone )
+ {
+ // if the dll is not found the response should be empty
+ LOGSTRING2( "err in loading pnp util dll: %i", result );
+ ConstructPaosResponseL( KPnpPaosResponse );
+ return;
+ }
+ CleanupClosePushL( pnpLibrary );
+
+ // Function at ordinal 1 is NewPnpUtilLC
+ //TLibraryFunction entry = pnpLibrary.Lookup(1);
+ // Call the function to create new Pnp util object
+ //MPnpToPaosInterface* pnpUtil = ( MPnpToPaosInterface* ) entry();
+
+ CPnpUtilImpl *pnpUtil = CPnpUtilImpl::NewLC();
+
+ // check version
+ TBuf8<KMaxVersionStringLength> version;
+ TBuf<KMaxVersionStringLength> version16;
+ pnpUtil->Version( version16 );
+ version.Copy( version16 );
+ LOGTEXT( version );
+ // BC break between versions NPnPS60-0.10 and newer ones; Version function
+ // should be binary compatible, though.
+ // (older versions of pnputil should not be a problem as updating PAOS filter
+ // without updating PnP-MS components should be possible only by installing
+ // HelpDeskConnect With PAOS filter)
+ if( version.Compare( _L8("NPnPS60-0.10") ) == 0 )
+ {
+ // if the dll is not compatible give an empty response
+ LOGSTRING( "Too old version of PnpUtil installed" );
+ ConstructPaosResponseL( KPnpPaosResponse );
+ CleanupStack::PopAndDestroy( pnpUtil );
+ CleanupStack::PopAndDestroy(); // pnpLibrary.Close();
+ return;
+ }
+
+ LOGSTRING( "CPnpPaosXml::ConstructPnPPaosResponseL 2" );
+
+ // MNCs and MCCs
+ LOGSTRING( "CPnpPaosXml::ConstructPnPPaosResponseL 2.01" );
+ pnpUtil->FetchHomeNetworkInfoL();
+ LOGSTRING( "CPnpPaosXml::ConstructPnPPaosResponseL 2.1" );
+ TRAPD( err, pnpUtil->FetchNetworkInfoL() );
+ if( err != KErrNone )
+ {
+ LOGSTRING2( "CPnpPaosXml::Could not fetch network info %i", err );
+ pnpUtil->SetNetworkMccL( _L("") );
+ pnpUtil->SetNetworkMncL( _L("") );
+ }
+
+ LOGSTRING( "CPnpPaosXml::ConstructPnPPaosResponseL 2.2" );
+ RMobilePhone::TMobilePhoneNetworkCountryCode homeMcc = pnpUtil->HomeMccL();
+ LOGSTRING( "CPnpPaosXml::ConstructPnPPaosResponseL 2.3" );
+ RMobilePhone::TMobilePhoneNetworkIdentity homeMnc = pnpUtil->HomeMncL();
+ LOGSTRING( "CPnpPaosXml::ConstructPnPPaosResponseL 2.4" );
+ RMobilePhone::TMobilePhoneNetworkCountryCode networkMcc = pnpUtil->NetworkMccL();
+ LOGSTRING( "CPnpPaosXml::ConstructPnPPaosResponseL 2.5" );
+ RMobilePhone::TMobilePhoneNetworkIdentity networkMnc = pnpUtil->NetworkMncL();
+ LOGSTRING( "CPnpPaosXml::ConstructPnPPaosResponseL 2.6" );
+ TBuf8<4> hmcc;
+ TBuf8<8> hmnc;
+ TBuf8<4> nmcc;
+ TBuf8<8> nmnc;
+ hmcc.Copy( homeMcc );
+ hmnc.Copy( homeMnc );
+ nmcc.Copy( networkMcc );
+ nmnc.Copy( networkMnc );
+
+ LOGSTRING( "CPnpPaosXml::ConstructPnPPaosResponseL 3" );
+ // keyinfo, nonce
+ TBuf8<KMaxKeyInfoLength> keyInfo;
+ pnpUtil->GetKeyInfoL( keyInfo );
+ TBuf8<KNonceLength> nonce;
+ TInt timeout(0);
+ pnpUtil->CreateNewNonceL( timeout, nonce );
+
+ LOGSTRING( "CPnpPaosXml::ConstructPnPPaosResponseL 4" );
+ // product model
+ TBuf8<KSysUtilVersionTextLength> deviceinfo;
+ FetchProductModelL( deviceinfo );
+
+ // Clear all service activation data in case if service
+ // activation fails
+ // This will avoid displaying service specific notes for
+ // example email service activation when help-portal service required
+ // As of now only Help-portal server sends PAOS request
+ // and NSA server(which provides email service activation) is not
+ // supporting PAOS.
+ // If NSA server provides PAOS then these resetting of
+ // service activation data to be commented
+
+ CPnpProvUtil* prov = CPnpProvUtil::NewLC();
+
+ const TUint32 uidval = 0;
+ prov->SetApplicationUidL(uidval);
+
+
+ TBuf<2> buf(_L(""));
+ prov->SetProvAdapterAppIdL(buf);
+
+ CleanupStack::PopAndDestroy();
+
+ LOGSTRING( "CPnpPaosXml::ConstructPnPPaosResponseL format response" );
+ // 1. Keyinfo
+ // 2. Nonce
+ // 3. Home MCC
+ // 4. Home MNC
+ // 5. Network (current) MCC
+ // 6. Network MNC
+ // 7. Version
+ // 8. deviceinfo
+ ConstructPaosResponseL( KPnpPaosResponse, keyInfo, nonce, hmcc, hmnc, nmcc, nmnc, version, deviceinfo );
+ LOGSTRING( "CPnpPaosXml::ConstructPnPPaosResponseL response formatted" );
+
+ LOGSTRING( "CleanupStack::PopAndDestroy( pnpUtil )" );
+ CleanupStack::PopAndDestroy( pnpUtil );
+ LOGSTRING( "pnpLibrary.Close()" );
+ CleanupStack::PopAndDestroy(); // pnpLibrary.Close()
+ LOGSTRING( "CPnpPaosXml::ConstructPnPPaosResponseL - done" );
+ }
+
+void CPnpPaosXml::ConstructPaosResponseL(
+ const TDesC8& aResponse,
+ const TDesC8& aParameter1,
+ const TDesC8& aParameter2,
+ const TDesC8& aParameter3,
+ const TDesC8& aParameter4,
+ const TDesC8& aParameter5,
+ const TDesC8& aParameter6,
+ const TDesC8& aParameter7,
+ const TDesC8& aParameter8
+ )
+ {
+ // Construct PAOS message id element if reference message id is available
+ HBufC8* messageIds(0);
+ if( iReferenceMessageId->Length() )
+ {
+ LOGSTRING( "iMessageId:" );
+ LOGTEXT( *iMessageId );
+ LOGSTRING( "iReferenceMessageId:" );
+ LOGTEXT( *iReferenceMessageId );
+
+ messageIds = HBufC8::NewLC(
+ KPaosResponseMessageIds().Length() +
+ iMessageId->Length() +
+ iReferenceMessageId->Length() );
+ messageIds->Des().Format( KPaosResponseMessageIds, iMessageId, iReferenceMessageId );
+ }
+
+ LOGSTRING( "CPnpPaosXml::ConstructPaosResponseL" );
+ // Construct a new PAOS response
+ TInt responseLength(
+ aResponse.Length() +
+ aParameter1.Length() +
+ aParameter2.Length() +
+ aParameter3.Length() +
+ aParameter4.Length() +
+ aParameter5.Length() +
+ aParameter6.Length() +
+ aParameter7.Length() +
+ aParameter8.Length()
+ );
+
+ // Add the length of messageIds buffer to responseLength
+ if( messageIds )
+ responseLength += messageIds->Length();
+
+ // Expand buffer if needed
+ if( iPaosResponse->Des().MaxSize() < responseLength )
+ iPaosResponse = iPaosResponse->ReAllocL( responseLength );
+
+ LOGSTRING( "CPnpPaosXml::ConstructPaosResponseL - format" );
+ if( messageIds )
+ {
+ iPaosResponse->Des().Format(
+ aResponse,
+ messageIds, /* The first parameter in aResponse is assumed to be messageids */
+ &aParameter1,
+ &aParameter2,
+ &aParameter3,
+ &aParameter4,
+ &aParameter5,
+ &aParameter6,
+ &aParameter7,
+ &aParameter8
+ );
+ LOGSTRING( "CleanupStack::PopAndDestroy( messageIds )" );
+ CleanupStack::PopAndDestroy( messageIds );
+ }
+ else
+ {
+ iPaosResponse->Des().Format(
+ aResponse,
+ &KNullDesC8(),
+ &aParameter1,
+ &aParameter2,
+ &aParameter3,
+ &aParameter4,
+ &aParameter5,
+ &aParameter6,
+ &aParameter7,
+ &aParameter8
+ );
+ }
+ LOGSTRING( "CPnpPaosXml::ConstructPaosResponseL - done" );
+ }
+
+void CPnpPaosXml::ResetPaosRequest()
+ {
+ delete iPaosRequest;
+ iPaosRequest = 0;
+ }
+
+TBool CPnpPaosXml::GetNextDataPart( TPtrC8& aDataPart )
+ {
+ LOGSTRING("CPnpPaosXml::GetNextDataPart");
+
+ if( !iPaosResponse )
+ {
+ LOGSTRING( "empty response!" );
+ // Panics are not shown (on browser process), the browser is just closed
+ __ASSERT_ALWAYS( EFalse, User::Panic( KResponseEmpty, KErrNotFound ) );
+ }
+ aDataPart.Set( *iPaosResponse );
+ return ETrue;
+ }
+
+void CPnpPaosXml::ReleaseData()
+ {
+ LOGSTRING("CPnpPaosXml::ReleaseData");
+ // No need to delete our data
+ // They are deleted in the destructor and reallocated when needed
+ iPaosResponse->Des().Zero();
+ iMessageId->Des().Zero();
+ iReferenceMessageId->Des().Zero();
+ iPaosPostUrlPath->Des().Zero();
+ }
+
+TInt CPnpPaosXml::OverallDataSize()
+ {
+ LOGSTRING("CPnpPaosXml::OverallDataSize");
+ if( !iPaosResponse )
+ {
+ LOGSTRING( "empty response!" );
+ // Panics are not shown (on browser process), the browser is just closed
+ __ASSERT_ALWAYS( EFalse, User::Panic( KResponseEmpty, KErrNotFound ) );
+ }
+ return iPaosResponse->Length();
+ }
+
+TInt CPnpPaosXml::Reset()
+ {
+ LOGSTRING("CPnpPaosXml::Reset");
+ return KErrNone;
+ }
+
+void CPnpPaosXml::OnStartDocumentL( const RDocumentParameters& aDocParam, TInt aErrorCode )
+ {
+ LOGSTRING2( "CPnpPaosXml::OnStartDocumentL: %i", aErrorCode );
+ if( aErrorCode != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+ // Keep compiler happy
+ (void)aDocParam;
+ LOGRSTRING( "CharSet: %S", aDocParam.CharacterSetName() );
+ }
+
+void CPnpPaosXml::OnEndDocumentL( TInt aErrorCode )
+ {
+ LOGSTRING2( "CPnpPaosXml::OnEndDocumentL: %i", aErrorCode );
+ if( aErrorCode != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+ }
+
+void CPnpPaosXml::OnStartElementL( const RTagInfo& aElement, const RAttributeArray& aAttributes,
+ TInt aErrorCode )
+ {
+ LOGSTRING2( "CPnpPaosXml::OnStartElementL: %i", aErrorCode );
+ if( aErrorCode != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ RString uri = aElement.Uri();
+ RString localName = aElement.LocalName();
+
+#ifdef LOGGING_ENABLED
+ RString prefix = aElement.Prefix();
+#endif
+ LOGRSTRING( "uri: %S", uri );
+ LOGRSTRING( "localName: %S", localName );
+ LOGRSTRING( "prefix: %S", prefix );
+
+ if( iCurrentElement == EElementKeyRequest )
+ {
+ if( localName.DesC().Compare( KElementGetKey ) == 0 )
+ {
+ LOGSTRING( "setting iCurrentElement = EElementGetKey" );
+ iCurrentElement = EElementGetKey;
+ }
+ }
+ else if( uri.DesC().Compare( KPnpMsNokiaUri ) == 0 )
+ {
+ if( localName.DesC().Compare( KKeyRequest ) == 0 )
+ {
+ LOGSTRING( "setting iCurrentElement = EElementKeyRequest" );
+ iCurrentElement = EElementKeyRequest;
+ }
+ }
+
+
+ for( TInt i(0); i < aAttributes.Count(); i++ )
+ {
+ RAttribute attribute = aAttributes[i];
+ RTagInfo tagInfo = attribute.Attribute();
+ RString attributeLocalName = tagInfo.LocalName();
+ RString value = attribute.Value();
+
+#ifdef LOGGING_ENABLED
+ RString attributeUri = tagInfo.Uri();
+ RString attributePrefix = tagInfo.Prefix();
+#endif
+ LOGRSTRING( "attribute uri: %S", attributeUri );
+ LOGRSTRING( "attribute localName: %S", attributeLocalName );
+ LOGRSTRING( "attribute prefix: %S", attributePrefix );
+ LOGRSTRING( "value: %S", value );
+
+ // According to PAOS spec: "SOAP request message that (provided that the
+ // SOAP processor wishes to use the PAOS binding) MUST contain a <paos:Request>
+ // SOAP header block."
+ // For some reason Futurice uses prefix ns1 (ns1:Request) for a SOAP request.
+ // So we allow any prefix for a SOAP request instead of only allowing "paos"
+
+ if( localName.DesC().Compare( KLocalNameRequest ) == 0 &&
+ uri.DesC().Compare( KUriPaosLiberty ) == 0 )
+ {
+ LOGSTRING("uri PAOS found");
+ const TDesC8& strAttributeLocalName = attributeLocalName.DesC();
+ const TDesC8& strValue = value.DesC();
+
+ if( strAttributeLocalName.Compare( KAttributeResponseConsumerUrl ) == 0 )
+ {
+ LOGSTRING( "PAOS post url found" );
+ if( iPaosPostUrlPath->Des().MaxLength() < strValue.Length() )
+ {
+ iPaosPostUrlPath = iPaosPostUrlPath->ReAllocL( strValue.Length() );
+ }
+ iPaosPostUrlPath->Des().Copy( strValue );
+ LOGSTRING( "iResponseConsumerUrlFound = ETrue" );
+ iResponseConsumerUrlFound = ETrue;
+ }
+ else if( attributeLocalName.DesC().Compare( KAttributeMessageId ) == 0)
+ {
+ LOGSTRING("messageID found");
+ const TDesC8& strValue = value.DesC();
+ if( iReferenceMessageId->Des().MaxLength() < strValue.Length() )
+ {
+ iReferenceMessageId = iReferenceMessageId->ReAllocL( strValue.Length() );
+ }
+ iReferenceMessageId->Des().Copy( strValue );
+ // Generate a random character string for our own messageID
+ TPtr8 messageIdPtr = iMessageId->Des();
+ GenerateNonceString( messageIdPtr );
+ }
+ }
+ else if( localName.DesC().Compare( KLocalNameCorrelation ) == 0 &&
+ uri.DesC().Compare( KUriSbLiberty ) == 0 )
+ {
+ LOGSTRING("uri SB found");
+ if( attributeLocalName.DesC().Compare( KAttributeMessageId ) == 0)
+ {
+ LOGSTRING("messageID found");
+ const TDesC8& strValue = value.DesC();
+ iReferenceMessageId = iReferenceMessageId->ReAllocL( strValue.Length() );
+ iReferenceMessageId->Des().Copy( strValue );
+ // Generate a random character string for our own messageID
+ TPtr8 messageIdPtr = iMessageId->Des();
+ GenerateNonceString( messageIdPtr );
+ }
+ }
+ }
+ LOGSTRING("CPnpPaosXml::OnStartElementL - done");
+ }
+
+void CPnpPaosXml::GenerateNonceString( TDes8& aString )
+ {
+ LOGSTRING("CPnpPaosXml::GenerateNonceString");
+ aString.Zero();
+
+ _LIT8( KTemp, "123456abcdef");
+ if( aString.MaxLength() <= KTemp().Length() )
+ {
+ aString.Copy( KTemp().Left( aString.MaxLength() ) );
+ }
+ else
+ {
+ aString.Copy( KTemp );
+ }
+
+ LOGSTRING("CPnpPaosXml::GenerateNonceString - done");
+ }
+
+void CPnpPaosXml::OnEndElementL( const RTagInfo& aElement, TInt aErrorCode )
+ {
+ LOGSTRING2( "CPnpPaosXml::OnEndElementL: %i", aErrorCode );
+ if( aErrorCode != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ RString uri = aElement.Uri();
+ RString localName = aElement.LocalName();
+ RString prefix = aElement.Prefix();
+
+ TBuf<255> buff;
+ buff.Copy( uri.DesC().Left(255) );
+ LOGSTRING2( "uri: %S", &buff );
+ buff.Copy( localName.DesC().Left(255) );
+ LOGSTRING2( "localName: %S", &buff );
+ buff.Copy( prefix.DesC().Left(255) );
+ LOGSTRING2( "prefix: %S", &buff );
+
+ if( iCurrentElement == EElementGetKey )
+ {
+ // Ending Get key element?
+ if( localName.DesC().Compare( KElementGetKey ) == 0 )
+ {
+ LOGSTRING( "setting iCurrentElement = EElementKeyRequest" );
+ // Must be inside key request
+ iCurrentElement = EElementKeyRequest;
+ }
+ }
+ else if( iCurrentElement == EElementKeyRequest )
+ {
+ // Ending Key request element?
+ if( uri.DesC().Compare( KPnpMsNokiaUri ) == 0 )
+ {
+ if( localName.DesC().Compare( KKeyRequest ) == 0 )
+ {
+ LOGSTRING( "setting iCurrentElement = EElementUnrecognized" );
+ iCurrentElement = EElementUnrecognized;
+ }
+ }
+ }
+ }
+
+void CPnpPaosXml::OnContentL( const TDesC8& aBytes, TInt aErrorCode )
+ {
+ LOGSTRING2( "CPnpPaosXml::OnContentL: %i", aErrorCode );
+ if( aErrorCode != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+ LOGTEXT( aBytes );
+
+ if( iCurrentElement == EElementGetKey )
+ {
+ LOGSTRING( "Element GetKey" );
+ if( aBytes.Compare( KContentSetOfKeys ) == 0 )
+ {
+ LOGSTRING("EPaosStatusRequestingPnPKeys");
+ iPaosStatus = EPaosStatusRequestingPnPKeys;
+ }
+ else if( aBytes.Compare( KContentHdcSetOfKeys ) == 0 || aBytes.Compare( KContentHdcSetOfKeys2 ) == 0 )
+ {
+ LOGSTRING("EPaosStatusRequestingHdcKeys");
+ iPaosStatus = EPaosStatusRequestingHdcKeys;
+ }
+ }
+ }
+
+void CPnpPaosXml::OnStartPrefixMappingL( const RString& /*aPrefix*/, const RString& /*aUri*/,
+ TInt aErrorCode )
+ {
+ LOGSTRING2( "CPnpPaosXml::OnStartPrefixMappingL: %i", aErrorCode );
+ if( aErrorCode != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+ }
+
+void CPnpPaosXml::OnEndPrefixMappingL( const RString& /*aPrefix*/, TInt aErrorCode )
+ {
+ LOGSTRING2( "CPnpPaosXml::OnEndPrefixMappingL: %i", aErrorCode );
+ if( aErrorCode != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+ }
+
+void CPnpPaosXml::OnIgnorableWhiteSpaceL( const TDesC8& aBytes, TInt aErrorCode )
+ {
+ LOGSTRING2( "CPnpPaosXml::OnIgnorableWhiteSpaceL: %i", aErrorCode );
+ if( aErrorCode != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+ LOGTEXT( aBytes );
+ // Keep compiler happy
+ (void)aBytes;
+ }
+
+void CPnpPaosXml::OnSkippedEntityL( const RString& aName, TInt aErrorCode )
+ {
+ LOGSTRING2( "CPnpPaosXml::OnSkippedEntityL: %i", aErrorCode );
+ if( aErrorCode != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+ LOGRSTRING( "name: %S", aName );
+ // Keep compiler happy
+ (void)aName;
+ }
+
+void CPnpPaosXml::OnProcessingInstructionL( const TDesC8& aTarget, const TDesC8& aData,
+ TInt aErrorCode )
+ {
+ LOGSTRING2( "CPnpPaosXml::OnProcessingInstructionL: %i", aErrorCode );
+ if( aErrorCode != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+ // Keep compiler happy
+ (void)aTarget;
+ (void)aData;
+ LOGSTRING( "target:" );
+ LOGTEXT( aTarget );
+ LOGSTRING( "data:" );
+ LOGTEXT( aData );
+ }
+
+void CPnpPaosXml::OnError( TInt aErrorCode )
+ {
+ LOGSTRING2( "CPnpPaosXml::OnError: %i", aErrorCode );
+ if( aErrorCode != KErrNone )
+ {
+ iErrorFound = ETrue;
+ }
+ }
+
+TAny* CPnpPaosXml::GetExtendedInterface( const TInt32 aUid )
+ {
+ LOGSTRING2( "CPnpPaosXml::GetExtendedInterface: %i", aUid );
+ // Keep compiler happy
+ (void)aUid;
+ return 0;
+ }
+
+void CPnpPaosXml::FetchProductModelL( TDes8& aModel )
+ {
+ HBufC* tmpVersion = HBufC::NewLC( KSysUtilVersionTextLength );
+ TPtr ptr( tmpVersion->Des() );
+ User::LeaveIfError( SysUtil::GetSWVersion( ptr ) );
+ LOGTEXT(ptr);
+
+ _LIT(KVerStrStart,"V ");
+ _LIT(KVerStrEnd,"\n");
+
+ TInt pos1 = tmpVersion->Find(KVerStrStart);
+ TInt pos2 = tmpVersion->Find(KVerStrEnd);
+ TInt verlen = ((TDesC)(KVerStrStart)).Length();
+
+ if( pos1==KErrNotFound) // Version does not start with "V "
+ {
+ pos1=0;
+ verlen=0;
+ }
+
+ if( (pos1!=KErrNotFound)
+ && (pos2!=KErrNotFound)
+ && (pos2 > (pos1 + verlen) )
+ )
+ {
+ TPtrC ptrSeek(ptr);
+ pos1 = ptrSeek.Find(KVerStrEnd);
+ if(pos1>=0)
+ {
+ ptrSeek.Set(ptrSeek.Mid(pos1+1));
+ pos1 = ptrSeek.Find(KVerStrEnd);
+ if( pos1 >= 0 )
+ {
+ ptrSeek.Set(ptrSeek.Mid(pos1+1));
+ pos1 = ptrSeek.Find(KVerStrEnd);
+ if( pos1 < 0 )
+ {
+ ptrSeek.Set(ptrSeek.Mid(1));
+ aModel.Copy(ptrSeek);
+ }
+ else if( pos1 > 0 )
+ {
+ ptrSeek.Set(ptrSeek.Mid(1,pos1-1));
+ aModel.Copy(ptrSeek);
+ }
+ LOGTEXT(aModel);
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy();
+ }
+// End of File