--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/commsfwtools/preparedefaultcommsdatabase/Tools/ced/src/ced.cpp Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,1609 @@
+// Copyright (c) 2003-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:
+//
+
+/**
+ @file ced.cpp
+ @internalComponent
+*/
+
+#include <e32base.h>
+#include <e32cons.h>
+#include <e32std.h>
+#include <f32file.h>
+#include <bacline.h>
+#include "dbdef.h"
+#include "filedump.h"
+#include "input.h"
+#include "database.h"
+#include "CXMLFile.h"
+#include "CXMLContentHandler.h"
+#include "CDBSTD.H"
+#include <centralrepository.h>
+
+/** max length of path/filename/column/table name */
+#define MAX_BUFFER_LEN 256
+
+/** max length of path/filename/column/table name */
+#define MAX_ATTRIB_LEN 32
+
+/** max length of arg list to program */
+#define MAX_ARG_LEN (MAX_BUFFER_LEN * 3)
+
+/** Application name */
+#define APPLICATIONNAME _L("CommsDat Configuration Utility")
+
+/** Version Info */
+#define CEDUNVERSIONED _L("CED deliberately un-versioned") /** refer DEF092743 */
+
+#ifdef __TOOLS2__
+
+_LIT(CFG_TARGET, "ced.cfg");
+_LIT(XML_TARGET, "ced.xml");
+_LIT(LOG_TARGET, "ced.log");
+_LIT(KMeshPrefaceFile, "meshpreface1.cfg");
+
+ #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ #ifndef SYMBIAN_COMMSDAT_USE_INT_RECORD_LINKS
+ _LIT(SUPPORTED_OS, "95");
+ #else
+ _LIT(SUPPORTED_OS, "");
+ #endif
+ #else
+ #ifndef SYMBIAN_COMMSDAT_USE_INT_RECORD_LINKS
+ _LIT(SUPPORTED_OS, "94");
+ #else
+ _LIT(SUPPORTED_OS, "93");
+ #endif
+ #endif
+
+#else
+
+_LIT(CFG_TARGET, "c:\\ced.cfg");
+_LIT(XML_TARGET, "c:\\ced.xml");
+_LIT(LOG_TARGET, "c:\\ced.log");
+_LIT(KMeshPrefaceFile, "z:\\system\\data\\meshpreface1.cfg");
+_LIT(DEFAULT_SESSION_PATH, "c:\\");
+#endif
+
+
+// GLOBALS
+/** Logging */
+CFileDump* gMsg;
+/** Database access */
+DBAccess* gDB;
+/** .ini file parsing */
+CfgFile gCfg;
+/** XML file parsing */
+XMLFile* gXML;
+/** Console accessor */
+LOCAL_D CConsoleBase* gConsole;
+/** Passed in arg list */
+HBufC* gArgumentLine;
+/** Flag to indicate a successful run */
+TBool gProcessingSuccessful = ETrue;
+/** Flag to indicate whether the '-V' arg was passed in */
+TBool gValidityChecking = EFalse;
+/** flag to indicate whether the execution format is .dll or .exe*/
+TBool gIsExeDLL = EFalse;
+/** flag to indicate whether the configuration file is in XML format */
+TBool gIsXML = ETrue;
+
+#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+TBool gDeprecatedFields = EFalse;
+#endif
+//SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+
+// PROTOTYPES
+
+TInt ParseCommandLineL(TInt &aDebugOn, TBool &aOverWrite, TBool &aForceXMLProcessing, TDes &aIn, TDes &aOut, TDes &aInPref);
+TInt ParseArgument(TInt &aDebugOn, TBool &aOverWrite, TBool &aForceXMLProcessing, TDes &aIn, TDes &aOut);
+
+TInt DoProcessL(TBool aIsCfg);
+void DoDeleteL();
+
+TInt DoCfgTemplateL(TDesC &aTable, const TInt &aIndex);
+TInt DoCfgInsertsL(TDesC &aTable, const TInt &aIndex);
+
+TInt DoXMLTemplateL(const TInt &aIndex);
+TInt DoXMLInsertsL(const TInt &aIndex);
+
+TInt SetColumnDetailsL(TInt aIndex, TInt aRecordCount);
+TInt SetXMLColumnDetailsL(TInt aEntryIndex, TInt aIndex, TInt aRecCount);
+
+void DisplayMessage(TPtrC aMessage, TInt aJustTheMessage = EFalse);
+void HelpDump();
+void MainL();
+LOCAL_C void doMainL();
+
+TInt DoProcessL(TBool aIsCfg)
+/** Store the information provided in the configuration file to CommDB
+
+@param aIsCfg Whether the file to be parsed is an older style .cfg rather than .xml
+@return TInt refer only called functions
+@leave refer only called functions and dependant components
+*/
+ {
+ TRAPD(ret, gDB->InitCommsdatL());
+
+ // connect to DB manager
+ if (ret==KErrNone)
+ {
+ TVersion version = gDB->Version();
+ gMsg->Msg(_L("Database Version Maj %d Min %d Build %d"), version.iMajor, version.iMinor, version.iBuild);
+
+ gMsg->Dbg(_L(""));
+ gMsg->Dbg(_L("Session started"));
+
+ // loop through tables
+ TInt i = 0;
+ TInt j = 0;
+ TBuf<MAX_BUFFER_LEN> table = tableArray[i];
+ TBuf<MAX_BUFFER_LEN> tempColumn;
+ TBool changed;
+
+ while (table.Compare(TPtrC(NO_MORE_RECORDS)) != 0)
+ {
+ gMsg->Msg(_L(" "));
+ gMsg->Msg(_L("%S Table"), &table);
+ // get a count of editable columns
+ j = 0;
+ tempColumn = ColumnArray[i][j];
+ while(tempColumn.Compare(TPtrC(NO_MORE_RECORDS)) != 0)
+ {
+ j++;
+ tempColumn = ColumnArray[i][j];
+ }
+ gMsg->Dbg(_L("(%d editable fields in table)"), j);
+
+ TBool commitIndividualRecords = (table.CompareC(_L("ConnectionPreferences")) == 0);
+
+ if(commitIndividualRecords)
+ {
+ // Commit any current changes
+ TInt ret = gDB->CommitTransaction();
+ if(ret != KErrNone)
+ {
+ gMsg->Msg(_L("ERROR: CommitTransaction returned err [%d]"), ret);
+ if (gValidityChecking)
+ {
+ gProcessingSuccessful = EFalse;
+ }
+ }
+ }
+ else
+ {
+ gDB->MaybeBeginTransactionL();
+ }
+ gDB->SetCommitIndividualRecords(commitIndividualRecords);
+
+ changed = EFalse;
+ //Create a recordset for the table
+ ret = KErrNone;
+ if(!commitIndividualRecords)
+ {
+ TRAP(ret, gDB->CreateOrInsertRecordL(DBAccess::ECreateNew,elementIdArray[i], 0));
+ }
+ if(ret == KErrNone)
+ {
+ if (aIsCfg?DoCfgTemplateL(table,i):DoXMLTemplateL(i))
+ {
+ gMsg->Msg(_L(" "));
+ changed = ETrue;
+ }
+
+ if (aIsCfg?DoCfgInsertsL(table, i):DoXMLInsertsL(i))
+ {
+ gMsg->Msg(_L(" "));
+ changed = ETrue;
+ }
+
+ if (changed)
+ {
+ TInt commitErr = gDB->CommitChanges();
+
+ if (commitErr == KErrNone)
+ {
+ gMsg->Msg(_L("Insert successful"));
+ }
+ else
+ {
+ gMsg->Msg(_L("Insert failed [%d ]"), commitErr);
+ if (gValidityChecking)
+ {
+ gProcessingSuccessful = EFalse;
+ }
+ }
+ }
+ else
+ {
+ gMsg->Dbg(_L("Nothing to process"));
+ }
+
+ if(gDB->CommitIndividualRecords())
+ {
+ ret = gDB->CommitChanges();
+ }
+ gDB->CloseTable();
+
+ }
+ else
+ {
+ gMsg->Dbg(_L("(Creating Record set Failed [%d ])"), ret);
+ }
+
+ i++;
+ table = tableArray[i];
+
+ }
+ ret = gDB->CommitTransaction();
+ gDB->Close();
+ }
+ else
+ {
+ gMsg->Dbg(_L("(Could not connect to Commsdat [%d ])"), ret);
+ }
+
+ return ret;
+ }
+
+void DoDeleteL()
+/** Completely erase the communications database, not used when the append flag set
+
+@return void
+@leave refer only called functions and dependant components
+*/
+ {
+ gMsg->Msg(_L("The old database will be replaced ") );
+
+ // Get a session with the central repository
+ const TUid KCDCommsRepositoryId = { 0xCCCCCC00 };
+ CRepository* storage = NULL;
+
+ TRAPD(err, storage = CRepository::NewL(KCDCommsRepositoryId));
+ if (KErrNone != err)
+ {
+ gMsg->Msg(_L("Failed to create Central Repository with ID : %x (error %d)"), KCDCommsRepositoryId, err);
+ _LIT(KCEDPanic, "CED");
+ User::Panic(KCEDPanic, KErrNotFound);
+ }
+ CleanupStack::PushL(storage);
+
+ // open transaction - if can't do this then fail.
+ User::LeaveIfError(storage->StartTransaction(CRepository::EReadWriteTransaction));
+
+ // Find everything in the database
+ RArray<TUint32> ids;
+ CleanupClosePushL(ids);
+ err = storage->FindL(0, 0, ids);
+ if(err != KErrNotFound)
+ {
+ User::LeaveIfError(err);
+ }
+
+ // delete everything in the database
+ if (ids.Count())
+ {
+ for ( TInt i = ids.Count()-1; i >=0 ; i--)
+ {
+ if( i == ids.Count()-1 || i>=10000 && i%10000==0 || i<10000 && i>= 1000 && i%1000==0 ||
+ i<1000 && i>=100 && i%100==0 || i<100 && i>=10 && i%10==0 || i<10)
+ {
+ gMsg->Msg(_L("%d"),i);
+ }
+ User::LeaveIfError(storage->Delete(ids[i]));
+ }
+ }
+
+ TUint32 aErrorId;
+ err = storage->CommitTransaction(aErrorId);
+
+ CleanupStack::PopAndDestroy(2);
+
+ if (err != KErrNone)
+ {
+ gMsg->Msg(_L("Central Repository CommitTransaction returned err [%d]"), err);
+ }
+ User::LeaveIfError(err);
+ }
+
+void MainL()
+/** Central processing unit of CED
+
+@return void
+@leave refer only called functions and dependant components
+*/
+ {
+ TInt bDebugOn = EFalse;
+ TBool bOverWrite = EFalse;
+ TBool bForceXMLProcessing = EFalse;
+
+ TBuf<MAX_BUFFER_LEN> fIn;
+ TBuf<MAX_BUFFER_LEN> fOut;
+ TBuf<MAX_BUFFER_LEN> fInPref;
+ RFs fsSession; // file system session
+
+ // connect to file system
+ User::LeaveIfError(fsSession.Connect());
+ CleanupClosePushL(fsSession);
+
+ // check command line
+ TInt valid;
+
+ if (gIsExeDLL == EFalse)
+ {
+ // exe's get arguments from the command line
+ valid = ParseCommandLineL(bDebugOn, bOverWrite, bForceXMLProcessing, fIn, fOut, fInPref);
+ }
+ else
+ {
+ // exedll'd get the parameters passed in
+ valid = ParseArgument(bDebugOn, bOverWrite, bForceXMLProcessing, fIn, fOut);
+ }
+
+ if (valid)
+ {
+ // Get the type of the input file i.e. whether it is
+ // an XML file or a CFG file
+ (fIn.FindF(_L(".XML")) != KErrNotFound)?gIsXML = ETrue:gIsXML = EFalse;
+
+ // display title
+ gConsole->Printf(_L("------------------------------------------------------------\n"));
+ gConsole->Printf(APPLICATIONNAME);
+ gConsole->Printf(_L("\n------------------------------------------------------------\n\n"));
+ gConsole->Printf(_L("CED is now processing the configuration file from [%S], \n"), &fIn);
+
+ if ( bOverWrite ) gConsole->Printf(_L("The old database will be replaced \n") );
+
+ if ( gIsXML )
+ {
+ gConsole->Printf(_L("The config file is in XML format \n") );
+ if ( bForceXMLProcessing )
+ {
+ gConsole->Printf(_L("Invalid table entry links will be allowed \n") );
+ }
+ else
+ {
+ gConsole->Printf(_L("Invalid table entry links will not be allowed \n") );
+ }
+ }
+ else
+ {
+ gConsole->Printf(_L("The config file is in CFG format \n") );
+ }
+
+ // initialise output log file
+
+#ifndef __TOOLS2__
+ // Set up the session path for WINSCW / ARMv5 incase the log file name has no path.
+ fsSession.SetSessionPath( DEFAULT_SESSION_PATH );
+#endif
+
+ gMsg = CFileDump::NewL(fsSession, fOut, TPtrC(APPLICATIONNAME),
+ TPtrC(CEDUNVERSIONED), bDebugOn, gConsole, EFalse);
+ CleanupStack::PushL(gMsg);
+
+ if (!gMsg->IsInitialised())
+ {
+ gConsole->Printf(_L("Failed to open the output log file [%S]\n"), &fOut);
+ }
+ gMsg->Msg(_L(" "));
+ gMsg->Msg(_L("===================================================="));
+ gMsg->Msg(APPLICATIONNAME);
+ gMsg->Msg(_L("===================================================="));
+ gMsg->Msg(_L(" "));
+ gMsg->Msg(_L("Processing configuration from [%S]"), &fIn);
+
+ gIsXML?gMsg->Msg(_L("The config file is in XML format ")):gMsg->Msg(_L("The config file is in CFG format ") );
+
+ if(gProcessingSuccessful)
+ {
+ gDB = new (ELeave) DBAccess(gIsXML);
+ CleanupStack::PushL(gDB);
+ gDB->CheckElementValidity(gValidityChecking);
+
+ //If the settings are not ovewritten we are appending
+ //This will take care of commdb ids
+ gDB->SetInAppendMode(!bOverWrite);
+
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ TBool isMeshCompatible(EFalse);
+
+ if (bOverWrite)
+ //The database has to be re-built...
+ {
+
+ CInputFileParser* fileParser = CInputFileParser::FactoryLC(gIsXML, fIn, gMsg);
+
+ TRAPD(leaveVal, isMeshCompatible = fileParser->IsMeshCompatibleL());
+ CleanupStack::PopAndDestroy(fileParser);
+
+ if (leaveVal == KErrNone)
+ {
+ if (!isMeshCompatible)
+ {
+ gMsg->Msg(_L("MESHINFO: Configuration file [%S] is not mesh-compatible, inserting default meshtables"), &fIn);
+
+ // Insert the new mesh related tables/records into the database.
+
+ // The preface is a .cfg file, whatever the type of the original input file.
+ //
+ if (gCfg.OpenConfigFile(fInPref))
+ {
+ if (bOverWrite)
+ {
+ DoDeleteL();
+ }
+ /**
+ create a link resolver object which resolves all of the
+ link by tag linking (Link.TableName.Id) to link by recordId
+ (TableName.RecordId).
+ This is important because there can be circular referencing
+ between tables and if these tables contain link by tag refencing
+ to each other commsDat doesn't allow to commit those tables...
+ */
+ //this object will resolve the linkByTag linking to simple linkByRecId format
+ LinkByTagResolver* resolver = LinkByTagResolver::NewLC(&gCfg, gMsg);
+
+ //set the resolver object to the gDB object
+ gDB->SetLinkByTagResolver(resolver);
+
+ //Set the iIsXML field to false as we are processing now a cfg file...
+ gDB->CfgXmlSetting() = EFalse;
+
+ //The MeshPreface file will be processed first. This is important to know since here
+ //we don't want to do any mappings...
+ gDB->SetMeshProcessing(ETrue);
+
+ DoProcessL(ETrue);
+
+ //if originally xml processing was set then set it back now...
+ gDB->CfgXmlSetting() = gIsXML;
+
+ //remove the resolver object form the gDB because it's not needed anymore
+ gDB->RemoveLinkByTagResolver();
+ CleanupStack::PopAndDestroy(resolver);
+ resolver = NULL;
+
+ gCfg.CloseConfigFile();
+ if (!gValidityChecking)
+ {
+ gProcessingSuccessful = ETrue;
+ }
+ }
+ else
+ {
+ gMsg->Error(_L("MESHERR: Configuration file [%S] could not be opened"), &fInPref);
+ gProcessingSuccessful = EFalse;
+ }
+ }
+ else
+ {
+ gMsg->Msg(_L("MESHINFO: Configuration file [%S] is mesh-compatible"), &fIn);
+ }
+ }
+ else
+ {
+ gMsg->Error(_L("MESHERR: Configuration file [%S], processing failed, reason=<%d>"), &fIn, leaveVal);
+ gProcessingSuccessful = EFalse;
+ }
+ }
+ else
+ {
+ gMsg->Msg(_L("Appending data to the DB - no need to use the meshpreface config file"));
+ }
+
+
+ if (gProcessingSuccessful)
+ {
+#endif
+ // Process the XML configuration file
+ if (gIsXML)
+ {
+ // Create the XML database
+ CXMLDatabase* xmlDb = CXMLDatabase::NewL();
+ CleanupStack::PushL(xmlDb);
+
+ gXML = new (ELeave) XMLFile;
+ CleanupStack::PushL(gXML);
+
+ if (gXML->OpenConfigFile(fsSession,fIn,xmlDb,bForceXMLProcessing, !bOverWrite))
+ {
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ if (isMeshCompatible)
+ {
+#endif
+ if (bOverWrite)
+ {
+ DoDeleteL();
+ }
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ }
+
+
+ if (isMeshCompatible)
+ {
+ gDB->SetMeshProcessing(ETrue);
+ }
+ else
+
+#endif
+ {
+ gDB->SetMeshProcessing(EFalse);
+ }
+
+ TRAPD(ret, DoProcessL(EFalse));
+ gXML->CloseConfigFile();
+
+ if (gValidityChecking && ret != KErrNone)
+ {
+ gProcessingSuccessful = EFalse;
+ }
+ }
+ else
+ {
+ gMsg->Msg(_L("ERR: A problem was encountered while processing the configuration file [%S]"), &fIn);
+ gProcessingSuccessful = EFalse;
+ }
+
+ // Cleanup
+ CleanupStack::PopAndDestroy(gXML);
+ CleanupStack::PopAndDestroy(xmlDb);
+
+ gXML=NULL;
+ xmlDb=NULL;
+ }
+ else
+ {
+ if (gCfg.OpenConfigFile(fIn))
+ {
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ if (isMeshCompatible)
+ {
+#endif
+ if (bOverWrite)
+ {
+ DoDeleteL();
+ }
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ }
+ /**
+ create a link resolver object which resolves all of the
+ link by tag linking (Link.TableName.Id) to link by recordId
+ (TableName.RecordId).
+ This is important because there can be circular referencing
+ between tables and if these tables contain link by tag refencing
+ to each other commsDat doesn't allow to commit those tables...
+ */
+ LinkByTagResolver* resolver = LinkByTagResolver::NewLC(&gCfg, gMsg);
+
+ if (isMeshCompatible)
+ {
+ //our config file is a mesh compatible one so we can use the latestVersion in the DBSession
+ gDB->SetMeshProcessing(ETrue);
+ }
+ else
+ {
+ //our config file is not a mesh compatible one so we can should the version 1_1 in the
+ //DBSession
+ gDB->SetMeshProcessing(EFalse);
+ }
+
+ gDB->SetLinkByTagResolver(resolver);
+#endif
+ TRAPD(ret, DoProcessL(ETrue));
+ gCfg.CloseConfigFile();
+
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ gDB->RemoveLinkByTagResolver();
+ CleanupStack::PopAndDestroy(resolver);
+ resolver = NULL;
+#endif
+
+ if (gValidityChecking && ret != KErrNone)
+ {
+ gProcessingSuccessful = EFalse;
+ }
+ }
+ else
+ {
+ gMsg->Msg(_L("ERR: Configuration file [%S] could not be opened"), &fIn);
+ gProcessingSuccessful = EFalse;
+ }
+ }
+
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ }
+#endif
+ CleanupStack::PopAndDestroy(gDB);
+ gDB=NULL;
+ }
+
+ gMsg->Dbg(_L(""));
+ gMsg->Dbg(_L("Session finished"));
+ gMsg->Dbg(_L(""));
+ gMsg->Msg(_L("==================="));
+
+#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+ if (gDeprecatedFields)
+ {
+ gMsg->Msg(_L("WARNING: USE OF DEPRECATED FIELDS"));
+ }
+#endif
+//SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+
+ // write our processing indicater to the log file
+ gProcessingSuccessful?gMsg->Msg(_L("SUCCESS")):gMsg->Msg(_L("ERROR"));
+
+ CleanupStack::PopAndDestroy(gMsg);
+ }
+
+ CleanupStack::PopAndDestroy(&fsSession);
+ }
+
+LOCAL_C void doMainL()
+ {
+ // allocate a gConsole
+ gConsole = Console::NewL(APPLICATIONNAME, TSize(KConsFullScreen, KConsFullScreen));
+ CleanupStack::PushL(gConsole);
+
+ // call main routine
+ MainL();
+
+ CleanupStack::PopAndDestroy(gConsole);
+ }
+
+TInt E32Main()
+ {
+ __UHEAP_MARK;
+
+ // set up trap cleanup framework
+ CTrapCleanup* theCleanup = CTrapCleanup::New();
+
+ // call main routine and trap any exceptions
+ TRAPD(ret,doMainL());
+ if(ret != KErrNone && gValidityChecking)
+ {
+ gProcessingSuccessful = EFalse;
+ }
+
+ // clean up when finished
+ delete theCleanup;
+
+ __UHEAP_MARKEND;
+
+ // Convert the boolean idea of "success" into the customary process idea of errorlevel, where zero
+ // is success and anything else designates particular kinds of failure. Specific failure reasons aren't
+ // provided, so the caller should only look for process exit != 0 to mean failure, and then examine the
+ // log to see what failed.
+ return !gProcessingSuccessful;
+ }
+
+
+TInt ParseCommandLineL(TBool &aDebugOn, TBool &aOverWrite, TBool &aForceXMLProcessing, TDes &aIn, TDes &aOut, TDes &aInPref)
+/** Parse the command line for any overriding settings from exe command line
+
+@param bDebugOn Wether to output debug messages to the log file using CFileDump::Dbg(TPtrC text, ...)
+@param bOverWrite Determines whether to append to or erase any existing databases
+@param bForceXMLProcessing Determines if invalid table entry links will be allowed
+@param fIn Path and filename of the configuration database file
+@param fOut Filename of the file to send logging too
+@return ETrue if Successful else EFalse
+*/
+ {
+ TInt valid = EFalse;
+ CCommandLineArguments *pCmd;
+ pCmd = CCommandLineArguments::NewL();
+ CleanupStack::PushL(pCmd);
+
+ // set defaults
+ aIn = XML_TARGET;
+ aOut = LOG_TARGET;
+ aInPref = KMeshPrefaceFile;
+
+ // Flags for encountering the specification
+ // of an input and an output file
+ TBool bInFound = EFalse;
+ TBool bOutFound = EFalse;
+ TBool bDatabaseSpecified = EFalse;
+
+ //By default delete old database
+ aOverWrite = ETrue;
+
+ if (pCmd)
+ {
+ TBuf<MAX_ARG_LEN> arg;
+
+ // check all arguments for switches
+ TInt i = 0;
+ while( ++i < pCmd->Count() )
+ {
+ arg = pCmd->Arg(i);
+ arg.UpperCase();
+
+ // CED will report all the failures on the end, unlike success in all the cases except missing cfg file
+ // Switch introduced because of high impact on test results and to avoid BC break
+ if ( arg.FindF(_L("-V")) != KErrNotFound )
+ {
+ gValidityChecking = ETrue;
+ continue;
+ }
+
+ //Display help
+ if ( arg.FindF(_L("-H")) != KErrNotFound )
+ {
+ HelpDump();
+ CleanupStack::Pop(pCmd);
+ delete pCmd;
+ return valid;
+ }
+
+ // Append database switch
+ if ( arg.FindF(_L("-A")) != KErrNotFound )
+ {
+ aOverWrite = EFalse;
+ continue;
+ }
+
+ // Debug switch
+ if ( arg.FindF(_L("-D")) != KErrNotFound )
+ {
+ aDebugOn = ETrue;
+ continue;
+ }
+
+ // Debug switch
+ if ( arg.FindF(_L("-M")) != KErrNotFound )
+ {
+ aInPref = pCmd->Arg(++i);
+ continue;
+ }
+
+ // Presence of invalid table entry links
+ // will not cause an error
+ if ( arg.FindF(_L("-F")) != KErrNotFound )
+ {
+ aForceXMLProcessing = ETrue;
+ continue;
+ }
+
+ // Specification of an input file
+ if ( arg.FindF(_L("-I")) != KErrNotFound )
+ {
+ if( i != pCmd->Count()-1 )
+ {
+ aIn = pCmd->Arg(++i);
+ bInFound = ETrue;
+ continue;
+ }
+ else
+ {
+ gConsole->Printf(_L("Argument missing after '-i' switch\n"));
+#ifndef __TOOLS2__
+ gConsole->Printf(_L("\nPress any key to finish"));
+ gConsole->Getch();
+#endif
+ CleanupStack::Pop(pCmd);
+ delete pCmd;
+ return valid;
+ }
+ }
+ // Specification of an output file
+ if ( arg.FindF(_L("-O")) != KErrNotFound )
+ {
+ if( i != pCmd->Count()-1 )
+ {
+ aOut = pCmd->Arg(++i);
+ bOutFound = ETrue;
+ continue;
+ }
+ else
+ gConsole->Printf(_L("Argument missing after '-o' switch\n"));
+#ifndef __TOOLS2__
+ gConsole->Printf(_L("\nPress any key to finish"));
+ gConsole->Getch();
+#endif
+ CleanupStack::Pop(pCmd);
+ delete pCmd;
+ return valid;
+ }
+#ifdef __TOOLS2__
+ // Specification of the database binary version
+ // This must be specified on the tools2 platform.
+ TBuf<16> databaseVersion;
+
+ if ( arg.FindF(_L("-B")) != KErrNotFound )
+ {
+ if( i != pCmd->Count()-1 )
+ {
+ databaseVersion = pCmd->Arg(++i);
+ if(databaseVersion.Compare(SUPPORTED_OS) == 0)
+ {
+ bDatabaseSpecified = ETrue;
+ continue;
+ }
+ else
+ {
+ gConsole->Printf(_L("O/S version '%S' is not supported by this version of CED"), &databaseVersion);
+ CleanupStack::Pop(pCmd);
+ delete pCmd;
+ return valid;
+ }
+ }
+ else
+ {
+ gConsole->Printf(_L("Argument missing after '-b' switch"));
+ CleanupStack::Pop(pCmd);
+ delete pCmd;
+ return valid;
+ }
+ }
+#endif
+ // No flag is supplied: first file encountered is the input
+ // file and the following one is the output file
+
+ if ( !bInFound )
+ {
+ aIn = pCmd->Arg(i);
+ bInFound = ETrue;
+ continue;
+ }
+ if ( !bOutFound )
+ {
+ aOut = pCmd->Arg(i);
+ bOutFound = ETrue;
+ continue;
+ }
+ }
+
+ if (aIn.Length() > 0)
+ valid = ETrue;
+
+ //If here then no prefered config file has been specified.
+ //Find default input file
+ if ( !bInFound )
+ {
+ RFs fs;
+ fs.Connect();
+ CleanupClosePushL(fs);
+ TUint dummy;
+
+ if(fs.Att(XML_TARGET,dummy)==KErrNone)
+ {
+ aIn = XML_TARGET;
+ }
+ else if(fs.Att(CFG_TARGET,dummy)==KErrNone)
+ {
+ aIn = CFG_TARGET;
+ }
+ else
+ {
+ gConsole->Printf(_L("No configuration files found please specify a .cfg or .xml file\n"));
+#ifndef __TOOLS2__
+ gConsole->Printf(_L("\nPress any key to finish"));
+ gConsole->Getch();
+#endif
+ valid=EFalse;
+ }
+ CleanupStack::PopAndDestroy(&fs);
+ }
+
+#ifdef __TOOLS2__
+ if ( !bDatabaseSpecified )
+ {
+ gConsole->Printf(_L("Must specify the '-b' switch\n"));
+ valid=EFalse;
+ }
+#endif
+ CleanupStack::Pop(pCmd);
+ delete pCmd;
+ }
+
+ return valid;
+}
+
+void HelpDump()
+/**
+Prints basic help information to the emulator window including command switches
+*/
+ {
+ gConsole->Printf(_L("Creates/Updates a Comms Database using an input file"));
+ gConsole->Printf(_L("\n\nCED [-a] [-d] [-f] [-i [path]filename] [-o [path]filename]"));
+ gConsole->Printf(_L("\n\n-a\tAppends the data read from the input file to the existing Comms Database."));
+ gConsole->Printf(_L("\n-d\tSwitches debug mode on giving more data in the log file."));
+ gConsole->Printf(_L("\n-f\tAllows invalid data entries. Primarily used for testing."));
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ gConsole->Printf(_L("\n-m Specifies the default mesh configuration file to CED. Defaults to reading '%S'."), &KMeshPrefaceFile);
+#endif
+ gConsole->Printf(_L("\n-v Enables validation of the configuration data while writing to the database."));
+ gConsole->Printf(_L("\n-i Specifies an input file to CED. Must be either *.xml or *.cfg. Defaults to reading '%S' or '%S'."), &CFG_TARGET, &XML_TARGET);
+ gConsole->Printf(_L("\n-o Specifies an output file for CED to log to. Defaults to '%S'."), &LOG_TARGET);
+#ifdef __TOOLS2__
+ gConsole->Printf(_L("\n-b Specifies the binary output should be compatible with this Symbian OS version.\n"));
+#endif
+#ifndef __TOOLS2__
+ gConsole->Printf(_L("\nPress any key to finish"));
+ gConsole->Getch();
+#endif
+ }
+
+TInt ParseArgument(TBool &aDebugOn, TBool &aOverWrite, TBool &aForceXMLProcessing, TDes &aIn, TDes &aOut)
+/** Parse the command line for any overriding settings from DLL call
+
+@param bDebugOn Wether to output debug messages to the log file using CFileDump::Dbg(TPtrC text, ...)
+@param bOverWrite Determines whether to append to or erase any existing databases
+@param bForceXMLProcessing Determines if invalid table entry links will be allowed
+@param fIn Path and filename of the configuration database file
+@param fOut Filename of the file to send logging too
+@return ETrue if Successful else EFalse
+*/
+ {
+ // use Tlex to decode the cmd line
+ TLex lex(gArgumentLine->Des());
+
+ // By default delete old database
+ aOverWrite = ETrue;
+
+ // get the input file
+ aIn=lex.NextToken();
+ if ( aIn.Length() == 0 )
+ aIn = XML_TARGET;
+
+ // get the output file
+ aOut = lex.NextToken();
+ if ( aOut.Length() == 0 ) // if valid potential
+ aOut = LOG_TARGET;
+
+ // get the debug switch parameters
+ if ( gArgumentLine->FindF(_L("-D")) != KErrNotFound )
+ aDebugOn = ETrue;
+
+ if ( gArgumentLine->FindF(_L("-O")) != KErrNotFound )
+ aDebugOn = ETrue;
+
+ // append switch
+ if ( gArgumentLine->FindF(_L("-A")) != KErrNotFound )
+ aOverWrite = EFalse;
+
+ // force processing of XML file even in the
+ // presence of invalid table entry links
+ if ( gArgumentLine->FindF(_L("-F")) != KErrNotFound )
+ aForceXMLProcessing = ETrue;
+
+ delete gArgumentLine;
+
+ return ETrue;
+ }
+
+LOCAL_C TInt ProcessCfgDataL(TDesC &aTable,const TInt &aIndex)
+/** Process old style .cfg database file
+
+@param aTable Name of the entry being processed
+@param aIndex Counted table number being processed
+@return ETrue if Successful else EFalse
+*/
+ {
+ TInt recordsInserted(0);
+ TInt fatalErr(KErrNone);
+ TBool firstRec(ETrue);
+ TInt valid(KErrNotReady);
+
+ _LIT(KConnectionPrefTableName, "ConnectionPreferences");
+ while(fatalErr == KErrNone && (firstRec || gCfg.StepToNextBlock()))
+ {
+ if (!firstRec)
+ {
+ gMsg->Msg(_L(" ")); // blank line between records
+ }
+
+ if(gDB->CommitIndividualRecords())
+ {
+ gDB->CreateOrInsertRecordL(firstRec? DBAccess::ECreateNew: DBAccess::ECreateInsert,elementIdArray[aIndex], 0);
+ }
+ firstRec = EFalse;
+
+ TInt value = recordsInserted + 1;
+ TPtrC idText;
+ _LIT(KCommDbIDTag, "COMMDB_ID ");
+ valid = gCfg.GetSetting(KCommDbIDTag, idText);
+ if (valid == KErrNone)
+ {
+ TLex lex(idText);
+ if(lex.Val(value) != KErrNone)
+ {
+ gMsg->Dbg(_L("Missing COMMDB_ID - defaulting to record count"));
+ }
+ }
+ gDB->CreateOrInsertRecordL(DBAccess::EInsert, 0, value);
+
+ // find out how many fields we are expecting in this insert
+ TPtrC result = NO_MORE_RECORDS;
+ TInt iValue;
+ valid = gCfg.GetSetting(FIELD_COUNT, result);
+ if (valid == KErrNone)
+ {
+ TLex iResult = result;
+ iValue = 0;
+ if (iResult.Val(iValue) == KErrNone)
+ gDB->SetFieldCount(iValue);
+ }
+
+ //Write column info
+ TInt err = SetColumnDetailsL(aIndex, recordsInserted + 1);
+ iValue = gDB->GetFieldCount(); //If Recordname was not supplied, SetColumnDetailsL fn would have added the misisng name..so refresh he actual field count
+
+ if(err == KErrNone)
+ {
+ if(gDB->GetActualFieldCount() != iValue)
+ {
+ gMsg->Msg(_L(" ERR Table %S Expected [%d] values, read [%d].Field count mismatch!"), &aTable, iValue, gDB->GetActualFieldCount());
+ gDB->RemoveCurrentRecord();
+ if (gValidityChecking)
+ {
+ gProcessingSuccessful = EFalse;
+ }
+ continue; // it's not fatal
+ }
+
+ if(aTable.Compare(KConnectionPrefTableName) == 0)
+ {
+ CMDBRecordBase* dontDelete = gDB->GetCurrentRecord();
+ if(!gDB->IsConnectionPrefValid(*(static_cast<CCDConnectionPrefsRecord*>(dontDelete))))
+ {
+ fatalErr = KErrArgument; // or should we continue?
+ }
+ }
+ if(gDB->CommitIndividualRecords())
+ {
+ err = gDB->CommitChanges();
+ }
+ if(err != KErrNone)
+ {
+ gMsg->Msg(_L("Error %d inserting record #%d to %S"), err, recordsInserted + 1, &aTable);
+ if (gValidityChecking)
+ {
+ gProcessingSuccessful = EFalse;
+ }
+ }
+ else
+ {
+ recordsInserted++;
+ }
+ }
+ else if(err != KErrCancel) //to ignore cancels called by ced itself, used to process unused entries produced by older ceddumpers
+ {
+ gMsg->Msg(_L("Error %d inserting record #%d to %S"), err, recordsInserted + 1, &aTable);
+ if (gValidityChecking)
+ {
+ gProcessingSuccessful = EFalse;
+ }
+
+ gDB->RemoveRecord(recordsInserted);
+ //fatalErr = err;
+ }
+ }
+
+ return ((fatalErr == KErrNone)?recordsInserted:fatalErr);
+ }
+
+TInt DoCfgTemplateL(TDesC &aTable, const TInt &aIndex)
+/**
+Applying the templates
+
+ @param table A reference to a descriptor containing the name of a table
+ @param index Index in the Table
+ @return ETrue if Successful else EFalse
+ */
+ {
+ // look for template and load it
+ if (!gCfg.OpenTemplateBlock(aTable))
+ return EFalse;
+
+ DisplayMessage(_L("Processing template"), ETrue);
+ gDB->RecordIsTemplate(ETrue);
+
+ TInt templateRecordsInserted = ProcessCfgDataL(aTable,aIndex);
+
+ if (templateRecordsInserted > 0)
+ {
+ gMsg->Msg(_L(" "));
+ gMsg->Msg(_L("[%d] Template record(s) successfully inserted"), templateRecordsInserted);
+ }
+ else
+ {
+ gMsg->Msg(_L(" "));
+ gMsg->Msg(_L("Insert record failed Err:[%d]"), templateRecordsInserted);
+ }
+
+ return templateRecordsInserted;
+ }
+
+TInt DoCfgInsertsL(TDesC &aTable, const TInt &aIndex)
+/**
+Runs through all the steps involved in applying an insert to a particular table.
+
+ @param table A reference to a descriptor containing the name of a table
+ @param index Index in the Table
+ @return ETrue if Successful else EFalse
+ */
+ {
+
+ // look for any inserts and load the first one
+ if (!gCfg.OpenAddBlock(aTable))
+ return EFalse;
+
+ DisplayMessage(_L("Processing inserts"), ETrue);
+ gDB->RecordIsTemplate(EFalse);
+
+ TInt recordsInserted = ProcessCfgDataL(aTable,aIndex);
+
+ if (recordsInserted >= 0)
+ {
+ gMsg->Msg(_L(" "));
+ gMsg->Msg(_L("[%d] record(s) successfully inserted"), recordsInserted);
+ }
+ else
+ {
+ gMsg->Msg(_L(" "));
+ gMsg->Msg(_L("Insert record failed Err:[%d]"), recordsInserted);
+ }
+ return recordsInserted;
+ }
+
+#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+/**
+Loops through the table of deprecated columns/parameters and gives an information
+to the user question column/parameter is deprecated.
+
+ @param aIndex Index in the elementIdArray Table
+ @param aColumnName Name of the questioned column/parameter
+*/
+void VerifyDeprecatedFields(TInt aIndex, TPtrC& aColumnName)
+ {
+ TBuf<MAX_BUFFER_LEN> tempColumn;
+ TInt i = 0;
+ if (elementIdArray[aIndex] == KCDTIdOutgoingGprsRecord
+ || elementIdArray[aIndex] == KCDTIdIncomingGprsRecord )
+ {
+ tempColumn = DeprecParamArray[i];
+ while(tempColumn.Compare(TPtrC(NO_MORE_RECORDS)) != 0)
+ {
+ if (aColumnName.Compare(tempColumn) == 0 )
+ {
+ gMsg->Msg(_L(" Warning - Use of deprecated parameter [%S]"), &aColumnName);
+ gDeprecatedFields = ETrue;
+ }
+ tempColumn = DeprecParamArray[++i];
+ }
+ }
+ }
+#endif
+// SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+
+TBool IsGprsGatewayField(TInt aIndex, const TPtrC& aColumnName)
+/**
+Determine if a field being processed is the IpGateway field in OutgoingGPRS table
+
+@param aIndex index into elementIdArray[] for identifying table
+@param aColumnName descriptor identifying the field
+*/
+ {
+ return (elementIdArray[aIndex] == KCDTIdOutgoingGprsRecord && aColumnName.Compare(TPtrC(GPRS_IP_GATEWAY)) == 0);
+ }
+
+TInt SetupIpGatewayFieldDefaultL(TInt aIndex)
+/**
+Setup a safe default value for the IpGateway field in OutgoingGPRS tables. If a value has not
+been specified in the CFG or XML file, then it would ordinarily default to 0.0.0.0. However,
+this value will mean that the TCP/IP stack will not setup a default route. Consequently,
+we must setup a safe default of 0.0.0.1.
+
+@param aIndex index into elementIdArray[] for identifying the table
+*/
+ {
+ if (elementIdArray[aIndex] == KCDTIdOutgoingGprsRecord) // only for OutgoingGPRS table records !
+ {
+ // Only setup IpGateway field if it is not already present in the OutgoingGPRS template record.
+ if (!gDB->TemplateFieldPresentL(KCDTIdOutgoingGprsRecord | KCDTIdWCDMAIPGateway))
+ {
+ TPtrC setting;
+ TPtrC column;
+ _LIT(KGprsIpGateway, "0.0.0.1");
+ setting.Set(KGprsIpGateway());
+ column.Set(TPtrC(GPRS_IP_GATEWAY));
+ gMsg->Msg(_L(" NOTE [%S] set to default value of %S"), &column, &setting);
+ TInt ret = gDB->SetColAndAttribL(column, setting);
+ gDB->SetFieldCount(gDB->GetFieldCount() + 1); //field count increment by one because we added the gateway field
+ return ret;
+ }
+ }
+ return KErrNone;
+ }
+
+void HandleConnPrefWithoutDefaultIap()
+/**
+Handle special case of ConnPref record without default IAP set (empty db use case)
+*/
+ {
+ if(gDB->GetCurrentRecord()->TableId() == KCDTIdConnectionPrefsRecord)
+ {
+ CCDConnectionPrefsRecord* connPref = static_cast<CCDConnectionPrefsRecord*>(gDB->GetCurrentRecord());
+ if(!(connPref->iDefaultIAP.ElementId() & KCDChangedFlag))
+ {
+ connPref->iDefaultIAP = 0;
+ }
+ }
+ }
+
+TInt SetColumnDetailsL(TInt aIndex, TInt aRecordCount)
+/**
+Loops through all the columns of a particular table. If any of the columns match the setting
+in the log file, it is stored, along with the value to write into this field.
+
+@param aTable A reference to a descriptor containing the name of a table
+@param aIndex Index in the Table
+@param aRecCnt Index of the Record in the table
+@return ETrue if Successful else EFalse
+*/
+ {
+
+ static TBuf<MAX_BUFFER_LEN> tempColumn;
+ TPtrC column;
+ TPtrC setting;
+ TInt valid(KErrNone);
+ TInt i = 0;
+ tempColumn = ColumnArray[aIndex][i];
+ TInt fieldValueRead(KErrNone);
+ TBool gprsGatewayFieldIsSet = EFalse; // whether IpGateway field in OutgoingGPRS table record has been set
+
+ // loop through columns of table
+ while( (valid==KErrNone) && (tempColumn.Compare(TPtrC(NO_MORE_RECORDS)) != 0))
+ {
+ // get a column from the config file
+ gMsg->Dbg(_L(" Looking for [%S]"), &tempColumn);
+ // set the read value to the column
+ fieldValueRead = gCfg.GetSetting(tempColumn,setting);
+ if(fieldValueRead == KErrNone)
+ {
+ column.Set(tempColumn);
+
+#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+ VerifyDeprecatedFields(aIndex, column);
+#endif
+// SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+
+ // Determine whether the GPRS IP Gateway field has been set or not
+ if (IsGprsGatewayField(aIndex, column))
+ {
+ gprsGatewayFieldIsSet = ETrue;
+ }
+
+ if( (tempColumn.Compare(TPtrC(COMMDB_NAME)) == 0) &&
+ (setting.Compare(TPtrC(COMMDB_UNUSED_NAME)) == 0)
+ )
+ {
+ //this record is not valid,,,remove
+ gDB->RemoveCurrentRecord();
+ if (gValidityChecking)
+ {
+ gProcessingSuccessful = EFalse;
+ }
+ return KErrCancel;
+ }
+
+ valid = gDB->SetColAndAttribL(column,setting);
+ }
+ // decrement the field count for fields simply left blank
+ else if(fieldValueRead == KErrArgument)
+ {
+ gDB->SetFieldCount(gDB->GetFieldCount() - 1);
+ }
+ i++;
+ tempColumn = ColumnArray[aIndex][i];
+ }
+
+ //if the record is not empty and also has its name field or fieldvalue missing, set a default name, using the
+ //record id if set, else simply the record count
+ //Only do this if not entering a Template Record
+ if(gDB->GetCurrentRecord()->RecordId() != KCDDefaultRecord &&
+ ((!gDB->IsNameSet() && gDB->GetActualFieldCount()) ||
+ (!gDB->IsNameSet() && KErrArgument)) )
+ {
+ _LIT(KNameTemplate, "DefaultRecordName-%d");
+ TBuf<MAX_BUFFER_LEN> recordName;
+ TInt recId = gDB->GetCurrentRecord()->RecordId();
+ recordName.Format(KNameTemplate, recId? recId: aRecordCount);
+ column.Set(TPtrC(COMMDB_NAME));
+ setting.Set(TPtrC(recordName));
+ valid = gDB->SetColAndAttribL(column,setting);
+ gDB->SetFieldCount(gDB->GetFieldCount() + 1); //field count increment by one because we added the missing name
+ }
+
+ if (valid == KErrNone && !gprsGatewayFieldIsSet)
+ {
+ // If required, setup a suitable default value for IpGateway field in OutgoingGPRS table records
+ valid = SetupIpGatewayFieldDefaultL(aIndex);
+ }
+
+ // Handle special case of ConnPref record without default IAP set (empty db use case)
+ HandleConnPrefWithoutDefaultIap();
+
+ return valid;
+ }
+
+LOCAL_C TInt ProcessXmlDataL(TBool aIsTemplate,const TInt &aIndex)
+/** Runs through all the steps involved in applying an insert to a particular table
+ (for the XML configuration file)
+
+@param aIsTemplate Wether the entry being processed is a template or add entry
+@param aIndex Counted table number being processed
+@return Number of successfully inserted records
+*/
+ {
+ TBuf<MAX_BUFFER_LEN> xmlTableName = xmlTableArray[aIndex];
+ xmlTableName.Append(_L("Table"));
+
+ // look for template
+ TInt startIndex = gXML->GetStartingIndex(xmlTableName);
+ TInt lastIndex = gXML->GetLastIndex(xmlTableName);
+
+ if(startIndex == -1 || lastIndex == -1)
+ return EFalse;
+
+ if(aIsTemplate)
+ {
+ DisplayMessage(_L("Processing template"), ETrue);
+ gDB->RecordIsTemplate(ETrue);
+ }
+ else
+ {
+ DisplayMessage(_L("Processing inserts"), ETrue);
+ gDB->RecordIsTemplate(EFalse);
+ }
+
+ TInt recordsInserted(0);
+ TInt ret(KErrNone);
+
+ for(TInt iEntryIndex = startIndex; iEntryIndex <= lastIndex; iEntryIndex++)
+ {
+ if(aIsTemplate)
+ {
+ if(gXML->GetOperation(iEntryIndex).Compare(_L("template")) != 0)
+ {
+ continue;
+ }
+ }
+ else
+ {
+ if(gXML->GetOperation(iEntryIndex).Compare(_L("add")) != 0)
+ {
+ continue;
+ }
+ }
+
+ gMsg->Msg(_L("Record Number: #[%d]"), gXML->GetElementRecordID(iEntryIndex));
+ if(gDB->CommitIndividualRecords())
+ {
+ gDB->CreateOrInsertRecordL(iEntryIndex == startIndex? DBAccess::ECreateNew: DBAccess::ECreateInsert,elementIdArray[aIndex], 0);
+ }
+
+ //!!!!!!!!!!!!!!!!!the record ID of the given xmlDBentry should be read here...
+
+ //gDB->CreateOrInsertRecordL(DBAccess::EInsert,0,0);
+
+ gDB->CreateOrInsertRecordL(DBAccess::EInsert,0,gXML->GetElementRecordID(iEntryIndex));
+
+ // find out how many fields we are expecting in this insert
+ TInt iValue = gXML->GetEntryNumberParameters(iEntryIndex);
+ gDB->SetFieldCount(iValue);
+
+ //Write column info
+ ret = SetXMLColumnDetailsL(iEntryIndex,aIndex,iEntryIndex - startIndex + 1);
+ /*if(ret != KErrNone)
+ return ret;*/
+
+ if(gDB->CommitIndividualRecords())
+ {
+ ret = gDB->CommitChanges();
+ }
+ if(ret != KErrNone)
+ {
+ gMsg->Msg(_L("Error %d inserting record #%d to %S"), ret, iEntryIndex - startIndex + 1, &xmlTableName);
+
+ if (gValidityChecking)
+ {
+ gProcessingSuccessful = EFalse;
+ }
+
+ gDB->RemoveRecord(gXML->GetElementRecordID(iEntryIndex)-1);
+
+ }
+ else
+ {
+ recordsInserted++;
+ }
+ }
+
+ if (recordsInserted)
+ {
+ gMsg->Msg(_L(" "));
+ gMsg->Msg(_L("[%d] record(s) successfully inserted"), recordsInserted);
+ }
+
+ return recordsInserted;
+ }
+
+
+TInt DoXMLInsertsL(const TInt &aIndex)
+/**
+Runs through all the steps involved in applying an insert to a particular table.
+
+@param index Index in the Table
+@return Number of successfully inserted records
+*/
+ {
+ return (ProcessXmlDataL(EFalse,aIndex));
+ }
+
+TInt DoXMLTemplateL(const TInt &aIndex)
+/**
+Applying the templates (for the XML configuration file)
+
+@param index Index in the Table
+@return Number of successfully inserted records
+*/
+ {
+ return (ProcessXmlDataL(ETrue,aIndex));
+ }
+
+TInt SetXMLColumnDetailsL(TInt aEntryIndex, TInt aIndex, TInt aRecCount)
+/** Loops through all the columns of a particular table. If any of the columns match the setting
+ in the log file, it is stored, along with the value to write into this field.
+
+@param aEntryIndex
+@param aIndex
+@param aRecCount
+@return True if successful else false
+*/
+ {
+ static TBuf<MAX_BUFFER_LEN> tempColumn;
+ TPtrC setting;
+ TPtrC column;
+ TInt valid(KErrNone);
+ TInt i = 0;
+ TBool gprsGatewayFieldIsSet = EFalse; // whether IpGateway field in OutgoingGPRS table record has been set
+
+ tempColumn = ColumnArray[aIndex][i];
+
+
+ // loop through columns of table
+ while( (valid==KErrNone) && tempColumn.Compare(TPtrC(NO_MORE_RECORDS)) != 0)
+ {
+ // get a column from the config file
+ gMsg->Dbg(_L(" Looking for [%S]"), &tempColumn);
+
+ if (gXML->GetSetting(aEntryIndex, tempColumn, setting))
+ {
+ column.Set(ColumnArray[aIndex][i]);
+ valid = gDB->SetColAndAttribL(column,setting);
+
+#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+ VerifyDeprecatedFields(aIndex, column);
+#endif
+// SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+
+ // Determine whether the GPRS IP Gateway field has been set or not
+ if (IsGprsGatewayField(aIndex, column))
+ {
+ gprsGatewayFieldIsSet = ETrue;
+ }
+ }
+ i++;
+ tempColumn = ColumnArray[aIndex][i];
+ }
+
+ //if the record is not empty and also has its name missing, set a default name
+ //only do this if not processing a template record
+ if(!gDB->IsNameSet() &&
+ gDB->GetActualFieldCount() &&
+ gDB->GetCurrentRecord()->RecordId() != KCDDefaultRecord)
+ {
+ _LIT(KNameTemplate, "DefaultRecordName-%d");
+ TBuf<MAX_BUFFER_LEN> recordName;
+ recordName.Format(KNameTemplate, aRecCount);
+ column.Set(TPtrC(COMMDB_NAME));
+ setting.Set(TPtrC(recordName));
+ valid = gDB->SetColAndAttribL(column,setting);
+ gDB->SetFieldCount(gDB->GetFieldCount() + 1); //field count increment by one because we added the missing name
+ }
+
+ if (valid == KErrNone && !gprsGatewayFieldIsSet)
+ {
+ // If required, setup a suitable default value for IpGateway field in OutgoingGPRS table records
+ valid = SetupIpGatewayFieldDefaultL(aIndex);
+ }
+
+ // Handle special case of ConnPref record without default IAP set (empty db use case)
+ HandleConnPrefWithoutDefaultIap();
+
+ return valid;
+ }
+
+void DisplayMessage(TPtrC aMessage, TInt aJustTheMessage)
+/**
+Writes a message to the log file, along with any associated error.
+
+@param aMessage Message to be written
+@param aJustTheMessage Output only the plain message to the log file
+*/
+ {
+ if (aJustTheMessage)
+ {
+ gMsg->Msg(_L("%S"), &aMessage);
+ }
+ else
+ {
+ if (gDB->ErrorCode() != KErrAlreadyExists && gDB->ErrorCode() != E_ALREADYEXISTS)
+ gMsg->Msg(_L(" "));
+
+ gMsg->Msg(_L(" "));
+
+ if (gDB->ErrorCode())
+ {
+ static TBuf<MAX_BUFFER_LEN> errorText;
+ errorText = gDB->ErrorText();
+
+ if (gDB->ErrorCode() == KErrAlreadyExists || gDB->ErrorCode() == E_ALREADYEXISTS)
+ gMsg->Msg(_L("WARN: %S failed: %S [%d]"), &aMessage, &errorText, gDB->ErrorCode());
+ else if (gDB->ErrorCode() < 0)
+ gMsg->Msg(_L("ERR: %S failed: %S [%d]"), &aMessage, &errorText, gDB->ErrorCode());
+ else
+ gMsg->Msg(_L("ERR: %S failed: %S"), &aMessage, &errorText);
+ }
+ else
+ {
+ gMsg->Msg(_L("ERR: %S failed"), &aMessage);
+ }
+
+ // don't fail when the record is there already
+ if (gDB->ErrorCode() != KErrAlreadyExists && gDB->ErrorCode() != E_ALREADYEXISTS)
+ {
+ gMsg->Msg(_L(" "));
+ gMsg->Msg(_L(" "));
+ gProcessingSuccessful = EFalse;
+ }
+ }
+ }
+
+
+#ifndef __TOOLS2__
+EXPORT_C TInt NewApplicationL(const TDesC& aText)
+/**
+entry point used in WINS when ced is build as a exedll
+
+@param Text Command line argument
+*/
+ {
+ // save the command line info
+ gArgumentLine=aText.AllocL();
+
+ // record that ced is running as a exe dll
+ gIsExeDLL = ETrue;
+
+ // call main
+ return E32Main();
+ }
+#endif
+
+