commsfwtools/preparedefaultcommsdatabase/Tools/ced/src/ced.cpp
changeset 0 dfb7c4ff071f
child 21 07656293a99c
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file ced.cpp
       
    18  @internalComponent
       
    19 */
       
    20 
       
    21 #include <e32base.h>
       
    22 #include <e32cons.h>
       
    23 #include <e32std.h>
       
    24 #include <f32file.h>
       
    25 #include <bacline.h>
       
    26 #include "dbdef.h"
       
    27 #include "filedump.h"
       
    28 #include "input.h"
       
    29 #include "database.h"
       
    30 #include "CXMLFile.h"
       
    31 #include "CXMLContentHandler.h"
       
    32 #include "CDBSTD.H"
       
    33 #include <centralrepository.h>
       
    34 
       
    35 /** max length of path/filename/column/table name */
       
    36 #define MAX_BUFFER_LEN			256								
       
    37 
       
    38 /** max length of path/filename/column/table name */
       
    39 #define MAX_ATTRIB_LEN			32		
       
    40 
       
    41 /** max length of arg list to program */
       
    42 #define MAX_ARG_LEN				(MAX_BUFFER_LEN * 3)			
       
    43 
       
    44 /** Application name  */
       
    45 #define APPLICATIONNAME			_L("CommsDat Configuration Utility")
       
    46 
       
    47 /** Version Info  */
       
    48 #define CEDUNVERSIONED			_L("CED deliberately un-versioned") /** refer DEF092743 */
       
    49 
       
    50 #ifdef __TOOLS2__
       
    51 
       
    52 _LIT(CFG_TARGET, "ced.cfg");
       
    53 _LIT(XML_TARGET, "ced.xml");
       
    54 _LIT(LOG_TARGET, "ced.log");
       
    55 _LIT(KMeshPrefaceFile, "meshpreface1.cfg");
       
    56 
       
    57 	#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
    58 		#ifndef SYMBIAN_COMMSDAT_USE_INT_RECORD_LINKS
       
    59 			_LIT(SUPPORTED_OS, "95");
       
    60 		#else
       
    61 			_LIT(SUPPORTED_OS, "");
       
    62 		#endif
       
    63 	#else
       
    64 		#ifndef SYMBIAN_COMMSDAT_USE_INT_RECORD_LINKS
       
    65 			_LIT(SUPPORTED_OS, "94");
       
    66 		#else
       
    67 			_LIT(SUPPORTED_OS, "93");
       
    68 		#endif
       
    69 	#endif
       
    70 
       
    71 #else
       
    72 
       
    73 _LIT(CFG_TARGET, "c:\\ced.cfg");
       
    74 _LIT(XML_TARGET, "c:\\ced.xml");
       
    75 _LIT(LOG_TARGET, "c:\\ced.log");
       
    76 _LIT(KMeshPrefaceFile, "z:\\system\\data\\meshpreface1.cfg");
       
    77 _LIT(DEFAULT_SESSION_PATH, "c:\\");
       
    78 #endif
       
    79 
       
    80 
       
    81 // GLOBALS
       
    82 /** Logging  */
       
    83 CFileDump* gMsg;	
       
    84 /** Database access */	
       
    85 DBAccess* gDB;
       
    86 /** .ini file parsing */
       
    87 CfgFile gCfg;
       
    88 /** XML file parsing */		
       
    89 XMLFile* gXML;
       
    90 /** Console accessor */		
       
    91 LOCAL_D CConsoleBase* gConsole;
       
    92 /** Passed in arg list */		
       
    93 HBufC* gArgumentLine;
       
    94 /** Flag to indicate a successful run */
       
    95 TBool gProcessingSuccessful = ETrue;
       
    96 /** Flag to indicate whether the '-V' arg was passed in */
       
    97 TBool gValidityChecking = EFalse;
       
    98 /** flag to indicate whether the execution format is .dll or .exe*/
       
    99 TBool gIsExeDLL = EFalse;
       
   100 /** flag to indicate whether the configuration file is in XML format */
       
   101 TBool gIsXML = ETrue; 
       
   102 
       
   103 #ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
       
   104 TBool gDeprecatedFields = EFalse;
       
   105 #endif
       
   106 //SYMBIAN_NETWORKING_3GPPDEFAULTQOS
       
   107 
       
   108 // PROTOTYPES
       
   109 
       
   110 TInt ParseCommandLineL(TInt &aDebugOn, TBool &aOverWrite, TBool &aForceXMLProcessing, TDes &aIn, TDes &aOut, TDes &aInPref);
       
   111 TInt ParseArgument(TInt &aDebugOn, TBool &aOverWrite, TBool &aForceXMLProcessing, TDes &aIn, TDes &aOut);
       
   112 
       
   113 TInt DoProcessL(TBool aIsCfg);
       
   114 void DoDeleteL();
       
   115 
       
   116 TInt DoCfgTemplateL(TDesC &aTable, const TInt &aIndex);
       
   117 TInt DoCfgInsertsL(TDesC &aTable, const TInt &aIndex);
       
   118 
       
   119 TInt DoXMLTemplateL(const TInt &aIndex);
       
   120 TInt DoXMLInsertsL(const TInt &aIndex);
       
   121 
       
   122 TInt SetColumnDetailsL(TInt aIndex, TInt aRecordCount);
       
   123 TInt SetXMLColumnDetailsL(TInt aEntryIndex, TInt aIndex, TInt aRecCount);
       
   124 
       
   125 void DisplayMessage(TPtrC aMessage, TInt aJustTheMessage = EFalse);
       
   126 void HelpDump();
       
   127 void MainL();
       
   128 LOCAL_C void doMainL();
       
   129 
       
   130 TInt DoProcessL(TBool aIsCfg)
       
   131 /** Store the information provided in the configuration file to CommDB
       
   132 
       
   133 @param aIsCfg Whether the file to be parsed is an older style .cfg rather than .xml
       
   134 @return TInt refer only called functions
       
   135 @leave refer only called functions and dependant components
       
   136 */
       
   137 	{
       
   138 	TRAPD(ret, gDB->InitCommsdatL());
       
   139 
       
   140 	// connect to DB manager
       
   141 	if (ret==KErrNone)
       
   142 		{
       
   143 		TVersion version = gDB->Version();
       
   144 		gMsg->Msg(_L("Database Version Maj %d Min %d Build %d"), version.iMajor, version.iMinor, version.iBuild);
       
   145 		
       
   146 		gMsg->Dbg(_L(""));
       
   147 		gMsg->Dbg(_L("Session started"));
       
   148 		
       
   149 		// loop through tables
       
   150 		TInt i = 0;
       
   151 		TInt j = 0;
       
   152 		TBuf<MAX_BUFFER_LEN> table = tableArray[i];
       
   153 		TBuf<MAX_BUFFER_LEN> tempColumn;
       
   154 		TBool changed;
       
   155 		
       
   156 		while (table.Compare(TPtrC(NO_MORE_RECORDS)) != 0)
       
   157 			{
       
   158 			gMsg->Msg(_L(" "));
       
   159 			gMsg->Msg(_L("%S Table"), &table);
       
   160 			// get a count of editable columns
       
   161 			j = 0;
       
   162 			tempColumn = ColumnArray[i][j];
       
   163 			while(tempColumn.Compare(TPtrC(NO_MORE_RECORDS)) != 0)
       
   164 				{
       
   165 				j++;
       
   166 				tempColumn = ColumnArray[i][j];
       
   167 				}
       
   168 			gMsg->Dbg(_L("(%d editable fields in table)"), j);
       
   169 			
       
   170 			TBool commitIndividualRecords = (table.CompareC(_L("ConnectionPreferences")) == 0);
       
   171 			
       
   172 			if(commitIndividualRecords)
       
   173 				{
       
   174 				// Commit any current changes
       
   175 				TInt ret = gDB->CommitTransaction();
       
   176 				if(ret != KErrNone)
       
   177 					{
       
   178 					gMsg->Msg(_L("ERROR: CommitTransaction returned err [%d]"), ret);
       
   179 					if (gValidityChecking) 
       
   180 						{
       
   181 						gProcessingSuccessful = EFalse;
       
   182 						}
       
   183 					}
       
   184 				}
       
   185 			else
       
   186 				{
       
   187 				gDB->MaybeBeginTransactionL();
       
   188 				}
       
   189 			gDB->SetCommitIndividualRecords(commitIndividualRecords);
       
   190 		
       
   191 			changed = EFalse;			
       
   192 			//Create a recordset for the table
       
   193 			ret = KErrNone;
       
   194 			if(!commitIndividualRecords)
       
   195 				{
       
   196 				TRAP(ret, gDB->CreateOrInsertRecordL(DBAccess::ECreateNew,elementIdArray[i], 0));			
       
   197 				}
       
   198 			if(ret == KErrNone)
       
   199 				{
       
   200 				if (aIsCfg?DoCfgTemplateL(table,i):DoXMLTemplateL(i))	
       
   201 					{
       
   202 					gMsg->Msg(_L(" "));
       
   203 					changed = ETrue;
       
   204 					}					
       
   205 				
       
   206 				if (aIsCfg?DoCfgInsertsL(table, i):DoXMLInsertsL(i))
       
   207 					{
       
   208 					gMsg->Msg(_L(" "));
       
   209 					changed = ETrue;
       
   210 					}				
       
   211 				
       
   212 				if (changed)
       
   213 					{
       
   214 					TInt  commitErr = gDB->CommitChanges();
       
   215 
       
   216 					if (commitErr == KErrNone)
       
   217 						{
       
   218 						gMsg->Msg(_L("Insert successful"));
       
   219 						}
       
   220 					else
       
   221 						{
       
   222 						gMsg->Msg(_L("Insert failed [%d ]"), commitErr);
       
   223 						if (gValidityChecking) 
       
   224 							{
       
   225 							gProcessingSuccessful = EFalse;
       
   226 							}
       
   227 						}
       
   228 					}	
       
   229 				else
       
   230 					{
       
   231 					gMsg->Dbg(_L("Nothing to process"));	
       
   232 					}
       
   233 				
       
   234 				if(gDB->CommitIndividualRecords())
       
   235 					{
       
   236 					ret = gDB->CommitChanges();
       
   237 					}
       
   238 					gDB->CloseTable();				
       
   239 
       
   240 				}
       
   241 			else
       
   242 				{
       
   243 				gMsg->Dbg(_L("(Creating Record set Failed [%d ])"), ret);	
       
   244 				}
       
   245 			
       
   246 			i++;
       
   247 			table = tableArray[i];
       
   248 			
       
   249 			}
       
   250 		ret = gDB->CommitTransaction();
       
   251 		gDB->Close();
       
   252 		}
       
   253 	else
       
   254 		{
       
   255 		gMsg->Dbg(_L("(Could not connect to Commsdat [%d ])"), ret);
       
   256 		}	
       
   257 	
       
   258 	return ret;
       
   259 	}
       
   260 
       
   261 void DoDeleteL()
       
   262 /** Completely erase the communications database, not used when the append flag set
       
   263 
       
   264 @return void
       
   265 @leave refer only called functions and dependant components
       
   266 */
       
   267 	{
       
   268 	gMsg->Msg(_L("The old database will be replaced ") );
       
   269 			
       
   270 	// Get a session with the central repository
       
   271 	const TUid KCDCommsRepositoryId = { 0xCCCCCC00 };
       
   272 	CRepository*  storage = NULL;
       
   273 
       
   274 	TRAPD(err, storage = CRepository::NewL(KCDCommsRepositoryId));
       
   275 	if (KErrNone != err)
       
   276 		{
       
   277 		gMsg->Msg(_L("Failed to create Central Repository with ID : %x   (error %d)"), KCDCommsRepositoryId, err);
       
   278 		_LIT(KCEDPanic, "CED");
       
   279 		User::Panic(KCEDPanic, KErrNotFound);
       
   280 		}
       
   281 	CleanupStack::PushL(storage);
       
   282 	
       
   283     // open transaction - if can't do this then fail.
       
   284     User::LeaveIfError(storage->StartTransaction(CRepository::EReadWriteTransaction));
       
   285 
       
   286 	// Find everything in the database
       
   287 	RArray<TUint32> ids;
       
   288     CleanupClosePushL(ids);
       
   289 	err = storage->FindL(0, 0, ids);
       
   290 	if(err != KErrNotFound)
       
   291 		{
       
   292 		User::LeaveIfError(err);
       
   293 		}
       
   294 	
       
   295 	// delete everything in the database
       
   296 	if (ids.Count())
       
   297 		{
       
   298 		for ( TInt i = ids.Count()-1; i >=0 ; i--)
       
   299 			{
       
   300 			if( i == ids.Count()-1 || i>=10000 && i%10000==0 || i<10000 && i>= 1000 && i%1000==0 ||
       
   301 				i<1000 && i>=100 && i%100==0 || i<100 && i>=10 && i%10==0 || i<10)
       
   302 				{
       
   303 				gMsg->Msg(_L("%d"),i);
       
   304 				}
       
   305 			User::LeaveIfError(storage->Delete(ids[i]));
       
   306 			}
       
   307 		}
       
   308 	
       
   309 	TUint32 aErrorId;
       
   310 	err = storage->CommitTransaction(aErrorId);
       
   311 
       
   312 	CleanupStack::PopAndDestroy(2);
       
   313 	
       
   314 	if (err != KErrNone)
       
   315 		{
       
   316 		gMsg->Msg(_L("Central Repository CommitTransaction returned err [%d]"), err);
       
   317 		}	
       
   318 	User::LeaveIfError(err);	
       
   319 	}
       
   320 
       
   321 void MainL()
       
   322 /** Central processing unit of CED
       
   323 
       
   324 @return void
       
   325 @leave refer only called functions and dependant components
       
   326 */
       
   327 	{
       
   328 	TInt bDebugOn = EFalse;
       
   329 	TBool bOverWrite = EFalse;
       
   330 	TBool bForceXMLProcessing = EFalse;
       
   331 	
       
   332 	TBuf<MAX_BUFFER_LEN> fIn;
       
   333 	TBuf<MAX_BUFFER_LEN> fOut;
       
   334 	TBuf<MAX_BUFFER_LEN> fInPref;
       
   335 	RFs fsSession;		// file system session
       
   336 	
       
   337 	// connect to file system
       
   338 	User::LeaveIfError(fsSession.Connect());
       
   339 	CleanupClosePushL(fsSession);
       
   340 	
       
   341 	// check command line
       
   342 	TInt valid;
       
   343 	
       
   344 	if (gIsExeDLL == EFalse)
       
   345 		{
       
   346 		// exe's get arguments from the command line
       
   347 		valid = ParseCommandLineL(bDebugOn, bOverWrite, bForceXMLProcessing, fIn, fOut, fInPref);
       
   348 		}
       
   349 	else
       
   350 		{
       
   351 		// exedll'd get the parameters passed in 
       
   352 		valid = ParseArgument(bDebugOn, bOverWrite, bForceXMLProcessing, fIn, fOut);
       
   353 		}
       
   354 	
       
   355 	if (valid)
       
   356 		{					
       
   357 		// Get the type of the input file i.e. whether it is
       
   358 		// an XML file or a CFG file
       
   359 		(fIn.FindF(_L(".XML")) != KErrNotFound)?gIsXML = ETrue:gIsXML = EFalse;
       
   360 		
       
   361 		// display title
       
   362 		gConsole->Printf(_L("------------------------------------------------------------\n"));
       
   363 		gConsole->Printf(APPLICATIONNAME);
       
   364 		gConsole->Printf(_L("\n------------------------------------------------------------\n\n"));
       
   365 		gConsole->Printf(_L("CED is now processing the configuration file from [%S], \n"), &fIn);
       
   366 		
       
   367 		if ( bOverWrite )	gConsole->Printf(_L("The old database will be replaced \n") );
       
   368 		
       
   369 		if ( gIsXML )
       
   370 			{
       
   371 			gConsole->Printf(_L("The config file is in XML format \n") );
       
   372 			if ( bForceXMLProcessing )
       
   373 				{
       
   374 				gConsole->Printf(_L("Invalid table entry links will be allowed \n") );
       
   375 				}
       
   376 			else
       
   377 				{
       
   378 				gConsole->Printf(_L("Invalid table entry links will not be allowed \n") );
       
   379 				}
       
   380 			}
       
   381 		else
       
   382 			{
       
   383 			gConsole->Printf(_L("The config file is in CFG format \n") );
       
   384 			}
       
   385 		
       
   386 		// initialise output log file
       
   387 
       
   388 #ifndef __TOOLS2__
       
   389 		// Set up the session path for WINSCW / ARMv5 incase the log file name has no path.
       
   390 		fsSession.SetSessionPath( DEFAULT_SESSION_PATH );
       
   391 #endif
       
   392 
       
   393 		gMsg = CFileDump::NewL(fsSession, fOut, TPtrC(APPLICATIONNAME),
       
   394 								TPtrC(CEDUNVERSIONED), bDebugOn, gConsole, EFalse);
       
   395 		CleanupStack::PushL(gMsg);
       
   396 
       
   397 		if (!gMsg->IsInitialised())
       
   398 			{
       
   399 			gConsole->Printf(_L("Failed to open the output log file [%S]\n"), &fOut);
       
   400 			}
       
   401 		gMsg->Msg(_L(" "));
       
   402 		gMsg->Msg(_L("===================================================="));
       
   403 		gMsg->Msg(APPLICATIONNAME);
       
   404 		gMsg->Msg(_L("===================================================="));
       
   405 		gMsg->Msg(_L(" "));
       
   406 		gMsg->Msg(_L("Processing configuration from [%S]"), &fIn);
       
   407 		
       
   408 		gIsXML?gMsg->Msg(_L("The config file is in XML format ")):gMsg->Msg(_L("The config file is in CFG format ") );			
       
   409 		
       
   410 		if(gProcessingSuccessful)
       
   411 			{
       
   412 			gDB = new (ELeave) DBAccess(gIsXML);
       
   413 			CleanupStack::PushL(gDB);
       
   414 			gDB->CheckElementValidity(gValidityChecking);
       
   415 
       
   416 	        //If the settings are not ovewritten we are appending
       
   417 		    //This will take care of commdb ids
       
   418 		    gDB->SetInAppendMode(!bOverWrite);
       
   419 
       
   420 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   421             TBool isMeshCompatible(EFalse);
       
   422                         
       
   423             if (bOverWrite)
       
   424             //The database has to be re-built...
       
   425                 {
       
   426                 
       
   427                 CInputFileParser* fileParser = CInputFileParser::FactoryLC(gIsXML, fIn, gMsg);
       
   428 
       
   429                 TRAPD(leaveVal, isMeshCompatible = fileParser->IsMeshCompatibleL());
       
   430                 CleanupStack::PopAndDestroy(fileParser);
       
   431 
       
   432                 if (leaveVal == KErrNone)
       
   433                     {
       
   434                     if (!isMeshCompatible)
       
   435                         {
       
   436         				gMsg->Msg(_L("MESHINFO: Configuration file [%S] is not mesh-compatible, inserting default meshtables"), &fIn);
       
   437 
       
   438                         // Insert the new mesh related tables/records into the database.
       
   439 
       
   440                         // The preface is a .cfg file, whatever the type of the original input file.
       
   441                         //
       
   442     			        if (gCfg.OpenConfigFile(fInPref))
       
   443     				        {
       
   444     						if (bOverWrite)
       
   445     							{
       
   446     				            DoDeleteL();
       
   447     							}
       
   448                             /**
       
   449                               create a link resolver object which resolves all of the
       
   450                               link by tag linking (Link.TableName.Id) to link by recordId
       
   451                               (TableName.RecordId).
       
   452                               This is important because there can be circular referencing
       
   453                               between tables and if these tables contain link by tag refencing
       
   454                               to each other commsDat doesn't allow to commit those tables...
       
   455                             */
       
   456                         	//this object will resolve the linkByTag linking to simple linkByRecId format
       
   457             				LinkByTagResolver* resolver = LinkByTagResolver::NewLC(&gCfg, gMsg);
       
   458                             
       
   459                             //set the resolver object to the gDB object
       
   460                             gDB->SetLinkByTagResolver(resolver);
       
   461                             
       
   462                             //Set the iIsXML field to false as we are processing now a cfg file...
       
   463             				gDB->CfgXmlSetting() = EFalse;
       
   464             				
       
   465             				//The MeshPreface file will be processed first. This is important to know since here
       
   466             				//we don't want to do any mappings...
       
   467             				gDB->SetMeshProcessing(ETrue); 
       
   468             				
       
   469             				DoProcessL(ETrue);
       
   470             				
       
   471             				//if originally xml processing was set then set it back now...
       
   472             				gDB->CfgXmlSetting() = gIsXML;
       
   473             				
       
   474             				//remove the resolver object form the gDB because it's not needed anymore
       
   475             				gDB->RemoveLinkByTagResolver();
       
   476             				CleanupStack::PopAndDestroy(resolver);
       
   477             				resolver = NULL;
       
   478             				
       
   479             				gCfg.CloseConfigFile();
       
   480             				if (!gValidityChecking)
       
   481             					{
       
   482             					gProcessingSuccessful = ETrue;
       
   483             					}
       
   484             				}
       
   485     			        else
       
   486     				        {
       
   487             				gMsg->Error(_L("MESHERR: Configuration file [%S] could not be opened"), &fInPref);
       
   488             				gProcessingSuccessful = EFalse;
       
   489             				}
       
   490             			}
       
   491             		else
       
   492             		    {
       
   493         				gMsg->Msg(_L("MESHINFO: Configuration file [%S] is mesh-compatible"), &fIn);
       
   494             		    }
       
   495             		}
       
   496                 else
       
   497                     {
       
   498     				gMsg->Error(_L("MESHERR: Configuration file [%S], processing failed, reason=<%d>"), &fIn, leaveVal);
       
   499     				gProcessingSuccessful = EFalse;
       
   500     				}
       
   501                 }
       
   502             else
       
   503                 {
       
   504                 gMsg->Msg(_L("Appending data to the DB - no need to use the meshpreface config file"));
       
   505                 }
       
   506             
       
   507             
       
   508             if (gProcessingSuccessful)
       
   509                 {
       
   510 #endif
       
   511 			// Process the XML configuration file
       
   512 			if (gIsXML)
       
   513 				{			    
       
   514 				// Create the XML database
       
   515 				CXMLDatabase* xmlDb = CXMLDatabase::NewL();
       
   516 				CleanupStack::PushL(xmlDb);
       
   517 				
       
   518 				gXML = new (ELeave) XMLFile;
       
   519 				CleanupStack::PushL(gXML);
       
   520 				
       
   521 				if (gXML->OpenConfigFile(fsSession,fIn,xmlDb,bForceXMLProcessing, !bOverWrite))
       
   522 					{
       
   523 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   524                     if (isMeshCompatible)
       
   525                         {
       
   526 #endif
       
   527 						if (bOverWrite)
       
   528     					    {
       
   529     					    DoDeleteL();
       
   530 							}
       
   531 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   532         				}
       
   533 
       
   534 
       
   535                     if (isMeshCompatible)
       
   536                     	{
       
   537                     	gDB->SetMeshProcessing(ETrue);
       
   538                     	}
       
   539                     else
       
   540                     	
       
   541 #endif
       
   542 						{
       
   543                     	gDB->SetMeshProcessing(EFalse);
       
   544                     	}
       
   545                     
       
   546 					TRAPD(ret, DoProcessL(EFalse));
       
   547                     gXML->CloseConfigFile();
       
   548                     
       
   549                     if (gValidityChecking && ret != KErrNone)
       
   550                     	{
       
   551                     	gProcessingSuccessful = EFalse;
       
   552                     	}
       
   553 					}
       
   554 				else
       
   555 					{
       
   556 					gMsg->Msg(_L("ERR: A problem was encountered while processing the configuration file [%S]"), &fIn);
       
   557 					gProcessingSuccessful = EFalse;
       
   558 					}
       
   559 				
       
   560 				// Cleanup
       
   561 				CleanupStack::PopAndDestroy(gXML);
       
   562 				CleanupStack::PopAndDestroy(xmlDb);
       
   563 
       
   564 				gXML=NULL;
       
   565 				xmlDb=NULL;
       
   566 				}
       
   567 			else
       
   568 				{
       
   569 				if (gCfg.OpenConfigFile(fIn))
       
   570 					{
       
   571 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   572                     if (isMeshCompatible)
       
   573                         {
       
   574 #endif
       
   575 						if (bOverWrite)
       
   576 						    {
       
   577     					    DoDeleteL();
       
   578 							}
       
   579 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   580         				}
       
   581                     /**
       
   582                       create a link resolver object which resolves all of the
       
   583                       link by tag linking (Link.TableName.Id) to link by recordId
       
   584                       (TableName.RecordId).
       
   585                       This is important because there can be circular referencing
       
   586                       between tables and if these tables contain link by tag refencing
       
   587                       to each other commsDat doesn't allow to commit those tables...
       
   588                     */
       
   589                     LinkByTagResolver* resolver = LinkByTagResolver::NewLC(&gCfg, gMsg);
       
   590                     
       
   591                     if (isMeshCompatible)
       
   592                     	{
       
   593                     	//our config file is a mesh compatible one so we can use the latestVersion in the DBSession
       
   594                     	gDB->SetMeshProcessing(ETrue);
       
   595                     	}
       
   596                     else
       
   597                     	{
       
   598                     	//our config file is not a mesh compatible one so we can should the version 1_1 in the 
       
   599                     	//DBSession
       
   600                     	gDB->SetMeshProcessing(EFalse);
       
   601                     	}
       
   602                     
       
   603                     gDB->SetLinkByTagResolver(resolver);
       
   604 #endif
       
   605 					TRAPD(ret, DoProcessL(ETrue));
       
   606 					gCfg.CloseConfigFile();
       
   607 					
       
   608 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   609 					gDB->RemoveLinkByTagResolver();
       
   610 					CleanupStack::PopAndDestroy(resolver);
       
   611 					resolver = NULL;
       
   612 #endif
       
   613 
       
   614                     if (gValidityChecking && ret != KErrNone)
       
   615                     	{
       
   616                     	gProcessingSuccessful = EFalse;
       
   617                     	}
       
   618 					}
       
   619 				else
       
   620 					{
       
   621 					gMsg->Msg(_L("ERR: Configuration file [%S] could not be opened"), &fIn);
       
   622 					gProcessingSuccessful = EFalse;
       
   623 					}
       
   624 				}
       
   625 
       
   626 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   627                 }
       
   628 #endif
       
   629 			CleanupStack::PopAndDestroy(gDB);
       
   630 			gDB=NULL;
       
   631 			}
       
   632 		
       
   633 		gMsg->Dbg(_L(""));
       
   634 		gMsg->Dbg(_L("Session finished"));
       
   635 		gMsg->Dbg(_L(""));
       
   636 		gMsg->Msg(_L("==================="));
       
   637 		
       
   638 #ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
       
   639 		if (gDeprecatedFields)
       
   640 			{
       
   641 			gMsg->Msg(_L("WARNING: USE OF DEPRECATED FIELDS"));
       
   642 			}
       
   643 #endif
       
   644 //SYMBIAN_NETWORKING_3GPPDEFAULTQOS
       
   645 
       
   646 		// write our processing indicater to the log file
       
   647 		gProcessingSuccessful?gMsg->Msg(_L("SUCCESS")):gMsg->Msg(_L("ERROR"));
       
   648 	
       
   649 		CleanupStack::PopAndDestroy(gMsg);
       
   650 		}
       
   651 		
       
   652 	CleanupStack::PopAndDestroy(&fsSession);
       
   653 	}
       
   654 
       
   655 LOCAL_C void doMainL()
       
   656 	{
       
   657 	// allocate a gConsole
       
   658 	gConsole = Console::NewL(APPLICATIONNAME, TSize(KConsFullScreen, KConsFullScreen));
       
   659 	CleanupStack::PushL(gConsole);
       
   660 	
       
   661 	// call main routine
       
   662 	MainL();
       
   663 	
       
   664 	CleanupStack::PopAndDestroy(gConsole);
       
   665 	}
       
   666 
       
   667 TInt E32Main()
       
   668 	{	
       
   669 	__UHEAP_MARK;
       
   670 	
       
   671 	// set up trap cleanup framework
       
   672 	CTrapCleanup* theCleanup = CTrapCleanup::New();
       
   673 	
       
   674 	// call main routine and trap any exceptions
       
   675 	TRAPD(ret,doMainL());
       
   676 	if(ret != KErrNone && gValidityChecking)
       
   677 		{
       
   678 		gProcessingSuccessful = EFalse;
       
   679 		}
       
   680 	
       
   681 	// clean up when finished
       
   682 	delete theCleanup;
       
   683 	
       
   684 	__UHEAP_MARKEND;
       
   685 	
       
   686 	// Convert the boolean idea of "success" into the customary process idea of errorlevel, where zero
       
   687 	// is success and anything else designates particular kinds of failure. Specific failure reasons aren't
       
   688 	// provided, so the caller should only look for process exit != 0 to mean failure, and then examine the
       
   689 	// log to see what failed.
       
   690 	return !gProcessingSuccessful;
       
   691 	}
       
   692 
       
   693 
       
   694 TInt ParseCommandLineL(TBool &aDebugOn, TBool &aOverWrite, TBool &aForceXMLProcessing, TDes &aIn, TDes &aOut, TDes &aInPref)
       
   695 /** Parse the command line for any overriding settings from exe command line 
       
   696 
       
   697 @param bDebugOn Wether to output debug messages to the log file using CFileDump::Dbg(TPtrC text, ...)
       
   698 @param bOverWrite Determines whether to append to or erase any existing databases
       
   699 @param bForceXMLProcessing Determines if invalid table entry links will be allowed
       
   700 @param fIn Path and filename of the configuration database file
       
   701 @param fOut Filename of the file to send logging too
       
   702 @return ETrue if Successful else EFalse 
       
   703 */
       
   704 	{
       
   705 	TInt valid = EFalse;
       
   706 	CCommandLineArguments *pCmd;
       
   707 	pCmd = CCommandLineArguments::NewL();
       
   708 	CleanupStack::PushL(pCmd);
       
   709 	
       
   710 	// set defaults
       
   711 	aIn  = XML_TARGET;
       
   712 	aOut = LOG_TARGET;
       
   713 	aInPref = KMeshPrefaceFile;
       
   714 	
       
   715 	// Flags for encountering the specification
       
   716 	// of an input and an output file
       
   717 	TBool bInFound  = EFalse;
       
   718 	TBool bOutFound = EFalse;
       
   719 	TBool bDatabaseSpecified = EFalse;
       
   720 	
       
   721 	//By default delete old database 
       
   722 	aOverWrite = ETrue;
       
   723 	
       
   724 	if (pCmd)
       
   725 		{
       
   726 		TBuf<MAX_ARG_LEN> arg;
       
   727 		
       
   728 		// check all arguments for switches
       
   729 		TInt i = 0;
       
   730 		while( ++i < pCmd->Count() )
       
   731 			{
       
   732 			arg = pCmd->Arg(i);
       
   733 			arg.UpperCase();
       
   734 			
       
   735 			// CED will report all the failures on the end, unlike success in all the cases except missing cfg file
       
   736 			// Switch introduced because of high impact on test results and to avoid BC break
       
   737 			if ( arg.FindF(_L("-V")) != KErrNotFound )
       
   738 				{
       
   739 				gValidityChecking = ETrue;
       
   740 				continue;
       
   741 				}
       
   742 
       
   743 			//Display help
       
   744 			if ( arg.FindF(_L("-H")) != KErrNotFound )
       
   745 				{
       
   746 				HelpDump();
       
   747 				CleanupStack::Pop(pCmd);
       
   748 				delete pCmd;
       
   749 				return valid;
       
   750 				}
       
   751 			
       
   752 			// Append database switch
       
   753 			if ( arg.FindF(_L("-A")) != KErrNotFound )
       
   754 				{
       
   755 				aOverWrite = EFalse;
       
   756 				continue;
       
   757 				}
       
   758 			
       
   759 			// Debug switch
       
   760 			if ( arg.FindF(_L("-D")) != KErrNotFound )
       
   761 				{
       
   762 				aDebugOn = ETrue;
       
   763 				continue;
       
   764 				}
       
   765 
       
   766 			// Debug switch
       
   767 			if ( arg.FindF(_L("-M")) != KErrNotFound )
       
   768 				{
       
   769 				aInPref = pCmd->Arg(++i);
       
   770 				continue;
       
   771 				}
       
   772 			
       
   773 			// Presence of invalid table entry links
       
   774 			// will not cause an error
       
   775 			if ( arg.FindF(_L("-F")) != KErrNotFound )
       
   776 				{
       
   777 				aForceXMLProcessing = ETrue;
       
   778 				continue;
       
   779 				}
       
   780 			
       
   781 			// Specification of an input file
       
   782 			if ( arg.FindF(_L("-I")) != KErrNotFound )
       
   783 				{
       
   784 				if( i != pCmd->Count()-1 )
       
   785 					{
       
   786 					aIn = pCmd->Arg(++i);
       
   787 					bInFound = ETrue;
       
   788 					continue;
       
   789 					}
       
   790 				else
       
   791 					{
       
   792 					gConsole->Printf(_L("Argument missing after '-i' switch\n"));
       
   793 #ifndef __TOOLS2__
       
   794 					gConsole->Printf(_L("\nPress any key to finish"));
       
   795 					gConsole->Getch();
       
   796 #endif
       
   797 					CleanupStack::Pop(pCmd);
       
   798 					delete pCmd;
       
   799 					return valid;
       
   800 					}
       
   801 				}
       
   802 			// Specification of an output file
       
   803 			if ( arg.FindF(_L("-O")) != KErrNotFound )
       
   804 				{
       
   805 				if( i != pCmd->Count()-1 )
       
   806 					{
       
   807 					aOut = pCmd->Arg(++i);
       
   808 					bOutFound = ETrue;
       
   809 					continue;
       
   810 					}
       
   811 				else
       
   812 					gConsole->Printf(_L("Argument missing after '-o' switch\n"));
       
   813 #ifndef __TOOLS2__
       
   814 					gConsole->Printf(_L("\nPress any key to finish"));
       
   815 					gConsole->Getch();
       
   816 #endif
       
   817 					CleanupStack::Pop(pCmd);
       
   818 					delete pCmd;
       
   819 					return valid;
       
   820 				}
       
   821 #ifdef __TOOLS2__
       
   822 			// Specification of the database binary version
       
   823 			// This must be specified on the tools2 platform.
       
   824 			TBuf<16> databaseVersion;
       
   825 			
       
   826 			if ( arg.FindF(_L("-B")) != KErrNotFound )
       
   827 				{
       
   828 				if( i != pCmd->Count()-1 )
       
   829 					{
       
   830 					databaseVersion = pCmd->Arg(++i);
       
   831 					if(databaseVersion.Compare(SUPPORTED_OS) == 0)
       
   832 						{
       
   833 						bDatabaseSpecified = ETrue;
       
   834 						continue;
       
   835 						}
       
   836 					else
       
   837 						{
       
   838 						gConsole->Printf(_L("O/S version '%S' is not supported by this version of CED"), &databaseVersion);
       
   839 						CleanupStack::Pop(pCmd);
       
   840 						delete pCmd;
       
   841 						return valid;
       
   842 						}
       
   843 					}
       
   844 				else
       
   845 					{
       
   846 					gConsole->Printf(_L("Argument missing after '-b' switch"));
       
   847 					CleanupStack::Pop(pCmd);
       
   848 					delete pCmd;
       
   849 					return valid;
       
   850 					}
       
   851 				}
       
   852 #endif
       
   853 			// No flag is supplied: first file encountered is the input
       
   854 			// file and the following one is the output file
       
   855 			
       
   856 			if ( !bInFound )
       
   857 				{
       
   858 				aIn = pCmd->Arg(i);
       
   859 				bInFound = ETrue;
       
   860 				continue;
       
   861 				}
       
   862 			if ( !bOutFound )
       
   863 				{
       
   864 				aOut = pCmd->Arg(i);
       
   865 				bOutFound = ETrue;
       
   866 				continue;
       
   867 				}     
       
   868 			}
       
   869 		
       
   870 		if (aIn.Length() > 0)
       
   871 			valid = ETrue;
       
   872 		
       
   873 		//If here then no prefered config file has been specified.
       
   874 		//Find default input file
       
   875         if ( !bInFound )
       
   876 			{
       
   877 			RFs fs;
       
   878 			fs.Connect();
       
   879 			CleanupClosePushL(fs);
       
   880 			TUint dummy;
       
   881 			
       
   882 			if(fs.Att(XML_TARGET,dummy)==KErrNone)
       
   883 				{
       
   884 				aIn  = XML_TARGET;
       
   885 				}
       
   886 			else if(fs.Att(CFG_TARGET,dummy)==KErrNone)
       
   887 				{
       
   888 				aIn  = CFG_TARGET;
       
   889 				}
       
   890 			else
       
   891 				{
       
   892 				gConsole->Printf(_L("No configuration files found please specify a .cfg or .xml file\n"));
       
   893 #ifndef __TOOLS2__
       
   894 				gConsole->Printf(_L("\nPress any key to finish"));
       
   895 				gConsole->Getch();
       
   896 #endif
       
   897 				valid=EFalse;
       
   898 				}
       
   899 			CleanupStack::PopAndDestroy(&fs);
       
   900 			}
       
   901 		
       
   902 #ifdef __TOOLS2__
       
   903 		if ( !bDatabaseSpecified )
       
   904 			{
       
   905 			gConsole->Printf(_L("Must specify the '-b' switch\n"));
       
   906 			valid=EFalse;
       
   907 			}
       
   908 #endif
       
   909 		CleanupStack::Pop(pCmd);
       
   910 		delete pCmd;	
       
   911 	}
       
   912 	
       
   913 	return valid;
       
   914 }
       
   915 
       
   916 void HelpDump()
       
   917 /**
       
   918 Prints basic help information to the emulator window including command switches
       
   919 */
       
   920 	{
       
   921 	gConsole->Printf(_L("Creates/Updates a Comms Database using an input file"));
       
   922 	gConsole->Printf(_L("\n\nCED [-a] [-d] [-f] [-i [path]filename] [-o [path]filename]"));
       
   923 	gConsole->Printf(_L("\n\n-a\tAppends the data read from the input file to the existing Comms Database."));
       
   924 	gConsole->Printf(_L("\n-d\tSwitches debug mode on giving more data in the log file."));
       
   925 	gConsole->Printf(_L("\n-f\tAllows invalid data entries. Primarily used for testing."));
       
   926 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   927 	gConsole->Printf(_L("\n-m  Specifies the default mesh configuration file to CED. Defaults to reading '%S'."), &KMeshPrefaceFile);
       
   928 #endif
       
   929 	gConsole->Printf(_L("\n-v  Enables validation of the configuration data while writing to the database."));
       
   930 	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);
       
   931 	gConsole->Printf(_L("\n-o  Specifies an output file for CED to log to. Defaults to '%S'."), &LOG_TARGET);
       
   932 #ifdef __TOOLS2__
       
   933 	gConsole->Printf(_L("\n-b  Specifies the binary output should be compatible with this Symbian OS version.\n"));
       
   934 #endif
       
   935 #ifndef __TOOLS2__
       
   936 	gConsole->Printf(_L("\nPress any key to finish"));
       
   937 	gConsole->Getch();
       
   938 #endif
       
   939 	}
       
   940 
       
   941 TInt ParseArgument(TBool &aDebugOn, TBool &aOverWrite, TBool &aForceXMLProcessing, TDes &aIn, TDes &aOut)
       
   942 /** Parse the command line for any overriding settings from DLL call
       
   943 
       
   944 @param bDebugOn Wether to output debug messages to the log file using CFileDump::Dbg(TPtrC text, ...)
       
   945 @param bOverWrite Determines whether to append to or erase any existing databases
       
   946 @param bForceXMLProcessing Determines if invalid table entry links will be allowed
       
   947 @param fIn Path and filename of the configuration database file
       
   948 @param fOut Filename of the file to send logging too
       
   949 @return ETrue if Successful else EFalse 
       
   950 */
       
   951 	{
       
   952 	// use Tlex to decode the cmd line
       
   953 	TLex lex(gArgumentLine->Des());
       
   954 	
       
   955 	// By default delete old database 
       
   956 	aOverWrite = ETrue;
       
   957 	
       
   958 	// get the input file
       
   959 	aIn=lex.NextToken();
       
   960 	if ( aIn.Length() == 0 ) 
       
   961 		aIn = XML_TARGET;
       
   962 	
       
   963 	// get the output file
       
   964 	aOut = lex.NextToken();
       
   965 	if ( aOut.Length() == 0 ) // if valid potential 
       
   966 		aOut = LOG_TARGET;
       
   967 	
       
   968 	// get the debug switch parameters
       
   969 	if ( gArgumentLine->FindF(_L("-D")) != KErrNotFound )
       
   970 		aDebugOn = ETrue;
       
   971 	
       
   972 	if ( gArgumentLine->FindF(_L("-O")) != KErrNotFound )
       
   973 		aDebugOn = ETrue;
       
   974 	
       
   975 	// append switch
       
   976 	if ( gArgumentLine->FindF(_L("-A")) != KErrNotFound )
       
   977 		aOverWrite = EFalse;
       
   978 	
       
   979 	// force processing of XML file even in the
       
   980 	// presence of invalid table entry links
       
   981 	if ( gArgumentLine->FindF(_L("-F")) != KErrNotFound )
       
   982 		aForceXMLProcessing = ETrue;	
       
   983 	
       
   984 	delete gArgumentLine;
       
   985 	
       
   986 	return ETrue;
       
   987 	}
       
   988 
       
   989 LOCAL_C TInt ProcessCfgDataL(TDesC &aTable,const TInt &aIndex)
       
   990 /** Process old style .cfg database file 
       
   991 
       
   992 @param aTable Name of the entry being processed
       
   993 @param aIndex Counted table number being processed
       
   994 @return ETrue if Successful else EFalse 
       
   995 */
       
   996 	{
       
   997 	TInt recordsInserted(0);  
       
   998 	TInt fatalErr(KErrNone); 
       
   999 	TBool firstRec(ETrue);
       
  1000 	TInt valid(KErrNotReady);
       
  1001 	
       
  1002 	_LIT(KConnectionPrefTableName, "ConnectionPreferences");
       
  1003 	while(fatalErr == KErrNone && (firstRec || gCfg.StepToNextBlock()))
       
  1004 		{
       
  1005 		if (!firstRec)
       
  1006 			{
       
  1007 			gMsg->Msg(_L(" "));	// blank line between records
       
  1008 			}
       
  1009 
       
  1010 		if(gDB->CommitIndividualRecords())
       
  1011 			{
       
  1012  			gDB->CreateOrInsertRecordL(firstRec? DBAccess::ECreateNew: DBAccess::ECreateInsert,elementIdArray[aIndex], 0);			
       
  1013  			}
       
  1014  		firstRec = EFalse;
       
  1015  		
       
  1016 		TInt value = recordsInserted + 1;
       
  1017 		TPtrC idText;
       
  1018 		_LIT(KCommDbIDTag, "COMMDB_ID ");
       
  1019 		valid = gCfg.GetSetting(KCommDbIDTag, idText);
       
  1020 		if (valid == KErrNone)
       
  1021 			{
       
  1022 			TLex lex(idText);
       
  1023 			if(lex.Val(value) != KErrNone)
       
  1024 				{
       
  1025 				gMsg->Dbg(_L("Missing COMMDB_ID - defaulting to record count"));
       
  1026 				}
       
  1027 			}
       
  1028 		gDB->CreateOrInsertRecordL(DBAccess::EInsert, 0, value); 			
       
  1029 		
       
  1030 		// find out how many fields we are expecting in this insert
       
  1031 		TPtrC result = NO_MORE_RECORDS;
       
  1032 		TInt iValue;
       
  1033 		valid = gCfg.GetSetting(FIELD_COUNT, result);
       
  1034 		if (valid == KErrNone)
       
  1035 			{
       
  1036 			TLex iResult = result;	
       
  1037 			iValue = 0;		
       
  1038 			if (iResult.Val(iValue) == KErrNone)
       
  1039 				gDB->SetFieldCount(iValue);
       
  1040 			}
       
  1041 		
       
  1042 		//Write column info
       
  1043 		TInt err = SetColumnDetailsL(aIndex, recordsInserted + 1);
       
  1044 		iValue = gDB->GetFieldCount(); //If Recordname was not supplied, SetColumnDetailsL fn would have added the misisng name..so refresh he actual field count
       
  1045 		
       
  1046 		if(err == KErrNone)
       
  1047 			{
       
  1048 			if(gDB->GetActualFieldCount() != iValue)
       
  1049 				{
       
  1050 				gMsg->Msg(_L(" ERR Table %S Expected [%d] values, read [%d].Field count mismatch!"), &aTable, iValue, gDB->GetActualFieldCount());
       
  1051 				gDB->RemoveCurrentRecord();
       
  1052 				if (gValidityChecking) 
       
  1053 					{
       
  1054 					gProcessingSuccessful = EFalse;
       
  1055 					}
       
  1056 				continue;	// it's not fatal
       
  1057 				}
       
  1058 			
       
  1059 			if(aTable.Compare(KConnectionPrefTableName) == 0)
       
  1060 				{
       
  1061 				CMDBRecordBase* dontDelete = gDB->GetCurrentRecord();
       
  1062 				if(!gDB->IsConnectionPrefValid(*(static_cast<CCDConnectionPrefsRecord*>(dontDelete))))
       
  1063 					{
       
  1064 					fatalErr = KErrArgument;	// or should we continue?
       
  1065 					}					
       
  1066 				}
       
  1067 			if(gDB->CommitIndividualRecords())
       
  1068 				{
       
  1069 				err = gDB->CommitChanges();
       
  1070 				}
       
  1071 			if(err != KErrNone)
       
  1072 				{
       
  1073 				gMsg->Msg(_L("Error %d inserting record #%d to %S"), err, recordsInserted + 1, &aTable);
       
  1074 				if (gValidityChecking) 
       
  1075 					{
       
  1076 					gProcessingSuccessful = EFalse;
       
  1077 					}
       
  1078 	 			}
       
  1079 			else
       
  1080 	 			{
       
  1081 				recordsInserted++;
       
  1082 	 			}
       
  1083 			}
       
  1084 		else if(err != KErrCancel)	//to ignore cancels called by ced itself, used to process unused entries produced by older ceddumpers
       
  1085 			{
       
  1086 			gMsg->Msg(_L("Error %d inserting record #%d to %S"), err, recordsInserted + 1, &aTable);
       
  1087 			if (gValidityChecking) 
       
  1088 				{
       
  1089 				gProcessingSuccessful = EFalse;
       
  1090 				}
       
  1091 			
       
  1092 			gDB->RemoveRecord(recordsInserted);
       
  1093 			//fatalErr = err;
       
  1094 			}
       
  1095 		}
       
  1096 		
       
  1097 	return ((fatalErr == KErrNone)?recordsInserted:fatalErr);
       
  1098 	}
       
  1099 
       
  1100 TInt DoCfgTemplateL(TDesC &aTable, const TInt &aIndex)
       
  1101 /**
       
  1102 Applying the templates
       
  1103 
       
  1104   @param table A reference to a descriptor containing the name of a table
       
  1105   @param index Index in the Table
       
  1106   @return ETrue if Successful else EFalse 
       
  1107   */
       
  1108 	{
       
  1109 	// look for template and load it
       
  1110 	if (!gCfg.OpenTemplateBlock(aTable))
       
  1111 		return EFalse;
       
  1112 	
       
  1113 	DisplayMessage(_L("Processing template"), ETrue);
       
  1114 	gDB->RecordIsTemplate(ETrue); 	
       
  1115 	
       
  1116 	TInt templateRecordsInserted = ProcessCfgDataL(aTable,aIndex);
       
  1117 	
       
  1118 	if (templateRecordsInserted > 0)
       
  1119 		{
       
  1120 		gMsg->Msg(_L(" "));
       
  1121 		gMsg->Msg(_L("[%d] Template record(s) successfully inserted"), templateRecordsInserted);
       
  1122 		}
       
  1123 	else
       
  1124 		{
       
  1125 		gMsg->Msg(_L(" "));
       
  1126 		gMsg->Msg(_L("Insert record failed Err:[%d]"), templateRecordsInserted);
       
  1127 		}
       
  1128 	
       
  1129 	return templateRecordsInserted;
       
  1130 	}
       
  1131 
       
  1132 TInt DoCfgInsertsL(TDesC &aTable, const TInt &aIndex)
       
  1133 /**
       
  1134 Runs through all the steps involved in applying an insert to a particular table.
       
  1135 
       
  1136   @param table A reference to a descriptor containing the name of a table
       
  1137   @param index Index in the Table
       
  1138   @return ETrue if Successful else EFalse 
       
  1139   */
       
  1140 	{
       
  1141 	
       
  1142 	// look for any inserts and load the first one
       
  1143 	if (!gCfg.OpenAddBlock(aTable))
       
  1144 		return EFalse;
       
  1145 	
       
  1146 	DisplayMessage(_L("Processing inserts"), ETrue);
       
  1147 	gDB->RecordIsTemplate(EFalse); 	
       
  1148 
       
  1149 	TInt recordsInserted = ProcessCfgDataL(aTable,aIndex);
       
  1150 	
       
  1151 	if (recordsInserted >= 0)
       
  1152 		{
       
  1153 		gMsg->Msg(_L(" "));
       
  1154 		gMsg->Msg(_L("[%d] record(s) successfully inserted"), recordsInserted);
       
  1155 		}
       
  1156 	else
       
  1157 		{
       
  1158 		gMsg->Msg(_L(" "));
       
  1159 		gMsg->Msg(_L("Insert record failed Err:[%d]"), recordsInserted);
       
  1160 		}
       
  1161 	return recordsInserted;			
       
  1162 	}
       
  1163 
       
  1164 #ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
       
  1165 /**
       
  1166 Loops through the table of deprecated columns/parameters and gives an information 
       
  1167 to the user question column/parameter is deprecated. 
       
  1168 
       
  1169   @param aIndex    Index in the elementIdArray Table
       
  1170   @param aColumnName Name of the questioned column/parameter
       
  1171 */
       
  1172 void VerifyDeprecatedFields(TInt aIndex, TPtrC& aColumnName)
       
  1173 	{
       
  1174 	TBuf<MAX_BUFFER_LEN> tempColumn;
       
  1175 	TInt i = 0;
       
  1176 	if (elementIdArray[aIndex] == KCDTIdOutgoingGprsRecord 
       
  1177 		|| elementIdArray[aIndex] == KCDTIdIncomingGprsRecord )
       
  1178 		{
       
  1179 		tempColumn = DeprecParamArray[i];
       
  1180 		while(tempColumn.Compare(TPtrC(NO_MORE_RECORDS)) != 0)
       
  1181 			{
       
  1182 			if (aColumnName.Compare(tempColumn) == 0 )
       
  1183 				{
       
  1184 				gMsg->Msg(_L(" Warning - Use of deprecated parameter [%S]"), &aColumnName);
       
  1185 				gDeprecatedFields = ETrue;
       
  1186 				}
       
  1187 			tempColumn = DeprecParamArray[++i];
       
  1188 			}
       
  1189 		}
       
  1190 	}
       
  1191 #endif
       
  1192 // SYMBIAN_NETWORKING_3GPPDEFAULTQOS
       
  1193 
       
  1194 TBool IsGprsGatewayField(TInt aIndex, const TPtrC& aColumnName)
       
  1195 /**
       
  1196 Determine if a field being processed is the IpGateway field in OutgoingGPRS table
       
  1197 
       
  1198 @param aIndex index into elementIdArray[] for identifying table
       
  1199 @param aColumnName descriptor identifying the field
       
  1200 */
       
  1201 	{
       
  1202 	return (elementIdArray[aIndex] == KCDTIdOutgoingGprsRecord && aColumnName.Compare(TPtrC(GPRS_IP_GATEWAY)) == 0);
       
  1203 	}
       
  1204 
       
  1205 TInt SetupIpGatewayFieldDefaultL(TInt aIndex)
       
  1206 /**
       
  1207 Setup a safe default value for the IpGateway field in OutgoingGPRS tables.  If a value has not
       
  1208 been specified in the CFG or XML file, then it would ordinarily default to 0.0.0.0.  However,
       
  1209 this value will mean that the TCP/IP stack will not setup a default route.  Consequently,
       
  1210 we must setup a safe default of 0.0.0.1.
       
  1211 
       
  1212 @param aIndex index into elementIdArray[] for identifying the table
       
  1213 */
       
  1214 	{
       
  1215 	if (elementIdArray[aIndex] == KCDTIdOutgoingGprsRecord)	// only for OutgoingGPRS table records !
       
  1216 		{
       
  1217 		// Only setup IpGateway field if it is not already present in the OutgoingGPRS template record.
       
  1218 		if (!gDB->TemplateFieldPresentL(KCDTIdOutgoingGprsRecord | KCDTIdWCDMAIPGateway))
       
  1219 			{
       
  1220 			TPtrC setting;
       
  1221 			TPtrC column;
       
  1222 			_LIT(KGprsIpGateway, "0.0.0.1");
       
  1223 			setting.Set(KGprsIpGateway());
       
  1224 			column.Set(TPtrC(GPRS_IP_GATEWAY));
       
  1225 			gMsg->Msg(_L(" NOTE  [%S] set to default value of %S"), &column, &setting);
       
  1226 			TInt ret = gDB->SetColAndAttribL(column, setting);
       
  1227 			gDB->SetFieldCount(gDB->GetFieldCount() + 1); //field count increment by one because we added the gateway field
       
  1228 			return ret;
       
  1229 			}
       
  1230 		}
       
  1231 	return KErrNone;
       
  1232 	}
       
  1233 	
       
  1234 void HandleConnPrefWithoutDefaultIap()
       
  1235 /**
       
  1236 Handle special case of ConnPref record without default IAP set (empty db use case)
       
  1237 */
       
  1238 	{
       
  1239 	if(gDB->GetCurrentRecord()->TableId() == KCDTIdConnectionPrefsRecord)
       
  1240 		{
       
  1241 		CCDConnectionPrefsRecord* connPref = static_cast<CCDConnectionPrefsRecord*>(gDB->GetCurrentRecord());
       
  1242 		if(!(connPref->iDefaultIAP.ElementId() & KCDChangedFlag))
       
  1243 			{
       
  1244 			connPref->iDefaultIAP = 0;
       
  1245 			}
       
  1246 		}
       
  1247 	}
       
  1248 
       
  1249 TInt SetColumnDetailsL(TInt aIndex, TInt aRecordCount)
       
  1250 /**
       
  1251 Loops through all the columns of a particular table.  If any of the columns match the setting
       
  1252 in the log file, it is stored, along with the value to write into this field.
       
  1253 
       
  1254 @param aTable    A reference to a descriptor containing the name of a table
       
  1255 @param aIndex    Index in the Table
       
  1256 @param aRecCnt   Index of the Record in the table
       
  1257 @return ETrue    if Successful else EFalse 
       
  1258 */
       
  1259 	{	
       
  1260 	
       
  1261 	static TBuf<MAX_BUFFER_LEN> tempColumn;
       
  1262 	TPtrC column;
       
  1263 	TPtrC setting;
       
  1264 	TInt valid(KErrNone);
       
  1265 	TInt i = 0;
       
  1266 	tempColumn = ColumnArray[aIndex][i];
       
  1267 	TInt fieldValueRead(KErrNone);
       
  1268 	TBool gprsGatewayFieldIsSet = EFalse;		// whether IpGateway field in OutgoingGPRS table record has been set
       
  1269 
       
  1270 	// loop through columns of table
       
  1271 	while( (valid==KErrNone) && (tempColumn.Compare(TPtrC(NO_MORE_RECORDS)) != 0))
       
  1272 		{		
       
  1273 		// get a column from the config file
       
  1274 		gMsg->Dbg(_L(" Looking for [%S]"), &tempColumn);
       
  1275 		// set the read value to the column
       
  1276 		fieldValueRead = gCfg.GetSetting(tempColumn,setting);
       
  1277 		if(fieldValueRead == KErrNone)
       
  1278 			{
       
  1279 			column.Set(tempColumn);
       
  1280          	
       
  1281 #ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS			
       
  1282 			VerifyDeprecatedFields(aIndex, column);
       
  1283 #endif
       
  1284 // SYMBIAN_NETWORKING_3GPPDEFAULTQOS			
       
  1285 
       
  1286 			// Determine whether the GPRS IP Gateway field has been set or not
       
  1287 			if (IsGprsGatewayField(aIndex, column))
       
  1288 				{
       
  1289 				gprsGatewayFieldIsSet = ETrue;
       
  1290 				}
       
  1291 
       
  1292 			if( (tempColumn.Compare(TPtrC(COMMDB_NAME)) == 0) &&
       
  1293 				(setting.Compare(TPtrC(COMMDB_UNUSED_NAME)) == 0)
       
  1294 				)
       
  1295 				{
       
  1296 				//this record is not valid,,,remove
       
  1297 				gDB->RemoveCurrentRecord();
       
  1298 				if (gValidityChecking) 
       
  1299 					{
       
  1300 					gProcessingSuccessful = EFalse;
       
  1301 					}
       
  1302 				return KErrCancel;				
       
  1303 				}
       
  1304 			
       
  1305 			valid = gDB->SetColAndAttribL(column,setting);
       
  1306 			}	
       
  1307 		// decrement the field count for fields simply left blank
       
  1308 		else if(fieldValueRead == KErrArgument)
       
  1309 			{
       
  1310 			gDB->SetFieldCount(gDB->GetFieldCount() - 1);	
       
  1311 			}
       
  1312 		i++;
       
  1313 		tempColumn = ColumnArray[aIndex][i];	
       
  1314 		}
       
  1315 	
       
  1316 	//if the record is not empty and also has its name field or fieldvalue missing, set a default name, using the 
       
  1317 	//record id if set, else simply the record count
       
  1318 	//Only do this if not entering a Template Record
       
  1319     if(gDB->GetCurrentRecord()->RecordId() != KCDDefaultRecord && 
       
  1320        ((!gDB->IsNameSet() && gDB->GetActualFieldCount()) ||
       
  1321         (!gDB->IsNameSet() && KErrArgument)) )	
       
  1322 		{
       
  1323 		_LIT(KNameTemplate, "DefaultRecordName-%d");
       
  1324 		TBuf<MAX_BUFFER_LEN> recordName;
       
  1325 		TInt recId = gDB->GetCurrentRecord()->RecordId();
       
  1326 		recordName.Format(KNameTemplate, recId? recId: aRecordCount);
       
  1327 		column.Set(TPtrC(COMMDB_NAME));		
       
  1328 		setting.Set(TPtrC(recordName));	    			
       
  1329 		valid = gDB->SetColAndAttribL(column,setting);			
       
  1330 		gDB->SetFieldCount(gDB->GetFieldCount() + 1); //field count increment by one because we added the missing name
       
  1331 	    }
       
  1332 	
       
  1333 	if (valid == KErrNone && !gprsGatewayFieldIsSet)
       
  1334 		{
       
  1335 		// If required, setup a suitable default value for IpGateway field in OutgoingGPRS table records
       
  1336 		valid = SetupIpGatewayFieldDefaultL(aIndex);
       
  1337 		}
       
  1338 	
       
  1339 	// Handle special case of ConnPref record without default IAP set (empty db use case)
       
  1340 	HandleConnPrefWithoutDefaultIap();
       
  1341 
       
  1342 	return valid;
       
  1343 	}
       
  1344 
       
  1345 LOCAL_C TInt ProcessXmlDataL(TBool aIsTemplate,const TInt &aIndex)
       
  1346 /** Runs through all the steps involved in applying an insert to a particular table
       
  1347 	(for the XML configuration file) 
       
  1348 
       
  1349 @param aIsTemplate Wether the entry being processed is a template or add entry
       
  1350 @param aIndex Counted table number being processed
       
  1351 @return Number of successfully inserted records
       
  1352 */
       
  1353 	{
       
  1354 	TBuf<MAX_BUFFER_LEN> xmlTableName = xmlTableArray[aIndex];
       
  1355 	xmlTableName.Append(_L("Table"));
       
  1356 	
       
  1357 	// look for template
       
  1358 	TInt startIndex = gXML->GetStartingIndex(xmlTableName);
       
  1359 	TInt lastIndex  = gXML->GetLastIndex(xmlTableName);
       
  1360 	
       
  1361 	if(startIndex == -1 || lastIndex == -1)
       
  1362 		return EFalse;
       
  1363 	
       
  1364 	if(aIsTemplate)
       
  1365 		{
       
  1366 		DisplayMessage(_L("Processing template"), ETrue);	
       
  1367 		gDB->RecordIsTemplate(ETrue); 
       
  1368 		}
       
  1369 	else
       
  1370 		{
       
  1371 		DisplayMessage(_L("Processing inserts"), ETrue);	
       
  1372 		gDB->RecordIsTemplate(EFalse); 
       
  1373 		}
       
  1374 	
       
  1375 	TInt recordsInserted(0);
       
  1376 	TInt ret(KErrNone);
       
  1377 	
       
  1378 	for(TInt iEntryIndex = startIndex; iEntryIndex <= lastIndex; iEntryIndex++)
       
  1379 		{
       
  1380 		if(aIsTemplate)
       
  1381 			{
       
  1382 			if(gXML->GetOperation(iEntryIndex).Compare(_L("template")) != 0)
       
  1383 				{
       
  1384 				continue;	
       
  1385 				}				
       
  1386 			}
       
  1387 		else
       
  1388 			{
       
  1389 			if(gXML->GetOperation(iEntryIndex).Compare(_L("add")) != 0)
       
  1390 				{
       
  1391 				continue;
       
  1392 				}					
       
  1393 			}
       
  1394 		
       
  1395 		gMsg->Msg(_L("Record Number: #[%d]"), gXML->GetElementRecordID(iEntryIndex));
       
  1396 		if(gDB->CommitIndividualRecords())
       
  1397 			{
       
  1398 			gDB->CreateOrInsertRecordL(iEntryIndex == startIndex? DBAccess::ECreateNew: DBAccess::ECreateInsert,elementIdArray[aIndex], 0);			
       
  1399 			}
       
  1400 	    
       
  1401 	    //!!!!!!!!!!!!!!!!!the record ID of the given xmlDBentry should be read here...
       
  1402 	    
       
  1403 		//gDB->CreateOrInsertRecordL(DBAccess::EInsert,0,0); 
       
  1404 		
       
  1405 		gDB->CreateOrInsertRecordL(DBAccess::EInsert,0,gXML->GetElementRecordID(iEntryIndex)); 
       
  1406 		
       
  1407 		// find out how many fields we are expecting in this insert
       
  1408 		TInt iValue = gXML->GetEntryNumberParameters(iEntryIndex);
       
  1409         gDB->SetFieldCount(iValue);
       
  1410         
       
  1411         //Write column info
       
  1412 		ret = SetXMLColumnDetailsL(iEntryIndex,aIndex,iEntryIndex - startIndex + 1);
       
  1413 		/*if(ret != KErrNone)
       
  1414 			return ret;*/
       
  1415 		
       
  1416 		if(gDB->CommitIndividualRecords())
       
  1417 			{
       
  1418 			ret = gDB->CommitChanges();
       
  1419 			}
       
  1420 		if(ret != KErrNone)
       
  1421 			{
       
  1422 			gMsg->Msg(_L("Error %d inserting record #%d to %S"), ret, iEntryIndex - startIndex + 1, &xmlTableName);
       
  1423 
       
  1424 			if (gValidityChecking) 
       
  1425 				{
       
  1426 				gProcessingSuccessful = EFalse;
       
  1427 				}
       
  1428 			
       
  1429 			gDB->RemoveRecord(gXML->GetElementRecordID(iEntryIndex)-1);
       
  1430 			
       
  1431 			}
       
  1432 		else
       
  1433 			{
       
  1434 			recordsInserted++;
       
  1435 			}
       
  1436 		}
       
  1437 	
       
  1438 	if (recordsInserted)
       
  1439 		{
       
  1440 		gMsg->Msg(_L(" "));
       
  1441 		gMsg->Msg(_L("[%d] record(s) successfully inserted"), recordsInserted);
       
  1442 		}
       
  1443 	
       
  1444 	return recordsInserted;	
       
  1445 	}
       
  1446 
       
  1447 
       
  1448 TInt DoXMLInsertsL(const TInt &aIndex)
       
  1449 /**
       
  1450 Runs through all the steps involved in applying an insert to a particular table.
       
  1451 
       
  1452 @param index Index in the Table
       
  1453 @return Number of successfully inserted records
       
  1454 */
       
  1455 	{
       
  1456 	return (ProcessXmlDataL(EFalse,aIndex));
       
  1457 	}
       
  1458 
       
  1459 TInt DoXMLTemplateL(const TInt &aIndex)
       
  1460 /**
       
  1461 Applying the templates (for the XML configuration file)
       
  1462 
       
  1463 @param index Index in the Table
       
  1464 @return Number of successfully inserted records
       
  1465 */
       
  1466 	{
       
  1467 	return (ProcessXmlDataL(ETrue,aIndex));
       
  1468 	}
       
  1469 
       
  1470 TInt SetXMLColumnDetailsL(TInt aEntryIndex, TInt aIndex, TInt aRecCount)
       
  1471 /** Loops through all the columns of a particular table.  If any of the columns match the setting
       
  1472 	in the log file, it is stored, along with the value to write into this field.
       
  1473 
       
  1474 @param aEntryIndex 
       
  1475 @param aIndex 
       
  1476 @param aRecCount 
       
  1477 @return True if successful else false 
       
  1478 */
       
  1479 	{
       
  1480 	static TBuf<MAX_BUFFER_LEN> tempColumn;
       
  1481 	TPtrC setting;
       
  1482 	TPtrC column;
       
  1483 	TInt valid(KErrNone);
       
  1484 	TInt i = 0;
       
  1485 	TBool gprsGatewayFieldIsSet = EFalse;		// whether IpGateway field in OutgoingGPRS table record has been set
       
  1486 
       
  1487 	tempColumn = ColumnArray[aIndex][i];
       
  1488 	
       
  1489 	
       
  1490 	// loop through columns of table
       
  1491 	while( (valid==KErrNone) && tempColumn.Compare(TPtrC(NO_MORE_RECORDS)) != 0)
       
  1492 		{
       
  1493 		// get a column from the config file
       
  1494 		gMsg->Dbg(_L(" Looking for [%S]"), &tempColumn);
       
  1495 		
       
  1496 		if (gXML->GetSetting(aEntryIndex, tempColumn, setting))
       
  1497 			{
       
  1498 			column.Set(ColumnArray[aIndex][i]);	
       
  1499 			valid = gDB->SetColAndAttribL(column,setting);
       
  1500 
       
  1501 #ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS			
       
  1502 			VerifyDeprecatedFields(aIndex, column);
       
  1503 #endif
       
  1504 // SYMBIAN_NETWORKING_3GPPDEFAULTQOS
       
  1505 
       
  1506 			// Determine whether the GPRS IP Gateway field has been set or not
       
  1507 			if (IsGprsGatewayField(aIndex, column))
       
  1508 				{
       
  1509 				gprsGatewayFieldIsSet = ETrue;
       
  1510 				}
       
  1511 			}
       
  1512 		i++;
       
  1513 		tempColumn = ColumnArray[aIndex][i];
       
  1514 		}	
       
  1515 	
       
  1516 	//if the record is not empty and also has its name missing, set a default name
       
  1517     //only do this if not processing a template record
       
  1518 	if(!gDB->IsNameSet() && 
       
  1519         gDB->GetActualFieldCount() && 
       
  1520         gDB->GetCurrentRecord()->RecordId() != KCDDefaultRecord)	
       
  1521 		{		
       
  1522 		_LIT(KNameTemplate, "DefaultRecordName-%d");
       
  1523 		TBuf<MAX_BUFFER_LEN> recordName;
       
  1524 		recordName.Format(KNameTemplate, aRecCount);
       
  1525 		column.Set(TPtrC(COMMDB_NAME));		
       
  1526 		setting.Set(TPtrC(recordName));	    			
       
  1527 		valid = gDB->SetColAndAttribL(column,setting);	
       
  1528 		gDB->SetFieldCount(gDB->GetFieldCount() + 1); //field count increment by one because we added the missing name
       
  1529 	    }
       
  1530 
       
  1531 	if (valid == KErrNone && !gprsGatewayFieldIsSet)
       
  1532 		{
       
  1533 		// If required, setup a suitable default value for IpGateway field in OutgoingGPRS table records
       
  1534 		valid = SetupIpGatewayFieldDefaultL(aIndex);
       
  1535 		}
       
  1536 	
       
  1537 	// Handle special case of ConnPref record without default IAP set (empty db use case)
       
  1538 	HandleConnPrefWithoutDefaultIap();
       
  1539 
       
  1540 	return valid;
       
  1541 	}
       
  1542 
       
  1543 void DisplayMessage(TPtrC aMessage, TInt aJustTheMessage)
       
  1544 /**
       
  1545 Writes a message to the log file, along with any associated error.
       
  1546 
       
  1547 @param aMessage Message to be written 
       
  1548 @param aJustTheMessage Output only the plain message to the log file
       
  1549 */
       
  1550 	{
       
  1551 	if (aJustTheMessage)
       
  1552 		{
       
  1553 		gMsg->Msg(_L("%S"), &aMessage);
       
  1554 		}
       
  1555 	else
       
  1556 		{
       
  1557 		if (gDB->ErrorCode() != KErrAlreadyExists && gDB->ErrorCode() != E_ALREADYEXISTS)
       
  1558 			gMsg->Msg(_L(" "));
       
  1559 		
       
  1560 		gMsg->Msg(_L(" "));
       
  1561 		
       
  1562 		if (gDB->ErrorCode())
       
  1563 			{
       
  1564 			static TBuf<MAX_BUFFER_LEN> errorText;
       
  1565 			errorText = gDB->ErrorText();
       
  1566 			
       
  1567 			if (gDB->ErrorCode() == KErrAlreadyExists || gDB->ErrorCode() == E_ALREADYEXISTS)
       
  1568 				gMsg->Msg(_L("WARN: %S failed: %S [%d]"), &aMessage, &errorText, gDB->ErrorCode());
       
  1569 			else if (gDB->ErrorCode() < 0)
       
  1570 				gMsg->Msg(_L("ERR: %S failed: %S [%d]"), &aMessage, &errorText, gDB->ErrorCode());
       
  1571 			else
       
  1572 				gMsg->Msg(_L("ERR: %S failed: %S"), &aMessage, &errorText);
       
  1573 			}
       
  1574 		else
       
  1575 			{
       
  1576 			gMsg->Msg(_L("ERR: %S failed"), &aMessage);
       
  1577 			}
       
  1578 		
       
  1579 		// don't fail when the record is there already
       
  1580 		if (gDB->ErrorCode() != KErrAlreadyExists && gDB->ErrorCode() != E_ALREADYEXISTS)
       
  1581 			{
       
  1582 			gMsg->Msg(_L(" "));
       
  1583 			gMsg->Msg(_L(" "));
       
  1584 			gProcessingSuccessful = EFalse;
       
  1585 			}
       
  1586 		}
       
  1587 	}
       
  1588 
       
  1589 
       
  1590 #ifndef __TOOLS2__
       
  1591 EXPORT_C TInt NewApplicationL(const TDesC& aText)
       
  1592 /**
       
  1593 entry point used in WINS when ced is build as a exedll
       
  1594 
       
  1595 @param Text Command line argument
       
  1596 */
       
  1597 	{
       
  1598 	// save the command line info
       
  1599 	gArgumentLine=aText.AllocL();
       
  1600 	
       
  1601 	// record that ced is running as a exe dll
       
  1602 	gIsExeDLL = ETrue;
       
  1603 	
       
  1604 	// call main
       
  1605 	return E32Main();
       
  1606 	}
       
  1607 #endif
       
  1608 
       
  1609