ncdengine/provider/deviceinteraction/src/ncddeviceserviceimpl.cpp
changeset 0 ba25891c3a9e
child 4 3eebb1e54d3a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ncdengine/provider/deviceinteraction/src/ncddeviceserviceimpl.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,1407 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:   Definition of CNcdDeviceService
+*
+*/
+
+
+#include "ncddeviceserviceimpl.h"
+
+#include <eikenv.h>
+#include <ProEngFactory.h> // Set as ringing tone
+#include <MProEngEngine.h> // Set as ringing tone
+#include <MProEngProfile.h> // Set as ringing tone
+#include <MProEngTones.h> // Set as ringing tone
+#include <AknsWallpaperUtils.h> // Set as wallpaper
+#include <centralrepository.h> // Set as theme
+#include <AknSkinsInternalCRKeys.h> // Set as theme
+#include <etel.h> // MCC and MNC
+#include <etelmm.h> // MCC and MNC
+#include <sysutil.h>
+#include <etel3rdparty.h>
+#include <f32file.h>
+#include <apgcli.h>
+
+#if !defined( __SERIES60_31__ ) && !defined( __SERIES60_30__ )
+	#include <sysversioninfo.h>
+#endif
+
+#ifdef GET_DEVICE_ID_FROM_USERAGENT
+    #include <CUserAgent.h>
+#endif
+
+#include "catalogs_device_config.h"
+#include "catalogsutils.h"
+#include "catalogsdebug.h"
+
+#ifdef CATALOGS_BUILD_CONFIG_DEBUG
+    #include "ncdtestconfig.h"
+#endif    
+
+// Make ifdeffing easier by creating a new define for product code support
+#if defined( __SERIES60_31__ ) || defined( __SERIES60_30__ )
+    #define NCD_PRODUCTCODE_NOT_SUPPORTED
+#endif
+
+#if !( defined( __WINS__ ) || defined( __SERIES60_31__ ) || defined( __SERIES60_30__ ) )
+    #define NCD_GIVE_EXTRA_FIRMWARE_DATA
+#endif
+
+_LIT( KPhoneTsy, "PHONETSY.TSY" );
+
+// This string is used to find Series 60 version from User Agent string
+//_LIT8( KSeries60VersionFinder, "Series60/" );
+
+// Note: This must be a request that is not used in device interaction
+const CTelephony::TCancellationRequest KNoPhoneOperationRunning =
+    CTelephony::EFlightModeChangeCancel;
+
+const TInt KFirmwareLength = 64;
+
+// Hardcoded device manufacturer string
+// <hardware><manufacturer>
+_LIT( KManufacturerNokia, "Nokia" );
+
+_LIT8( KFlashMovieMime, "application/x-shockwave-flash" );
+
+#ifdef __WINS__
+_LIT( KWinsProductCode, "0000000" );
+#endif
+
+
+#ifdef NCD_GIVE_EXTRA_FIRMWARE_DATA
+_LIT( KFirmwareEol, "\n" );
+#endif
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// Constructor.
+// ---------------------------------------------------------------------------
+//
+CNcdDeviceService* CNcdDeviceService::NewL()
+    {
+    CNcdDeviceService* self = NewLC();
+    CleanupStack::Pop();
+    return self;
+    }
+    
+// ---------------------------------------------------------------------------
+// Constructor.
+// ---------------------------------------------------------------------------
+//
+CNcdDeviceService* CNcdDeviceService::NewLC()
+    {
+    CNcdDeviceService* self = new (ELeave) CNcdDeviceService();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+    
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CNcdDeviceService::~CNcdDeviceService()
+    {
+    DLTRACEIN((""));
+    delete iCurrentThemeName;
+    Cancel();
+    delete iImsi;
+    delete iFirmware;
+    delete iDeviceManufacturer;
+    delete iDeviceModel;
+    Close();
+    delete iTelephony;
+    
+#ifdef CATALOGS_BUILD_CONFIG_DEBUG    
+    delete iTestConfig;
+#endif     
+    DLTRACEOUT((""));
+    }
+    
+// ---------------------------------------------------------------------------
+// Constructor.
+// ---------------------------------------------------------------------------
+//
+CNcdDeviceService::CNcdDeviceService() : CActive( EPriorityStandard ),
+    iPhoneIdV1Pckg( iPhoneIdV1 ), 
+    iSubscriberIdV1Pckg( iSubscriberIdV1 ),
+    iNetworkInfoV1Pckg( iNetworkInfoV1 ), 
+    iConnected( EFalse ),
+    iCurrentCancelCode( KNoPhoneOperationRunning ),
+    iError( KErrNone )
+    {
+    CActiveScheduler::Add( this );
+    }
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CNcdDeviceService::ConstructL()
+    {
+    DLTRACEIN((""));
+    iTelephony = CTelephony::NewL();
+    InitializeL();
+    DLTRACEOUT((""));
+    }
+    
+    
+// ---------------------------------------------------------------------------
+// RunL
+// ---------------------------------------------------------------------------
+//    
+void CNcdDeviceService::RunL()
+    {
+    DLTRACEIN(( "iStatus: %d", iStatus.Int() ));
+    
+    // GetSubscriberId fails with KErrNotFound if there's no SIM in the device
+    switch ( iState ) 
+        {
+        case EGetPhoneId:
+            {            
+            DLTRACE((_L("manufacturer: %S, model: %S, IMEI: %S"),
+                &iPhoneIdV1.iManufacturer, &iPhoneIdV1.iModel, 
+                &iPhoneIdV1.iSerialNumber ));
+            GetSubscriberId();    
+            break;
+            }
+        
+        case EGetSubscriberId:
+            {
+            if ( iStatus.Int() == KErrNone ||
+                 iStatus.Int() == KErrNotFound ) 
+                {
+                
+                DLTRACE(("Got subscriber ID"));
+                DLINFO(( _L("IMSI: %S"), &iSubscriberIdV1.iSubscriberId ))                
+                GetNetworkInfo();
+                }
+            else 
+                {
+                DLTRACE(("Unrecoverable error"));
+                iError = iStatus.Int();
+                }
+            break;                        
+            }
+            
+        case EGetNetworkInfo:
+            {
+            DLTRACE(("EGetNetworkInfo"));
+            if ( iStatus.Int() == KErrAccessDenied ) 
+                {
+                DLTRACE(("Couldn't access network information, probably SIM is not present"));
+                FinishInitialization();
+                break;
+                }
+            else if ( iStatus.Int() != KErrNone )
+                {
+                DLTRACE(("Unrecoverable error"));
+                iError = iStatus.Int();
+                break;
+                }
+                
+            DLTRACE(("Got network info"));
+            // All is well
+            DLINFO(( _L("Mode: %d, Status: %d, MCC: %S, MNC: %S, DisplayTag: %S"),
+                iNetworkInfoV1.iMode, iNetworkInfoV1.iStatus, 
+                &iNetworkInfoV1.iCountryCode,
+                &iNetworkInfoV1.iNetworkId,
+                &iNetworkInfoV1.iDisplayTag ));
+            DLINFO(( _L("Short: %S, Long: %S, Access: %d, AreaKnown: %d"),
+                &iNetworkInfoV1.iShortName, &iNetworkInfoV1.iLongName,
+                iNetworkInfoV1.iAccess, iNetworkInfoV1.iAreaKnown ));
+            
+            if ( iNetworkInfoV1.iAreaKnown ) 
+                {
+                DLINFO(( "LocationAreaCode: %u, CellId: %u", 
+                    iNetworkInfoV1.iLocationAreaCode,
+                    iNetworkInfoV1.iCellId ));                        
+                }
+            else 
+                {
+                DLINFO(( "Area not known" ));
+                }
+                
+            FinishInitialization();
+            break;
+            }
+                        
+        case EInitialized:
+            {
+            DLTRACE(("Initialization done"));
+            FinishInitialization();
+            break;
+            }
+        
+        }
+
+
+    if ( iError != KErrNone )
+        {
+        DLTRACE(("Error: %d", iError));        
+        DeleteWait();
+        }
+    DLTRACEOUT((""));
+    }
+
+
+// ---------------------------------------------------------------------------
+// DoCancel
+// ---------------------------------------------------------------------------
+//
+void CNcdDeviceService::DoCancel()
+    {
+    DLTRACEIN((""));
+    DeleteWait();
+    if ( iTelephony && iCurrentCancelCode != KNoPhoneOperationRunning ) 
+        {     
+        
+        iTelephony->CancelAsync( iCurrentCancelCode ) ;
+        }
+    DLTRACEOUT((""));
+    }
+    
+    
+// ---------------------------------------------------------------------------
+// RunError
+// ---------------------------------------------------------------------------
+//
+TInt CNcdDeviceService::RunError( TInt aError )
+    {    
+    DLERROR((" Silently ignoring an error: %d", aError ));
+    iError = aError;
+    DeleteWait();
+    return KErrNone;
+    }
+    
+// ---------------------------------------------------------------------------
+// Set sound file as ringing tone to the currently active profile.
+// ---------------------------------------------------------------------------
+//
+void CNcdDeviceService::SetAsRingingToneL( const TDesC& aFileName )
+    {
+    DLTRACEIN((""));
+    
+    MProEngEngine* engine = ProEngFactory::NewEngineLC();
+    MProEngProfile* profile = engine->ActiveProfileLC();
+    MProEngTones& tones = profile->ProfileTones();
+    
+    User::LeaveIfError( tones.SetRingingTone1L( aFileName ) );
+    profile->CommitChangeL();
+    
+    DLINFO(("Ringing tone set"));
+    
+    // Can't use PopAndDestroy( 2, MProEngEngine ) etc. because
+    // ProEngFactory puts a C-class in the cleanupstack but returns an M-class
+    // so the pointer comparison done by PopAndDestroy will fail and cause
+    // a panic with E32User-CBase 90
+    CleanupStack::PopAndDestroy( 2 ); // MProEngProfile, MProEngEngine    
+        
+    DLTRACEOUT((""));
+    }
+
+// ---------------------------------------------------------------------------
+// Set graphics file as wallpaper.
+// ---------------------------------------------------------------------------
+//
+void CNcdDeviceService::SetAsWallpaperL( const TDesC& aFileName )
+    {
+    DLTRACEIN((""));
+    User::LeaveIfError(
+        AknsWallpaperUtils::SetIdleWallpaper( aFileName,
+                                              CCoeEnv::Static() ) );
+    DLTRACEOUT((""));
+    }
+
+// ---------------------------------------------------------------------------
+// Set theme by using its name.
+// ---------------------------------------------------------------------------
+//
+void CNcdDeviceService::SetAsThemeL( const TDesC& aThemeName )
+    {
+    DLTRACEIN((""));
+    RAknsSrvSession aknsSrv;
+    CleanupClosePushL( aknsSrv );
+    User::LeaveIfError( aknsSrv.Connect() );
+    
+    TAknsPkgID pid;
+    TAknSkinSrvSkinPackageLocation location = EAknsSrvPhone;
+
+    CArrayPtr<CAknsSrvSkinInformationPkg>* skins;
+    skins = aknsSrv.EnumerateSkinPackagesL( EAknsSrvAll );
+
+    TInt i = 0;
+    TInt skinCount = skins->Count();
+    for ( i = 0; i < skinCount; i++ )
+        {
+        if ( skins->At( i )->Name().CompareF( aThemeName ) == 0 )
+            {
+            // Name found from theme list
+            pid = skins->At( i )->PID();
+            location = SkinLocationFromPath(
+                skins->At( i )->IniFileDirectory() );
+            break;
+            }
+        }
+
+    skins->ResetAndDestroy();
+    delete skins;
+    skins = NULL;
+
+    if ( i == skinCount )
+        {
+        User::Leave( KErrNotFound );
+        }
+
+    // Set all active item definition sets
+    User::LeaveIfError( aknsSrv.SetAllDefinitionSets( pid ) );
+
+    TAknsPkgIDBuf pidBuf;
+    pid.CopyToDes( pidBuf );
+
+    // Save settings to repository
+    CRepository* skinsRepository =
+        CRepository::NewLC( KCRUidPersonalisation );
+    User::LeaveIfError( skinsRepository->Set( KPslnActiveSkinUid, pidBuf ) );
+    User::LeaveIfError( skinsRepository->Set( KPslnActiveSkinLocation,
+                                              location ) );
+
+    CleanupStack::PopAndDestroy( skinsRepository );
+    CleanupStack::PopAndDestroy( &aknsSrv );
+    DLTRACEOUT((""));
+    }
+
+
+// ---------------------------------------------------------------------------
+// Get name of the currently active theme.
+// ---------------------------------------------------------------------------
+//
+const TDesC& CNcdDeviceService::CurrentThemeNameL()
+    {
+    DLTRACEIN((""));
+    TAknsPkgIDBuf pidBuf;
+
+    CRepository* skinsRepository =
+        CRepository::NewLC( KCRUidPersonalisation );
+
+    User::LeaveIfError( skinsRepository->Get( KPslnActiveSkinUid, pidBuf ) );
+
+    CleanupStack::PopAndDestroy( skinsRepository );
+
+    RAknsSrvSession aknsSrv;
+    CleanupClosePushL( aknsSrv );
+    User::LeaveIfError( aknsSrv.Connect() );
+    
+    TAknsPkgID pid;
+    pid.SetFromDesL( pidBuf );
+
+    DLTRACE((""));
+    CArrayPtr<CAknsSrvSkinInformationPkg>* skins;
+    skins = aknsSrv.EnumerateSkinPackagesL( EAknsSrvAll );
+    DLTRACE((""));
+
+    delete iCurrentThemeName;
+    iCurrentThemeName = NULL;
+
+    TInt skinCount = skins->Count();
+    TInt i = 0;
+    for ( ; i < skinCount; i++ )
+        {
+        if ( skins->At( i )->PID().iNumber == pid.iNumber &&
+             skins->At( i )->PID().iTimestamp == pid.iTimestamp )
+            {
+            // Package ID found from theme list.
+            iCurrentThemeName = skins->At( i )->Name().Alloc();
+            break;
+            }
+        }
+
+    skins->ResetAndDestroy();
+    delete skins;
+    skins = NULL;
+
+    CleanupStack::PopAndDestroy( &aknsSrv );
+
+    if ( iCurrentThemeName )
+        {
+        DLTRACEOUT(( _L("Theme name %S"), iCurrentThemeName ));
+        return *iCurrentThemeName;
+        }
+    else
+        {
+        DLTRACEOUT(("No theme name"));
+        return KNullDesC;
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// Retrieves home network information.
+// ---------------------------------------------------------------------------
+//
+void CNcdDeviceService::HomeNetworkInfoL( TDes& aMCC, TDes& aMNC )
+    {
+    DLTRACEIN((""));
+
+#ifdef CATALOGS_OVERRIDE_NETWORK
+    aMCC.Copy( KCatalogsOverrideHomeMcc );
+    aMNC.Copy( KCatalogsOverrideHomeMnc );
+    
+#else // CATALOGS_OVERRIDE_NETWORK
+
+    TBool neededConnect = !iConnected;
+    if ( !iConnected ) 
+        {
+        DLTRACE(("Was not connected"));
+        ConnectL();
+        }
+
+    RMobilePhone::TMobilePhoneNetworkInfoV1 networkInfo;
+    RMobilePhone::TMobilePhoneNetworkInfoV1Pckg info2( networkInfo );
+
+    TRequestStatus status;
+
+    iPhone.GetHomeNetwork( status, info2 );
+    User::WaitForRequest( status );
+
+    if ( networkInfo.iCountryCode.Length() > KMccLength )
+        {
+        aMCC.Copy( networkInfo.iCountryCode.Left( KMccLength ) );
+        }
+    else
+        {
+        aMCC.Copy( networkInfo.iCountryCode );
+        }
+
+    if ( networkInfo.iNetworkId.Length() > KMncLength )
+        {
+        aMNC.Copy( networkInfo.iNetworkId.Left( KMncLength ) );
+        }
+    else
+        {
+        aMNC.Copy( networkInfo.iNetworkId );
+        }
+
+    if ( neededConnect ) 
+        {
+        Close();
+        }
+        
+
+    // Test config is handled afterwards since it's just easier to
+    // handle mixed cases where one param is taken from the file
+    // and another from the device
+    #ifdef CATALOGS_BUILD_CONFIG_DEBUG
+
+    if ( iTestConfig ) 
+        {
+        if ( iTestConfig->IsSet( CNcdTestConfig::EConfigHomeMcc ) ) 
+            {            
+            aMCC.Copy( iTestConfig->Value( CNcdTestConfig::EConfigHomeMcc ) );
+            }
+
+        if ( iTestConfig->IsSet( CNcdTestConfig::EConfigHomeMnc ) ) 
+            {            
+            aMNC.Copy( iTestConfig->Value( CNcdTestConfig::EConfigHomeMnc ) );
+            }
+                
+        DLTRACE(( _L("test MCC: %S, MNC: %S"), &aMCC, &aMNC ));        
+        }
+    
+    #endif  // CATALOGS_BUILD_CONFIG_DEBUG
+        
+#endif // CATALOGS_OVERRIDE_NETWORK       
+    DLTRACEOUT(( _L("MCC: %S, MNC: %S"), &aMCC, &aMNC ));
+    }
+
+    
+// ---------------------------------------------------------------------------
+// MCC getter
+// ---------------------------------------------------------------------------
+//
+const TDesC& CNcdDeviceService::CurrentMccL()
+    {
+    DLTRACEIN((""));
+#ifndef CATALOGS_OVERRIDE_NETWORK  
+
+    #ifdef CATALOGS_BUILD_CONFIG_DEBUG
+
+    if ( iTestConfig && 
+         iTestConfig->IsSet( CNcdTestConfig::EConfigCurrentMcc ) ) 
+        {
+        DLTRACEOUT(( _L("test MCC: %S"), 
+            &iTestConfig->Value( CNcdTestConfig::EConfigCurrentMcc ) ));    
+        return iTestConfig->Value( CNcdTestConfig::EConfigCurrentMcc );
+        }
+    
+    #endif  // CATALOGS_BUILD_CONFIG_DEBUG
+    
+    WaitForInitL();
+    DLTRACEOUT(( _L("MCC"), &iNetworkInfoV1.iCountryCode ));
+    return iNetworkInfoV1.iCountryCode;
+#else // CATALOGS_OVERRIDE_NETWORK    
+    return KCatalogsOverrideCurrentMcc();    
+#endif    
+    }
+    
+// ---------------------------------------------------------------------------
+// MNC getter
+// ---------------------------------------------------------------------------
+//
+const TDesC& CNcdDeviceService::CurrentMncL()
+    {
+    DLTRACEIN((""));
+#ifndef CATALOGS_OVERRIDE_NETWORK      
+
+    #ifdef CATALOGS_BUILD_CONFIG_DEBUG
+
+    if ( iTestConfig && 
+         iTestConfig->IsSet( CNcdTestConfig::EConfigCurrentMnc ) ) 
+        {
+        DLTRACEOUT(( _L("test MNC: %S"), 
+            &iTestConfig->Value( CNcdTestConfig::EConfigCurrentMnc ) ));    
+        return iTestConfig->Value( CNcdTestConfig::EConfigCurrentMnc );
+        }
+    
+    #endif  // CATALOGS_BUILD_CONFIG_DEBUG
+  
+    WaitForInitL();
+    DLTRACEOUT(( _L("MNC"), &iNetworkInfoV1.iNetworkId ));
+    return iNetworkInfoV1.iNetworkId;
+#else // CATALOGS_OVERRIDE_NETWORK        
+    return KCatalogsOverrideCurrentMnc();    
+#endif // CATALOGS_OVERRIDE_NETWORK        
+    }
+
+
+// ---------------------------------------------------------------------------
+// Retrieves service provider information.
+// ---------------------------------------------------------------------------
+//
+void CNcdDeviceService::ServiceProviderL( TDes& aServiceProvider )
+    {
+    DLTRACEIN((""));
+
+#ifndef CATALOGS_OVERRIDE_NETWORK
+    TBool neededConnect = !iConnected;
+    if ( !iConnected ) 
+        {
+        ConnectL();
+        }
+
+    RMobilePhone::TMobilePhoneServiceProviderNameV2 serviceProviderName;
+    RMobilePhone::TMobilePhoneServiceProviderNameV2Pckg
+        serviceProviderNamePckg( serviceProviderName );
+
+    TRequestStatus status;
+
+    iPhone.GetServiceProviderName( status, serviceProviderNamePckg );
+    User::WaitForRequest( status );
+
+    // Operator name, service provider
+    if ( serviceProviderName.iSPName.Length() > 0 )
+        {
+        aServiceProvider.Copy( serviceProviderName.iSPName );
+        }
+
+    if ( neededConnect ) 
+        {
+        Close();
+        }
+#else // CATALOGS_OVERRIDE_NETWORK
+
+    aServiceProvider.Copy( KCatalogsOverrideServiceProvider );
+
+#endif // CATALOGS_OVERRIDE_NETWORK        
+    DLTRACEOUT((""));
+    }
+
+
+// ---------------------------------------------------------------------------
+// IMSI getter
+// ---------------------------------------------------------------------------
+//
+const TDesC& CNcdDeviceService::ImsiL()
+    {
+    DLTRACEIN(( "" ));
+    
+    // Handle possible IMSI override from config file
+    #ifdef CATALOGS_BUILD_CONFIG_DEBUG
+
+    if ( iTestConfig && 
+         iTestConfig->IsSet( CNcdTestConfig::EConfigImsi ) ) 
+        {
+        DLTRACEOUT(( _L("test IMSI: %S"), 
+            &iTestConfig->Value( CNcdTestConfig::EConfigImsi ) ));    
+        return iTestConfig->Value( CNcdTestConfig::EConfigImsi );
+        }
+    
+    #endif  // CATALOGS_BUILD_CONFIG_DEBUG
+    
+    WaitForInitL();
+    DLTRACEOUT(( _L("IMSI: %S"), &iSubscriberIdV1.iSubscriberId ));    
+    return iSubscriberIdV1.iSubscriberId;
+    }
+    
+    
+// ---------------------------------------------------------------------------
+// IMEI getter
+// ---------------------------------------------------------------------------
+//
+const TDesC& CNcdDeviceService::ImeiL()
+    {
+    DLTRACEIN(( "" ));
+    WaitForInitL();
+    return iPhoneIdV1.iSerialNumber;
+    }
+        
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+HBufC* CNcdDeviceService::DeviceIdentificationLC()
+    {
+    DLTRACEIN((""));
+#ifdef CATALOGS_OVERRIDE_MODEL
+    return KCatalogsOverrideDeviceId().AllocLC();
+#endif    
+
+#ifdef GET_DEVICE_ID_FROM_USERAGENT    
+    // Assume the device id begins with "Nokia" and ends with "/"
+    HBufC8* userAgent = UserAgentL();
+    CleanupStack::PushL( userAgent );
+    TInt offset = userAgent->Find( _L8( "Nokia" ));
+    if ( offset == KErrNotFound )
+        {
+        DLTRACEOUT(("No Nokia"));
+        CleanupStack::PopAndDestroy( userAgent );
+        return KNullDesC().AllocLC();
+        }
+    TPtrC8 id = userAgent->Des().Mid( offset );
+    offset = id.Locate( '/' );
+    if ( offset == KErrNotFound )
+        {
+        DLTRACEOUT(("no /"));
+        CleanupStack::PopAndDestroy( userAgent );
+        return KNullDesC().AllocLC();
+        }
+    TPtrC8 id2 = id.Left( offset );
+    HBufC* devId = HBufC::NewL( id2.Length() );
+    devId->Des().Copy( id2 );
+    CleanupStack::PopAndDestroy( userAgent );
+    CleanupStack::PushL( devId );
+    DLTRACEOUT(( _L("devId: %S"), devId ));
+    return devId;
+    
+#else // Get devId from CTelephony
+
+#error User agent must not be fetched from CTelephony!
+
+    WaitForInitL();
+    
+    HBufC* devId = HBufC::NewLC( iPhoneIdV1.iManufacturer.Length() + 
+        iPhoneIdV1.iModel.Length() );
+    devId->Des().Copy( iPhoneIdV1.iManufacturer );
+    devId->Des().Append( iPhoneIdV1.iModel );
+    DLTRACEOUT(( _L("devId: %S"), devId ));
+    return devId;
+#endif    
+    }
+
+
+// ---------------------------------------------------------------------------
+// Device manufacturer getter
+// ---------------------------------------------------------------------------
+//
+const TDesC& CNcdDeviceService::DeviceManufacturerL()
+    {
+    DLTRACEIN((""));
+    //WaitForInitL();    
+    //return iPhoneIdV1.iManufacturer;
+    return KManufacturerNokia;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Device model getter
+// ---------------------------------------------------------------------------
+//
+const TDesC& CNcdDeviceService::DeviceModelL()
+    {
+    DLTRACEIN((""));
+
+#ifdef CATALOGS_OVERRIDE_MODEL
+    return KCatalogsOverrideDeviceModel();
+#else // CATALOGS_OVERRIDE_MODEL
+    
+    if ( !iDeviceModel )
+        {
+        // Get manufacturer 
+        HBufC8* manufacturer = Des16ToDes8LC( DeviceManufacturerL() );
+        
+        HBufC8* userAgent = UserAgentL();
+        CleanupStack::PushL( userAgent );
+        
+        TInt offset = userAgent->FindF( *manufacturer ); 
+        if ( offset == KErrNotFound )
+            {
+            DLTRACEOUT(("Device manufacturer not found"));
+            CleanupStack::PopAndDestroy( 2, manufacturer ); // manufacturer, useragent
+            return KNullDesC();
+            }
+        
+        // Strip manufacturer of the string    
+        TPtrC8 id = userAgent->Des().Mid( offset + manufacturer->Length() );
+        
+        // Locate the end of the device model
+        offset = id.Locate( '/' );
+        if ( offset == KErrNotFound )
+            {
+            DLTRACE(("no /"));
+            CleanupStack::PopAndDestroy( 2, manufacturer ); // manufacturer, useragent
+            return KNullDesC();
+            }
+        TPtrC8 id2 = id.Left( offset );
+        iDeviceModel = Des8ToDes16L( id2 );                        
+        
+        CleanupStack::PopAndDestroy( 2, manufacturer ); // manufacturer, useragent
+        }
+    DLTRACEOUT(( _L("device model: %S"), iDeviceModel ));
+    return *iDeviceModel;
+#endif // CATALOGS_OVERRIDE_MODEL   
+    }
+
+// ---------------------------------------------------------------------------
+// Returns device language
+// ---------------------------------------------------------------------------
+//    
+HBufC* CNcdDeviceService::DeviceLanguageLC()
+    {
+    DLTRACEIN((""));
+#ifdef CATALOGS_OVERRIDE_LANGUAGE
+    return KCatalogsOverrideDeviceLanguage().AllocLC();
+#else
+    TLanguage code = User::Language();
+    return LangCodeToDescLC( code);
+#endif    
+    }
+
+
+// ---------------------------------------------------------------------------
+// Returns device firmware
+// ---------------------------------------------------------------------------
+//    
+const TDesC& CNcdDeviceService::FirmwareL()
+    {
+    DLTRACEIN((""));
+#ifndef CATALOGS_OVERRIDE_FIRMWARE
+    if ( iFirmware ) 
+        {
+        return *iFirmware;
+        }
+        
+    iFirmware = HBufC::NewL( KFirmwareLength );
+    TPtr ptr = iFirmware->Des();
+#ifndef __WINS__
+    User::LeaveIfError( SysUtil::GetSWVersion( ptr ) );
+#else
+    ptr.Copy( _L( "emulator" ));
+#endif
+    return *iFirmware;
+    
+#else // CATALOGS_OVERRIDE_FIRMWARE
+    if ( iFirmware ) 
+        {
+        return *iFirmware;
+        }
+        
+    iFirmware = KCatalogsOverrideFirmware().AllocL();
+
+    return *iFirmware;
+#endif    
+    }
+
+
+// ---------------------------------------------------------------------------
+// Parses skin package location from path.
+// ---------------------------------------------------------------------------
+//
+TAknSkinSrvSkinPackageLocation
+    CNcdDeviceService::SkinLocationFromPath( const TDesC& aPath )
+    {
+    DLTRACEIN((""));
+    TBuf<1> driveLetterBuf;
+    driveLetterBuf.CopyUC( aPath.Left( 1 ) );
+    if ( driveLetterBuf.CompareF( _L( "e" ) ) == 0 )
+        {
+        return EAknsSrvMMC;
+        }
+    return EAknsSrvPhone;
+    }
+    
+
+// ---------------------------------------------------------------------------
+// On SDK 3.0 UA looks like this:
+// Mozilla/4.0 ( compatible; MSIE 5.0; Series60/3.0 Nokia6630/4.06.0 Profile/MIDP-2.0 Configuration/CLDC-1.1 ) 
+// ---------------------------------------------------------------------------
+#ifdef GET_DEVICE_ID_FROM_USERAGENT
+
+HBufC8* CNcdDeviceService::UserAgentL() const
+    {
+    DLTRACEIN((""));
+#ifndef CATALOGS_OVERRIDE_USERAGENT    
+    CUserAgent* ua = CUserAgent::NewL();
+    CleanupStack::PushL( ua );
+    HBufC8* uas = ua->UserAgentL();
+    CleanupStack::PopAndDestroy( ua );
+    DLTRACEOUT(("UserAgent: %S", uas));
+    return uas;
+#else // CATALOGS_OVERRIDE_USERAGENT
+    return KCatalogsOverrideUserAgent().AllocL(); 
+#endif    
+    }
+
+#endif    
+
+// ---------------------------------------------------------------------------
+// GetPhoneLC
+// ---------------------------------------------------------------------------
+void CNcdDeviceService::GetPhoneLC( RTelServer& aServer, RPhone& aPhone )
+    {    
+    DLTRACEIN((""));
+    CleanupClosePushL( aServer );
+
+    User::LeaveIfError( aServer.Connect() );
+    User::LeaveIfError( aServer.LoadPhoneModule( KPhoneTsy ) );
+
+    RTelServer::TPhoneInfo info;
+
+    // Find the number of phones available from the tel server
+    TInt numberPhones;
+    User::LeaveIfError( aServer.EnumeratePhones( numberPhones ) );
+
+    // Check there are available phones
+    if ( numberPhones < 1 )
+        {
+        User::Leave( KErrNotFound );
+        }
+
+    // Get the details for the first (and only) phone
+    User::LeaveIfError( aServer.GetPhoneInfo( 0, info ) );   
+    
+    User::LeaveIfError( aPhone.Open( aServer, info.iName ) );
+    CleanupClosePushL( aPhone );    
+    DLTRACEOUT((""));
+    }
+    
+
+// ---------------------------------------------------------------------------
+// ConnectL
+// ---------------------------------------------------------------------------    
+void CNcdDeviceService::ConnectL()
+    {
+    DLTRACEIN((""));
+    if ( !iConnected ) 
+        {        
+        GetPhoneLC( iServer, iPhone );
+        CleanupStack::Pop( 2 );
+        iConnected = ETrue;
+        }
+    DLTRACEOUT((""));
+    }
+    
+
+// ---------------------------------------------------------------------------
+// Close
+// ---------------------------------------------------------------------------    
+TInt CNcdDeviceService::Close()
+    {
+    DLTRACEIN((""));
+    TInt err = KErrNone;
+    if ( iConnected ) 
+        {
+        iPhone.Close();
+        err = iServer.UnloadPhoneModule( KPhoneTsy );
+        iServer.Close();
+        iConnected = EFalse;
+        }
+    DLTRACEOUT(("err: %d", err));
+    return err;
+    }
+    
+    
+
+// ---------------------------------------------------------------------------
+// InitializeL
+// ---------------------------------------------------------------------------    
+void CNcdDeviceService::InitializeL()
+    {
+    DLTRACEIN((""));
+    iTelephony->GetPhoneId( iStatus, iPhoneIdV1Pckg );
+    iState = EGetPhoneId;
+    iCurrentCancelCode = CTelephony::EGetPhoneIdCancel;
+    SetActive();    
+    DLTRACEOUT((""));
+    }
+    
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------        
+#ifdef CATALOGS_BUILD_CONFIG_DEBUG
+
+void CNcdDeviceService::SetTestConfig( CNcdTestConfig* aTestConfig )
+    {
+    DLTRACEIN((""));
+    delete iTestConfig;
+    iTestConfig = aTestConfig;
+    }
+    
+#endif // CATALOGS_BUILD_CONFIG_DEBUG    
+    
+// ---------------------------------------------------------------------------
+// GetSubscriberId
+// ---------------------------------------------------------------------------        
+void CNcdDeviceService::GetSubscriberId()
+    {
+    DLTRACEIN((""));
+    iTelephony->GetSubscriberId( iStatus, iSubscriberIdV1Pckg );
+
+#ifndef __WINS__
+    iState = EGetSubscriberId;
+#else // Skip other phases since 3.2 week 50 emulator doesn't support GetNetworkInfo
+    iState = EInitialized;
+#endif    
+    iCurrentCancelCode = CTelephony::EGetSubscriberIdCancel;
+    SetActive();
+    DLTRACEOUT((""));
+    }
+    
+
+// ---------------------------------------------------------------------------
+// GetNetworkInfo
+// ---------------------------------------------------------------------------        
+void CNcdDeviceService::GetNetworkInfo()
+    {
+    DLTRACEIN((""));
+    iTelephony->GetCurrentNetworkInfo( iStatus, iNetworkInfoV1Pckg );
+    iState = EGetNetworkInfo;
+    iCurrentCancelCode = CTelephony::EGetCurrentNetworkInfoCancel;
+    SetActive();
+    DLTRACEOUT((""));
+    }    
+
+
+// ---------------------------------------------------------------------------
+// WaitForInitL
+// ---------------------------------------------------------------------------        
+void CNcdDeviceService::WaitForInitL()
+    {    
+    if ( iState != EInitialized && iError == KErrNone ) 
+        {
+        DLTRACE(("Start waiter"));
+        DASSERT( !iWaiter );
+        iWaiter = new(ELeave) CActiveSchedulerWait;
+        iWaiter->Start();
+        }
+    User::LeaveIfError( iError );
+    }
+
+
+// ---------------------------------------------------------------------------
+// DeleteWait
+// ---------------------------------------------------------------------------    
+void CNcdDeviceService::DeleteWait()
+    {
+    if ( iWaiter ) 
+        {
+        DLTRACE(("Stopping and deleting wait-object"));
+        iWaiter->AsyncStop();
+        delete iWaiter;
+        iWaiter = NULL;
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// FinishInitialization
+// ---------------------------------------------------------------------------
+//
+void CNcdDeviceService::FinishInitialization()
+    {
+    DLTRACEIN((""));
+        
+    DeleteWait();
+    iCurrentCancelCode = CTelephony::ECurrentNetworkInfoChangeCancel;
+    iState = EInitialized;
+
+    // Get notifications for changes in network info
+    iTelephony->NotifyChange( iStatus, 
+        CTelephony::ECurrentNetworkInfoChange,
+        iNetworkInfoV1Pckg );                                           
+                                  
+    SetActive();
+    DLTRACEOUT(("Observing for changes in network"));
+    }
+
+
+
+// ---------------------------------------------------------------------------
+// Appends variant information to firmware string
+// ---------------------------------------------------------------------------
+//
+void CNcdDeviceService::AppendVariantToFirmwareL( RFs& aFs )
+    {
+    DLTRACEIN((""));
+
+// Don't try to append any variant information if the firmware string is
+// overridden in catalogs_device_config.h 
+#ifndef CATALOGS_OVERRIDE_FIRMWARE    
+    // Ensure that variant is not appended multiple times
+    delete iFirmware;
+    iFirmware = NULL;
+    
+    // Update firmware string
+    FirmwareL();
+    _LIT( KLineSeparator, "\n" );
+    HBufC* variant = ReadVariantInformationLC( aFs );
+    iFirmware = iFirmware->ReAllocL( 
+        iFirmware->Length() + 
+        variant->Length() + 
+        KLineSeparator().Length() );
+        
+    DLTRACE(("Appending variant to firmware"));
+    iFirmware->Des().Append( KLineSeparator );
+    iFirmware->Des().Append( *variant );
+    DLINFO(( _L("Firmware now: %S"), iFirmware ));
+    CleanupStack::PopAndDestroy( variant );
+#endif    
+    }
+
+TUid CNcdDeviceService::FlashPlayerUidL()
+    {
+    DLTRACEIN((""));
+    
+    RApaLsSession session;
+    CleanupClosePushL( session );
+    User::LeaveIfError( session.Connect() );
+    session.GetAllApps();
+    
+    // Get the uid of the flash player
+    TDataType flashType( KFlashMovieMime() );
+    TUid flashUid;
+    
+    User::LeaveIfError( session.AppForDataType( flashType, flashUid ) );
+    
+    // Calls close
+    CleanupStack::PopAndDestroy( &session );    
+    
+    DLTRACEOUT(("Flash player Uid: %d", flashUid.iUid));
+    
+    return flashUid;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Reads the variant information from the platform's depths
+// ---------------------------------------------------------------------------
+//
+HBufC* CNcdDeviceService::ReadVariantInformationLC( RFs& aFs )
+    {    
+    DLTRACEIN((""));
+#ifndef __WINS__
+
+#ifdef __SERIES60_31__
+
+    _LIT(KSalesModelFileName, "Z:\\resource\\versions\\model.txt");
+    
+    // TFileText::Read Reads a single line text record into the specified descriptor.
+    // Maximum record length is described as 256 characters in the class' header.
+    const TInt KMaxRecordLength = 256;
+
+    HBufC* phoneModel = HBufC::NewLC( KMaxRecordLength );
+    
+    RFile file;
+    User::LeaveIfError( 
+        file.Open( aFs, KSalesModelFileName, 
+                   EFileShareReadersOnly | EFileRead ) );
+                   
+    CleanupClosePushL( file );
+         
+    TPtr ptr = phoneModel->Des();
+
+    // Read the data from file.
+    TFileText reader;
+    reader.Set( file );
+    User::LeaveIfError( reader.Read( ptr ) );
+
+    CleanupStack::PopAndDestroy( &file ); // file
+    
+    // Append lang version
+    _LIT( KSpace, " " );
+    
+    HBufC* variant = HBufC::NewLC( KSysUtilVersionTextLength );
+    TPtr variantPtr = variant->Des();
+    User::LeaveIfError( SysUtil::GetLangVersion( variantPtr ) );
+    
+    phoneModel = phoneModel->ReAllocL( 
+        phoneModel->Length() + 
+        variant->Length() + 
+        KSpace().Length() );
+    
+    phoneModel->Des().Append( KSpace );
+    phoneModel->Des().Append( *variant );
+    
+    CleanupStack::PopAndDestroy( variant );
+
+    // ReAllocL may change the location of the descriptor so 
+    // we have to pop the old phoneModel pointer
+    CleanupStack::Pop(); // phoneModel 
+    CleanupStack::PushL( phoneModel );    
+    
+    DLTRACEOUT(( _L("Variant: %S"), phoneModel));    
+    return phoneModel;
+    
+#else // __SERIES60_31__   
+    _LIT( KSpace, " " );
+       
+    // Get model version.
+    TBuf< KSysVersionInfoTextLength > modelVersion;
+    User::LeaveIfError( SysVersionInfo::GetVersionInfo(
+        SysVersionInfo::EModelVersion, modelVersion ) );
+
+    // Get lang version.
+    TBuf<KSysUtilVersionTextLength> langVersion;
+    User::LeaveIfError( SysUtil::GetLangVersion( langVersion ) );
+    
+    // Create buffer.
+    HBufC* variantInfo = HBufC::NewLC( modelVersion.Length() + 
+        langVersion.Length() + 
+        KSpace().Length() );
+    variantInfo->Des().Append( modelVersion );
+    variantInfo->Des().Append( KSpace );
+    variantInfo->Des().Append( langVersion );
+    DLTRACEOUT(( _L("Variant info: %S"), variantInfo ));
+    return variantInfo;
+#endif // __SERIES60_31__
+    
+#else
+    (void) aFs;
+    return KNullDesC().AllocLC();
+#endif
+    }
+
+// -----------------------------------------------------------------------------
+// Returns device product code
+// -----------------------------------------------------------------------------
+//
+HBufC* CNcdDeviceService::ProductCodeLC()
+    {
+    DLTRACEIN((""));
+
+#ifdef NCD_PRODUCTCODE_NOT_SUPPORTED
+    // Product code information is not provided from the
+    // platform for the emulator. So, use a hard coded 
+    // product code value for the emulator.    
+    DLTRACEOUT(("Product code not supported"));
+    return NULL;
+
+#elif defined(__WINS__)
+
+    return KWinsProductCode().AllocLC();
+
+#else
+
+    // Buffer for the product code.
+    HBufC* productCode(
+        HBufC::NewLC( KSysVersionInfoTextLength ) );
+    TPtr productCodeDes( productCode->Des() );
+
+    // Get productCode to the buffer.
+    TInt errorCode( 
+        SysVersionInfo::GetVersionInfo(
+//             SysVersionInfo::EProductCode, productCodeDes ) );
+// This is just temporary line to use before NCD gets SDK that
+// has the EProductCode defined in the sysversioninfo.h. When correct
+// enum is available, remove this line and use the commented line above
+// instead.
+             static_cast<SysVersionInfo::TVersionInfoType>(SysVersionInfo::EModelVersion + 1), productCodeDes ) );
+
+    if ( errorCode == KErrNotSupported )
+        {
+        // Because product code getter is not supported in the platform,
+        // return NULL.
+        DLTRACEOUT(("Product code not supported, KErrNotSupported."));
+        CleanupStack::PopAndDestroy( productCode );
+        return NULL;
+        }
+    else
+        {
+        // Leave if error occurred. 
+        // Above, KErrNotSupported was handled as
+        // a special case.
+        User::LeaveIfError( errorCode );
+        }
+
+    DLTRACEOUT(( _L("Product code: %S"), productCode ));
+
+    return productCode;
+#endif // NCD_PRODUCTCODE_NOT_SUPPORTED
+    }
+
+
+// -----------------------------------------------------------------------------
+// Returns device product type
+// -----------------------------------------------------------------------------
+//
+TInt CNcdDeviceService::GetProductType( TDes& aType, RFs& aFs )
+    {
+    DLTRACEIN((""));
+#ifdef NCD_GIVE_EXTRA_FIRMWARE_DATA    
+
+    SysVersionInfo::TProductVersion productVersion;
+    TInt err = SysVersionInfo::GetVersionInfo( productVersion, aFs );
+    aType.Copy( productVersion.iProduct );
+    return err;
+    
+#else
+    
+    (void) aType;
+    (void) aFs;
+    
+    return KErrNotSupported;
+    
+#endif    
+    }
+
+
+// -----------------------------------------------------------------------------
+// Gets firmware id 
+// -----------------------------------------------------------------------------
+//
+TInt CNcdDeviceService::GetFirmwareId( TDes& aId, RFs& aFs )
+    {
+    DLTRACEIN((""));    
+#ifdef NCD_GIVE_EXTRA_FIRMWARE_DATA    
+
+    return SysVersionInfo::GetVersionInfo(
+        SysVersionInfo::EFWVersion, 
+        aId,
+        aFs );
+    
+#else
+    
+    (void) aId;
+    (void) aFs;
+    
+    return KErrNotSupported;
+    
+#endif    
+    }
+
+
+
+void CNcdDeviceService::GetFirmwareVersion1( TDes& aTarget )
+    {
+#ifdef NCD_GIVE_EXTRA_FIRMWARE_DATA    
+
+    DLTRACEIN((""));
+    TBuf<KSysUtilVersionTextLength> version;    
+
+    if ( SysUtil::GetSWVersion( version ) == KErrNone )
+        {         
+        TInt len = version.Length();
+        TInt pos1 = version.Find( KFirmwareEol );
+        if( pos1 != KErrNotFound && len > pos1 )
+            {
+            aTarget.Append( version.Left( pos1 ) );
+            }
+        }
+    DLTRACE(( _L("aTarget: %S"), &aTarget ));
+
+#else
+
+    (void) aTarget;
+
+#endif        
+    }
+
+
+void CNcdDeviceService::GetFirmwareVersion2( TDes& aTarget )
+    {
+    DLTRACEIN((""));
+#ifdef NCD_GIVE_EXTRA_FIRMWARE_DATA
+    
+    TBuf<KSysUtilVersionTextLength> version;    
+
+    if ( SysUtil::GetLangSWVersion( version ) == KErrNone )
+        {         
+        TInt len = version.Length();
+        TInt pos1 = version.Find( KFirmwareEol );
+        if( pos1 != KErrNotFound && len > pos1 )
+            {
+            aTarget.Append( version.Left( pos1 ) );
+            }
+        }
+
+    DLTRACE(( _L("aTarget: %S"), &aTarget ));
+
+#else
+
+    (void) aTarget;
+
+#endif            
+    }
+
+
+void CNcdDeviceService::GetFirmwareVersion3( TDes& aTarget, RFs& aFs )
+    {
+    DLTRACEIN((""));
+#ifdef NCD_GIVE_EXTRA_FIRMWARE_DATA
+    
+    TBuf<KSysUtilVersionTextLength> version;            
+
+    if ( SysVersionInfo::GetVersionInfo( 
+            SysVersionInfo::EOPVersion, 
+            version,
+            aFs ) == KErrNone )
+        {
+        TInt len = version.Length();
+        TInt pos1 = version.Find( KFirmwareEol );
+        if( pos1 != KErrNotFound && len > pos1 )
+            {        
+            aTarget.Append( version.Left( pos1 ) );        
+            }
+        }  
+
+    DLTRACE(( _L("aTarget: %S"), &aTarget ));
+
+#else
+
+    (void) aTarget;
+    (void) aFs;
+    
+#endif            
+    }
+
+
+
+// For testing purposes only, avoiding several mmp changes by including
+// the cpp
+#ifdef CATALOGS_BUILD_CONFIG_DEBUG
+    #include "ncdtestconfig.cpp"
+#endif
+