diff -r 000000000000 -r 8e480a14352b messagingfw/biomsgfw/wappsrc/wapp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/messagingfw/biomsgfw/wappsrc/wapp.cpp Mon Jan 18 20:36:02 2010 +0200 @@ -0,0 +1,3830 @@ +// Copyright (c) 2000-2009 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: +// + +#include +#include +#include +#include +#include +#include "wapperr.h" +#include + +#include "CWappBookmark.h" +#include "IspTableData.h" +#include "IpBearerData.h" +#include "SmsBearerData.h" +#include "GprsBearerData.h" + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef SYMBIAN_BOOKMARK_DATABASE +#include +#include +#endif // SYMBIAN_BOOKMARK_DATABASE + +#ifdef _DEBUG +const TUid KUidSmartMessageMtm = {0x10001262}; +const TInt32 KUidBIOWAPAccessPointMsg = 0x10005532; +#endif + +const TInt KMaxNameBufferLength = 35; + +_LIT8(KCRLinefeed, "\r\n"); +_LIT8(KEBookmarkItemBegin, "BEGIN:eBOOKMARK\r\n"); // Precedes a Bookmark in the Bookmark file +_LIT8(KEBookmarkItemName, "NAME:"); // Precedes a Bookmark Name +_LIT8(KEBookmarkItemURL, "URL:"); // Precedes a Bookmark URL +_LIT8(KEBookmarkType, "TYPE:Wap\r\n"); +_LIT8(KEBookmarkItemEnd, "END:eBOOKMARK\r\n"); + +_LIT(KEBookmarkExtension, ".eBM"); + +_LIT(KWappResourceFile, "\\resource\\messaging\\wappstr.rsc"); + +const TUint32 KCharsetUCS2 = 1000; +const TUint32 KCharsetUTF8 = 106; +const TUint32 KCharsetASCII = 3; + + +// The number of characters that are constant for an eBookmark +// file. It is the sum of the above literals. +// +const TInt KEBookmarkConstantChars = 55; + +CMsvBIOWapAccessParser::CMsvBIOWapAccessParser(CRegisteredParserDll& aRegisteredParserDll, CMsvEntry& aEntry, RFs& aFs) +: CBaseScriptParser2(aRegisteredParserDll, aEntry, aFs) + { + } + +EXPORT_C CMsvBIOWapAccessParser* CMsvBIOWapAccessParser::NewL(CRegisteredParserDll& aRegisteredParserDll, CMsvEntry& aEntry, RFs& aFs) + { + CMsvBIOWapAccessParser* self = new (ELeave) CMsvBIOWapAccessParser(aRegisteredParserDll, aEntry, aFs); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +CMsvBIOWapAccessParser::~CMsvBIOWapAccessParser() + { + Cancel(); + // Char Conversion + delete iCharsetConverter; + delete iSettings; + delete iSmsBuf; + delete iStringTable; + if (iBookmarkList!=NULL) + { + iBookmarkList->ResetAndDestroy(); + delete iBookmarkList; + } + delete iModemInitString; + if (iParsedFieldArray != NULL) + { + iParsedFieldArray->ResetAndDestroy(); + delete iParsedFieldArray; + } + delete iWapIpISPTable; + delete iWapSmsTable; + delete iWapGprsTable; + delete iGsmCsdWapIpTable; + delete iGprsWapIpTable; + + delete iDBSession; + REComSession::FinalClose(); + } + +// +// ConstructL - ConstructL fn - creates the Parsed Field array, +// and connects the file system if unconnected +// +void CMsvBIOWapAccessParser::ConstructL() + { + iParsedFieldArray = new(ELeave) CArrayPtrSeg(16); + iDBSession = CMDBSession::NewL(CMDBSession::LatestVersion()); + iBookmarkList = new(ELeave) CArrayPtrSeg (4);// 4 should be enough + iGsmCsdData = EFalse; + iGsmSmsData = EFalse; + iGprsData = EFalse; + iURLData = EFalse; + iNameData = EFalse; + iIdData = EFalse; + iMMSURLData = EFalse; + CActiveScheduler::Add(this); + } + +// +// ParseL - public method forming part of the API. Calls ChangeState to set +// state for parsing. Helper functions do the parsing +// +void CMsvBIOWapAccessParser::ParseL(TRequestStatus& aStatus, const TDesC& aSms) + { + TMsvEntry entry = iEntry.Entry(); // Get the generic stuff + iEntryId = entry.Id(); // store the TMsvId + + // Message must be unparsed, or parsed or committed - anything else is a big error + __ASSERT_DEBUG(( entry.MtmData3() == BIO_MSG_ENTRY_UNPARSED + || entry.MtmData3() == BIO_MSG_ENTRY_PARSED + || entry.MtmData3() == BIO_MSG_ENTRY_PROCESSED), + Panic(EWappErrMessageProcessed)); + + // Message must not be empty + __ASSERT_DEBUG (aSms.Length() > 0 ,Panic( EWappEmptyBuffer)); + + // Already parsed....just return + if(entry.MtmData3() == BIO_MSG_ENTRY_PARSED || entry.MtmData3() == BIO_MSG_ENTRY_PROCESSED) + { + iReport = &aStatus; + User::RequestComplete(iReport, KErrNone); + } + // not parsed so start the Parsing operation + else if(entry.MtmData3() == BIO_MSG_ENTRY_UNPARSED) + { + delete iSmsBuf; + iSettings = NULL; + iSmsBuf = aSms.AllocL(); + ChangeStateL(EStart); // Do do initial processing, and go Active + aStatus = KRequestPending; + iReport = &aStatus; + } + else + { + User::Leave(KErrNotSupported); + } + } + +// +// ProcessL() -- If parsed data is not already in memory, ProcessL loads it from the store +// created during parsing. Creates a new entry in the WAP settings CommDb tables, from the data +// +void CMsvBIOWapAccessParser::ProcessL(TRequestStatus& aStatus) + { + // Calls ChangeState to get State Engine going. ( DoProcess does the hard work) + + iEntryId= iEntry.Entry().Id(); //store id of Bio Msg entry + + // Must be a smart/Bio message, of type WAP access point and not have the failure flag set + __ASSERT_DEBUG(iEntry.Entry().iMtm==KUidSmartMessageMtm, Panic(EWappInvalidEntry)); + __ASSERT_DEBUG(iEntry.Entry().iBioType ==KUidBIOWAPAccessPointMsg, Panic(EWappInvalidEntry)); + __ASSERT_DEBUG(iEntry.Entry().Failed()== 0 , Panic(EWappInvalidEntry)); + + ResetProcessVariablesL(); // Reset variables to initial state + ChangeStateL(EProcessInitialise); //Set the initial state + + aStatus = KRequestPending; + iReport = &aStatus; + } + +// DoCancel - Cancels the Active Object operation and returns control to the caller +// +void CMsvBIOWapAccessParser::DoCancel() + { + User::RequestComplete(iReport,KErrCancel); + } + +// +// RunL() - Called by the Active Scheduler when it finishes its Wait Loop. +// Doesn't do much as ParseL and Process keep going until they are complete. +// Returns the current status. +// +void CMsvBIOWapAccessParser::RunL() + { + iCompleted = iStatus.Int(); + + if (iCompleted != KErrNone) + { + User::RequestComplete(iReport,iCompleted); + return; + } + TInt currentState = iState; + TRAPD(error, CallChangeStateL(currentState)); + switch (currentState) + { + case EStart: + case EProcessInitialise: + case EProcessMessage: + if (error!=KErrNone) + User::RequestComplete(iReport, error); // Return error code + break; + case EParseMessage: + case ECompleteMessage: + User::RequestComplete(iReport, iCompleted); // Nothing more - allow calling RunL to complete and return status + break; + default: + break; + } + } + +void CMsvBIOWapAccessParser::CallChangeStateL(TInt aState) + { + switch (aState) + { + case EStart: + ChangeStateL(EParseMessage); + break; + case EProcessInitialise: + ChangeStateL(EProcessMessage); + break; + case EProcessMessage: + ChangeStateL(ECompleteMessage); // last stage change iMtmData3 + break; + default: + break; + } + } + +// +// ChangeStateL - Used to advance the state to the next level. +// Makes most of the important calls. +// +void CMsvBIOWapAccessParser::ChangeStateL(TParseSession aState) + { + iState = aState; + switch (iState) + { + case EStart: // Check the data we've got - if OK get the Active Stuff going + if (!iSmsBuf) + User::Leave(KWappErrNullValue); + else if (iSmsBuf->Length() == 0) + User::Leave(KWappErrContent); + break; + case EParseMessage: + iSms = iSmsBuf->Des(); // initialise TLex object + ParseMessageL(); + break; + case EProcessInitialise: + if (!iSmsParsed) + RestoreParsedDataL(); + PreProcessL(); //Scan iParsedFieldArray extracting data - leaves if data is invalid + ValidateCharacteristicsL(); // Ensures that the mix of characteristic is valid + break; + case EProcessMessage: + DoProcessL(); // Do the proper processing of and committing to CommDb + break; + case ECompleteMessage: + CompleteMessageL(); + break; + default: + break; + } + + // Finished this step -add ourselves to Scheduler,& return error code to calling thread. + RequestComplete(iStatus, KErrNone); + SetActive(); + } + +// +// ParseMessageL() - Performs various checks, if data has been saved it restores it +// else it calls DoParseL which does the hard stuff). +// +void CMsvBIOWapAccessParser::ParseMessageL() + { + // MUST have Bio message, of type WAP access point and no failure flag set + __ASSERT_DEBUG(iEntry.Entry().iMtm==KUidSmartMessageMtm, Panic(EWappInvalidEntry)); + __ASSERT_DEBUG(iEntry.Entry().iBioType ==KUidBIOWAPAccessPointMsg, Panic(EWappInvalidEntry)); + __ASSERT_DEBUG(iEntry.Entry().Failed()== 0 , Panic(EWappInvalidEntry)); + + // Message already parsed(includes processed). Just restore data and return + if (iEntry.Entry().MtmData3() == BIO_MSG_ENTRY_PARSED || + iEntry.Entry().MtmData3() == BIO_MSG_ENTRY_PROCESSED) + iSmsParsed = ETrue; // Have a store produced during parsing. + else + iSmsParsed = EFalse; + + if(iSmsParsed) // parsed before - restore data + { + RestoreParsedDataL(); + return; + } + + DoParseL(); // Does the actual parsing of the message contents + SettingsNamePresentL(); // Check for Name Characteristic- if not found appends a default one + StoreParsedDataL(); // Saves the parsed fields to store & sets TMSvEntry values + iSmsParsed=ETrue; + } + +// +// CompleteMessageL() - Completes the ProcessL operation, by setting the iMtmData3 +// flag to BIO_MSG_ENTRY_PROCESSEDMessage body, and TMsvEntry's +// iDescription and iDetails are left unchanged +// +void CMsvBIOWapAccessParser::CompleteMessageL() + { + TMsvEntry entry= iEntry.Entry(); + entry.SetMtmData3(BIO_MSG_ENTRY_PROCESSED); + + iEntry.ChangeL(entry); + } + +// +// RequestComplete() - Completes an AO operation, and passes control back to the caller +// +void CMsvBIOWapAccessParser::RequestComplete(TRequestStatus& aStatus, TInt aError) + { + TRequestStatus* p = &aStatus; + User::RequestComplete(p, aError); + } + +// +// DoParseL() - Parses through encoded message body extracting the fields from the characteristics +// Uses helper functions to handle reading and storing of characteristics and parms. +// Parsing performed in one continuous operation. +// +void CMsvBIOWapAccessParser::DoParseL() + { + const TInt KDecimalSizeOfMaxInt = 10; // length of 0xFFFFFFFF in a string in decimal + TBuf localBuf; + TChar thisCharacter; + + thisCharacter = GetNextMessageByteL(); // Read the first char to get XML version number + /* + The version byte contains the the major version minus one in the upper four bits + of the 8 bit integer, and the minor version in the lower four bits. + */ + TUint wbxmlversionbyte = thisCharacter; + TUint majorversion = ((wbxmlversionbyte & 0xF0) + 0x10) - 0x0F; // gives the major version, eg if wbxml spec version 1.2, it gives 1. + TUint minorversion = wbxmlversionbyte & 0x0F; //gives the minor version, eg if wbxml spec version 1.2, it gives 2. + + iWBXMLversionX10 = (majorversion *10) + minorversion; //i.e. If actual version is 1.1 this is *10 to remove the decimal place. + + //Append this to the array + localBuf.NumUC(iWBXMLversionX10,EDecimal); //Format to a decimal string + AppendDataPairL(KWappXMLversion, localBuf); // Append to array of parsed fields + + // Now need to get the 32bit int encoded over a number of bytes + iPublicID = Read_mb_u_int32L(); // Read in a multi byte 32bit int value + localBuf.NumUC(iPublicID, EHex); // Format to a string as hex + AppendDataPairL(KWappPublicID, localBuf); + + // WAP Binary XML version 1.1 also has additional info for the character set. + if (iWBXMLversionX10 !=10) // If WAP Binary XML version > 1.0 + iCharacterSet = Read_mb_u_int32L(); // Get the character set + else + //This is the character set MIBenum for UTF-8. + //According to WBXML spec version 1.1 and 1.2, this is the default which should + //be assumed if the charset value is not available. Value 0 must not be used. + iCharacterSet = 106; + + delete iCharsetConverter; + iCharsetConverter = NULL; + iCharsetConverter = CWapCharsetConverter::NewL(iFs, iCharacterSet); + + localBuf.NumUC(iCharacterSet, EHex); // Convert to string as hex + AppendDataPairL(KWappCharacterSet,localBuf); + + // Coded string table length - don't need this once we have string table + // as we store copies of the strings within parsed data fields + TUint32 stringTableLength = Read_mb_u_int32L(); + + //Read in string table if it exists, i.e. length >0 otherwise skip this step + if (stringTableLength>0) + { + iStringTable = HBufC::NewL(stringTableLength); + iSms.Mark(); // Mark the current position + + TUint32 remaining = iSms.RemainderFromMark().Length(); //Eliminates warning about comparison in next line + + if ( remaining > stringTableLength) // Sting Table doesn't exceed end of message + iSms.Inc(stringTableLength); // so increment to the character following the string table + else + User::Leave(KWappErrEOS); // Table exceeds message length - unrecoverable error + iStringTable->Des().Copy(iSms.MarkedToken()); + } + + thisCharacter = GetNextMessageByteL(); + //This should be a Characteristic List with content, but no attributes + if (thisCharacter == (KWAPP_CHAR_LIST+KWAPP_TAG_CONTENT)) + { + // Main loop - keep moving through the message, until we reach the end or error + TBool finished = EFalse; + while (!finished) + { + // Read in characteristics, any order is accepted + if (!iSms.Eos() && (iSms.Peek() & 0x3F) == KWAPP_CHARACTERISTIC) + { + // Read in characteristic, inc. its terminator tag - no terminator =error! + ReadCharacteristicL(); + } + else + { + if (iSms.Eos()) // Error end of message + User::Leave(KWappErrEOS); + else if ((TUint)iSms.Peek()==KWAPP_END_TAG) // END Tag - OK we've finished! + finished = ETrue; + else if ( (iSms.Peek()& 0x3F != KWAPP_CHARACTERISTIC) || (iSms.Peek() != KWAPP_END_TAG) ) + User::Leave(KWappErrUnexpectedValue); //Not a Characteristic or END token + } + } + } // End of if (thisCharacter == (KWAPP_CHAR_LIST..... ) + else + User::Leave(KWappErrMandatoryTagMissing); + } +// end CMsvBIOWapAccessParser::DoParseL() + +// +// ReadCharacteristicL() - Reads in a characteristic from the message. +// +void CMsvBIOWapAccessParser::ReadCharacteristicL() + { + TBool hasContent; + TInt characteristicIndex=0; // start position in array for this characteristic + CParsedField* parsedField = new(ELeave)CParsedField(); + CleanupStack::PushL(parsedField); + + TChar currentCharacter = GetNextMessageByteL(); + iCurrentCharacteristic =EWappUnknown; // Reset flag for current characteristic's type + + // Use bit comparison of token with mask 0x3F to check explicitly that correct + // bits are set i.e. that bits 0-5 = 0x06 (NB Actual value = 0x86 or =0xC6) + if ( ( currentCharacter & 0x3F) != KWAPP_CHARACTERISTIC ) // i.e. not or 0x06 + User::Leave(KWappErrUnexpectedValue); + else + { + if ( !(currentCharacter & KWAPP_TAG_ATTRIBUTES)) // Bit 7 must be set! + User::Leave(KWappErrNoAttributes); + if (currentCharacter & KWAPP_TAG_CONTENT) //Bit 6 is set - characteristic has content + hasContent =ETrue; + else + hasContent =EFalse; + + + // *************** IMPORTANT NOTE ************************ + // An XML element name without a defined token is sent as an inline string or + // string table ref. prefixed by the TYPE token 0x05 (ie "TYPE="). (True for + // WirelessFuture web site!!) THE ONLY UNDEFINED Type tag is BOOKMARK in version + // 1.0. Therefore if it's 0x05 - check the version. For 1.0 read next char. + // Token must be an inline string or string table ref.Otherwise we have an error. + // **************************************************************************** + + // Read the next byte - info on the type of our characteristic + currentCharacter = (TUint) GetNextMessageByteL(); + + // Check if the tokens 0x05 "TYPE=" - should be for WBXML version = 1.0 + // Read next character + if (currentCharacter == KWAPP_TYPE) + { + // "TYPE=" should be followed by an inline string, or string table reference + // So read another char & increment a place - should now 0x03 or 0x83 + currentCharacter = (TUint) GetNextMessageByteL(); + if ( !(currentCharacter & KWAPP_STR_I) && // Is current character != 0x03 ? + !(currentCharacter & KWAPP_STR_T)) // or != 0x83 + User::Leave(KWappErrUnexpectedValue); // Doc is badly formed doc - leave + } + + // NB for address characteristics, need to store position of the start, so that + // we can search for certain fields. If they're not present we must add defaults. + // Could just scan from the end of the array, but if we miss our target then may + // just increment past this characteristic, through previous ones. + + switch (currentCharacter) + { + case KWAPP_ADDR_TYPE: // Token = 0x06 + { + AppendNameFieldL(KWappCharAddress); + characteristicIndex = iParsedFieldArray->Count()-1; // Store index for this element + iCurrentCharacteristic = EWappAddressCharacteristic; //General code for an address + break; + } + case KWAPP_URL_TYPE: //Token = 0x07 + { + AppendNameFieldL(KWappCharURL); + iCurrentCharacteristic = EWappURLCharacteristic; // it's a URL characteristic + break; + } + case KWAPP_NAME_TYPE: // Token = 0x08 + { + AppendNameFieldL(KWappCharName); + iCurrentCharacteristic = EWappNameCharacteristic;//it's a NAME characteristic + break; + } + case KWAPP_STR_I: // Token = 0x03 , Global WAP XML value + { + // Null terminated inline string follows the token, call fn to read it + parsedField->SetFieldNameL(*ReadInlineStringLC()); + CleanupStack::PopAndDestroy(); //inline string + break; + } + case KWAPP_STR_T: // Token = 0x83, Global WAP XML value + { + // multi byte 32 bit integer follows, an reference to an offset in the string table + TUint32 offset =0; + offset = Read_mb_u_int32L(); // read in the integer + parsedField->SetFieldNameL(*ReadStringTableReferenceLC(offset));//Get string table value,& set the descriptor + CleanupStack::PopAndDestroy(); // string table reference + break; + } + case KWAPP_ID: // Token = 0x7D. Used in version 5.0 + { + AppendNameFieldL(KWappCharID); + iCurrentCharacteristic = EWappIDCharacteristic; + break; + } + case KWAPP_BOOKMARK: // Token = 07F, currently bookmarks stored in file + { + AppendNameFieldL(KWappCharBookmark); + iCurrentCharacteristic = EWappBookmarkCharacteristic; + break; + } + case KWAPP_MMS_URL: + { + AppendNameFieldL(KWappCharMMSURL); + iCurrentCharacteristic = EWappMMSURLCharacteristic; + break; + } + default: + User::Leave(KWappErrUnrecognised); // Unrecognised token or somethings badly wrong + } + + + // If iCurrentCharacteristic isn't set we've just read in a string table ref + // or inline string. Now check the token and set the flag. + if (iCurrentCharacteristic == EWappUnknown) + { + // Get index of last element + if (parsedField->FieldName().CompareF(KWappAddr)==0) + { + iCurrentCharacteristic = EWappAddressCharacteristic; + AppendNameFieldL(KWappCharAddress); + characteristicIndex = iParsedFieldArray->Count()-1;//May be an address so store index + } + else if (parsedField->FieldName().CompareF(KWappURL)==0) + { + iCurrentCharacteristic = EWappURLCharacteristic; + AppendNameFieldL(KWappCharURL); + } + else if (parsedField->FieldName().CompareF(KWappMMSURL)==0) + { + iCurrentCharacteristic = EWappMMSURLCharacteristic; + AppendNameFieldL(KWappCharMMSURL); + } + else if (parsedField->FieldName().CompareF(KWappName)==0) + { + iCurrentCharacteristic = EWappNameCharacteristic; + AppendNameFieldL(KWappCharName); + } + else if (parsedField->FieldName().CompareF(KWappBookmark)==0) + { + iCurrentCharacteristic = EWappBookmarkCharacteristic; + AppendNameFieldL(KWappCharBookmark); + } + else if (parsedField->FieldName().CompareF(KWappID)==0) + { + iCurrentCharacteristic = EWappIDCharacteristic; + AppendNameFieldL(KWappCharID); + } + else + { + User::Leave(KWappErrUnrecognised);// Unrecognised characteristic type + } + } + CleanupStack::PopAndDestroy(parsedField); + + //Check for a VALUE attribute before checking for Parms + currentCharacter =(TUint) GetNextMessageByteL(); + if (currentCharacter ==KWAPP_VALUE_ATTRIB) + { + // Have a value following the TYPE - read in value and store it. + TInt lastElement = iParsedFieldArray->Count()-1; + currentCharacter = (TUint) GetNextMessageByteL(); + + if (currentCharacter == KWAPP_STR_I) //Inline string + { + iParsedFieldArray->At(lastElement)->SetFieldValueL(*ReadInlineStringLC()); //Set value of last element in array + CleanupStack::PopAndDestroy(); + } + + else if (currentCharacter ==KWAPP_STR_T) //String table reference + { + TUint32 tableOffset = Read_mb_u_int32L(); + iParsedFieldArray->At(lastElement)->SetFieldValueL(*ReadStringTableReferenceLC(tableOffset)); //Set Value of last element in array + CleanupStack::PopAndDestroy(); + } + + else + { + User::Leave(KWappErrUnexpectedValue); + } + + // Read the next character for the END TAG check in the following line + currentCharacter = (TUint)GetNextMessageByteL(); + } + + //Check the character- should be 0x01 the end of the characteristic header + if (!currentCharacter ==KWAPP_END_TAG) // Not END - error condition + { + User::Leave(KWappErrNoTermination); + } + + // We shouldn't be at the end of the message. The next byte should be one of the following + // - PARM if this characteristic has content, + // - start of another characteristic + // - END token (0x01). + // So take a peek at the next byte + TUint peekAhead; + + if (iSms.Eos()) + User::Leave(KWappErrEOS); // Somethings wrong - message end + + peekAhead = (TUint) iSms.Peek(); + + // Type is Set - address,URL,Name, Bookmark or ID. Check hasContent flag set correctly. + if ( ((iCurrentCharacteristic == EWappAddressCharacteristic) && !hasContent) || //Address must have Content + ((iCurrentCharacteristic == EWappNameCharacteristic) && !hasContent) || //Name must have Content + ((iCurrentCharacteristic == EWappBookmarkCharacteristic) && !hasContent)|| //Bookmark must have Content + ((iCurrentCharacteristic == EWappIDCharacteristic) && !hasContent) || //ID must have Content + ((iCurrentCharacteristic == EWappURLCharacteristic) && hasContent) || // Url must NOT have Content + ((iCurrentCharacteristic == EWappMMSURLCharacteristic) && hasContent) ) // MmsUrl does not have content + User::Leave(KWappErrContent); // Test for validity of content flag failed. + + + if (hasContent) // passed previous test, - exclude URL as hasContent=EFalse + { + if ( (peekAhead & 0x3F) ==KWAPP_PARM) // bit comparison with 0x07 + { + // Check sucessful, now check for attributes and content (0x80, & 0x40) + if ( (peekAhead & KWAPP_TAG_ATTRIBUTES) && ( !(peekAhead & KWAPP_TAG_CONTENT) ) ) + { + //Have attributes, and no content - ALL OK! + currentCharacter = (TUint32) GetNextMessageByteL(); + while (currentCharacter != KWAPP_END_TAG) + { + ReadParmL(); // Sets iCurrentCharacteristic for addresses + + currentCharacter = (TUint32) GetNextMessageByteL(); // Get the next character from message + + if ( (currentCharacter != (KWAPP_PARM+KWAPP_TAG_ATTRIBUTES)) + && (currentCharacter !=KWAPP_END_TAG) ) // Not 0x87, nor 0x01 = error + User::Leave(KWappErrUnexpectedValue); + } + } + else // Token MUST be 0x87, parms MUST have content but NO attributes! + User::Leave(KWappErrNoAttributes); + } + else //Bits 0-5 are Not 0x07 Should be a PARM token + User::Leave(KWappErrUnexpectedValue); + } //END of (hasContent) + } + // END of if ( !( (TUint32)currentCharacter & KWAPP_CHARACTERISTIC) ) + + + +// ************************** MANDATORY PARMS & DEFAULT VALUES ************************** +// Finished reading in the parms for the characteristic. Each Address Characteristic +// has it's own set of defaults. If this is an address - ensure defaults are present. + + +// CHARACTERISTIC TYPE = ADDRESS, BEARER TYPE = GSM/CSD or IS-136/CSD +// Bearer, Proxy, and Csd_Dialstring are mandatory.. +// Auth. Names and Passwords don't have defaults so are not set here! + + if ( iCurrentCharacteristic == EWappGsmCsdCharacteristic|| + iCurrentCharacteristic == EWappIS136CsdCharacteristic ) + { + //Required PARMS OTA v4.0 v5.0 + //CSD- PROXY Y Y + // PORT add default of 9200 + // CSD_DIALSTRING Y Y + // CSD_AUTHNAME Y N + // CSD_AUTHSECRET Y N + // CSD_CALLTYPE Y Add default of PAP + // CSD_CALLSPEED Y Add default of AUTO + + // Check mandatory PARMS present else bad message - unrecoverable error! + TInt index; + + // OTA v4.0 & 5.0: required Parms present? + index = LocateParsedFieldName(KWappProxy,characteristicIndex); + if (index == KErrNotFound) // TODO can this be null? || (iParsedFieldArray->At(index)->FieldValue() == TPtrC())) + User::Leave(KWappErrMandatoryTagMissing); + + index = LocateParsedFieldName(KWappCsdDial,characteristicIndex); + if (index == KErrNotFound) // Can this be Null?? || (iParsedFieldArray->At(index)->FieldValue() == TPtrC()) ) + User::Leave(KWappErrMandatoryTagMissing); + + // OTA v4.0 only, mandatory Parms present? + if (iWBXMLversionX10 == 10) + { + index = LocateParsedFieldName(KWappPPPAuthName,characteristicIndex); + if (index == KErrNotFound)// Can this be NULL || (iParsedFieldArray->At(index)->FieldValue() == TPtrC())) + User::Leave(KWappErrMandatoryTagMissing); + + index = LocateParsedFieldName(KWappPPPAuthSecret,characteristicIndex); + if (index == KErrNotFound) // Can this be a Null value? || (iParsedFieldArray->At(index)->FieldValue() == TPtrC()) ) + User::Leave(KWappErrMandatoryTagMissing); + } + + // Search for PORT from beginning of this characteristic to array end or next + // Characteristic - whichever's first. NB this is currently the last characteristic in array! + + index = LocateParsedFieldName(KWappPort, characteristicIndex); + if (index ==KErrNotFound) // Not Found - add the default value + { + index = LocateParsedFieldName(KWappProxy,characteristicIndex); // Mandatory - check already made + InsertDataPairL(KWappPort, KWappPort9200, index+1); + } + + // Check for the PPP_AUTHTYPE element + index = LocateParsedFieldName(KWappPPPAuthType, characteristicIndex); + if (index ==KErrNotFound) // Not Found - add the default value + { + index = LocateParsedFieldName(KWappCsdDial, characteristicIndex); // always present + // Create new element,NAME="PPP_CALLTYPE", VALUE="PAP" + InsertDataPairL(KWappPPPAuthType, KWappPAP, index+1); + } + + // Check for the CSD_CALLTYPE element + index = LocateParsedFieldName(KWappCsdCallType, characteristicIndex); + if (index ==KErrNotFound) // Not Found - add the default value + { + index = LocateParsedFieldName(KWappPPPAuthType, characteristicIndex); + if (index ==KErrNotFound) + User::Leave(KWappErrMandatoryTagMissing); // Error - should be here from step above!!! + else + // Create new element,NAME="CSD_CALLTYPE", VALUE="ANALOGUE" + InsertDataPairL(KWappCsdCallType, KWappAnalogue, index+1); + } + + // Check for the CSD_CALLSPEED element + index = LocateParsedFieldName(KWappCsdCallSpeed, characteristicIndex); + if (index ==KErrNotFound) // Not Found - add the default value + { + index = LocateParsedFieldName(KWappCsdCallType,characteristicIndex); + if (index ==KErrNotFound) + User::Leave(KWappErrMandatoryTagMissing); // Error - should be here from step above!!! + else + //Create new PARM, + // If CSD_CALLTYPE="ANALOGUE" -> NAME="CSD_CALLSPEED", VALUE="AUTO" + // else if CSD_CALLTYPE="ISDN" -> NAME="CSD_CALLSPEED", VALUE="9600" + if (iParsedFieldArray->At(index)->FieldValue().CompareF(KWappISDN)==0) + InsertDataPairL(KWappCsdCallSpeed, KWappSpeed9600, index+1); + else + InsertDataPairL(KWappCsdCallSpeed, KWappSpeedAuto, index+1); + } + }// END of if(iCurrentCharacteristic == EWappCSDCharacteristic)|| ....... + + +// CHARACTERISTIC TYPE = ADDRESS, BEARER TYPE = GSM/SMS +// Only the PORT PARM value is optional - all the rest are mandatory + + if (iCurrentCharacteristic == EWappGsmSmsCharacteristic) + { + //Required PARMS OTA v4.0 v5.0 + //SMS- PROXY Y Y + // SMS_SMSC_ADDRESS Y + + // Check that required fields are present - badly formed message otherwise + TInt fieldIndex = LocateParsedFieldName(KWappProxy, characteristicIndex); + if (fieldIndex == KErrNotFound ) // TODO Check if this can be null || (iParsedFieldArray->At(fieldIndex)->FieldValue().Length()==0) ) + User::Leave(KWappErrMandatoryTagMissing); + + fieldIndex = LocateParsedFieldName(KWappSMSCAddress, characteristicIndex); + if ((fieldIndex ==KErrNotFound)) // TODO Check if this can be null || (iParsedFieldArray->At(fieldIndex)->FieldValue().Length()==0) ) + User::Leave(KWappErrMandatoryTagMissing); + + + if (LocateParsedFieldName(KWappPort, characteristicIndex) ==KErrNotFound) //Tag not found + { + fieldIndex = LocateParsedFieldName(KWappProxy, characteristicIndex); //Mandatory field + // Create a new element, NAME="PORT", VALUE="9200" + InsertDataPairL(KWappPort,KWappPort9200, fieldIndex+1); + } + }//END of if(iCurrentCharacteristic == EWappSMSCharacteristic) + + +// CHARACTERISTIC TYPE = ADDRESS, BEARER TYPE = GSM/USSD + if (iCurrentCharacteristic == EWappGsmUssdCharacteristic) + { + + //Only USSD Service Code is mandatory - MUST not be NULL + TInt index = LocateParsedFieldName(KWappUSSDCode, characteristicIndex); + if (index == KErrNotFound || iParsedFieldArray->At(index)->FieldValue().Length()==0) + User::Leave(KWappErrMandatoryTagMissing); + + // PROXY is optional for USSD but has no default value + // Do have defaults for PROXY_TYPE and PORT + if (LocateParsedFieldName(KWappProxyType, characteristicIndex) ==KErrNotFound) //Tag not found + { + index = LocateParsedFieldName(KWappUSSDCode, characteristicIndex); //Mandatory field + + // Create a new element, NAME="PROXY_TYPE", VALUE="MSISDNNO" + InsertDataPairL(KWappProxyType,KWappMsisdnNo, index+1); + } + + if ( LocateParsedFieldName(KWappPort, characteristicIndex) == KErrNotFound) // Not Found - add the default value + { + index = LocateParsedFieldName(KWappProxyType,characteristicIndex); + if (index ==KErrNotFound) + User::Leave(KWappErrMandatoryTagMissing); // Error - should be here from step above!!! + else // Create new element,NAME="PORT", VALUE="9200" + InsertDataPairL(KWappPort, KWappPort9200, index+1); + } + } // END of - if (iCurrentCharacteristic == EWappGsmUssdCharacteristic)... + + +// CHARACTERISTIC TYPE = ADDRESS, BEARER TYPE = GPRS + if (iCurrentCharacteristic == EWappGprsCharacteristic) + { + // AHF - Removed check for tag GPRSACCESSPOINTNAME - no longer mandatory in OTA v7.0 + + // Check that mandatory PROXY field is present - else it's a badly formed msg + TInt index = LocateParsedFieldName(KWappProxy, characteristicIndex); + if (index == KErrNotFound ) + User::Leave(KWappErrMandatoryTagMissing); + + //Search for optional Port field - if not found, search for mandatory Proxy field and insert "9200" + index = LocateParsedFieldName(KWappPort, characteristicIndex); + if (index ==KErrNotFound) + { + index = LocateParsedFieldName(KWappProxy,characteristicIndex); // Mandatory - check already made + InsertDataPairL(KWappPort, KWappPort9200, index+1); // NAME="PORT", VALUE = "9200" + } + + // Check for the PPP_AUTHTYPE element - add default value if not found + index = LocateParsedFieldName(KWappPPPAuthType, characteristicIndex); + if (index ==KErrNotFound) + { + index = LocateParsedFieldName(KWappCsdDial, characteristicIndex); // always present + InsertDataPairL(KWappPPPAuthType, KWappPAP, index+1); // NAME="PPP_CALLTYPE", VALUE="PAP" + } + } + + + + } +// END of CMsvBIOWapAccessParser::ReadCharacteristicL() + +// +// ReadParmL() - Reads in contents of a PARM & inserts into iParsedFieldArray +// as a CParsedField object. ASSUME that the PARM tag has +// been read & verified before this is called. Consequently +// now positioned at the start of the attributes + +void CMsvBIOWapAccessParser::ReadParmL() + { + + CParsedField* parsedField = new(ELeave) CParsedField; + CleanupStack::PushL(parsedField); + TChar currentCharacter = GetNextMessageByteL(); + + switch ((TUint) currentCharacter) + { + case KWAPP_NAME_ATTRIB: //0x10 "NAME=..." ,string(inline or table ref.) should follow + { + //Start of NAME attribute, check for inline string/string table reference + currentCharacter=GetNextMessageByteL(); + if ((TUint32) currentCharacter == KWAPP_STR_I) + { + parsedField->SetFieldNameL(*ReadInlineStringLC()); + CleanupStack::PopAndDestroy(); + } + else if ((TUint32) currentCharacter== KWAPP_STR_T) + { + TUint32 offset = Read_mb_u_int32L(); + parsedField->SetFieldNameL(*ReadStringTableReferenceLC(offset)); + CleanupStack::PopAndDestroy(); + } + else // it isn't an inline string or string table ref - ERROR! + User::Leave(KWappErrNoTermination); + break; + } + case KWAPP_BEARER: //0x12 NAME="BEARER" + { + parsedField->SetFieldNameL(KWappBearer); + break; + } + case KWAPP_PROXY: //0x13 NAME="PROXY" (Mandatory for GSM/CSD, GSM/SMS, IS136/CSD) + { + parsedField->SetFieldNameL(KWappProxy); + break; + } + case KWAPP_PORT ://0x14 NAME="PORT" + { + parsedField->SetFieldNameL(KWappPort); + break; + } + case KWAPP_NAME ://0x15 NAME = "NAME" + { + parsedField->SetFieldNameL(KWappName); + break; + } + case KWAPP_PROXYTYPE ://0x16 NAME="PROXY_TYPE" + { + parsedField->SetFieldNameL(KWappProxyType); + break; + } + case KWAPP_URL : // 0x17 NAME="URL" + { + parsedField->SetFieldNameL(KWappURL); + break; + } + case KWAPP_PROXY_AUTHNAME : // 0x18 NAME="PROXY_AUTHNAME" + { + parsedField->SetFieldNameL(KWappProxyAuthName); + break; + } + case KWAPP_PROXY_AUTHSECRET : //0x19 NAME="PROXY_AUTHSECRET" + { + parsedField->SetFieldNameL(KWappProxyAuthSecret); + break; + } + case KWAPP_PROXY_LOGIN_TYPE : + { + parsedField->SetFieldNameL(KWappProxyLoginType); + break; + } + case KWAPP_SMS_SMSC_ADDR : //0x1A NAME="SMS_SMSC_ADDR" (Mandatory field for GSM/SMS) + { + parsedField->SetFieldNameL(KWappSMSCAddress); + break; + } + case KWAPP_USSD_SERV_CODE : //0x1B NAME="USSD_SER_CODE" (Mandatory for GSM/USSD) + { + parsedField->SetFieldNameL(KWappUSSDCode); + break; + } + case KWAPP_ACCESS_POINT_NAME : //0x1C NAME="ACCESSPOINTNAME" (Mandatory for GPRS) + { + parsedField->SetFieldNameL(KWappAccessPointName); + break; + } + case KWAPP_CSD_DIALSTRING : //0x21 NAME="CSD_DIALSTRING" (Mandatory for GSM/CSD,IS136/CSD) + { + parsedField->SetFieldNameL(KWappCsdDial); + break; + } + case KWAPP_PPP_AUTHTYPE : //0x22 NAME="CSD_AUTHTYPE" + { + parsedField->SetFieldNameL(KWappPPPAuthType); + break; + } + case KWAPP_PPP_AUTHNAME : //0x23 NAME="CSD_AUTHNAME" + { + parsedField->SetFieldNameL(KWappPPPAuthName); + break; + } + case KWAPP_PPP_AUTHSECRET : //0x24 NAME="CSD_AUTHSECRET" + { + parsedField->SetFieldNameL(KWappPPPAuthSecret); + break; + } + case KWAPP_PPP_LOGIN_TYPE : + { + parsedField->SetFieldNameL(KWappPPPLoginType); + break; + } + case KWAPP_CSD_CALLTYPE : // 0x25 NAME="CSD_CALLTYPE" + { + parsedField->SetFieldNameL(KWappCsdCallType); + break; + } + case KWAPP_CSD_CALLSPEED : //0x28 NAME="CSD_CALLSPEED" + { + parsedField->SetFieldNameL(KWappCsdCallSpeed); + break; + } + case KWAPP_NAME_ISP : //0x7E NAME="ISP_NAME" + { + parsedField->SetFieldNameL(KWappISP); + break; + } + + default: + User::Leave(KWappErrUnexpectedValue); // don't recognise the tag + } + + // The early version of the WAP server, supporting version 4.0 of the Nokia OTA specs + // codes up PROXY_AUTHNAME & PROXY_AUTHSECRET as the PROXY token followed by + // a string/str ref. So we MUST check if inline string/str table ref follows + if (currentCharacter==KWAPP_PROXY) + { + if (iSms.Eos()) + User::Leave(KWappErrEOS); // ERROR - Unexpected end of message!! Nothing to peek at! + else if ( ((TUint)iSms.Peek() == KWAPP_STR_I) || ((TUint)iSms.Peek() == KWAPP_STR_T)) + { + // String follows immediately after Name token not a Value Tag + TUint32 anOffset; + currentCharacter = GetNextMessageByteL(); + HBufC* name = NULL; + if ((TUint) currentCharacter == KWAPP_STR_I) + { + name = ReadInlineStringLC(); + } + else + { + if ((TUint) currentCharacter != KWAPP_STR_T) + User::Leave(KWappErrUnexpectedValue); // Should not get here unless something is very wrong! + anOffset = Read_mb_u_int32L(); + name = ReadStringTableReferenceLC(anOffset); + } + + //Defect fix for Def021848-Incorrect use of ReAllocL in wapp + HBufC* newName = name->ReAllocL(name->Length() + parsedField->FieldName().Length()); + CleanupStack::Pop(name);//Remove name from the Cleanup Stack as it would have been deleted by ReAllocL() + CleanupStack::PushL(newName); + newName->Des().Append(parsedField->FieldName()); //insert PROXY at front of string + parsedField->SetFieldNameL(*newName); //replace current string with new one + CleanupStack::PopAndDestroy(newName); + } + } + + TBool addParsedField = ETrue; + + currentCharacter=GetNextMessageByteL(); //Get next byte - should be the Value tag + switch( (TUint32) currentCharacter) + { + case KWAPP_VALUE_ATTRIB : // 0x11 "VALUE=", string(inline or table ref) follows + { + if (iSms.Eos()) + { + User::Leave(KWappErrEOS); // ERROR - Unexpected end of message!! Nothing to peek at! + } + //Check for 0x01 (KWAPP_END_TAG) - assign fieldvalue with empty value and ignore the other + if ( ((TUint)iSms.Peek() == KWAPP_END_TAG)) //Something wrong - Wrong PARAM Value + { + addParsedField = EFalse; + break; + } + // Start of VALUE attribute, string should follow + currentCharacter= GetNextMessageByteL(); + if ((TUint32) currentCharacter == KWAPP_STR_I) //Inline string + { + HBufC* value = ReadInlineStringLC(); + parsedField->SetFieldValueL(*value); + CleanupStack::PopAndDestroy(); + } + else if ((TUint32) currentCharacter== KWAPP_STR_T) //String Table ref + { + TUint32 offset = Read_mb_u_int32L(); // Read 32bit int + HBufC* value = ReadStringTableReferenceLC(offset); // Read in characters + parsedField->SetFieldValueL(*value); + CleanupStack::PopAndDestroy(); + } + else //Not an inline string or string table ref - somethings wrong! + User::Leave(KWappErrUnexpectedValue); + break; + } + case KWAPP_GSM_SMS_OLD : // 0x41 VALUE="GSM/SMS" + { + // Old value of GSM/SMS tag - ONLY valid for Version 4.0 of the specs, ie WBXML = 1.0! + parsedField->SetFieldValueL(KWappGsmSms); + break; + } + case KWAPP_GSM_CSD : // 0x45 VALUE="GSM/CSD" + { + parsedField->SetFieldValueL(KWappGsmCsd); + break; + } + case KWAPP_GSM_SMS_NEW : // 0x46 VALUE="GSM/SMS" ONLY valid for Version 5.0 of the specs, i.e.WBXML = 1.1! + { + parsedField->SetFieldValueL(KWappGsmSms); + break; + } + case KWAPP_GSM_USSD : //0x47 VALUE="GSM/USSD" only defined for version 5.0 only + { + parsedField->SetFieldValueL(KWappGsmUssd); + break; + } + case KWAPP_IS136 : // 0x48 VALUE="IS136/CSD" for version 5.0 only + { + parsedField->SetFieldValueL(KWappIS136Csd); + break; + } + case KWAPP_GPRS : // 0x49 VALUE="GSM/GPRS" + { + parsedField->SetFieldValueL(KWappGprs); + break; + } + case KWAPP_PORT_9200 : // 0x60 VALUE="9200" + { + parsedField->SetFieldValueL(KWappPort9200); + break; + } + case KWAPP_PORT_9201 : // 0x61 VALUE="9201" + { + parsedField->SetFieldValueL(KWappPort9201); + break; + } + case KWAPP_PORT_9202 : // 0x62 VALUE="9202" + { + parsedField->SetFieldValueL(KWappPort9202); + break; + } + case KWAPP_PORT_9203 : // 0x63 VALUE="9203" + { + parsedField->SetFieldValueL(KWappPort9203); + break; + } + case KWAPP_AUTOMATIC : // 0x64 + { + parsedField->SetFieldValueL(KWappAuthAutomatic); + break; + } + case KWAPP_MANUAL : // 0x65 + { + parsedField->SetFieldValueL(KWappAuthManual); + break; + } + case KWAPP_SPEED_AUTO : // 0x6A VALUE="AUTO" + { + parsedField->SetFieldValueL(KWappSpeedAuto); + break; + } + case KWAPP_SPEED_9600 : // 0x6B VALUE="9600" + { + parsedField->SetFieldValueL(KWappSpeed9600); + break; + } + case KWAPP_SPEED_14400 : // 0x6C VALUE="14400" + { + parsedField->SetFieldValueL(KWappSpeed14400); + break; + } + case KWAPP_SPEED_19200 : //0x6D VALUE="19200" + { + parsedField->SetFieldValueL(KWappSpeed19200); + break; + } + case KWAPP_SPEED_28800 : //0x6E VALUE="28800" + { + parsedField->SetFieldValueL(KWappSpeed28800); + break; + } + case KWAPP_SPEED_38400 : //0X6F VALUE="38400" + { + parsedField->SetFieldValueL(KWappSpeed38400); + break; + } + case KWAPP_PAP : // 0x70 VALUE="PAP" + { + parsedField->SetFieldValueL(KWappPAP); + break; + } + case KWAPP_CHAP : //0X71 VALUE="CHAP" + { + parsedField->SetFieldValueL(KWappCHAP); + break; + } + case KWAPP_ANALOGUE : //0X72 VALUE="ANALOGUE" + { + parsedField->SetFieldValueL(KWappAnalogue); + break; + } + case KWAPP_ISDN : //0X73 VALUE="ISDN" + { + parsedField->SetFieldValueL(KWappISDN); + break; + } + case KWAPP_SPEED_43200 : //0X74 VALUE="43200" + { + parsedField->SetFieldValueL(KWappSpeed43200); + break; + } + case KWAPP_SPEED_56700 : //0X75 VALUE="56700" + { + parsedField->SetFieldValueL(KWappSpeed56700); + break; + } + case KWAPP_MSISDN_NO : //0X76 VALUE="MSISDN_NO" + { + parsedField->SetFieldValueL(KWappMsisdnNo); + break; + } + case KWAPP_IPV4 : //OX77 VALUE="IPV4" + { + parsedField->SetFieldValueL(KWappIpv4); + + break; + } + case KWAPP_MSCHAP : //0x78 VALUE="MSCHAP" + { + parsedField->SetFieldValueL(KWappMSCHAP); + break; + } + + default: + User::Leave(KWappErrUnexpectedValue); // Unknown tag - can't process it + } + + // If iCurrentCharacteristic is a general address type and NAME="BEARER". Then + // set the current type flag to the correct type, so we know exactly what we're dealing with + if (iCurrentCharacteristic==EWappAddressCharacteristic + && parsedField->FieldName().CompareF(KWappBearer)==0) + { + if (parsedField->FieldValue().CompareF(KWappGsmCsd)==0) + iCurrentCharacteristic =EWappGsmCsdCharacteristic; + else if (parsedField->FieldValue().CompareF(KWappGsmSms)==0) + iCurrentCharacteristic = EWappGsmSmsCharacteristic; + else if (parsedField->FieldValue().CompareF(KWappGsmUssd)==0) + iCurrentCharacteristic = EWappGsmUssdCharacteristic; + else if (parsedField->FieldValue().CompareF(KWappIS136Csd)==0) + iCurrentCharacteristic = EWappIS136CsdCharacteristic; + else if (parsedField->FieldValue().CompareF(KWappGprs)==0) + iCurrentCharacteristic = EWappGprsCharacteristic; + else + User::Leave(KWappErrUnrecognised); + } + + // Got our Name and Value fields- check next byte - should be 0x01 =END + currentCharacter = GetNextMessageByteL(); + + if (currentCharacter != KWAPP_END_TAG) // Our PARM is not correctly terminated! + User::Leave(KWappErrNoTermination); + + // Check flag to see if parsed field should be added or not + if (addParsedField) + { + // Extracted the NAME and VALUE so create a container and append to our array + iParsedFieldArray->AppendL(parsedField); + CleanupStack::Pop(parsedField); + } + else + { + CleanupStack::PopAndDestroy(parsedField); + } + } +//End of CMsvBIOWapAccessParser::ReadParmL() + + +// SettingsNamePresentL() - Check if the NAME characteristic is defined. if it isn't add +// a default one that is unique. Use a base stem of "WAP Settings" and +// append a suffix to it. The suffix is calculated by incrementing, until +// a unique digit is found. +// +void CMsvBIOWapAccessParser::SettingsNamePresentL() + { + TBool nameDefined = EFalse; // Is a Name characteristic present? + TBool bearerPresent = EFalse; // Is address characteristic present? + + // Search for the start of a NAME characteristic - i.e. Field Name="NAME" + TInt nFields = iParsedFieldArray->Count(); + + TInt loopCount=0; + while (loopCount < nFields && !nameDefined) + { + if (iParsedFieldArray->At(loopCount)->FieldName().CompareF(KWappCharName)==0) + { + // At start of a Name characteristic + // Make sure that we won't try checking past the end of the array + if (loopCount+1 < nFields) // NB loopCount started at zero + { + // Verify that this is followed by NAME parm - NAME token & a non NULL value + if (iParsedFieldArray->At(loopCount+1)->FieldName().CompareF(KWappName)==0) + { + if (iParsedFieldArray->At(loopCount+1)->FieldValue().Length()!=0) + nameDefined = ETrue; + } + } + } + loopCount++; + } + + loopCount = 0; + while (loopCount < nFields) + { + // Beginning of an Address Characteristic? + if (iParsedFieldArray->At(loopCount)->FieldName().CompareF(KWappCharAddress) ==0) + bearerPresent = ETrue; // Assume all Parms are present- will leave later if not! + loopCount++; + } + + if (nameDefined ==EFalse && bearerPresent) // NAME characteristic not defined - add a default + { + TBuf recordName; + HBufC* nameBuffer = HBufC::NewLC(30); + TInt currentRecord = 1; + TBool nameExists = EFalse; + + TFileName fileName; + Dll::FileName(fileName); + TParse parse; + parse.Set(KWappResourceFile, &fileName, NULL); + fileName = parse.FullName(); + BaflUtils::NearestLanguageFile(iFs, fileName); + + RResourceFile resourceFile; + resourceFile.OpenL(iFs, fileName); + CleanupClosePushL(resourceFile); + HBufC8* buffer = resourceFile.AllocReadLC(DEFAULT_WAP_SETTINGS_NAME); + TResourceReader resourceReader; + resourceReader.SetBuffer(buffer); + TPtrC defaultSettingsName = resourceReader.ReadTPtrC(); + CCDWAPAccessPointRecord *wapRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdWAPAccessPointRecord)); + CleanupStack::PushL(wapRecord); + nameBuffer->Des().Format(defaultSettingsName, currentRecord); // create our name string + while(!nameExists) + { + wapRecord->iRecordName.SetMaxLengthL(nameBuffer->Length()); + wapRecord->iRecordName = *nameBuffer; + + if(wapRecord->FindL(*iDBSession)) + { + ++currentRecord; + nameBuffer->Des().Format(defaultSettingsName, currentRecord); + } + else + nameExists = ETrue; + } + CleanupStack::PopAndDestroy(wapRecord); + + // Add characteristic header, then name and value to the parsed fields + AppendNameFieldL(KWappCharName); + AppendDataPairL(KWappName, nameBuffer->Des()); + CleanupStack::PopAndDestroy(3, nameBuffer); // nameBuffer, resourceFile, buffer + } + + }//END of SettingsNamePresentL() + +// RestoreParsedDataL() - Restores CParsedField data into the array +// +// +void CMsvBIOWapAccessParser::RestoreParsedDataL() + { + // Assume that our server message context is correctly set to the Bio Msg entry + iEntry.SetEntryL(iEntryId); + + // Has the entry been parsed,(iMtmData3 =1) or parsed & processed (iMtmData3 =2) + // If not leave with error code + if ( iEntry.Entry().MtmData3() != BIO_MSG_ENTRY_PARSED + && iEntry.Entry().MtmData3() != BIO_MSG_ENTRY_PROCESSED) + { + iSmsParsed=EFalse; // Entry has not been parsed yet no data to restore + User::Leave(KWappErrMsgUnparsed); + } + + if(!iEntry.HasStoreL()) + { + iSmsParsed=EFalse; // Entry has no store - not parsed yet? + User::Leave(KWappErrStoreNotFound); + } + //Message has been parsed and data stored = restore it! + CMsvStore* store=iEntry.EditStoreL(); + CleanupStack::PushL(store); + RestoreL(*store); + CleanupStack::PopAndDestroy();//store + + //Now set a few key variables using the data in the iParsedFieldArray + TLex myLex; + if (iParsedFieldArray->At(0)->FieldName().CompareF(KWappXMLversion)==0) + { + myLex =iParsedFieldArray->At(0)->FieldName(); + myLex.Mark(); + myLex.Val(iWBXMLversionX10, EDecimal); + } + else + User::Leave(KWappErrMandatoryTagMissing); // error- XML version is missing + + // Field at index=1 is PublicID - don't currently need this + // Field at index=2 is Character Set - will present if XML version =1.1, but not for 1.0 + + if (iWBXMLversionX10==11) + { // Have the Character Set + if (iParsedFieldArray->At(2)->FieldName().CompareF(KWappCharacterSet)==0 ) + { + myLex =iParsedFieldArray->At(1)->FieldName(); + myLex.Mark(); //Mark the start. + myLex.Val(iCharacterSet, EHex); + } + } + else + iCharacterSet=0; + } +// End of function CMsvBIOWapAccessParser::RestoreParsedDataL() + +// StoreParsedDataL() - stores array of parsed data in a store - calls base class StoreL() +// +void CMsvBIOWapAccessParser::StoreParsedDataL() + { + // Set to the current Entry id, create a store & save data + iEntry.SetEntryL(iEntryId); + CMsvStore* store=iEntry.EditStoreL(); + CleanupStack::PushL(store); + StoreL(*store); + CleanupStack::PopAndDestroy();//store + + // Set the parsed flag on the TMsvEntry + iEntry.SetEntryL(iEntryId); + TMsvEntry entry= iEntry.Entry(); + entry.SetMtmData3(BIO_MSG_ENTRY_PARSED); + + iEntry.ChangeL(entry); + } + +// +// ResetProcessVariablesL()-Resets array of bookmarks and recreates the objects mapping to CommDb Table s +// +// +void CMsvBIOWapAccessParser::ResetProcessVariablesL() + { + // Re-set boolean flags + iGsmCsdData = EFalse; + iGsmSmsData = EFalse; + iGprsData = EFalse; + iURLData = EFalse; + iMMSURLData = EFalse; + iNameData = EFalse; + iIdData = EFalse; + // Zero IDs + iRecordId = 0; + iWapAccessPtID = 0; + iWapLocation = 0; + iWapChargeCard = 0; + + iBookmarkList->ResetAndDestroy(); + + iWAPSettingsName.Set(TPtrC()); // Null the value in this descriptor + + delete iGsmCsdWapIpTable; + iGsmCsdWapIpTable = NULL; + delete iGprsWapIpTable; + iGprsWapIpTable =NULL; + delete iWapIpISPTable; + iWapIpISPTable = NULL; + delete iWapSmsTable; + iWapSmsTable = NULL; + delete iWapGprsTable; + iWapGprsTable = NULL; + delete iModemInitString; + iModemInitString = NULL; + } + +// +// Read_mb_u_int32() -- Helper function that uses the TLex iSms to extract a 32-bit +// integer encoded in a number of bytes. If Bit7 of the first +// byte is set, the number continues over into the next byte, +// and so on. If Bit7 is not set then it's the last byte. +// +TUint32 CMsvBIOWapAccessParser::Read_mb_u_int32L() + { + TUint32 decodedValue = 0; + TBool completed =EFalse; + + while(!completed) + { + TUint32 thisByte = (TUint) GetNextMessageByteL(); // cast the character returned by Get to a TUint32 + if (decodedValue & 0x2000000) // is Bit25 set? If so, bitshifting 7 places + User::Leave(KWappErrOutsideBoundaries); // left will cause overflow + + (decodedValue = decodedValue<<7); // assignment to keep compiler happy + //shift current value 7 places to the left, i.e. *256 + + if ( (thisByte & KWAPP_MB_INT32_CONTINUATION) ) + { + // bit 7 set, integer continues into next byte so keep processing + thisByte = thisByte & 0x7F; // mask Bit7 by AND'ing with all other bits + // set to 1, i.e. 01111111 =0x7F + decodedValue += thisByte; + // leave completed set to EFalse + } + else // bit 7 isn't set, processing's completed so set flag + { + decodedValue += thisByte; + completed = ETrue; + } + } + return decodedValue; + } + +// +// GetStringTableItemL() - Returns the string contained within the string table starting +// at the offset passed in as a parameter. +// +HBufC* CMsvBIOWapAccessParser::ReadStringTableReferenceLC(TUint32 anOffset) + { + if (iStringTable ==NULL) + User::Leave(KWappErrStringTable); // Making a call to an nonexistant object! + TUint32 stringTableLength = iStringTable->Length(); + if (stringTableLength<=0) //Nothing to process, or worse, an error! + User::Leave(KWappErrOutsideBoundaries); //Past end of table + if (anOffset >= stringTableLength) // anOffset must be < last element of buffer + User::Leave(KWappErrOutsideBoundaries); // Last element must be NULL terminator! + + TUint32 stringTableItem = anOffset; // Current element in iStringTable + TUint32 stringLength=0; // Length of string + while ( iStringTable->Des()[stringTableItem] !=KWAPP_STR_TERM) + { + // increment through the String Table to first NULL terminator + stringTableItem++; + if (stringTableItem > (TUint)iStringTable->Length()) // Cast to remove warning, Length >=0 + User::Leave(KWappErrOutsideBoundaries); // Problem -gone past the end of the descriptor + stringLength++; + } + // return a descriptor starting at the offset and up to the char before the NULL terminator + + // Char Conversion + TPtrC data = iStringTable->Des().Mid(stringTableItem, stringTableLength-1); + HBufC* text = HBufC::NewLC(data.Length()); + TPtr des(text->Des()); + iCharsetConverter->ConvertL(data, des); + return text; + } + + +/* +Finds the end of the UCS2 string. Each character is represented by exactly 2bytes of data +According to WBXML version 1.0 +"if a character encoding includes a NULL then that NULL character must be used as the termination character" +Hence we are assuming that the end of the string is marked by two NULL bytes. +*/ +void CMsvBIOWapAccessParser::ReadUCS2StringL() +{ + TBool endofinlinestring = EFalse; + TBool endoflexstring = EFalse; + TBool foundNull; + + while (!endoflexstring && !endofinlinestring) + { + foundNull = EFalse; + endoflexstring = iSms.Eos(); + + if (!endoflexstring) + { + if (iSms.Peek() == KWAPP_STR_TERM) + { + foundNull = ETrue; + } + + iSms.Inc(); + if (iSms.Eos()) //check we haven't reached the end of the sms + User::Leave(KWappErrEOS); + + else if (foundNull && iSms.Peek()== KWAPP_STR_TERM) + endofinlinestring = ETrue; + } + else + User::Leave(KWappErrEOS); + } + +} + + + +/* +According to WBXML version 1.0 +"if a character encoding includes a NULL then that NULL character must + be used as the termination character" + +Finding the end of the ASCII string: + This is simply done as each character is represented by a maximum + of 7 bits of data, hence each character is one byte only. + Thus, it is assumed that the end of the string is marked by a NULL which in ASCII is 0x00 + + so the string "hi" would be represented as + 0x68 0x69 0x00 + +Finding the end of the UTF-8 string. + From RFC 2279: + "In UTF-8, characters are encoded using sequences of 1 to 6 octets. + The only octet of a "sequence" of one has the higher-order bit set to + 0, the remaining 7 bits being used to encode the character value. In + a sequence of n octets, n>1, the initial octet has the n higher-order + bits set to 1, followed by a bit set to 0. The remaining bit(s) of + that octet contain bits from the value of the character to be + encoded. The following octet(s) all have the higher-order bit set to + 1 and the following bit set to 0, leaving 6 bits in each to contain + bits from the character to be encoded. + + The table below summarizes the format of these different octet types. + The letter x indicates bits available for encoding bits of the UCS-4 + character value. + + UCS-4 range (hex.) UTF-8 octet sequence (binary) + 0000 0000-0000 007F 0xxxxxxx + 0000 0080-0000 07FF 110xxxxx 10xxxxxx + 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx + + 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + 0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx + " + ASCII values 0-127 are represented in UTF8 by one byte with the msb set to 0. + + This means that no byte in a stream of bytes representing a (non NULL) character will ever be 0x00. + So there will only be one 0x00 in the string and this will represent the end of the string. + + For example + the string of roman numerals "VIIIIII" where VIII is the first character and III is the second character + would be represented in UTF-8 as: + + 0xE2 0x85 0xA2 0xE2 0x85 0xA7 0x00 + + The single byte 0x00 is the NULL terminator representing the end of the string. +*/ +void CMsvBIOWapAccessParser::ReadASCIIorUTF8StringL() +{ + while (!iSms.Eos() && iSms.Peek() !=KWAPP_STR_TERM /*0x00*/) + { + iSms.Inc(); + } + + if (iSms.Eos()) // End of the string! Other chars should follow + User::Leave(KWappErrEOS); + +} + +/* +because iSms is a TLex it is padded out and so +when parsing unicode strings you end up with unnecessary characters +*/ + +//HBufC* CMsvBIOWapAccessParser::RemovePadding() +//{ +//} + + +// +// ReadInlineStringL() - Returns the string begining at the current position in the +// message. Increments TLex position until string termination found. +// +HBufC* CMsvBIOWapAccessParser::ReadInlineStringLC() + { + if (!iSms.Eos())//Mark the starting point of the string + iSms.Mark(); + else // End of the string! Can't proceed! + User::Leave(KWappErrEOS); + + //find the end of the string by taking into accout how it is encoded + switch (iCharacterSet) + { + case KCharsetASCII: + case KCharsetUTF8: + ReadASCIIorUTF8StringL(); + break; + case KCharsetUCS2: + ReadUCS2StringL(); + break; + default: + User::Leave(KErrNotSupported); + break; + }; + + //the end of the string has been found so mark it. + TPtrC data =iSms.MarkedToken(); + iSms.Inc(); //Increment up to the KWAPP_STR_TERM so next time we read the char after the end of the string + /* + Marked token is now converted to unicode + for the purpose of applying to commdb for example. + */ + + // Char Conversion + //for unicode parsing to remove unnecessary padding + if (iCharacterSet == KCharsetUCS2) + { + HBufC* text = HBufC::NewMaxLC(data.Length() / 2); + TPtr destext(text->Des()); + + TInt j = 0; + TInt i = 1; + + while (j < data.Length() / 2) + { + destext[j] = data[i]; + i += 2; + j++; + } + + return text; + } + else + { + HBufC* text = HBufC::NewMaxLC(data.Length()); + TPtr destext(text->Des()); + + iCharsetConverter->ConvertL(data, destext); + + return text; + } + } + + +// +// AppendDataPairL() - Appends a CParsedField containing data from the message, to the +// array of parsed fields (iParsedFieldsArray). +// +void CMsvBIOWapAccessParser::AppendDataPairL(const TDesC& aFieldName, const TDesC& aFieldValue) + { + // Appends a CParsedField object to iParsedFieldArray. + // Both fields have valid data + CParsedField* localData = new (ELeave) CParsedField; + CleanupStack::PushL(localData); + localData->SetFieldNameL(aFieldName); + localData->SetFieldValueL(aFieldValue); + CleanupStack::Pop(); + iParsedFieldArray->AppendL(localData); + } + +// +// AppendNameFieldL() - Appends a CParsedField containing just a Name from the message, +// to the array of parsed fields (iParsedFieldsArray). +// +void CMsvBIOWapAccessParser::AppendNameFieldL(const TDesC& aFieldName) + { + // Appends a CParsedField object to iParsedFieldArray. + // Only the Name field has valid data, the Value field is left NULL + CParsedField* localData = new (ELeave) CParsedField; + CleanupStack::PushL(localData); + localData->SetFieldNameL(aFieldName); + localData->SetFieldValueL(KNullDesC); // Set to an empty descriptor + CleanupStack::Pop(); + iParsedFieldArray->AppendL(localData); + } + +void CMsvBIOWapAccessParser::InsertDataPairL(const TDesC& aFieldName, const TDesC& aFieldValue, TInt anIndex) + { + // check that the position is valid! Leave if out of bounds + // Limits 0 - insert at front of array, iParsedData->Count() append to end + if (!(anIndex<= iParsedFieldArray->Count() && anIndex >= 0) ) + User::Leave(KErrArgument); + CParsedField* localField = new (ELeave)CParsedField; + CleanupStack::PushL(localField); + localField->SetFieldNameL(aFieldName); + localField->SetFieldValueL(aFieldValue); + CleanupStack::Pop(); + iParsedFieldArray->InsertL(anIndex, localField); + } + +TChar CMsvBIOWapAccessParser::GetNextMessageByteL() + { + if (iSms.Eos()) // Error - unexpectedly reached the end of the TLex buffer!!!!! + User::Leave(KWappErrEOS); + return iSms.Get(); + } + +TInt CMsvBIOWapAccessParser::LocateParsedFieldName(const TDesC& aFieldName, const TInt aStartIndex) + { + //Searches from a start pos'n, default=0, until either finds a match, or end of array + TInt count=aStartIndex; + TBool nextCharacteristic =EFalse; + + //loop until end of the array, found the first match or found another Characteristic! + TInt nFields = iParsedFieldArray->Count(); + while (count < nFields && // End of array? + (iParsedFieldArray->At(count)->FieldName().CompareF(aFieldName) !=0) && //Match found? + !nextCharacteristic ) + { + + if ( (count !=aStartIndex) && (IsCharacteristicName(count)) ) + // Not 1st first element of characteristic and found field for another + // characteristic- Must have reached next characteristic - stop looping + { + nextCharacteristic =ETrue; + } + + ++count; + } + + if (count < nFields && !nextCharacteristic) // found a match in the array, even if it is last element + return count; + else + return KErrNotFound; // Didn't find a match or reached next characteristic - flag the errror + } + +// +// DoProcessL() - Workhorse for ProcessL function. Extracts information from parsed field +// array into separate objects. Writes settings to the COMMS DB, if +// there is data for at least one bearer type. Saves any Bookmarks to file. +// +void CMsvBIOWapAccessParser::DoProcessL() + { + if (iGsmCsdData || iGsmSmsData || iGprsData) + { + WriteDataToDBL(); + } + WriteBookmarksToFileL(); + + if( iMMSURLData ) + { + WriteMMSURLL(); + } + + if (!iGprsData && !iGsmCsdData && !iGsmSmsData && !iMMSURLData && (iBookmarkList->Count()==0)) + { + // No bearers, no bookmarks - must be a settings message - wouldn't be here otherwise + if (iNameData && iURLData) // iIDData optional + { + UpdateStartPageUrlL(); // update the URL of the start page in WAP table + } + } + + } + +// +// PreProcessL - goes through the fields in the array of parsed data, extracting information +// only extracts information for first of each of the 4 bearer types - i.e. max +// of 4 entries in the ISP/WAP tables. Additional address characteristics are +// ignored. +// +void CMsvBIOWapAccessParser::PreProcessL() + { + TInt arrayPtr=0; // current position in the array of ParsedFields + + while (arrayPtr < iParsedFieldArray->Count()) + { + // Check current field if characteristic - peek at next field -> bearer type + // GSM/CSD - extract data from GSM/CSD Address characteristic + // GSM/SMS - extract data from GSM/SMS Address characteristic + // GPRS - extract data from GPRS Address characteristic + // GSM/USSD - TO DO, GSM/USSD Address characteristic unsupported + // IS136/CSD - TO DO, IS136/CSD Address characteristic unsupported + // ID - extract data from ID characteristic + // NAME - extract data from NAME characteristic + // URL - extract data from URL characteristic + // BOOKMARK - extract Bookmark characteristic & append to Bookmark array + // Otherwise report an error + + // Increment past WBXML Version, public ID or character set to the data we want + if ((iParsedFieldArray->At(arrayPtr)->FieldName().CompareF(KWappXMLversion) ==0) || + (iParsedFieldArray->At(arrayPtr)->FieldName().CompareF(KWappPublicID) ==0)|| + (iParsedFieldArray->At(arrayPtr)->FieldName().CompareF(KWappCharacterSet) ==0)) + + arrayPtr++; + else if (iParsedFieldArray->At(arrayPtr)->FieldName().CompareF(KWappCharAddress) ==0) + { + // Stepped past first 3 fields & its an Address Characteristic + // So read the next line to determine type of bearer + + TPtrC addressValue; + arrayPtr++; //increment to the next element + + if (iParsedFieldArray->At(arrayPtr)->FieldName().CompareF(KWappBearer)==0) + addressValue.Set(iParsedFieldArray->At(arrayPtr)->FieldValue()); // Note the bearer type + else + User::Leave(KWappErrMandatoryTagMissing); // Not a BEARER - error! + + // Next - either extract the bearer data into the table objects, if this is the + // first of this type, or skip past the data to the next characteristic. + if ((addressValue.CompareF(KWappGsmCsd)==0)) + { + // GSM/CSD Characteristic so add data to ISP and WAP table objects, or go to next characteristic + ExtractBearerDataL(arrayPtr); + } + + else if ((addressValue.CompareF(KWappGsmSms)==0)) + { + // GSM/CSD Characteristic so either add data to ISP and WAP table objects, or skip past to next characteristic + ExtractBearerDataL(arrayPtr); + } + + else if (addressValue.CompareF(KWappGsmUssd)==0) + { + User::Leave(KWappErrNotSupported); // Don't support these at the moment! + + // ExtractBearerDataL(arrayPtr); //Add data to ISP and WAP table objects + } + + else if (addressValue.CompareF(KWappIS136Csd)==0) + { + User::Leave(KWappErrNotSupported); // Don't do these at the moment! + // ExtractBearerDataL(arrayPtr); //Add data to ISP and WAP table objects + } + else if (addressValue.CompareF(KWappGprs)==0) + { + ExtractBearerDataL(arrayPtr); + } + else + User::Leave(KWappErrUnrecognised); // Value doesn't match any of the known ones + } + + // Check if it's a URL characteristic + else if (iParsedFieldArray->At(arrayPtr)->FieldName().CompareF(KWappCharURL) ==0) + { + // The URL Characteristic has NO PARM elements only a value + + if (iURLData == EFalse) // Not been set previously + { + // Use the first instance of a URL - set it to the characteristic value even if it's null + iUrl.Set(iParsedFieldArray->At(arrayPtr)->FieldValue()); + iURLData = ETrue; + } + arrayPtr++; + } + + // Check if it's a Name Characteristic + else if (iParsedFieldArray->At(arrayPtr)->FieldName().CompareF(KWappCharName) ==0) + { + // The NAME Characteristic should have EXACTLY 1 PARM element + arrayPtr++; // increment to the Parm in this characteristic + if (arrayPtr == iParsedFieldArray->Count() || + iParsedFieldArray->At(arrayPtr)->FieldName().CompareF(KWappName)!=0) + User::Leave(KWappErrBadMessage); + + // Initialise the Settings Name variable if it hasn't been set + if (iWAPSettingsName.Length()==0) + { + // Use the first instance of NAME - set it to the value even if it's null + iWAPSettingsName.Set(iParsedFieldArray->At(arrayPtr)->FieldValue()); + iNameData = ETrue; + } + + while ( arrayPtr< iParsedFieldArray->Count() && !(IsCharacteristicName(arrayPtr)) ) + arrayPtr++; // increment to beginning of next characteristic + + } + + //Is it a BOOKMARK ? Bookmarks must contain EXACTLY 2 PARM elements - NAME then URL + else if (iParsedFieldArray->At(arrayPtr)->FieldName().CompareF(KWappCharBookmark)==0) + { + arrayPtr++; + ExtractBookmarkDataL(arrayPtr); + } + + // Is it an ID characteristic ? + else if (iParsedFieldArray->At(arrayPtr)->FieldName().CompareF(KWappCharID) ==0) + { + arrayPtr++; //Increment to the NAME Parm + + // End of array or PARM Type != NAME + if (arrayPtr == iParsedFieldArray->Count() || + iParsedFieldArray->At(arrayPtr)->FieldName().CompareF(KWappName)!=0) + User::Leave(KWappErrBadMessage); + + if (iIdData == EFalse) + { + // Use the 1st instance of an ID - set to value even if it's null! + iID.Set(iParsedFieldArray->At(arrayPtr)->FieldValue()); + iIdData = ETrue; + } + + while ( arrayPtr< iParsedFieldArray->Count() && !(IsCharacteristicName(arrayPtr)) ) + arrayPtr++; // increment to beginning of next characteristic + } + else if(iParsedFieldArray->At(arrayPtr)->FieldName().CompareF(KWappCharMMSURL) ==0) + { + // The MMSURL Characteristic has NO PARM elements only a value + + if (iMMSURLData == EFalse) // Not been set previously + { + // Use the first instance of a URL - set it to the characteristic value even if it's null + iMMSUrl.Set(iParsedFieldArray->At(arrayPtr)->FieldValue()); + iMMSURLData = ETrue; + } + + arrayPtr++; // Increment to the next element in the array + } + + else // Unrecognised characteristic token + User::Leave(KWappErrUnrecognised); + } + } +// END of function CMsvBIOWapAccessParser::PreProcessL() + +// +// ExtractBearerDataL() - +// +// Called by PreProcessL when it finds an address bearer type. Uses the reference to +// the current position in iParsedFieldArray to extract info to insert into CWapTableData +// and CIspTableData objects. Increment the index position as the function scans +// through the iParsedFieldArray - ensures the value in calling function is correct. +// +void CMsvBIOWapAccessParser::ExtractBearerDataL(TInt& aCurrentPos) + { + + TWappBearerType currentBearer = EWappUnknownBearer; + + // local flags - + // For all address characteristics, only process 1st instance of each parm type - ignore the rest + TBool bearer = EFalse; + TBool proxy = EFalse; + TBool port = EFalse; + TBool csdDialstring = EFalse; + TBool pppAuthType = EFalse; + TBool pppAuthName = EFalse; + TBool pppAuthSecret = EFalse; + TBool pppLoginType = EFalse; + TBool csdCallType = EFalse; + TBool csdCallSpeed = EFalse; + TBool pxAuthName = EFalse; + TBool pxAuthSecret = EFalse; + TBool pxLoginType = EFalse; + TBool ispName = EFalse; + TBool smsSMSCAddr = EFalse; +// TBool ussdServiceCode = EFalse; //Currently not used - will be needed if GSM/USSD supported + + TInt arrayEnd = iParsedFieldArray->Count(); + TCsdCallType callType =EAnalogue; + TCsdCallSpeed callSpeed =EAutobauding; + + // First check - current parm MUST BE A BEARER + // Following Parms can be in any order, but the first must be a BEARER. + + if (iParsedFieldArray->At(aCurrentPos)->FieldName().CompareF(KWappBearer) !=0) + User::Leave(KWappErrMandatoryTagMissing); // First Parm is not a BEARER - big problem!! + + + while ( aCurrentPos< arrayEnd && // Stop checking if past the array end, or next value + !(IsCharacteristicName(aCurrentPos)) ) // is another Characteristic, ie. address, URL, Bookmark, ID or Name + { + TPtrC fieldName = iParsedFieldArray->At(aCurrentPos)->FieldName(); + if (IsValidTokenNameL(aCurrentPos) !=KErrNone) //Validate this Parm Name + User::Leave(KWappErrUnrecognised); + + // Check the next parsed field data - BEARER type + + if (fieldName.CompareF(KWappBearer) ==0) + { + //Set the current local bearer type, & then bearer variable + TPtrC currentValue = iParsedFieldArray->At(aCurrentPos)->FieldValue(); + if (currentValue.CompareF(KWappGsmCsd) ==0) + { + if (!bearer) // first time here! + { + if (!iGsmCsdData) // No previous GSM bearers + { + iGsmCsdWapIpTable = CWapIpBearerData::NewL(); // Create the required table mapping objects + iWapIpISPTable = CIspTableData::NewL(); + currentBearer = EWappGsmCsdBearer;// set local bearer type variable + bearer = ETrue; // ignore further BEARER's only for this characteristic + } + else // Already got data increment to next characteristic and return + { + while ( aCurrentPos< arrayEnd && !(IsCharacteristicName(aCurrentPos)) ) + aCurrentPos++; // increment to beginning of next characteristic + return; // return to PrePocessL + } + } + } + + else if (currentValue.CompareF(KWappGsmSms) ==0) + { + if (!bearer) // haven't set the bearer type yet, ignore all after first + { + if (!iGsmSmsData) // No previous SMS bearers + { + iWapSmsTable = CWapSmsBearerData::NewL(); + currentBearer =EWappGsmSmsBearer; + bearer = ETrue; // ignore any further BEARERs in this Characteristic + } + else // Already got bearer data goto next characteristic & return + { + while ( aCurrentPos< arrayEnd && !(IsCharacteristicName(aCurrentPos)) ) + aCurrentPos++; // increment to beginning of next characteristic + return; // return to PrePocessL + } + } + } + + else if (currentValue.CompareF(KWappGsmUssd) ==0) + { + currentBearer =EWappGsmUssdBearer; + //NB Add support for USSD bearer here when required + // NOTE - must consider proxy & proxy type with USSD! + User::Leave(KWappErrNotSupported); + } + + else if (currentValue.CompareF(KWappIS136Csd) ==0) + { + currentBearer =EWappIS136CsdBearer; + //NB Add support for IS 136 when required + // NOTE - will it be the same as for GSM/CSD ? + User::Leave(KWappErrNotSupported); + } + else if (currentValue.CompareF(KWappGprs) ==0) + { + if (!bearer) // first time here! + { + if (!iGprsData) // No previous bearers + { + iGprsWapIpTable = CWapIpBearerData::NewL(); // Create the required table mapping objects + iWapGprsTable = CWapGprsBearerData::NewL(); + iWapIpISPTable = CIspTableData::NewL(); + currentBearer = EWappGprsBearer;// set local bearer type variable + bearer = ETrue; // ignore further BEARER's only for this characteristic + } + else // Already got bearer data, increment to next characteristic and return + { + while ( aCurrentPos< arrayEnd && !(IsCharacteristicName(aCurrentPos)) ) + aCurrentPos++; // increment to beginning of next characteristic + return; // return to PrePocessL + } + } + } + else + User::Leave(KWappErrUnrecognised); // Unknown bearer type - Help!!!! + } + + //Check for the PROXY characteristics - String used to set Table Data + + // CSD proxy value into iIspTable::iGateway - goes in ISP_IP_GATEWAY + // iWapTable::iGatewayAddr - goes into WAP_GATEWAY_ADDRESS + // SMS proxy value into iWapTable::iGatewayAddr - goes into WAP_GATEWAY_ADDRESS + + // NB If support for USSD, or IS136 required, add additional code here. + else if (fieldName.CompareF(KWappProxy) ==0) + { + if(!proxy) // First PROXY for this characteristic + { + switch(currentBearer) + { + case EWappGsmSmsBearer: + iWapSmsTable->iGatewayAddr.Set(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + break; + case EWappGsmCsdBearer: + iGsmCsdWapIpTable->iGatewayAddr->SetAddrL(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + iWapIpISPTable->iGateway->SetAddrL(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + break; + case EWappGprsBearer: + iGprsWapIpTable->iGatewayAddr->SetAddrL(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + iWapGprsTable->iGatewayAddr->SetAddrL(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + break; + default: + User::Leave(KWappErrUnrecognised); // Unrecognised currentBearer + } + proxy = ETrue; + } + } + + + //Check for the PORT characteristics - first encounter set it, ignore it afterwards + else if ((fieldName.CompareF(KWappPort)==0) && !port) + { + // Record that we've checked a port value - should be one of 4 values! + + if ( (iParsedFieldArray->At(aCurrentPos)->FieldValue().CompareF(KWappPort9200) ==0) + ||(iParsedFieldArray->At(aCurrentPos)->FieldValue().CompareF(KWappPort9201) ==0) + ||(iParsedFieldArray->At(aCurrentPos)->FieldValue().CompareF(KWappPort9202) ==0) + ||(iParsedFieldArray->At(aCurrentPos)->FieldValue().CompareF(KWappPort9203) ==0)) + + { + if (currentBearer == EWappGsmSmsBearer) + iWapSmsTable->iPort.Set(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + else if (currentBearer == EWappGsmCsdBearer) + iGsmCsdWapIpTable->iPort.Set(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + else if (currentBearer == EWappGprsBearer) + iGprsWapIpTable->iPort.Set(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + } + else + { + if (currentBearer == EWappGsmSmsBearer) + iWapSmsTable->iPort.Set(KWappPort9200); + else if (currentBearer == EWappGsmCsdBearer) + iGsmCsdWapIpTable->iPort.Set(KWappPort9200); + else if (currentBearer == EWappGprsBearer) + iGprsWapIpTable->iPort.Set(KWappPort9200); + } + port = ETrue; + } + + +// ******* Following group are for GSM/CSD & IS136/CSD - GSM/SMS and GSM/USSD follow after ******** + + // Is it a CSD_DIALSTRING? + else if (fieldName.CompareF(KWappCsdDial)==0) + { + // Must be either GSM/CSD or IS136/CSD + if ( (currentBearer != EWappGsmCsdBearer) && + (currentBearer != EWappIS136CsdBearer) ) + User::Leave(KWappErrUnexpectedValue); + else if (!csdDialstring) + { + iWapIpISPTable->iDefaultPhoneNum.Set(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + csdDialstring=ETrue; + } + } + + // Check for PPP_AUTHTYPE + // Now don't set the iIFName - always "ppp" & this protocol takes care of rest + else if (fieldName.CompareF(KWappPPPAuthType)==0 && !pppAuthType) + { + if(currentBearer==EWappGprsBearer) + { + if(iParsedFieldArray->At(aCurrentPos)->FieldValue().CompareF(KWappPAP)==0) + iWapGprsTable->iPlainTextAuthDisabled = EFalse; + else + iWapGprsTable->iPlainTextAuthDisabled = ETrue; + } + // set the flag so we don't check again + pppAuthType =ETrue; + } + + // Check if its a PPP_AUTHNAME + else if (fieldName.CompareF(KWappPPPAuthName)==0) + { + if (!pppAuthName) + { + switch(currentBearer) + { + case EWappGsmCsdBearer: + case EWappIS136CsdBearer: + iWapIpISPTable->iLoginName.Set(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + break; + case EWappGprsBearer: + iWapGprsTable->iLoginName.Set(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + break; + default: + // SMS, USSD and GPRS don't have CSD authentication names + User::Leave(KWappErrUnexpectedValue); + } + pppAuthName = ETrue; + } + } + + // Is it PPP_AUTHSECRET? + else if (fieldName.CompareF(KWappPPPAuthSecret)==0 ) + { + + if (!pppAuthSecret) + { + switch(currentBearer) + { + case EWappGsmCsdBearer: + case EWappIS136CsdBearer: + iWapIpISPTable->iLoginPass.Set(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + break; + case EWappGprsBearer: + iWapGprsTable->iLoginPass.Set(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + break; + default: + // SMS, GPRS & USSD don't have authentication type + User::Leave(KWappErrUnexpectedValue); + } + pppAuthSecret = ETrue; + } + } + // Is it a PPP_LOGIN_TYPE? + else if (fieldName.CompareF(KWappPPPLoginType)==0) + { + if(!pppLoginType) + { + const TDesC& val = iParsedFieldArray->At(aCurrentPos)->FieldValue(); + switch(currentBearer) + { + case EWappGsmCsdBearer: + case EWappIS136CsdBearer: + { + if(val.CompareF(KWappAuthAutomatic)==0) + { + iWapIpISPTable->iIFPromptForAuthentication = EFalse; + iWapIpISPTable->iPromptForLoginDetails = EFalse; + } + else + { + iWapIpISPTable->iIFPromptForAuthentication = ETrue; + iWapIpISPTable->iPromptForLoginDetails = ETrue; + } + } + break; + case EWappGprsBearer: + { + if(val.CompareF(KWappAuthAutomatic)==0) + iWapGprsTable->iIFPromptForAuth = EFalse; + else + iWapGprsTable->iIFPromptForAuth = ETrue; + } + break; + default: + User::Leave(KWappErrUnexpectedValue); + } + } + pppLoginType = ETrue; + } + + // Is it a CSD_CALLTYPE? + else if (fieldName.CompareF(KWappCsdCallType)==0) + { + // ONLY GSM/CSD bearer has call types + if ( (currentBearer != EWappGsmCsdBearer) ) + User::Leave(KWappErrUnexpectedValue); + + else if (!csdCallType) + { + // Can have values ANALOGUE (don't set nothing) & ISDN (set modem init string) + if (iParsedFieldArray->At(aCurrentPos)->FieldValue().CompareF(KWappISDN)==0) + { + // TODO implement this function when Symbian know device specs + SetModemInitStringL(); + callType = EIsdn; + } + else if ((iParsedFieldArray->At(aCurrentPos)->FieldValue().CompareF(KWappAnalogue)==0)) + { + callType = EAnalogue; + } + else + callType = EAnalogue; // Not recognised so set to default of ANALOGUE + csdCallType =ETrue; + } + } + + //Check if its a CSD_CALLSPEED + else if (fieldName.CompareF(KWappCsdCallSpeed)==0) + { + // ONLY CSD bearer has call speed - anything else is an error + if (currentBearer != EWappGsmCsdBearer) + User::Leave(KWappErrUnexpectedValue); + else if (!csdCallSpeed) + { + TPtrC value = iParsedFieldArray->At(aCurrentPos)->FieldValue(); + // Set the local variable for callspeed - will set the iIspTable value at end of fn + if (value.CompareF(KWappSpeedAuto)==0) + callSpeed = EAutobauding ; // Auto speed select - device chooses + else if (value.CompareF(KWappSpeed9600)==0) + callSpeed = E9600baud; + else if (value.CompareF(KWappSpeed14400)==0) + callSpeed = E14400baud; + else if (value.CompareF(KWappSpeed19200)==0) + callSpeed = E19200baud; + else if (value.CompareF(KWappSpeed28800)==0) + callSpeed = E28800baud; + else if (value.CompareF(KWappSpeed38400)==0) + callSpeed = E38400baud; + else if (value.CompareF(KWappSpeed43200)==0) + callSpeed = E43200baud; + else if (value.CompareF(KWappSpeed56700)==0) + callSpeed = E57600baud; + else + callSpeed = EAutobauding;// Set to the default of AUTO + + csdCallSpeed =ETrue; + } + } + + // Check if its a PROXY_AUTHNAME - must be CSD or GPRS + else if (fieldName.CompareF(KWappProxyAuthName)==0 ) + { + switch(currentBearer) + { + case EWappGsmCsdBearer: + case EWappIS136CsdBearer: + if (!pxAuthName) + { + iGsmCsdWapIpTable->iProxyAuthName.Set(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + pxAuthName =ETrue; + } + break; + case EWappGprsBearer: + if (!pxAuthName) + { + iGprsWapIpTable->iProxyAuthName.Set(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + pxAuthName =ETrue; + } + break; + default: + User::Leave(KWappErrUnexpectedValue); + } + } + + // Is it a PROXY_AUTHSECRET? + else if (fieldName.CompareF(KWappProxyAuthSecret)==0) + { + switch(currentBearer) + { + case EWappGsmCsdBearer: + case EWappIS136CsdBearer: + if (!pxAuthSecret) + { + iGsmCsdWapIpTable->iProxyAuthSecret.Set(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + pxAuthSecret =ETrue; + } + break; + case EWappGprsBearer: + if (!pxAuthSecret) + { + iGprsWapIpTable->iProxyAuthSecret.Set(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + pxAuthSecret =ETrue; + } + break; + default: + User::Leave(KWappErrUnexpectedValue); + } + } + + // Is it a PROXY_LOGIN_TYPE? + + else if (fieldName.CompareF(KWappProxyLoginType)==0) + { + //We just set the variable in the mapping object for the WAP IP Bearer Table. Don't do anything with it yet. + switch(currentBearer) + { + case EWappGsmCsdBearer: + case EWappIS136CsdBearer: + if (!pxAuthSecret) + { + if (iParsedFieldArray->At(aCurrentPos)->FieldValue().CompareF(KWappAuthAutomatic)) + iGsmCsdWapIpTable->iProxyUseAutoLogin = ETrue; + else + iGsmCsdWapIpTable->iProxyUseAutoLogin = EFalse; + } + break; + case EWappGprsBearer: + if (!pxAuthSecret) + { + if (iParsedFieldArray->At(aCurrentPos)->FieldValue().CompareF(KWappAuthAutomatic)) + iGprsWapIpTable->iProxyUseAutoLogin = ETrue; + else + iGprsWapIpTable->iProxyUseAutoLogin = EFalse; + } + break; + default: + User::Leave(KWappErrUnexpectedValue); + } + + + pxLoginType = ETrue; + } + + + // Is it a ISP _NAME element? + else if (fieldName.CompareF(KWappISP)==0) + { + // Must be a CSD or Grps bearer + if ( (currentBearer != EWappGsmCsdBearer) && + (currentBearer != EWappIS136CsdBearer) && + (currentBearer != EWappGprsBearer) ) + User::Leave(KWappErrUnexpectedValue); + else if (!ispName) + { + iWapIpISPTable->iISPDescription.Set(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + ispName =ETrue; + } + } + + +// ****************** Following are for GSM/SMS settings ********************* + else if (fieldName.CompareF(KWappSMSCAddress)==0) + { + if (currentBearer != EWappGsmSmsBearer) + User::Leave(KWappErrUnexpectedValue);// Only SMS has a SMSC address - error condition + else if (!smsSMSCAddr) + { + iWapSmsTable->iWapServiceAddr.Set(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + smsSMSCAddr = ETrue; + } + } + + //Check for PROXY_TYPE characteristic + + // TO DO When/If USSD support is required! Add it here + // Need to know how to set Addressing Scheme for USSD & CSD/SMS/etc!!!!! + // Currently only alter value of dummy variable to keep the compiler happy + else if (fieldName.CompareF(KWappProxyType) ==0) + { + // Must be a USSD or GPRS bearer type - otherwise error! + if (currentBearer == EWappGsmUssdBearer) + { + // NB If USSD support req'd,set the Addressing type here. NB Not yet defined in CommDb! + } + else if(currentBearer == EWappGprsBearer) + { + if(iParsedFieldArray->At(aCurrentPos)->FieldValue().CompareF(KWappIpv4)!=0) + User::Leave(KWappErrUnrecognised); + } + else + User::Leave(KWappErrUnrecognised); + } + + // Check for USSD service code + else if (fieldName.CompareF(KWappUSSDCode)==0) + { + if (currentBearer == EWappGsmUssdBearer) + { + // NB - If USSD support req'd, set the Service Centre Address here! + } + else + User::Leave(KWappErrUnrecognised); // Not a USSD address, so shouldn't be here - error + } + + // Access point is GPRS only + else if (fieldName.CompareF(KWappAccessPointName)==0) + { + if (currentBearer == EWappGprsBearer) + { + iWapGprsTable->iAccessPointName.Set(iParsedFieldArray->At(aCurrentPos)->FieldValue()); + } + else + User::Leave(KWappErrUnrecognised); // Shouldn't have a GPRS address if we aren't GPRS! + } + + aCurrentPos++; + }// END of the While loop + + if (currentBearer == EWappGsmCsdBearer) + { + if (!iGsmCsdData) + { + if (!pppLoginType) + { + // Login type not set so determine value for whether login and authorisation set + if (iWapIpISPTable->iLoginName.Length()!=0 && iWapIpISPTable->iLoginPass.Length()!=0) + { + iWapIpISPTable->iPromptForLoginDetails =EFalse; + iWapIpISPTable->iIFPromptForAuthentication =EFalse; + } + } + if (! pxLoginType) + if (iGsmCsdWapIpTable->iProxyAuthName.Length()!=0 && iGsmCsdWapIpTable->iProxyAuthSecret.Length()!=0) + { + iGsmCsdWapIpTable->iProxyUseAutoLogin = ETrue; + } + + // Set the iIspTable->iCsdCallSpeed member - need the calltype and the callspeed values + if (callType == EAnalogue) + { + switch (callSpeed) + { + case EAutobauding: + iWapIpISPTable->iCallSpeed = RMobileCall::ESpeedAutobauding; + iWapIpISPTable->iCallDataProtocol = RMobileCall::EProtocolV34; + break; + case E9600baud: + iWapIpISPTable->iCallSpeed = RMobileCall::ESpeed9600; + iWapIpISPTable->iCallDataProtocol = RMobileCall::EProtocolV32; + break; + case E14400baud: + iWapIpISPTable->iCallSpeed = RMobileCall::ESpeed14400; + iWapIpISPTable->iCallDataProtocol = RMobileCall::EProtocolV34; + break; + case E19200baud: + iWapIpISPTable->iCallSpeed =RMobileCall::ESpeed19200; + iWapIpISPTable->iCallDataProtocol = RMobileCall::EProtocolV34; + break; + case E28800baud: + iWapIpISPTable->iCallSpeed =RMobileCall::ESpeed28800; + iWapIpISPTable->iCallDataProtocol = RMobileCall::EProtocolV34; + break; + case E38400baud: + case E43200baud: + case E57600baud: + iWapIpISPTable->iCallSpeed = RMobileCall::ESpeedAutobauding; + iWapIpISPTable->iCallDataProtocol = RMobileCall::EProtocolV34; + break; + default: //SHOULD be one of the above! + iWapIpISPTable->iCallSpeed = RMobileCall::ESpeedAutobauding; + iWapIpISPTable->iCallDataProtocol = RMobileCall::EProtocolV34; + break; + } + } + else if (!iGsmCsdData && callType == EIsdn) + { + iWapIpISPTable->iCallDataProtocol = RMobileCall::EProtocolV110; + switch (callSpeed) + { + case EAutobauding: + iWapIpISPTable->iCallSpeed = RMobileCall::ESpeedAutobauding; + break; + case E9600baud: + iWapIpISPTable->iCallSpeed = RMobileCall::ESpeed9600; + break; + case E14400baud: + iWapIpISPTable->iCallSpeed =RMobileCall::ESpeed14400; + break; + case E19200baud: + iWapIpISPTable->iCallSpeed =RMobileCall::ESpeed19200; + break; + case E28800baud: + iWapIpISPTable->iCallSpeed =RMobileCall::ESpeed28800; + break; + case E38400baud: + iWapIpISPTable->iCallSpeed =RMobileCall::ESpeed38400; + break; + case E43200baud: + iWapIpISPTable->iCallSpeed =RMobileCall::ESpeed48000; + break; + case E57600baud: + iWapIpISPTable->iCallSpeed = RMobileCall::ESpeed56000; + break; + default: //SHOULD be one of the above! + iWapIpISPTable->iCallSpeed = RMobileCall::ESpeedAutobauding; + break; + } + } + else + User::Leave(KWappErrUnrecognised); //Unrecognised value for calltype - error + } + iGsmCsdData = ETrue; + } + + else if (currentBearer == EWappGsmSmsBearer) + iGsmSmsData = ETrue; + else if(currentBearer == EWappGprsBearer) + { + if (!pppLoginType) + { + if (iWapGprsTable->iLoginName.Length() > 0 && iWapGprsTable->iLoginPass.Length() > 0) + iWapGprsTable->iIFPromptForAuth =EFalse; + } + iGprsData = ETrue; + } + + } +// End of function CMsvBIOWapAccessParser::ExtractBearerDataL() + +// +// ExtractBookmarkDataL() - +// Extracts bookmark from parsed data. Adds default if name field is not +// set. Discards the Bookmark if URL field is blank (ie nothing added to Bookmark +// List) NB exactly 2 PARMs in a bookmark, NAME & URL, any order. +// +void CMsvBIOWapAccessParser::ExtractBookmarkDataL(TInt& aIndex) + { + TPtrC tempPtr; + TBool foundName = EFalse; + TBool foundURL = EFalse; + TInt parmsChecked = 0; + + HBufC* bookmarkName = NULL; + HBufC* bookmarkURL = NULL; + + // Should be set to the next parm in the Bookmark NOTE: Can't properly check that + // an Empty Name or URL Parsed field is not the start of another characteristic + while (aIndex < iParsedFieldArray->Count() && !IsCharacteristicName(aIndex)) + { + // check token is correct - copy NAME + if (parmsChecked <2 && iParsedFieldArray->At(aIndex)->FieldName().CompareF(KWappName) ==0) + { + if (foundName ==EFalse) + { + tempPtr.Set(iParsedFieldArray->At(aIndex)->FieldValue()); + if (tempPtr.Length()==0) + tempPtr.Set(KWappDefaultBMName); + bookmarkName = tempPtr.AllocL(); + CleanupStack::PushL(bookmarkName); + foundName =ETrue; + } + parmsChecked++; + } + else if (parmsChecked <2 && iParsedFieldArray->At(aIndex)->FieldName().CompareF(KWappURL)==0) + { + if (foundURL == EFalse) + { + tempPtr.Set(iParsedFieldArray->At(aIndex)->FieldValue()); + if (tempPtr.Length() > 0) + { + bookmarkURL = tempPtr.AllocL(); + CleanupStack::PushL(bookmarkURL); + foundURL =ETrue; + } + } + parmsChecked++; + } + // Advance to next field if not at the end of the array + if (aIndex Count()) + aIndex++; + } + // If we've only looked at 2 Parms and have both a Name AND URL + // it's a well-formed bookmark so add to it to our List + if (foundName && foundURL && parmsChecked ==2) + { + CWappBookmark* newBookmark = CWappBookmark::NewLC(); + newBookmark->SetNameL(*bookmarkName); + newBookmark->SetUrlL(*bookmarkURL); + iBookmarkList->AppendL(newBookmark); + CleanupStack::Pop(); // release newBookmark + } + if(bookmarkName) CleanupStack::PopAndDestroy(); + if(bookmarkURL) CleanupStack::PopAndDestroy(); + } + +// +// ValidateCharacteristicsL() - Validates the data extracted by PreProcessL. +// +// Following are legitimate messages +// - entirely bookmarks +// - 1+ bearers with any no of other characteristics +// - Non-Null URL and Non Null name of existing settings records +// +// Any other combinations are invalid i.e. +// +// Bookmarks with ID/URL/NAME & NO Bearer +// +void CMsvBIOWapAccessParser::ValidateCharacteristicsL() + { + + // Bookmarks message - bookmarks & no bearers, should be no URL, ID or Settings Name + if ((iBookmarkList->Count() >0) && + !(iGsmCsdData || iGsmSmsData || iGprsData) && + (iURLData || iNameData || iIdData)) + User::Leave(KWappErrBadMessage); + + // start page update message - URL+NAME but no Bearers, no bookmarks + if (iURLData && iNameData && + !(iGsmCsdData || iGsmSmsData || iGprsData) && + (iBookmarkList->Count()==0) && + ((iUrl.Length()==0) || (iWAPSettingsName.Length()==0))) + User::Leave(KWappErrBadMessage); + + if ((iGsmCsdData || iGsmSmsData || iGprsData) && + (iWAPSettingsName.Length()==0)) // Need a name for CommDb - default + User::Leave(KWappErrBadMessage); // should have been given if nothing in message + } + +// +// IsCharacteristicName - Returns ETrue if the Name at the index is a genuine +// Characteristic Type and the Value is NULL +// +TBool CMsvBIOWapAccessParser::IsCharacteristicName(TInt anIndex) + { + TPtrC name = iParsedFieldArray->At(anIndex)->FieldName(); + if ( + (name.CompareF(KWappCharAddress) ==0) || // Address + (name.CompareF(KWappCharURL) ==0) || // URL + (name.CompareF(KWappCharMMSURL) ==0) || // MMS URL + (name.CompareF(KWappCharName) ==0) || // NAME + (name.CompareF(KWappCharBookmark) ==0) || // Bookmark + (name.CompareF(KWappCharID) ==0) ) // ID + return ETrue; // Is a characteristic name + else + return EFalse; // Not a characteristic name + } + +// +// SetModemInitStringL() - Sets the modem initialisation string +// +void CMsvBIOWapAccessParser::SetModemInitStringL() // Sets the modem initialisation string + { + delete iModemInitString; + iModemInitString =NULL; + iModemInitString=KDummyModemInitStr().AllocL(); + } + + +void CMsvBIOWapAccessParser::DeleteCommDatTableEntryL(TMDBElementId aElementName, const TDesC& aCsdNameStr) + { + switch (aElementName) + { + case KCDTIdWAPIPBearerRecord: + { + CCDWAPIPBearerRecord *wapIPRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdWAPIPBearerRecord)); + CleanupStack::PushL(wapIPRecord); + wapIPRecord->iWAPAccessPointId = iWapAccessPtID; + + if(wapIPRecord->FindL(*iDBSession)) + { + TUint32 accessId = wapIPRecord->iWAPIAP; + if ( !((iGsmCsdData && iGsmCsdWapIpTable->iIapId == accessId) || + (iGprsData && iGprsWapIpTable->iIapId == accessId))) + { + wapIPRecord->DeleteL(*iDBSession); + } + } + CleanupStack::PopAndDestroy(wapIPRecord); + } + break; + case KCDTIdWAPSMSBearerRecord: + { + CCDWAPSMSBearerRecord *smsRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdWAPSMSBearerRecord)); + CleanupStack::PushL(smsRecord); + smsRecord->iWAPAccessPointId = iWapAccessPtID; + if(smsRecord->FindL(*iDBSession)) + { + smsRecord->DeleteL(*iDBSession); + } + CleanupStack::PopAndDestroy(smsRecord); + } + break; + case KCDTIdIAPRecord: + { + CCDIAPRecord *iapRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdIAPRecord)); + CleanupStack::PushL(iapRecord); + iapRecord->iRecordName.SetMaxLengthL(aCsdNameStr.Length()); + iapRecord->iRecordName = aCsdNameStr; + if(iapRecord->FindL(*iDBSession)) + { + iapRecord->DeleteL(*iDBSession); + } + CleanupStack::PopAndDestroy(iapRecord); + } + break; + case KCDTIdDialOutISPRecord: + { + CCDDialOutISPRecord *dialOutISPRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdDialOutISPRecord)); + CleanupStack::PushL(dialOutISPRecord); + dialOutISPRecord->iRecordName.SetMaxLengthL(aCsdNameStr.Length()); + dialOutISPRecord->iRecordName = aCsdNameStr; + if(dialOutISPRecord->FindL(*iDBSession)) + { + dialOutISPRecord->DeleteL(*iDBSession); + } + CleanupStack::PopAndDestroy(dialOutISPRecord); + } + break; + case KCDTIdOutgoingGprsRecord: + { + CCDOutgoingGprsRecord *gprsRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdOutgoingGprsRecord)); + CleanupStack::PushL(gprsRecord); + gprsRecord->iRecordName.SetMaxLengthL(aCsdNameStr.Length()); + gprsRecord->iRecordName = aCsdNameStr; + if(gprsRecord->FindL(*iDBSession)) + { + gprsRecord->DeleteL(*iDBSession); + } + CleanupStack::PopAndDestroy(gprsRecord); + } + break; + } + } + +void CMsvBIOWapAccessParser::WriteDataToDBL() + { + // Should have a table for at least one bearer!! + __ASSERT_DEBUG (iWapSmsTable != NULL || iWapGprsTable != NULL || (iGsmCsdWapIpTable != NULL && iWapIpISPTable !=NULL), + Panic(EWappNullPointer)); + + if (iWAPSettingsName.Length()==0) + { + iWAPSettingsName.Set(KWapDefaultSettingsName); + } + + TBuf csdNameStr; + csdNameStr.Copy(iWAPSettingsName); + csdNameStr.Append(KGsmCsdSuffix); + if (iGsmCsdData) + { + iCurrentBearerType = EWappGsmCsdBearer; // Set the bearer type indicator for use in next functions + + WriteToCommDatDialOutISPTableL(csdNameStr); + SetWapIspEntryIdL(csdNameStr); // Sets iWapIspID + + WriteToCommsDatIAPTableL(csdNameStr); + SetWapIapEntryIdL(csdNameStr, *iGsmCsdWapIpTable); // Sets iWapIapID + } + else + { + DeleteCommDatTableEntryL(KCDTIdDialOutISPRecord,csdNameStr); + DeleteCommDatTableEntryL(KCDTIdIAPRecord,csdNameStr); + } + + TBuf gprsNameStr; + gprsNameStr.Copy(iWAPSettingsName); + gprsNameStr.Append(KGprsSuffix); + if(iGprsData) + { + iCurrentBearerType = EWappGprsBearer; + WriteToCommDatGprsTableL(gprsNameStr); + SetWapIspEntryIdL(gprsNameStr); // Sets iWapIspID + WriteToCommsDatIAPTableL(gprsNameStr); + + SetWapIapEntryIdL(gprsNameStr, *iGprsWapIpTable); // Sets iWapIapID + } + else + { + DeleteCommDatTableEntryL(KCDTIdOutgoingGprsRecord,gprsNameStr); + DeleteCommDatTableEntryL(KCDTIdIAPRecord,gprsNameStr); + } + + WriteToCommDatWapAccessPointTableL(iWAPSettingsName); + + SetWapAPEntryIdL(); + + + if (iGsmCsdData) + { + // Set the flag so that correct mapping object is used to set the data in the WAP IP Bearer table + iCurrentBearerType = EWappGsmCsdBearer; + WriteToCommDatWapIpBearerTableL(); + } + else + { + DeleteCommDatTableEntryL(KCDTIdWAPIPBearerRecord,csdNameStr); + } + + + if ((iGprsData)) + { + // Set the flag so that correct mapping object is used to set the data in the WAP IP Bearer table + iCurrentBearerType = EWappGprsBearer; + WriteToCommDatWapIpBearerTableL(); + } + else + { + DeleteCommDatTableEntryL(KCDTIdWAPIPBearerRecord,gprsNameStr); + } + + + if (iGsmSmsData) + { + WriteToCommDatWapSmsBearerTableL(); + } + else + { + DeleteCommDatTableEntryL(KCDTIdWAPSMSBearerRecord,iWAPSettingsName); + } + + + + +// if ((iGsmCsdData) && iModemInitString) // Only if CSD and has string set (ie ISDN) +// CreateTableL(TPtrC(MODEM), iWAPSettingsName); //TODO Not yet implemented + } + +// End of function CMsvBIOWapAccessParser::WriteDataToDBL() + + +void CMsvBIOWapAccessParser::WriteToCommsDatIAPTableL(const TDesC& aRecName) + { + CCDIAPRecord *iapRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdIAPRecord)); + CleanupStack::PushL(iapRecord); + iapRecord->iRecordName.SetMaxLengthL(aRecName.Length()); + iapRecord->iRecordName = aRecName; + + TBool newRecord = EFalse; + if(!iapRecord->FindL(*iDBSession)) + { + iapRecord->SetRecordId(KCDNewRecordRequest); + newRecord = ETrue; + } + + switch (iCurrentBearerType) + { + case EWappGsmCsdBearer: + { + iapRecord->iService = iWapIpISPTable->iISPCommDbRecordId; + iapRecord->iServiceType.SetMaxLengthL(((TPtrC)KCDTypeNameDialOutISP).Length()); + iapRecord->iServiceType = (TPtrC)KCDTypeNameDialOutISP; + + //there are 7 fields in IAP table which cannot have null values, and so when creating an IAP record we were only filling in one of the fields which meant we were submitting a record with lots of null values which can't be handled. + iapRecord->iBearer = (TUint32)2; + + iapRecord->iBearerType.SetMaxLengthL(((TPtrC)KCDTypeNameModemBearer).Length()); + iapRecord->iBearerType = (TPtrC)KCDTypeNameModemBearer; + iapRecord->iNetwork = (TUint32)1; + iapRecord->iNetworkWeighting = (TUint32)0; + iapRecord->iLocation = (TUint32)4; + } + break; + case EWappGprsBearer: + { + iapRecord->iService = iWapGprsTable->iGprsCommDbRecordId; + iapRecord->iServiceType.SetMaxLengthL(((TPtrC)KCDTypeNameDialOutISP).Length()); + iapRecord->iServiceType = (TPtrC)KCDTypeNameOutgoingWCDMA; + + //there are 7 fields in IAP table which cannot have null values, and so when creating an IAP record we were only filling in one of the fields which meant we were submitting a record with lots of null values which can't be handled. + iapRecord->iBearer = (TUint32)2; + iapRecord->iBearerType.SetMaxLengthL(((TPtrC)KCDTypeNameModemBearer).Length()); + iapRecord->iBearerType = (TPtrC)KCDTypeNameModemBearer; + iapRecord->iNetwork = (TUint32)1; + iapRecord->iNetworkWeighting = (TUint32)0; + iapRecord->iLocation = (TUint32)4; + } + break; + default: + break; + } + + if(newRecord) + { + iapRecord->StoreL(*iDBSession); + } + else + { + iapRecord->ModifyL(*iDBSession); + } + + CleanupStack::PopAndDestroy(iapRecord); + } + +void CMsvBIOWapAccessParser::WriteToCommDatWapSmsBearerTableL() + { + CCDWAPSMSBearerRecord *wapSMSBearerRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdWAPSMSBearerRecord)); + CleanupStack::PushL(wapSMSBearerRecord); + //Search based on WAPAccessPointId + wapSMSBearerRecord->iWAPAccessPointId = iWapAccessPtID; + + TBool newRecord = EFalse; + if(!wapSMSBearerRecord->FindL(*iDBSession)) + { + wapSMSBearerRecord->SetRecordId(KCDNewRecordRequest); + newRecord = ETrue; + } + + wapSMSBearerRecord->iWAPGatewayAddress.SetMaxLengthL(iWapSmsTable->iGatewayAddr.Length()); + wapSMSBearerRecord->iWAPGatewayAddress = iWapSmsTable->iGatewayAddr; + + wapSMSBearerRecord->iWAPServiceCentreAddress.SetMaxLengthL(iWapSmsTable->iWapServiceAddr.Length()); + wapSMSBearerRecord->iWAPServiceCentreAddress = iWapSmsTable->iWapServiceAddr; + + wapSMSBearerRecord->iWAPWSPOption = GetWSPType(iWapSmsTable->iPort); + wapSMSBearerRecord->iWAPSecurity = UseSecurity(iWapSmsTable->iPort); + + if(newRecord) + { + wapSMSBearerRecord->StoreL(*iDBSession); + } + else + { + wapSMSBearerRecord->ModifyL(*iDBSession); + } + + CleanupStack::PopAndDestroy(wapSMSBearerRecord); + } + +void CMsvBIOWapAccessParser::WriteToCommDatWapIpBearerTableL() + { + CCDWAPIPBearerRecord *wapIPBearerRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdWAPIPBearerRecord)); + CleanupStack::PushL(wapIPBearerRecord); + //Search based on WAPAccessPointId + wapIPBearerRecord->iWAPAccessPointId = iWapAccessPtID; + + TBool newRecord = EFalse; + if(!wapIPBearerRecord->FindL(*iDBSession)) + { + wapIPBearerRecord->SetRecordId(KCDNewRecordRequest); + newRecord = ETrue; + } + + CWapIpBearerData* wapIpTableData = NULL; + switch (iCurrentBearerType) + { + case EWappGsmCsdBearer: + { + wapIpTableData = iGsmCsdWapIpTable; + } + break; + case EWappGprsBearer: + { + wapIpTableData = iGprsWapIpTable; + } + break; + default: + User::Leave(KWappErrUnexpectedValue); + } + __ASSERT_DEBUG(wapIpTableData, Panic(KWappErrNullValue)); + + wapIPBearerRecord->iWAPAccessPointId = iWapAccessPtID; + wapIPBearerRecord->iWAPIAP = wapIpTableData->iIapId; // Get from SetWapEntryIdsL + + wapIPBearerRecord->iWAPGatewayAddress.SetMaxLengthL((wapIpTableData->iGatewayAddr->Addr()).Length()); + wapIPBearerRecord->iWAPGatewayAddress = wapIpTableData->iGatewayAddr->Addr(); + + wapIPBearerRecord->iWAPWSPOption = GetWSPType(wapIpTableData->iPort); + wapIPBearerRecord->iWAPSecurity = UseSecurity(wapIpTableData->iPort); + + TLex lex = wapIpTableData->iPort; + TInt port = 0; + User::LeaveIfError(lex.Val(port)); + wapIPBearerRecord->iWAPProxyPort = port; + + wapIPBearerRecord->iWAPProxyLoginName.SetMaxLengthL(wapIpTableData->iProxyAuthName.Length()); + wapIPBearerRecord->iWAPProxyLoginName = wapIpTableData->iProxyAuthName; + + wapIPBearerRecord->iWAPProxyLoginPass.SetMaxLengthL(wapIpTableData->iProxyAuthSecret.Length()); + wapIPBearerRecord->iWAPProxyLoginPass = wapIpTableData->iProxyAuthSecret; + + if(newRecord) + { + wapIPBearerRecord->StoreL(*iDBSession); + } + else + { + wapIPBearerRecord->ModifyL(*iDBSession); + } + + CleanupStack::PopAndDestroy(wapIPBearerRecord); + } + +void CMsvBIOWapAccessParser::WriteToCommDatWapAccessPointTableL(const TDesC& aRecName) + { + CCDWAPAccessPointRecord *wapAPRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdWAPAccessPointRecord)); + CleanupStack::PushL(wapAPRecord); + wapAPRecord->iRecordName.SetMaxLengthL(aRecName.Length()); + wapAPRecord->iRecordName = aRecName; + TBool newRecord = EFalse; + if(!wapAPRecord->FindL(*iDBSession)) + { + wapAPRecord->SetRecordId(KCDNewRecordRequest); + newRecord = ETrue; + } + + if (iUrl.Length() != 0) + { + wapAPRecord->iWAPStartPage.SetMaxLengthL(iUrl.Length()); + wapAPRecord->iWAPStartPage = iUrl; + } + + if ((iGsmCsdData) || (iGprsData)) + wapAPRecord->iWAPCurrentBearer = TPtrC(WAP_IP_BEARER); + else if (iGsmSmsData) + wapAPRecord->iWAPCurrentBearer = TPtrC(WAP_SMS_BEARER); + else + User::Leave(KWappErrUnexpectedValue); + + if(newRecord) + { + wapAPRecord->StoreL(*iDBSession); + } + else + { + wapAPRecord->ModifyL(*iDBSession); + } + + CleanupStack::PopAndDestroy(wapAPRecord); + } + +void CMsvBIOWapAccessParser::WriteToCommDatGprsTableL(const TDesC& aRecName) + { + CCDOutgoingGprsRecord *gprsRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdOutgoingGprsRecord)); + CleanupStack::PushL(gprsRecord); + gprsRecord->iRecordName.SetMaxLengthL(aRecName.Length()); + gprsRecord->iRecordName = aRecName; + + TBool newRecord = EFalse; + if(!gprsRecord->FindL(*iDBSession)) + { + gprsRecord->SetRecordId(KCDNewRecordRequest); + newRecord = ETrue; + } + + gprsRecord->iGPRSAPN.SetMaxLengthL(iWapGprsTable->iAccessPointName.Length()); + gprsRecord->iGPRSAPN = iWapGprsTable->iAccessPointName; + + gprsRecord->iGPRSPDPType = iWapGprsTable->iPDPType; + + gprsRecord->iGPRSPDPAddress.SetMaxLengthL(iWapGprsTable->iPDPAddress->Des().Length()); + gprsRecord->iGPRSPDPAddress = iWapGprsTable->iPDPAddress->Des(); + + gprsRecord->iGPRSIfPromptForAuth = iWapGprsTable->iIFPromptForAuth; + + gprsRecord->iGPRSIfAuthName.SetMaxLengthL(iWapGprsTable->iLoginName.Length()); + gprsRecord->iGPRSIfAuthName = iWapGprsTable->iLoginName; + + gprsRecord->iGPRSIfAuthPass.SetMaxLengthL(iWapGprsTable->iLoginPass.Length()); + gprsRecord->iGPRSIfAuthPass = iWapGprsTable->iLoginPass; + + gprsRecord->iGPRSIPGateway.SetMaxLengthL(iWapGprsTable->iGatewayAddr->Addr().Length()); + gprsRecord->iGPRSIPGateway = iWapGprsTable->iGatewayAddr->Addr(); + + gprsRecord->iGPRSIPAddrFromServer = iWapGprsTable->iIpAddrFromServer; + + gprsRecord->iGPRSIPDNSAddrFromServer = iWapGprsTable->iIPDnsAddrFromServer; + gprsRecord->iGPRSDisablePlainTextAuth = iWapGprsTable->iPlainTextAuthDisabled; + + if(newRecord) + { + gprsRecord->StoreL(*iDBSession); + } + else + { + gprsRecord->ModifyL(*iDBSession); + } + + CleanupStack::PopAndDestroy(gprsRecord); + } + +void CMsvBIOWapAccessParser::WriteToCommDatDialOutISPTableL(const TDesC& aRecName) + { + CCDDialOutISPRecord *dialoutRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdDialOutISPRecord)); + CleanupStack::PushL(dialoutRecord); + dialoutRecord->iRecordName.SetMaxLengthL(aRecName.Length()); + dialoutRecord->iRecordName = aRecName; + + TBool newRecord = EFalse; + if(!dialoutRecord->FindL(*iDBSession)) + { + dialoutRecord->SetRecordId(KCDNewRecordRequest); + newRecord = ETrue; + + iWapIpISPTable->iISPCommDbRecordId = dialoutRecord->iRecordTag.RecordId(); + } + + //It's time to write values + (dialoutRecord->iDescription).SetMaxLengthL(iWapIpISPTable->iISPDescription.Length()); + dialoutRecord->iDescription = iWapIpISPTable->iISPDescription; + + dialoutRecord->iType = iWapIpISPTable->iISPType; + + dialoutRecord->iDefaultTelNum.SetMaxLengthL(iWapIpISPTable->iDefaultPhoneNum.Length()); + dialoutRecord->iDefaultTelNum = iWapIpISPTable->iDefaultPhoneNum; + + dialoutRecord->iDialResolution = iWapIpISPTable->iDialResolution; //Mandatory, ETrue default + + dialoutRecord->iUseLoginScript = iWapIpISPTable->iUseScript; //Mandatory, EFalse by default + + if (iWapIpISPTable->iLoginScript.Length() != 0) + { + (dialoutRecord->iLoginScript).SetMaxLengthL(iWapIpISPTable->iLoginScript.Length()); + dialoutRecord->iLoginScript = iWapIpISPTable->iLoginScript; + } + dialoutRecord->iPromptForLogin = iWapIpISPTable->iPromptForLoginDetails; // Mandatory, ETrue by default + dialoutRecord->iLoginName.SetMaxLengthL((iWapIpISPTable->iLoginName).Length()); + dialoutRecord->iLoginName = iWapIpISPTable->iLoginName; + + (dialoutRecord->iLoginPass).SetMaxLengthL((iWapIpISPTable->iLoginPass).Length()); + dialoutRecord->iLoginPass = iWapIpISPTable->iLoginPass; + + dialoutRecord->iDisplayPct = iWapIpISPTable->iDisplayPCT; + + (dialoutRecord->iIfParams).SetMaxLengthL((iWapIpISPTable->iIFParams).Length()); + dialoutRecord->iIfParams = iWapIpISPTable->iIFParams; + + (dialoutRecord->iIfNetworks).SetMaxLengthL((iWapIpISPTable->iIFNetworks->Des()).Length()); + dialoutRecord->iIfNetworks = iWapIpISPTable->iIFNetworks->Des(); // Set to "IP" + + dialoutRecord->iIfPromptForAuth = iWapIpISPTable->iPromptForLoginDetails; //Mandatory, default is ETrue + + (dialoutRecord->iIfAuthName).SetMaxLengthL((iWapIpISPTable->iLoginName).Length()); + dialoutRecord->iIfAuthName = iWapIpISPTable->iLoginName; + + (dialoutRecord->iIfAuthPass).SetMaxLengthL((iWapIpISPTable->iLoginPass).Length()); + dialoutRecord->iIfAuthPass = iWapIpISPTable->iLoginPass; + + dialoutRecord->iIfAuthRetries = iWapIpISPTable->iNumAuthAttempts; + + dialoutRecord->iIfCallbackEnabled = iWapIpISPTable->iCallBackEnabled; + if (iWapIpISPTable->iCallBackEnabled) + { + dialoutRecord->iIfCallbackType = iWapIpISPTable->iCallBackType; + TPtr8 tempPtr(0,0); + tempPtr.Copy(iWapIpISPTable->iCallBackInfo); + + dialoutRecord->iIfCallbackInfo.SetMaxLengthL(tempPtr.Length()); + dialoutRecord->iIfCallbackInfo = tempPtr; + dialoutRecord->iCallbackTimeout = 10000; + } + + dialoutRecord->iIpAddrFromServer = iWapIpISPTable->iAddrFromServer; //Mandatory set to True + + (dialoutRecord->iIpAddr).SetMaxLengthL((iWapIpISPTable->iInOutAddress->Addr()).Length()); + dialoutRecord->iIpNetMask = iWapIpISPTable->iNetmask->Addr(); + + (dialoutRecord->iIpGateway).SetMaxLengthL((iWapIpISPTable->iGateway->Addr()).Length()); + dialoutRecord->iIpGateway = iWapIpISPTable->iGateway->Addr(); + + dialoutRecord->iIpDnsAddrFromServer = iWapIpISPTable->iDNSFromServer; + // Following will write NULL strings to database, clearing any previous settings. + + (dialoutRecord->iIpNameServer1).SetMaxLengthL((iWapIpISPTable->iDNS1->Addr()).Length()); + dialoutRecord->iIpNameServer1 = iWapIpISPTable->iDNS1->Addr(); + + (dialoutRecord->iIpNameServer2).SetMaxLengthL((iWapIpISPTable->iDNS2->Addr()).Length()); + dialoutRecord->iIpNameServer2 = iWapIpISPTable->iDNS2->Addr(); + + dialoutRecord->iEnableIpHeaderComp = iWapIpISPTable->iHeaderCompressionEnabled; + // Don't bother with LCP extensions - leave as null field + dialoutRecord->iDisablePlainTextAuth = iWapIpISPTable->iPlainTextAuthDisabled; + dialoutRecord->iEnableSwComp = iWapIpISPTable->iSwCompressionEnabled; + dialoutRecord->iBearerSpeed = iWapIpISPTable->iCallSpeed; + dialoutRecord->iBearerProtocol = iWapIpISPTable->iCallDataProtocol; + + if(newRecord) + { + dialoutRecord->StoreL(*iDBSession); + } + else + { + dialoutRecord->ModifyL(*iDBSession); + } + + CleanupStack::PopAndDestroy(dialoutRecord); + } + + +// +// SetWapIspEntryIdL - The iCurrentBearerType variable MUST be correctly set before this +// function is called. Searches the appropriate Service table - DIAL_OUT_ISP +// or OUTGOING_WCDMA - for records named as aEntryName (which should be unique!) +// When it finds the record, it uses the record ID to set the class member iWapIspID. +// +void CMsvBIOWapAccessParser::SetWapIspEntryIdL(const TDesC& aEntryName) + { + TUint32 recId = 0; + switch (iCurrentBearerType) + { + case EWappGsmCsdBearer: + { + CCDDialOutISPRecord *dialOutRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdDialOutISPRecord)); + CleanupStack::PushL(dialOutRecord); + dialOutRecord->iRecordName.SetMaxLengthL(aEntryName.Length()); + dialOutRecord->iRecordName = aEntryName; + + if (dialOutRecord->FindL(*iDBSession)) + { + recId = dialOutRecord->iRecordTag.RecordId(); + } + else + { + User::Leave(KErrNotFound); + } + CleanupStack::PopAndDestroy(dialOutRecord); + } + break; + case EWappGprsBearer: + { + CCDOutgoingGprsRecord *gprsRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdOutgoingGprsRecord)); + CleanupStack::PushL(gprsRecord); + gprsRecord->iRecordName.SetMaxLengthL(aEntryName.Length()); + gprsRecord->iRecordName = aEntryName; + + if (gprsRecord->FindL(*iDBSession)) + { + recId = gprsRecord->iRecordTag.RecordId(); + } + else + { + User::Leave(KErrNotFound); + } + CleanupStack::PopAndDestroy(gprsRecord); + } + break; + default: + User::Leave(KWappErrUnexpectedValue); + } + + switch (iCurrentBearerType) + { + case EWappGsmCsdBearer: + iWapIpISPTable->iISPCommDbRecordId = recId; + break; + case EWappGprsBearer: + iWapGprsTable->iGprsCommDbRecordId = recId; + break; + default: + User::Leave(KWappErrUnexpectedValue); + break; + } + } + + +// +// SetWapIapEntryIdL - Searches the IAP database for records of the same name +// as aEntryName (which should be unique!). When it finds the +// record, it uses the record ID to set the class member iWapIapID. +// +void CMsvBIOWapAccessParser::SetWapIapEntryIdL(const TDesC& aEntryName, CWapIpBearerData& aWapIpTable) + { + CCDIAPRecord *iAPRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdIAPRecord)); + CleanupStack::PushL(iAPRecord); + iAPRecord->iRecordName.SetMaxLengthL(aEntryName.Length()); + iAPRecord->iRecordName = aEntryName; + + if (iAPRecord->FindL(*iDBSession)) + { + aWapIpTable.iIapId = iAPRecord->iRecordTag.RecordId(); + } + else + { + User::Leave(KErrNotFound); + } + CleanupStack::PopAndDestroy(iAPRecord); + } + +// +// SetWapIspEntryIdL - Searches the WAP_ACCESS_POINT table for records of the same name +// as iWapSettingsName (which should be unique!). When it finds the +// record, it uses the record ID to set the class member iWapIspID. +// +void CMsvBIOWapAccessParser::SetWapAPEntryIdL() + { + CCDWAPAccessPointRecord *wapAccessRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdWAPAccessPointRecord)); + CleanupStack::PushL(wapAccessRecord); + wapAccessRecord->iRecordName.SetMaxLengthL(iWAPSettingsName.Length()); + wapAccessRecord->iRecordName = iWAPSettingsName; + + if (wapAccessRecord->FindL(*iDBSession)) + { + iWapAccessPtID = wapAccessRecord->iRecordTag.RecordId(); // set the WAP AP table ID + } + else + { + User::Leave(KErrNotFound); + } + CleanupStack::PopAndDestroy(wapAccessRecord); + } + + +void CMsvBIOWapAccessParser::WriteMMSURLL() + { + + // check that the version of the MMS settings proxy dll is suitable + RImplInfoPtrArray list; + REComSession::ListImplementationsL(KMMSSettingsProxyInterfaceUid, list); + TInt count = list.Count(); + TBool found = EFalse; + // may be more than one implementation, look for the 'right' one + while (!found && count-- > 0) + { + if (list[count]->ImplementationUid() == KMMSSettingsProxyBaseUid && + list[count]->Version() == KMMSSettingsProxyVersionSupported) + { + // Found supported version - stop looking. + found = ETrue; + } + } + list.ResetAndDestroy(); + // if there are no implementations or the version is unsupported, then leave + if (!found) + User::Leave(KErrNotFound); + + CMMSSettingsProxyBase* settings = CMMSSettingsProxyBase::NewL(KMMSSettingsProxyBaseUid); + CleanupStack::PushL(settings); + + TSglQue settingList(_FOFF(TMMSSettingsPair, iLink)); + + // Different MMS implementations require different things. Pass all the things they might + // want and allow the implementation to use those it chooses. + + // The MMS Url + TMMSSettingsPair urlPair; + urlPair.iName.Set(KMMSUrl); + urlPair.iValue = &iMMSUrl; + settingList.AddFirst(urlPair); + + + TBuf nameStr; + nameStr.Copy(iWAPSettingsName); + if (iGsmCsdData) + { + nameStr.Append(KGsmCsdSuffix); + } + + if(iGprsData) + { + nameStr.Append(KGprsSuffix); + } + + + TUint32 id=0; + + switch (iCurrentBearerType) + { + case EWappGsmCsdBearer: + { + CCDDialOutISPRecord *dialOutISPRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdDialOutISPRecord)); + CleanupStack::PushL(dialOutISPRecord); + dialOutISPRecord->iRecordName.SetMaxLengthL(nameStr.Length()); + dialOutISPRecord->iRecordName = nameStr; + if(!dialOutISPRecord->FindL(*iDBSession)) + { + User::Leave(KErrNotFound); + } + id = dialOutISPRecord->iRecordTag.RecordId(); + CleanupStack::PopAndDestroy(dialOutISPRecord); + } + break; + case EWappGprsBearer: + { + CCDOutgoingGprsRecord *gprsRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdOutgoingGprsRecord)); + CleanupStack::PushL(gprsRecord); + gprsRecord->iRecordName.SetMaxLengthL(nameStr.Length()); + gprsRecord->iRecordName = nameStr; + + if(!gprsRecord->FindL(*iDBSession)) + { + User::Leave(KErrNotFound); + } + id = gprsRecord->iRecordTag.RecordId(); + CleanupStack::PopAndDestroy(gprsRecord); + } + break; + default: + User::Leave(KWappErrUnexpectedValue); + } + + TMMSSettingsPair commDbRecordId; + commDbRecordId.iName.Set(KCommDbRecordId); + commDbRecordId.iValue = &id; + settingList.AddFirst(commDbRecordId); + + TMMSSettingsPair msvServerEntryPair; + // 24/08/04 + // In messaging API v2, iEntry is no longer a CMsvServerEntry, but rather a CMsvEntry. + // For this reason, the following code has been changed. + // This breaks data compatability. + // CMsvEntry + msvServerEntryPair.iName.Set(KMsvEntry); + msvServerEntryPair.iValue = &iEntry; + settingList.AddFirst(msvServerEntryPair); + + settings->SetMMSValuesL(settingList); + CleanupStack::PopAndDestroy(settings); + } + + +// GetWSPTypeL - Helper function used by IP and SMS functions above. Returns appropriate enum +// +TCommsDbWapWspOption CMsvBIOWapAccessParser::GetWSPType(TDesC& aPortValue) + { + TCommsDbWapWspOption wspType; + + // Is it Connection Orientated link ? + if ( (aPortValue.CompareF(KWappPort9201)==0)|| + (aPortValue.CompareF(KWappPort9203)==0) ) + + wspType=EWapWspOptionConnectionOriented; + + else + if ( (aPortValue.CompareF(KWappPort9200)==0)|| + (aPortValue.CompareF(KWappPort9202)==0) ) + + wspType=EWapWspOptionConnectionless; + else //unknown type - so apply the default + wspType=EWapWspOptionConnectionless; + + return wspType; + } + +TBool CMsvBIOWapAccessParser::UseSecurity(TDesC& aPortValue) + { + TBool useWapSecurity; + // Is it unsecured link? + if ( (aPortValue.CompareF(KWappPort9200)==0)|| + (aPortValue.CompareF(KWappPort9201)==0) ) + useWapSecurity=EFalse; + else + if ( (aPortValue.CompareF(KWappPort9202)==0)|| + (aPortValue.CompareF(KWappPort9203)==0) ) + useWapSecurity=ETrue; + else // unknown Port value - shouldn't happen but use default anyway + useWapSecurity = EFalse; + + return useWapSecurity; + } + +// UpdateStartPageUrlL() - Searchs the WAP table for a match to the name and updates +// the WAP_START_PAGE field with the value in the URL char of the message +// + +void CMsvBIOWapAccessParser::UpdateStartPageUrlL() + { + __ASSERT_DEBUG(iWAPSettingsName.Length() != 0, Panic(EWappEmptyBuffer)); + __ASSERT_DEBUG(iUrl.Length() != 0, Panic(EWappEmptyBuffer)); + + CCDWAPAccessPointRecord *wapAPRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdWAPAccessPointRecord)); + CleanupStack::PushL(wapAPRecord); + wapAPRecord->iRecordName.SetMaxLengthL(iWAPSettingsName.Length()); + wapAPRecord->iRecordName = iWAPSettingsName; + + if(!wapAPRecord->FindL(*iDBSession)) + { + User::Leave(KErrNotFound); + } + wapAPRecord->iWAPStartPage.SetMaxLengthL(iUrl.Length()); + wapAPRecord->iWAPStartPage = iUrl; + wapAPRecord->ModifyL(*iDBSession); + CleanupStack::PopAndDestroy(wapAPRecord); + } + + +// +// IsValidTokenNameL() - Checks that the name field at the position specified is +// a valid Characteristic or Parm name +// + +TInt CMsvBIOWapAccessParser::IsValidTokenNameL(const TInt aArrayIndex) + { + TPtrC name; + + name.Set(iParsedFieldArray->At(aArrayIndex)->FieldName()); + + if ( (name.CompareF(KWappXMLversion) ==0)|| + (name.CompareF(KWappPublicID) ==0)|| + (name.CompareF(KWappCharacterSet) ==0)|| + (name.CompareF(KWappCharAddress) ==0)|| // ADDRESS Characteristic + (name.CompareF(KWappCharURL) ==0)|| // URL Characteristic + (name.CompareF(KWappCharMMSURL) ==0)|| // URL Characteristic + (name.CompareF(KWappCharName) ==0)|| // NAME Characteristic OR ATTRIBUTE + (name.CompareF(KWappCharBookmark) ==0)|| // BOOKMARK Characteristic + (name.CompareF(KWappCharID) ==0)|| // ID Characteristic + (name.CompareF(KWappURL) ==0)|| // URL Parm + (name.CompareF(KWappName) ==0)|| // NAME Parm OR ATTRIBUTE + (name.CompareF(KWappBearer) ==0)|| // BEARER Attribute + (name.CompareF(KWappProxy) ==0)|| // PROXY + (name.CompareF(KWappPort) ==0)|| // PORT + (name.CompareF(KWappProxyType) ==0)|| // PROXY_TYPE - for USSD only + (name.CompareF(KWappProxyAuthName) ==0)|| // PROXY_AUTHNAME + (name.CompareF(KWappProxyAuthSecret) ==0)|| // PROXY_AUTHSECRET + (name.CompareF(KWappProxyLoginType) ==0)|| // PROXY_LOGIN_TYPE + (name.CompareF(KWappSMSCAddress) ==0)|| // SMS_SMSC_ADDRESS + (name.CompareF(KWappUSSDCode) ==0)|| // USSD SERVICE CODE + (name.CompareF(KWappAccessPointName) ==0)|| // ACCESSPOINTNAME + (name.CompareF(KWappCsdDial) ==0)|| // CSD_DIALSTRING + (name.CompareF(KWappPPPAuthType) ==0)|| // PPP_AUTHTYPE + (name.CompareF(KWappPPPAuthName) ==0)|| // PPP_AUTHNAME + (name.CompareF(KWappPPPAuthSecret) ==0)|| // PPP_AUTHSECRET + (name.CompareF(KWappPPPLoginType) ==0)|| // PPP_LOGIN_TYPE + (name.CompareF(KWappCsdCallType) ==0)|| // CSD_CALLTYPE + (name.CompareF(KWappCsdCallSpeed) ==0)|| // CSD_CALLSPEED + (name.CompareF(KWappISP) ==0) ) // ISP_NAME + + + return KErrNone; + else + return KWappErrUnrecognised; + } + +// +// WriteBookmarksToFileL() - Store Bookmarks as an attachment file +// in the .eBM format. If the system runs out of memory while +// the bookmarks are being written to the file, the file will be +// deleted. For example, if 2 bookmarks have already been written +// to the file, and the writing of the third bookmark fails, the +// file will be deleted. Otherwise, a failure of file writing would +// need to be handled differently from memory allocation failure. +// +void CMsvBIOWapAccessParser::WriteBookmarksToFileL() +{ + + TInt numberOfItems = iBookmarkList->Count(); + + if (numberOfItems > 0) // Only create a file if there is something + //to save + { + + TFileName filePath; + + + // build the filename + TMsvId entryId = iEntry.Entry().Id(); + filePath.Num(entryId,EHex); + filePath.Append(KEBookmarkExtension); + + // Get the attachment manager and create an empty attachment file + CMsvStore* store = iEntry.EditStoreL(); + CleanupStack::PushL(store); + + MMsvAttachmentManager& manager = store->AttachmentManagerL(); + MMsvAttachmentManagerSync& managerSync = store->AttachmentManagerExtensionsL(); + RemoveAttachmentIfExistL(filePath, manager, managerSync); + CMsvAttachment* attachment = CMsvAttachment::NewL(CMsvAttachment::EMsvFile); + CleanupStack::PushL(attachment); + attachment->SetAttachmentNameL(filePath); + + RFile file; + managerSync.CreateAttachmentL(filePath, file, attachment); + CleanupStack::Pop(attachment); // ownership passed + + CleanupClosePushL(file); + + +#ifdef SYMBIAN_BOOKMARK_DATABASE + // Open the bookmark database ready to add the bookmarks + RBkDatabase bookmarkDb; + bookmarkDb.OpenL(); + CleanupClosePushL(bookmarkDb); +#endif // SYMBIAN_BOOKMARK_DATABASE + + // Stream each bookmark into the file. + // The eBookmark file must contain only 8bit ascii. + // Add a linefeed to the end of each line. + + TInt count = 0; + + while(count < numberOfItems) + { + CWappBookmark& item = *iBookmarkList->At(count); + + // Allocate enough space to hold the full bookmark entry. + + TInt length = item.Name().Length() + + item.Url().Length() + + KEBookmarkConstantChars; + + HBufC8* writeBuf = HBufC8::NewLC(length); + + TPtr8 des = writeBuf->Des(); + + des.Append(KEBookmarkItemBegin); + des.Append(KEBookmarkItemURL); + des.Append(item.Url()); + des.Append(KCRLinefeed); + des.Append(KEBookmarkItemName); + des.Append(item.Name()); + des.Append(KCRLinefeed); + des.Append(KEBookmarkType); + des.Append(KEBookmarkItemEnd); + + User::LeaveIfError(file.Write(des)); + + CleanupStack::PopAndDestroy(); + +#ifdef SYMBIAN_BOOKMARK_DATABASE + // Add the bookmark to the bookmark database + RBkBookmark bookmark = bookmarkDb.CreateBookmarkL(); + CleanupClosePushL(bookmark); + bookmark.SetTitleL(item.Name()); + // Convert Uri to 8-bit + HBufC8* bookmarkUri = HBufC8::NewLC(item.Url().Length()); + bookmarkUri->Des().Copy(item.Url()); + bookmark.SetUriL(*bookmarkUri); + CleanupStack::PopAndDestroy(2, &bookmark); // bookmarkUri, bookmark +#endif // SYMBIAN_BOOKMARK_DATABASE + + count++; + } + +#ifdef SYMBIAN_BOOKMARK_DATABASE + // Commit all the added bookmarks and close bookmark db + bookmarkDb.CommitL(); + CleanupStack::PopAndDestroy(&bookmarkDb); +#endif // SYMBIAN_BOOKMARK_DATABASE + + // File writing has completed, set the size in the attachment + TInt fileSize; + User::LeaveIfError(file.Size(fileSize)); + attachment->SetSize(fileSize); + + // commit the changes + store->CommitL(); + CleanupStack::PopAndDestroy(2, store); // file, store + + } +} +// End of function WriteBookmarksToFileL() + +void CMsvBIOWapAccessParser::RemoveAttachmentIfExistL(const TDesC& aFileName, MMsvAttachmentManager& aManager, MMsvAttachmentManagerSync& aManagerSync) + { + // If an attachment already exists with the same filename then delete + // the existing one so multiple files of the same name dont exist + for( TInt ii=0; iiAttachmentName().CompareF(aFileName) == 0 ) + { + + // We have a match, delete the attachment as we will have + // to add it as new one + aManagerSync.RemoveAttachmentL(ii); + CleanupStack::PopAndDestroy(attachmentInfo); // attachmentInfo + break; + } + CleanupStack::PopAndDestroy(attachmentInfo); + } + } + +void CMsvBIOWapAccessParser::Panic(TInt aPanic) + { + User::Panic(KWappDll, aPanic); + } + + +CWapCharsetConverter* CWapCharsetConverter::NewL(RFs& aFs, TUint aMibEnum) + { + CWapCharsetConverter* self = new (ELeave) CWapCharsetConverter(aFs); + CleanupStack::PushL(self); + self->ConstructL(aMibEnum); + CleanupStack::Pop(self); + return self; + } + +void CWapCharsetConverter::ConstructL(TInt aMibEnum) + { + iConverter = CCnvCharacterSetConverter::NewL(); + iAvailableCharsets = iConverter->CreateArrayOfCharacterSetsAvailableL(iFs); + + if(aMibEnum == 0) + { + iParseable = EFalse; + return; + } + + TInt charset = iConverter->ConvertMibEnumOfCharacterSetToIdentifierL(aMibEnum, iFs); + + if(charset==0) + { + iParseable = EFalse; + return; + } + + CCnvCharacterSetConverter::TAvailability t = iConverter->PrepareToConvertToOrFromL(charset, iFs); + iParseable = (t == CCnvCharacterSetConverter::EAvailable); + } + +void CWapCharsetConverter::ConvertL(const TDesC& aSource, TDes& aSink) + { + if(iParseable) + { + //defect fix for Inc021752 + HBufC8* des = HBufC8::NewLC(aSource.Length()); + des->Des().Copy(aSource); + + TInt state = CCnvCharacterSetConverter::KStateDefault; + + //defect fix for Inc021752 + User::LeaveIfError(iConverter->ConvertToUnicode(aSink, *des, state)); + CleanupStack::PopAndDestroy(des); + } + else + { + aSink.Copy(aSource); + } + } + +CWapCharsetConverter::~CWapCharsetConverter() + { + delete iConverter; + delete iAvailableCharsets; + }