connectivitymodules/SeCon/services/csc/src/capinfo.cpp
branchRCL_3
changeset 20 4a793f564d72
parent 0 d0791faffa3f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/connectivitymodules/SeCon/services/csc/src/capinfo.cpp	Wed Sep 01 12:20:56 2010 +0100
@@ -0,0 +1,1031 @@
+/*
+* Copyright (c) 2005-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:  CCapInfo implementation
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <utf.h>
+#include <driveinfo.h>
+#include <pathinfo.h>    // for PathInfo::SoundsPath
+#include <seconsdkcrkeys.h>
+#include "sconsyncservice.h"
+#include "capinfo.h"
+#include "caplist.h"
+#include "capparser.h"
+#include "caputils.h"
+#include "stringlist.h"
+#include "sconversioninfo.h"
+#include "debug.h"
+
+
+_LIT8( KLineFeed, "\r\n" );
+
+const TInt KDefaultArrayGranularity = 5;
+
+
+// ============================= MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CCapInfo::NewL()
+// Two-phase constructor
+// -----------------------------------------------------------------------------
+//
+CCapInfo* CCapInfo::NewL()
+    {
+    TRACE_FUNC_ENTRY;
+    CCapInfo* self = new (ELeave) CCapInfo();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    TRACE_FUNC_EXIT;
+    return self;
+    }
+    
+// -----------------------------------------------------------------------------
+// CCapInfo::~CCapInfo()
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CCapInfo::~CCapInfo()
+    {
+    TRACE_FUNC_ENTRY;
+    iFsSession.Close();
+    delete iHeapBuf;
+    delete iCapList;
+    delete iSconInfo;
+    TRACE_FUNC_EXIT;
+    }
+    
+// -----------------------------------------------------------------------------
+// CCapInfo::CapabilityDocumentL(CBufFlat* aBuf)
+// Creates capability xml document end places it in aBuf
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::CapabilityDocumentL(CBufFlat* aBuf)
+    {
+    TRACE_FUNC_ENTRY;
+    TInt err( KErrNone );
+    
+    // set buffer where capability document is written
+    SetCapabilityBuf( aBuf );
+    
+    WriteL( KXmlVersion );
+    WriteL( KComment1 );
+    WriteL( KDocType );
+    WriteL( KRootBegin );
+    
+    
+    //
+    // general
+    //
+    TRAP( err, GeneralInfoL() );
+    if ( err != KErrNone )
+        {
+        LOGGER_WRITE_1( "GeneralInfoL failed : %d", err );
+        User::Leave( err ); 
+        }
+    
+    
+    //
+    // services
+    //
+    // Search service files first from C-drive, and then from Z
+    // Do not add same files twice.
+    
+    RArray<TFileName> excludeList( KDefaultArrayGranularity );
+    CleanupClosePushL( excludeList );
+    RArray<TFileName> filesAdded( KDefaultArrayGranularity );
+    CleanupClosePushL( filesAdded );
+    
+    //read service files from C Import folder
+    TRAP( err, ServiceInfoL( KCapabilityDirCImport, excludeList, filesAdded ) );     
+    LOGGER_WRITE_1( "ServiceInfoL(KCapabilityDirCImport) returned : %d", err );
+    for ( TInt i=0; i<filesAdded.Count(); i++ )
+        {
+        excludeList.Append( filesAdded[i] );
+        }
+    filesAdded.Reset();
+    
+    // read service files from C Capability folder
+    TRAP( err, ServiceInfoL( KCapabilityDirC, excludeList, filesAdded ) ); 
+    LOGGER_WRITE_1( "ServiceInfoL(KCapabilityDirC) returned : %d", err );
+    for ( TInt i=0; i<filesAdded.Count(); i++ )
+        {
+        excludeList.Append( filesAdded[i] );
+        }
+    filesAdded.Reset();
+    
+    // read service files from Z Capability folder
+    TRAP( err, ServiceInfoL( KCapabilityDirZ, excludeList, filesAdded ) );
+    LOGGER_WRITE_1( "ServiceInfoL(KCapabilityDirZ) returned : %d", err );
+    
+    CleanupStack::PopAndDestroy( &filesAdded );
+    CleanupStack::PopAndDestroy( &excludeList );
+    
+        
+    // this service does not come from file
+    TRAP( err, FolderServiceL() );
+    LOGGER_WRITE_1( "FolderServiceL() returned : %d", err );
+    
+    TRAP( err, SyncSolutionsServiceL() );
+    LOGGER_WRITE_1( "SyncSolutionsServiceL() returned: %d", err );
+
+    WriteL( KRootEnd );
+    TRACE_FUNC_EXIT;
+    }
+    
+// -----------------------------------------------------------------------------
+// CCapInfo::ConstructL()
+// Initializes member data
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::ConstructL()
+    {
+    TRACE_FUNC_ENTRY;
+    User::LeaveIfError( iFsSession.Connect() );
+    
+    iHeapBuf = HBufC8::NewL( KMaxSize*2 );
+    iCapList = CCapList::NewL();
+    iIdStack.Reset();
+    
+    iSconInfo = CSconVersionInfo::NewL();
+    TInt err(KErrNone);
+    TRAP(err, iSconInfo->FetchInfoL( iFsSession ));
+    LOGGER_WRITE_1("sconInfo->FetchInfoL() Leaved: %d", err);
+    TRACE_FUNC_EXIT;
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::CCapInfo()
+// Constuctor
+// -----------------------------------------------------------------------------
+//
+CCapInfo::CCapInfo()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::CapList()
+// Returns caplist
+// -----------------------------------------------------------------------------
+//
+CCapList* CCapInfo::CapList()
+    {
+    TRACE_FUNC;
+    __ASSERT_DEBUG(iCapList, CapUtil::Panic(KErrGeneral));
+    return iCapList;
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::SetCapabilityBuf( CBufFlat* aBuf )
+// Set capability buffer
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::SetCapabilityBuf( CBufFlat* aBuf )
+    {
+    TRACE_FUNC;
+    iCapabilityBuf=aBuf;
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::GeneralInfoL()
+// Write general device capability information.
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::GeneralInfoL()
+    {
+    TRACE_FUNC_ENTRY;
+    TInt err( KErrNone );
+    TBuf<KBufSize> buf;
+    TBuf<KBufSize> longName;
+    TBuf<KBufSize> coutryCode;
+    TBuf<KBufSize> networkID;
+    
+    WriteTagL(EGeneral, TXmlParser::EElementBegin);
+    
+    if ( !iSconInfo->IsReady() )
+        {
+        LOGGER_WRITE("iSconInfo wasn't ready, call iSconInfo->FetchInfoL");
+        iSconInfo->FetchInfoL( iFsSession );
+        }
+    
+    if ( iSconInfo->iManufacturer )
+        {
+        WriteValueL( EManufacturer, *iSconInfo->iManufacturer );
+        }
+    
+    if ( iSconInfo->iProduct )
+        {
+        WriteValueL( EModel, *iSconInfo->iProduct );
+        }
+    
+    // serial number
+    if ( iSconInfo->iSerialNumber )
+        {
+        WriteValueL( ESN, *iSconInfo->iSerialNumber );
+        }
+    
+    // software version 
+    if ( iSconInfo->iSWVersion )
+        {
+        WriteAttributeL( ESW, *iSconInfo->iSWVersion, iSconInfo->iDate );
+        }
+    
+    // language
+    WriteValueL( ELanguage, iSconInfo->iLanguage );
+
+    // this must succeed - do not trap
+    MemoryInfoL();
+    
+    // Operator
+    TRAP( err, CapUtil::GetOperatorNameL( longName, coutryCode, networkID ) );
+    LOGGER_WRITE_1( "CapUtil::GGetOperatorNameL returned : %d", err );
+    if( err == KErrNone )
+        {
+        LOGGER_WRITE_3( "CSConFsHandler::GetOperatorNameL longName =  %S coutryCode = %S networkID = %S", &longName, &coutryCode, &networkID );       
+        _LIT( KNetworkInfo, "NetworkInfo" );
+        _LIT( KCurrentNetwork, "CurrentNetwork=" );
+        _LIT( KCountryCode, "CountryCode=" );
+        _LIT( KNetworkID, "NetworkID=" );
+        
+        WriteTagL( EExt, TXmlParser::EElementBegin );
+        WriteValueL( EXNam, KNetworkInfo );
+        
+        // write CurrentNetwork
+        buf.Copy( KCurrentNetwork );
+        buf.Append( longName );
+        WriteValueL( EXVal, buf );
+        
+        // write CountryCode
+        buf.Copy( KCountryCode );
+        buf.Append( coutryCode );
+        WriteValueL( EXVal, buf );
+        
+        // write NetworkID
+        buf.Copy( KNetworkID );
+        buf.Append( networkID );
+        WriteValueL( EXVal, buf );
+        
+        WriteTagL( EExt, TXmlParser::EElementEnd );     
+        }
+    
+    if ( iSconInfo->iModel )
+        {
+        // print modelname (phone model sales name. For example "N01".)
+        WriteTagL( EExt, TXmlParser::EElementBegin );
+        _LIT(KModelName, "ModelName");
+        WriteValueL( EXNam, KModelName );
+        WriteValueL( EXVal, *iSconInfo->iModel );
+        WriteTagL( EExt, TXmlParser::EElementEnd ); 
+        }
+        
+    if ( iSconInfo->iProductCode )
+        {
+        // print productcode
+        WriteTagL( EExt, TXmlParser::EElementBegin );
+        _LIT( KProductCode, "ProductCode" );
+        WriteValueL( EXNam, KProductCode );
+        WriteValueL( EXVal, *iSconInfo->iProductCode );
+        WriteTagL( EExt, TXmlParser::EElementEnd );
+        }
+    
+    
+    // print advanced info
+    WriteTagL( EExt, TXmlParser::EElementBegin );
+    _LIT(KAdvancedDeviceInfo, "AdvancedDeviceInfo");
+    WriteValueL( EXNam, KAdvancedDeviceInfo );
+    
+    TBuf<KSysVersionInfoTextLength> temp;
+    
+    if ( iSconInfo->iRevision )
+        {
+        // product revision. For example "01"
+        _LIT( KRevision, "Revision=" );
+        temp.Copy( KRevision );
+        temp.Append( *iSconInfo->iRevision );
+        LOGGER_WRITE_1( "CCapInfo::GeneralInfoL() : %S ", &temp );
+        WriteValueL( EXVal, temp );
+        }
+    
+    
+    if ( iSconInfo->iSysVersionInfo )
+        {
+        _LIT( KFWVersion, "FWVersion=" );
+        temp.Copy( KFWVersion );
+        temp.Append( *iSconInfo->iSysVersionInfo );
+        LOGGER_WRITE_1( "CCapInfo::GeneralInfoL() : %S ", &temp );
+        WriteValueL( EXVal, temp );
+        }
+    
+    SysVersionInfo::TSymbianOSVersion osVersion;
+    err = iSconInfo->GetSymbianVersion( osVersion );
+    LOGGER_WRITE_1("TSymbianOSVersion info error: %d", err)
+    if ( !err )
+        {
+        // Now osVersion contains the Symbian OS version information
+        _LIT( KSymbianOSVersion, "SymbianOSVersion=%d.%d" );
+        temp.Format( KSymbianOSVersion,
+                osVersion.iMajorVersion,
+                osVersion.iMinorVersion  );
+        LOGGER_WRITE_1( "CCapInfo::GeneralInfoL() : %S ", &temp );
+                        
+        WriteValueL( EXVal, temp );
+        }
+    
+    VersionInfo::TPlatformVersion platformVersion;
+    err = iSconInfo->GetS60Version( platformVersion );
+    if ( !err )
+       {
+       _LIT( KS60Version, "S60PlatformVersion=%d.%d" );
+       temp.Format( KS60Version,
+               platformVersion.iMajorVersion,
+               platformVersion.iMinorVersion  );
+       LOGGER_WRITE_1( "CCapInfo::GeneralInfoL() : %S ", &temp );
+       WriteValueL( EXVal, temp );
+       }
+    
+    
+    if ( iSconInfo->iLangVersion )
+        {
+        _LIT( KLangVersion, "LangVersion=" );
+        temp.Copy( KLangVersion );
+        temp.Append( *iSconInfo->iLangVersion );
+        LOGGER_WRITE_1( "CCapInfo::GeneralInfoL() : %S ", &temp );
+        WriteValueL( EXVal, temp );
+        }
+    
+    if ( iSconInfo->iLangSWVersion )
+        {
+        _LIT( KLangSWVersion, "LangSWVersion=" );
+        temp.Copy( KLangSWVersion );
+        temp.Append( *iSconInfo->iLangSWVersion );
+        LOGGER_WRITE_1( "CCapInfo::GeneralInfoL() : %S ", &temp );
+        WriteValueL( EXVal, temp );
+        }
+    
+    if ( iSconInfo->iOPVersion )
+        {
+        // CustomerVersion
+        _LIT( KOPVersion, "OPVersion=" );
+        temp.Copy( KOPVersion );
+        temp.Append( *iSconInfo->iOPVersion );
+        LOGGER_WRITE_1( "CCapInfo::GeneralInfoL() : %S ", &temp );
+        WriteValueL( EXVal, temp );
+        }
+    
+    // screen size
+    LOGGER_WRITE_2("Size, width: %d, height: %d",
+            iSconInfo->iScreenSize.iWidth,
+            iSconInfo->iScreenSize.iHeight );
+    _LIT( KWidth, "ScreenWidth=%d" );
+    _LIT( KHeight, "ScreenHeight=%d" );
+    
+    temp.Format( KWidth, iSconInfo->iScreenSize.iWidth );
+    WriteValueL( EXVal, temp );
+    
+    temp.Format( KHeight, iSconInfo->iScreenSize.iHeight );
+    WriteValueL( EXVal, temp );
+    
+    WriteTagL( EExt, TXmlParser::EElementEnd ); 
+    // end of advanced info
+    
+    WriteTagL(EGeneral, TXmlParser::EElementEnd);
+    TRACE_FUNC_EXIT;
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::MemoryInfoL()
+// Create memory info for all drives (RAM excluded).
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::MemoryInfoL()
+    {
+    TRACE_FUNC_ENTRY;
+    
+    TMemoryInfo info;
+    TInt devDriveCount = 0;
+    TInt mmcDriveCount = 0;
+    
+    //Write all drivers to folderlisting object
+    TDriveList driveList;
+    // Get all drives that are visible to the user.
+    TInt driveCount;
+    User::LeaveIfError( DriveInfo::GetUserVisibleDrives( iFsSession, driveList, driveCount ) );
+    
+    for( TInt i = EDriveA; i < KMaxDrives; i++ )
+        {
+        if( driveList[i] )
+            {
+            TUint driveStatus;
+            TInt err = DriveInfo::GetDriveStatus( iFsSession, i, driveStatus );
+            if( err )
+                {
+                LOGGER_WRITE_1( "CCapInfo::MemoryInfoL() : DriveInfo::GetDriveStatus: %d", i);
+                continue;
+                }
+            
+            if( !(driveStatus & DriveInfo::EDrivePresent )
+                || driveStatus & DriveInfo::EDriveCorrupt
+                || (driveStatus & DriveInfo::EDriveRemote) )
+                {
+                LOGGER_WRITE_1( "skip drive %d", i);
+                continue;
+                }
+            
+            TRAP( err, CapUtil::GetMemoryInfoL( iFsSession, i, info ));
+            if ( err )
+                {
+                LOGGER_WRITE_1( "CapUtil::GetMemoryInfoL() : Leaved with: %d", err);
+                continue;
+                }
+            
+            info.iDriveStatus = driveStatus;
+            if( driveStatus & DriveInfo::EDriveInternal )
+                {
+                // if internal (DEV) drive, save drive number
+                devDriveCount++;
+                info.iMemNr = devDriveCount;
+                }
+            else if ( driveStatus & DriveInfo::EDriveRemovable )
+                {
+                // if removable (MMC) drive, save drive number
+                mmcDriveCount++;
+                info.iMemNr = mmcDriveCount;
+                }
+            else
+                {
+                // was not internal or removable, skip.
+                LOGGER_WRITE( "CCapInfo::MemoryInfoL() : not internal or removable, skip." );
+                continue;
+                }
+                
+            WriteMemoryInfoL(info);
+            
+            }
+        }
+    
+    TRACE_FUNC_EXIT;
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::MemoryInfoL(TMemoryInfo& aInfo)
+// Create memory info for all drives (RAM excluded).
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::WriteMemoryInfoL(TMemoryInfo& aInfo)
+    {
+    TRACE_FUNC_ENTRY;
+    TBuf<KBufSize> buf;
+
+    WriteTagL(EMemory, TXmlParser::EElementBegin);
+
+    if( aInfo.iDriveStatus & DriveInfo::EDriveInternal )
+        {
+        buf = KMediaFlash;
+        }
+    else
+        {
+        buf = KMediaMMC;  // memory card (MMC)
+        }
+        
+    if( aInfo.iMemNr > 1 )
+        {
+        // append memory number DEV2, MMC2..
+        buf.AppendNum( aInfo.iMemNr ); 
+        }
+    
+    WriteValueL(EMemType, buf);
+    WriteValueL(ELocation, aInfo.iLocation);
+    WriteValueL(EFree, aInfo.iFree);
+    WriteValueL(EUsed, aInfo.iUsed);
+    
+    WriteValueL(EFileNLen, aInfo.iFileNameSize);
+
+    WriteTagL(EMemory, TXmlParser::EElementEnd);
+    TRACE_FUNC_EXIT;
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::ServiceInfoL(const TDesC& aDir)
+// Reads service xml-files from directory and writes them into capability 
+// document.
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::ServiceInfoL(const TDesC& aDir, const RArray<TFileName>& aExcludeList,
+    RArray<TFileName>& aFilesAdded)
+    {
+    TRACE_FUNC_ENTRY;
+    CCapList* capList=CapList();
+
+    RArray<TFileName> array( KDefaultArrayGranularity );
+    CleanupClosePushL(array);
+
+    CStringList* stringList=CStringList::NewLC();
+
+    CapUtil::GetFileListL(iFsSession, aDir, array);
+    
+    _LIT(KFormat, "%S%S");
+    TFileName name;
+    TInt count=array.Count();
+    for (TInt i=0; i<count; i++)
+        {
+        TBool exludeFromList(EFalse);
+        
+        // Check if file is already added to list
+        for ( TInt j=0; j<aExcludeList.Count() && !exludeFromList; j++ )
+            {
+            if ( array[i].CompareF(aExcludeList[j]) == 0 )
+                {
+                LOGGER_WRITE_1( "match found at pos %d", j);
+                exludeFromList = ETrue;
+                }
+            }
+        
+        if ( !exludeFromList )
+            {
+            name.Format(KFormat, &aDir, &array[i]);
+            if (!CapUtil::CheckFileType(name, KXmlExtension))
+                {
+                continue;  // only accept .xml files
+                }
+            
+            capList->List()->Reset();
+            capList->List()->ReadFromFileL( iFsSession, name );
+            if (capList->FindServiceL(stringList))
+                {
+                WriteNewLineL();
+                WriteFromListL(stringList);
+                
+                User::LeaveIfError( aFilesAdded.Append(array[i]) );
+                LOGGER_WRITE_1( "File '%S' added to list", &array[i] );
+                }
+            }
+        }
+
+    CleanupStack::PopAndDestroy(stringList);
+    CleanupStack::PopAndDestroy(&array);
+    TRACE_FUNC_EXIT;
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::FolderServiceL()
+// Writes folder service. Notice that this service is created in code because
+// pathinfo component is used to get folder names.
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::FolderServiceL()
+    {
+    TRACE_FUNC_ENTRY;
+    TBuf<KBufSize> rootPath;
+    TBuf<KBufSize> memoryType(KNullDesC);
+    TFileName folderName;
+    _LIT( KFormat, "%S%S" );
+    
+    WriteNewLineL();
+    WriteTagL(EService, TXmlParser::EElementBegin);
+
+    WriteValueL(EName,  KFolderServiceName);
+    WriteValueL(EUUID,  KFolderServiceUid);
+    WriteValueL(EVersion,  KFolderServiceVersion);
+
+    WriteTagL(EObject, TXmlParser::EElementBegin);
+    WriteValueL(EType,  KFolderServiceType);
+    WriteTagL(EObject, TXmlParser::EElementEnd);
+    TInt drive;
+    TInt err;
+    
+    CapUtil::GetDefaultRootPathL( iFsSession, rootPath );
+    if( rootPath.Length() > 0 )
+        {
+        err = iFsSession.CharToDrive( rootPath[0], drive );
+        if( err == KErrNone )
+            {
+            CapUtil::GetMemoryType( iFsSession, memoryType, drive );
+            }
+        }
+
+    // EFolderImages
+    folderName.Format( KFormat, &rootPath, &PathInfo::ImagesPath() );
+    WriteFolderL( KFolderImages, folderName, memoryType );
+    
+    // EFolderGraphics
+    folderName.Format( KFormat, &rootPath, &PathInfo::ImagesPath() );
+    WriteFolderL(KFolderGraphics, folderName, memoryType);
+    
+    // EFolderTones
+    folderName.Format( KFormat, &rootPath, &PathInfo::DigitalSoundsPath() );
+    WriteFolderL(KFolderTones, folderName, memoryType);
+    
+    // EFolderMusic
+    folderName.Format( KFormat, &rootPath, &PathInfo::SoundsPath() );
+    WriteFolderL(KFolderMusic, folderName, memoryType);
+    
+    // EFolderVideos
+    folderName.Format( KFormat, &rootPath, &PathInfo::VideosPath() );
+    WriteFolderL(KFolderVideos, folderName, memoryType);
+    
+    // EFolderInstalls
+    folderName.Format( KFormat, &rootPath, &PathInfo::InstallsPath() );
+    WriteFolderL(KFolderInstalls, folderName, memoryType);
+
+
+    WriteTagL(EService, TXmlParser::EElementEnd);
+    WriteNewLineL();
+    TRACE_FUNC_EXIT;
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::SyncSolutionsServiceL()
+// Reads last used syncSolutions from cenrep and writes to capability object
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::SyncSolutionsServiceL()
+    {
+    TRACE_FUNC_ENTRY;
+    TSConSolutionInfo calendar;
+    TSConSolutionInfo contact;
+    TSConSolutionInfo sms;
+    TSConSolutionInfo bookmark;
+    
+    CSConSyncService *syncService = CSConSyncService::NewLC();
+    syncService->GetSolutionL( KSeconCalendarUid, calendar );
+    syncService->GetSolutionL( KSeconContactsUid, contact );
+    syncService->GetSolutionL( KSeconSmsUid, sms );
+    syncService->GetSolutionL( KSeconBookmarkUid, bookmark );
+    CleanupStack::PopAndDestroy( syncService );
+    
+    WriteSyncSolutionsServiceL( calendar, contact, sms, bookmark );
+    
+    TRACE_FUNC_EXIT;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCapInfo::WriteSyncSolutionsServiceL()
+// Writes SyncSolutionsService data to capability object.
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::WriteSyncSolutionsServiceL( const TSConSolutionInfo& aCalendar,
+        const TSConSolutionInfo& aContact,
+        const TSConSolutionInfo& aSms,
+        const TSConSolutionInfo& aBookmark)
+    {
+    TRACE_FUNC_ENTRY;
+    
+    WriteTagL( EService, TXmlParser::EElementBegin );
+
+    WriteValueL( EName,  KSyncSolutionsServiceName );
+    WriteValueL( EVersion,  KSyncSolutionsServiceVersion );
+    
+    if ( aCalendar.iUid != 0 )
+        {
+        WriteSolutionTagL( KSyncCalendar, aCalendar );
+        }
+    
+    if ( aContact.iUid != 0 )
+        {
+        WriteSolutionTagL( KSyncContacts, aContact );
+        }
+    
+    if ( aSms.iUid != 0 )
+        {
+        WriteSolutionTagL( KSyncSms, aSms );
+        }
+    
+    if ( aBookmark.iUid != 0 )
+        {
+        WriteSolutionTagL( KSyncBookmark, aBookmark );
+        }
+    
+    /*
+     * <Ext>
+     *   <XNam>DesktopSync</XNam>
+     *   <XVal></XVal>
+     * </Ext>
+     * 
+     */
+    if ( !iSconInfo->iDesktopSyncError )
+        {
+        WriteTagL( EExt, TXmlParser::EElementBegin );
+        WriteValueL( EXNam, KDesktopSync );
+        
+        TBuf<KBufSize> buffer;
+        buffer.AppendNum( iSconInfo->iDesktopSync );
+        
+        WriteValueL( EXVal, buffer );
+        WriteTagL( EExt, TXmlParser::EElementEnd );
+        }
+    
+    
+    
+    WriteTagL( EService, TXmlParser::EElementEnd );
+    TRACE_FUNC_EXIT;
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CCapInfo::WriteSolutionTagL()
+// Writes SyncSolutionsService solution data to capability object.
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::WriteSolutionTagL( const TDesC& aContentName,
+        const TSConSolutionInfo& aSolution )
+    {
+    TRACE_FUNC_ENTRY;
+    _LIT( KFormatUID, "UID=0x%08x" );
+    _LIT( KFormatName, "Name=%S" );
+    _LIT( KFormatDate, "Timestamp=%04d%02d%02dT%02d%02d%02dZ" );
+    
+    WriteTagL( EExt, TXmlParser::EElementBegin );
+    WriteValueL( EXNam, aContentName );
+    
+    TFileName temp;
+    temp.Format( KFormatUID, aSolution.iUid );
+    WriteValueL( EXVal, temp );
+    
+    temp.Format( KFormatName, &aSolution.iSolutionName );
+    WriteValueL( EXVal, temp );
+    
+    if ( aSolution.iTime.Int64() != 0 )
+        {
+        // write time
+        TDateTime time = aSolution.iTime.DateTime();
+        temp.Format( KFormatDate, time.Year(), time.Month() + 1,
+            time.Day() + 1, time.Hour(), time.Minute(), time.Second() );
+        WriteValueL( EXVal, temp );
+        
+        }
+    
+    
+    WriteTagL( EExt, TXmlParser::EElementEnd );
+    TRACE_FUNC_EXIT;
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::WriteFolderL(const TDesC& aType, const TDesC& aFullName, 
+// const TDesC& aMemory)
+// Writes one folder name element.
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::WriteFolderL(const TDesC& aType, const TDesC& aFullName, 
+                            const TDesC& aMemory)
+    {
+    TRACE_FUNC_ENTRY;
+    _LIT(KFormat, "%S=%S");
+
+    TBuf<KBufSize> buf; 
+    const TInt KReservedSize = 10;
+    if ( aFullName.Length() + KReservedSize > KBufSize )
+        {
+        return;
+        }
+    buf.Format(KFormat, &KFolderNameTag, &aFullName);
+    
+
+    WriteTagL(EExt, TXmlParser::EElementBegin);
+
+    WriteValueL(EXNam, aType);
+    WriteValueL(EXVal, buf);
+
+    buf.Format(KFormat, &KFolderMemoryTypeTag, &aMemory);
+    WriteValueL(EXVal, buf);
+    
+
+    WriteTagL(EExt, TXmlParser::EElementEnd);
+    TRACE_FUNC_EXIT;
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::WriteL(const TDesC& aText)
+// Writes one element to capability buffer.
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::WriteL(const TDesC& aText)
+    {
+    if (aText.Length() > iBuf.MaxLength())
+        {
+        User::Leave(KErrTooBig);
+        }
+        
+
+    iBuf=aText;
+    iBuf.Trim();
+    FormatElement(iBuf);
+    TPtr8 ptr = iHeapBuf->Des();
+
+    if ( iBuf.Length()+2 > ptr.MaxLength() )
+        {
+        User::Leave(KErrTooBig);
+        }
+        
+    //unicode conversion
+    HBufC8* convBuf = HBufC8::NewLC( iBuf.Size() );
+    TPtr8 convPtr = convBuf->Des();
+    
+    CnvUtfConverter::ConvertFromUnicodeToUtf8(convPtr, iBuf);
+
+    ptr.Copy(convPtr);
+    ptr.Append( KLineFeed );  // linefeed
+    
+    CleanupStack::PopAndDestroy( convBuf );
+    
+    TInt pos=iCapabilityBuf->Size();
+    iCapabilityBuf->InsertL(pos, ptr);
+
+    iBuf=KNullDesC;
+    }
+
+void CCapInfo::WriteNewLineL()
+    {
+    TInt pos=iCapabilityBuf->Size();
+    iCapabilityBuf->InsertL(pos, KLineFeed );
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::WriteValueL(TInt aId, const TDesC& aValue)
+// Constructs element with value (eg <Language>en</Language>)
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::WriteValueL(TInt aId, const TDesC& aValue)
+    {
+    // empty values not written to capability object
+    if (aValue.Length()<1)
+        {
+        LOGGER_WRITE( "WriteValueL: value is empty" );
+        return;
+        }
+
+    TBuf<KBufSize> buf;
+
+    TRAPD(err, CapParser::MakeElementL(buf, aId, aValue));
+    if (err==KErrNone)
+        {
+        WriteL(buf);
+        }
+    else if (err==KErrTooBig)
+        {
+        WriteBigValueL(aId, aValue);
+        }
+    else
+        {
+        User::Leave(err);
+        }
+    
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::WriteBigValueL(TInt aId, const TDesC& aValue)
+// Constructs element with value
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::WriteBigValueL(TInt aId, const TDesC& aValue)
+    {
+    HBufC* hBuf=HBufC::NewL(aValue.Length()+KBufSize);
+    CleanupStack::PushL(hBuf);
+
+    TPtr pBuf(hBuf->Des());
+    CapParser::MakeElementL(pBuf, aId, aValue);
+    WriteL(*hBuf);
+    
+    CleanupStack::PopAndDestroy(hBuf);
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::WriteValueL(TInt aId, TInt64 aValue)
+// Constructs element with integer value
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::WriteValueL(TInt aId, TInt64 aValue)
+    {
+    TBuf<KBufSize> buf;
+    TBuf<KTagSize> value;
+    CapUtil::IntToStr(value, aValue);
+    CapParser::MakeElementL(buf, aId, value);
+    WriteL(buf);
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::WriteTagL(TInt aId, TInt aType)
+// Constructs element without value (eg <Memory>)
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::WriteTagL(TInt aId, TInt aType)
+    {
+    TBuf<KBufSize> buf;
+    CapParser::MakeElementL(buf, aId, aType);
+    WriteL(buf);
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::WriteAttributeL(TInt aId, const TDesC& aVersion, const TDesC& aDate)
+// Constructs element with attributes "Version" and "Date" 
+// (eg <HW Version="1.5"/>)
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::WriteAttributeL(TInt aId, const TDesC& aVersion, 
+                                const TDesC& aDate)
+    {
+    // empty values not written to capability object
+    if (aVersion.Length()<1 && aDate.Length()<1)
+        {
+        LOGGER_WRITE( "WriteAttributeL: attributes are empty" );
+        return;
+        }
+    
+    TBuf<KBufSize> buf;
+    CapParser::MakeElementL(buf, aId, aVersion, aDate);
+    WriteL(buf);
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::WriteFromListL(CStringList* aList)
+// Writes elements from list to capability buffer.
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::WriteFromListL(CStringList* aList)
+    {
+    TInt count=aList->Count();
+
+    for (TInt i=0; i<count; i++)
+        {
+        WriteL(aList->ReadPtr(i));
+        }
+    }   
+
+// -----------------------------------------------------------------------------
+// CCapInfo::FormatElement(TDes& aText)
+// Function adds indentation spaces to capability elements to improve 
+// readability.
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::FormatElement(TDes& aText)
+    {
+    TXmlParser parser;
+
+    parser.Set(aText);
+    TInt type=parser.Type();
+    TBuf<KTagSize> tag;
+    parser.GetTag(tag);
+        
+    if (type==TXmlParser::EElementEnd)
+        {
+        TInt id1=CapParser::ElementId(tag);
+        TInt id2=iIdStack.Pop();
+        
+        __ASSERT_DEBUG(id1==id2, CapUtil::Panic(KErrGeneral));
+        id1=0;
+        id2=0;
+        }
+
+    AddFormatText(aText, iIdStack.Size());
+
+    if (type==TXmlParser::EElementBegin)
+        {
+        TInt id1=CapParser::ElementId(tag);
+        iIdStack.Push(id1);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCapInfo::AddFormatText( TDes& aText, TInt aNum ) const
+// Adds format text
+// -----------------------------------------------------------------------------
+//
+void CCapInfo::AddFormatText( TDes& aText, TInt aNum ) const
+    {
+    TBuf<KBufSize> buf;
+    buf = KNullDesC;
+
+    if ( aNum > KNestingLimit )
+        {
+        aNum = KNestingLimit;
+        }
+        
+    for ( TInt i=0; i<aNum; i++ )
+        {
+        buf.Append( KFormatText );
+        }
+    if ( aText.MaxLength()-aText.Length()>buf.Length() )
+        {
+        aText.Insert( 0, buf );
+        }
+    }
+    
+// End of file
+
+