/*===========================================================================

  FILE: OEMAppFuncs_Sim.c
  
  SERVICES: Windows implementation of the OEM Functions
   
  DESCRIPTION
     This file provides the windows implementation of some of the functions
     in OEMAppFuncs.c. These functions are also used by the BREW Simulator. 
     This file is shipped with the Porting Kit. OEMs will be able to modify these 
     functions, re-build the BREW.DLL and test them using the BREW Simulator.
      
  PUBLIC CLASSES:  
        N/A
        
  INITIALIZATION AND SEQUENCING REQUIREMENTS:  N/A
         
           
  Copyright (c) 2000 by QUALCOMM Incorporated.  All Rights Reserved.
===========================================================================*/

#include <windows.h>
#include "sim_dns.h"
#include "OEMSafeMode.h"
#include "OEMConfig.h"
#include "OEMFS.h"
#include "AEE_OEM.h"
#include "AEE.h"
#include "AEEDownload.h"
#include "AEEStdLib.h"
#include "AEEComdef.h"
#include "AEEClassIDs.h"
#include "AEEFile.h"
#include "AEESMS.h"

#define AEECLSID_OEM_DL_CONFIG     (AEECLSID_SAMPLE_APP + 23)

#define SIM_CHIP_ID  "Simulator"

#define SIM_SUBSCRIBER_ID "1234567890"

#define OEM_MAX_ESN_STRING_SIZE  20    // ESN string in Hex or Decimal, or "Not supported"

#define OEM_DL_CFG_VER  (10)

#define DEFAULT_PLATFORM_ID   (1000)

static void GetDownloadFSAvail(DLItemSize * pi);
static void GetMobileInfo(AEEMobileInfo * pmi);

extern boolean TAPI_CompressNumber(char * pszSrc);

extern int GetDisplayInfo(AVSType avs, AEEBitmapInfo *pInfo, int nSize);

extern void GetDownloadHeader(char* pBuff, int* pnSize);

extern boolean AEESIM_GetMobileInfo(char* pszESN, int nESNSize);
extern boolean AEESIM_GetSubscriberID(char* pBuff);
extern void   AEESIM_GetDownloadConfig(char* pszServer, uint32 *dwCarrierID, uint32 *dwPlatformID);
extern void   AEESIM_GetFSLimit(MIFFSLimit * pfsLimit);
extern uint8  AEESIM_GetSoftkeyCount();
extern uint32 AEESIM_GetDeviceID(void);
extern int    AEESIM_GetDisplayInfo(AVSType avs, AEEBitmapInfo *pInfo, int *pnSize);
extern uint32 AEESIM_GetHeapSize(void);
extern uint16 AEESIM_GetEnc(void);
extern const RGBVAL *AEESIM_GetSysColors(AVSType avsCode);
extern uint32 AEESIM_GetLang(void);
extern void   AEESIM_GetKeySupported(KeySupportType *keySupport);
extern boolean AEESIM_GetAutoStartApp(AEECLSID *pcls);
extern boolean AEESIM_GetAutoStartArgs(char *pBuff, int nSize);
extern BOOL AEESIM_GetEFSMax(uint32 * pdwMaxSpace, uint32 * pdwMaxFiles);

extern boolean OEMSound_IsVibratorON(void);

//Class ID of Idle App.Launcher will attempt to start this app as an idle app
#define AEECLSID_IDLEAPP_BID     0x01010ec1

static gbCFGI_AUTOSTART = TRUE;
static AECHAR * gpCFGI_AUTOSTARTARGS = NULL;

extern RGBVAL gSysRGBs[];

static int GetFirmwareVersion(byte *pVer, int *pnVerLen);

int OEM_GetConfig(AEEConfigItem i, void * pBuff, int nSize)
{

   switch(i){
#if 0
   // Note: Added this code to better emulate the size limits on downloading apps.  

      case CFGI_CACHED_RESOURCES:
         {
         OEMResCacheInfo   *  pri = (OEMResCacheInfo *)pBuff;
         uint32               dwTotal;

         if(pri){
            GETRAMFREE(&dwTotal,NULL);
            if(dwTotal < (250 * 1024)){
               pri->nCachedFiles = 12;
               break;
            }
            pri->nCachedFiles = 24;
            return(0);
         }
         break;
         }
#endif
      
      case CFGI_FILE_CACHE_INFO:
         {
         OEMFileCacheInfo *   pi = (OEMFileCacheInfo *)pBuff;
         uint32               dwTotal;

         if(pi){
            GETRAMFREE(&dwTotal,NULL);
            if(dwTotal < (250 * 1024))
               break;
            if(dwTotal < (500 * 1024))
               pi->nCacheMax = 100 * 1024;
            else
               pi->nCacheMax = 150 * 1024;
            return(0);
         }
         break;
         }

#if defined(AEE_SIMULATOR)
      case CFGI_DOWNLOAD_FS_INFO:
         {
         DLItemSize * pi = (DLItemSize *)pBuff;

         if(!pi || nSize < sizeof(DLItemSize))
            return(EBADPARM);

         GetDownloadFSAvail(pi);
         return(0);
         }

      case CFGI_AUTOSTARTARGS:
         {
            if (gpCFGI_AUTOSTARTARGS)
            {
               if (!AEESIM_GetAutoStartArgs(pBuff, nSize))
               {
                  char *pArgs = (char *)pBuff;
                  WSTRTOSTR(gpCFGI_AUTOSTARTARGS, pArgs, nSize);
               }
            }
            return(0);
         }
#endif

     case CFGI_SYSMEM_SIZE:
         if(pBuff && nSize == sizeof(uint32)){
            *((uint32 *)pBuff) = 2048;
            return(0);
         }  
         return(EBADPARM);
         
     case CFGI_MOBILEINFO:
         if(!pBuff || nSize != sizeof(AEEMobileInfo))
            return(EBADPARM);
         GetMobileInfo((AEEMobileInfo *)pBuff);
         return(0);


      case CFGI_AUTOSTART:
         {
         AEECLSID * pcls = (AEECLSID *)pBuff;

         if(pcls && gbCFGI_AUTOSTART)
         {
#if defined(AEE_SIMULATOR)
            if (!AEESIM_GetAutoStartApp(pcls))
            {
               // could not read devicepack or invalid entry in devicepack,
               // use default
               *pcls = AEECLSID_APPMANAGER;
            }
#else
            *pcls = AEECLSID_APPMANAGER;
#endif
         }

         return(0);
         }

   case CFGI_DNS_IP1:
   case CFGI_DNS_IP2:
      {
         INAddr aa[2];
         int nWhich = (i == CFGI_DNS_IP1) ? 0 : 1;
         
         /* try to retrieve first 2 name servers */
         if ((nWhich + 1) > GetSysDNS(aa, ARR_SIZE(aa))) {
            break;
         }
         
         MEMMOVE(pBuff, &aa[nWhich], min(nSize, sizeof(INAddr)));
         return 0;
      }

   case CFGI_DOWNLOAD:
      {
      AEEDownloadInfo * pdi = (AEEDownloadInfo *)pBuff;

      if(!pBuff || nSize != sizeof(AEEDownloadInfo))
         return(EBADPARM);

      MEMSET((void *)pdi, 0, nSize);

      if(!ISHELL_GetPrefs(AEE_GetShell(), AEECLSID_OEM_DL_CONFIG, OEM_DL_CFG_VER, pBuff, (uint16)nSize))
         return(SUCCESS);
   
      // The following values correspond to values 
      // which can be used with PEK OATDownload module for
      // test purposes: 
      // 1. pdi->szServer = ADS Server
      // 2. pdi->dwCarrierID = Carrier ID
      // 3. pdi->dwPlatformID = Platform ID.
      // You may change these values in 
      // order to use the BREW Simulator with other
      // ADS servers, carrier IDs or platform IDs.
      // The values can be changed either in the Devicepack files or
      // the default values in the AEESIM_GetDownloadConfig function in 
      // ...sdkdev/src/qemu/qemu2.cpp

      AEESIM_GetDownloadConfig(pdi->szServer, &(pdi->dwCarrierID), &(pdi->dwPlatformID));

      // Specify Auth Policy for Simulator to use
      pdi->nAuth = APOLICY_NONE;
//         pdi->nAuth = APOLICY_SID;
//         pdi->nAuth = APOLICY_TEXT;
//         pdi->nAuth = APOLICY_NUM;
      pdi->wFlags = DIF_TEST_ALLOWED | DIF_MIN_FOR_SID;
      pdi->nPolicy = PPOLICY_BREW_OR_CARRIER;
      return(0);
      }

   case CFGI_SUBSCRIBERID:
      // Fetch the info from the device loaded in Simulator, or else use default
      if (!AEESIM_GetSubscriberID((char *)pBuff))
         strcpy((char *)pBuff,SIM_SUBSCRIBER_ID);   // default
      return(0);

   case CFGI_MODULE_FSLIMIT:
   {
      MIFFSLimit *   pfsLimit = (MIFFSLimit *)pBuff;

      if (!pBuff || (size_t)nSize < sizeof(MIFFSLimit))
         return EBADPARM;

      // Fetch the info from the device loaded in Simulator
      AEESIM_GetFSLimit(pfsLimit);

      return 0;
   }

   case CFGI_APP_KEY_1:
   {
      // Mechanism for the BREW Simulator to specify CFGI_APP_KEY_1.  
      // For information on using this with a device, please refer
      // to documentation for OEM_GetConfig().
      OEMConfigData* pConfigData = (OEMConfigData*)pBuff;
      uint32 dwSize;
      int nErr = EFAILED;
      void* fp;

#define APPKEY_FILENAME AEEFS_SYS_DIR"priv/appkey1.dat"

      if (OEMFS_GetAttributes(APPKEY_FILENAME, 0,0,&dwSize) == SUCCESS)
      {
         if (dwSize > pConfigData->nSize)
         {
            pConfigData->nSize = dwSize;
            nErr = ENEEDMORE;
         }
         else
         {
            nErr = OEMFS_Open(APPKEY_FILENAME, _OFM_READ, &fp);
            if (SUCCESS == nErr) {

               int32 nRead;

               nRead = OEMFS_Read(fp, pConfigData->pData, pConfigData->nSize,
                                  &nErr);

               if (nRead >= 0 && nRead <= (int32)pConfigData->nSize) {
                  nErr = SUCCESS;
               }

               pConfigData->nSize = (uint32)nRead;
               OEMFS_Close(fp);
            }
         }
      }

      return nErr;
   }

#if defined(FEATURE_BREW_DEV) || defined(AEE_SIMULATOR)
      // short safe mode timer during development and emulation
      case CFGI_SAFEMODE_TIMER:
         if(nSize != sizeof(int32))
            return EBADPARM;
         *(int32*)pBuff = 5;
         return SUCCESS;
#endif // defined(FEATURE_BREW_DEV) || defined(AEE_SIMULATOR)

      case CFGI_MOBILE_DIR_NUM_LEN:
         if(nSize != sizeof(int))
            return EBADPARM;
         *(int *)pBuff = STRLEN(SIM_SUBSCRIBER_ID) + 1;
         return SUCCESS;

      case CFGI_MOBILE_DIR_NUM:
         if(nSize < (int) STRLEN(SIM_SUBSCRIBER_ID))
            return EBADPARM;
         STRLCPY((char *)pBuff, SIM_SUBSCRIBER_ID, nSize); 
         return SUCCESS;

      case CFGI_FIRMWARE_ID_LEN:
         if(nSize != sizeof(int))
            return EBADPARM;
         return GetFirmwareVersion(NULL, (int *)pBuff);

      case CFGI_FIRMWARE_ID:
      {
         int nVerLen;
         if(GetFirmwareVersion(NULL, (int *)&nVerLen))
            return EUNSUPPORTED;
         if(nSize < nVerLen)
            return EBADPARM;
         return GetFirmwareVersion((byte *)pBuff, &nVerLen); 
      }      
     
      case CFGI_SMS_GW_SCADDRESS:           
         if(nSize < (int)(STRLEN(SIM_SUBSCRIBER_ID) + 1))
            return EBADPARM;
         STRNCPY((char*)pBuff, SIM_SUBSCRIBER_ID, STRLEN(SIM_SUBSCRIBER_ID));
         return SUCCESS;
         
      case CFGI_SMS_GW_SCADDRESS_LENGTH:           
         if(nSize < sizeof(uint32))
            return EBADPARM;         
         *(uint32*)pBuff = STRLEN(SIM_SUBSCRIBER_ID) + 1;
         return SUCCESS;
         
      // Maximum payload length in terms of number of bytes
     case CFGI_SMS_MAX_PAYLOAD_LENGTH:
         if(nSize < sizeof(uint32))
            return EBADPARM;
         *(uint32*)pBuff = 140;
         return SUCCESS;       
         
      // Default encoding for MO SMS
      case CFGI_SMS_DEFAULT_MO_ENC:
         if(nSize < sizeof(AEESMSEncType))
            return EBADPARM;
         *(AEESMSEncType*)pBuff = AEESMS_ENC_ASCII;
         return SUCCESS;
         
      // Count of encoding types available for MO SMS
      case CFGI_SMS_MO_ENC_TYPES_COUNT:  
         if(nSize < sizeof(uint32))
            return EBADPARM;
         *(uint32*)pBuff = 4;
         return SUCCESS;
         
      // Encoding types available for MO SMS
      case CFGI_SMS_MO_ENC_TYPES:
         if(nSize < sizeof(uint32)*4)
            return EBADPARM;
         *(uint32*)pBuff = AEESMS_ENC_ASCII;
         *(((uint32*)pBuff) + 1) = AEESMS_ENC_LATIN;
         *(((uint32*)pBuff) + 2) = AEESMS_ENC_UNICODE;
         *(((uint32*)pBuff) + 3) = AEESMS_ENC_OCTET;
         return SUCCESS;

      // boolean, if TRUE, SMS message is sent on access channel
      case CFGI_SMS_MO_ON_ACCESS_CHANNEL:
         if(nSize < sizeof(boolean))
            return EBADPARM;
         *(boolean*)pBuff = TRUE;
         return SUCCESS;

      // boolean, if TRUE, SMS message is sent on traffic channel. If both of
      // CFGI_SMS_MO_ON_ACCESS_CHANNEL and CFGI_SMS_MO_ON_TRAFFIC_CHANNEL
      // are TRUE, SMS message is first sent on access channel and on being
      // too large for access channel is sent on traffic channel
      case CFGI_SMS_MO_ON_TRAFFIC_CHANNEL:
         if(nSize < sizeof(boolean))
            return EBADPARM;
         *(boolean*)pBuff = TRUE;
         return SUCCESS;

      case CFGI_LNG:
         if(nSize < sizeof(uint32))
            return EBADPARM;
         *(uint32*)pBuff = AEESIM_GetLang();
         return SUCCESS;

      default:
         return(EUNSUPPORTED);
   }
   return(EBADPARM);
}



/*==================================================================
Function: OEM_SetConfig

Description: Sets configuration information from the OEM

Prototype:
   int  OEM_SetConfig(AEEConfigItem i, void * pBuff, int nSize)

Parameter(s):

Return Value:  None
Comments:      None
Side Effects:  None
See Also:      None

==================================================================*/
int OEM_SetConfig(AEEConfigItem i, void * pBuff, int nSize)
{
   // 
   // NOTE: This code should be replaced by code that stores/retrieves values in
   // NV-RAM.  You will need to add NV items for each of the items referenced here.
   //

   switch(i) {
      case CFGI_DOWNLOAD:
         return(ISHELL_SetPrefs(AEE_GetShell(), AEECLSID_OEM_DL_CONFIG, OEM_DL_CFG_VER, pBuff, (uint16)nSize));
      default:
         return(EUNSUPPORTED);
   }
   return(EUNSUPPORTED);
}

static void GetMobileInfo(AEEMobileInfo * pmi)
{
   char pszESN[OEM_MAX_ESN_STRING_SIZE];

   if(!pmi)
      return;

   MEMSET(pmi, 0, sizeof(AEEMobileInfo));

   // read the ESN from the device pack, if not found, use default
   if ( AEESIM_GetMobileInfo(pszESN, OEM_MAX_ESN_STRING_SIZE) )
   {
      // See if the value is decimal or Hex
      if ( STRSTR(pszESN, "0x") ) // Hex
      {
         pmi->dwESN = STRTOUL(pszESN, NULL, 16);
      }
      else  // decimal
         pmi->dwESN = STRTOUL(pszESN, NULL, 10);
   }
   else  // not found in device pack, use default
      pmi->dwESN = 0xbabababa;

   pmi->nCurrNAM = 100;

   strcpy(pmi->szMobileID, SIM_SUBSCRIBER_ID);
}


void OEM_GetDeviceInfo(AEEDeviceInfo * pi)
{
   AEEBitmapInfo bi;
   int nSize = sizeof(bi);

   if(!pi) 
      return;
   
   AEESIM_GetDisplayInfo(AVS_SCREEN_0, &bi, &nSize);
   
   memset(pi,0, sizeof(AEEDeviceInfo));
   pi->cxScreen = (uint16)bi.cx;
   pi->cyScreen = (uint16)bi.cy;
   pi->cxScrollBar = 4;
   pi->nColorDepth = (uint16)bi.nDepth;
   
   pi->dwRAM = AEESIM_GetHeapSize();
   
   pi->bPosLoc = 1;
   pi->dwPromptProps = CP_3D_BORDER|ST_MIDDLETEXT|ST_UNDERLINE;
   pi->wKeyCloseApp     = AVK_CLR;
   pi->wKeyCloseAllApps = AVK_END;
   
   // Set Language Support...
   pi->dwLang    = AEESIM_GetLang();
   pi->wEncoding = AEESIM_GetEnc();

   pi->wMaxPath  = (uint16)OEMFS_GetMaxPathLength();
   
#if defined(FEATURE_UI_FLIP_PHONE)
   pi->bFlip            = TRUE;
   pi->bAltDisplay      = FALSE;
   pi->cxAltScreen      = 0;
   pi->cyAltScreen      = 0;
#endif
   
#if defined(FEATURE_VIBRATOR)
   pi->bVibrator = TRUE;
#endif
   
#if defined(FEATURE_SPEAKER_PHONE)
   pi->bExtSpeaker = TRUE;
#endif
   
#if defined(FEATURE_PHONE_VR)
   pi->bVR = TRUE;
#endif

   pi->dwPlatformID = AEESIM_GetDeviceID();

}


/*===========================================================================

===========================================================================*/
int   OEM_GetDeviceInfoEx(AEEDeviceItem nItem, void *pBuff, int *pnSize)
{
   switch (nItem) {
      case AEE_DEVICEITEM_CHIP_ID:
      {
         char szStr[32];

         if(!pnSize)
            return(EBADPARM);

         if(pBuff && *pnSize) {
            STRCPY(szStr,"Simulator");
            STRTOWSTR(szStr,(AECHAR *)pBuff,*pnSize);
         }
         *pnSize = (STRLEN("Simulator")+1)*2;
         return(SUCCESS);
      }

      case AEE_DEVICEITEM_MOBILE_ID:
      {
         AEEMobileInfo mi;

         MEMSET(&mi,0,sizeof(AEEMobileInfo));

         if(!pnSize)
            return(EBADPARM);

         if(!OEM_GetConfig(CFGI_MOBILEINFO,&mi,sizeof(AEEMobileInfo))) {
            TAPI_CompressNumber(mi.szMobileID);
            if(pBuff && *pnSize > 0)
               STRLCPY(pBuff,mi.szMobileID,*pnSize);
            *pnSize = STRLEN(mi.szMobileID)+1;
            return(SUCCESS);
         }
         else
            return(EUNSUPPORTED);
      }

      case AEE_DEVICEITEM_CARRIER_ID:
      {
         AEEDownloadInfo di;

         MEMSET(&di,0,sizeof(AEEDownloadInfo));

         if(!pnSize)
            return(EBADPARM);

         if(!OEM_GetConfig(CFGI_DOWNLOAD,&di,sizeof(AEEDownloadInfo))) {
            if(pBuff && (*pnSize == sizeof(di.dwCarrierID)))
               *(uint32 *)pBuff = di.dwCarrierID;
            *pnSize = sizeof(di.dwCarrierID);
            return(SUCCESS);
         }
         else
            return(EUNSUPPORTED);
      }

      case AEE_DEVICEITEM_SYS_COLORS_DISP1:
      case AEE_DEVICEITEM_SYS_COLORS_DISP2:
      case AEE_DEVICEITEM_SYS_COLORS_DISP3:
      case AEE_DEVICEITEM_SYS_COLORS_DISP4:
      {
         const RGBVAL *pColors = AEESIM_GetSysColors(nItem - AEE_DEVICEITEM_SYS_COLORS_DISP1 + AVS_SCREEN_0);
         int nSize;

         if (NULL == pColors) {
            return EUNSUPPORTED;
         }

         if(!pnSize)
            return(EBADPARM);

         nSize = MIN(*pnSize, CLR_SYS_LAST * sizeof(RGBVAL));
         *pnSize = CLR_SYS_LAST * sizeof(RGBVAL);

         if (NULL == pBuff) {
            return SUCCESS;
         }

         MEMCPY(pBuff, pColors, nSize);

         return SUCCESS;
      }

      case AEE_DEVICEITEM_DISPINFO1:
      case AEE_DEVICEITEM_DISPINFO2:
      case AEE_DEVICEITEM_DISPINFO3:
      case AEE_DEVICEITEM_DISPINFO4:
         return AEESIM_GetDisplayInfo(nItem - AEE_DEVICEITEM_DISPINFO1 + AVS_SCREEN_0, pBuff, pnSize);

      case AEE_DEVICEITEM_SOFTKEY_COUNT:
      {
         if (!pnSize)
            return EBADPARM;

         if (pBuff && *pnSize >= sizeof(uint8))
            *((uint8 *)pBuff) = AEESIM_GetSoftkeyCount(); 
         *pnSize = sizeof(uint8);
         return SUCCESS;
      }

      case AEE_DEVICESTATE_FLIP_OPEN:
      {
         if(!pnSize)
            return(EBADPARM);

         if(!pBuff || *pnSize < sizeof(boolean)) {
            *pnSize = sizeof(boolean);
            return(SUCCESS);
         }

         *((boolean *)pBuff) = FALSE;
         *pnSize = sizeof(boolean);

         return(SUCCESS);
      }

      case AEE_DEVICESTATE_HEADPHONE_ON:
      {
         if(!pnSize)
            return(EBADPARM);

         if(!pBuff || *pnSize < sizeof(boolean)) {
            *pnSize = sizeof(boolean);
            return(SUCCESS);
         }

         *((boolean *)pBuff) = FALSE;
         *pnSize = sizeof(boolean);

         return(SUCCESS);
      }

      case AEE_DEVICESTATE_KEYGUARD_ON:
      {
         if(!pnSize)
            return(EBADPARM);

         if(!pBuff || *pnSize < sizeof(boolean)) {
            *pnSize = sizeof(boolean);
            return(SUCCESS);
         }

         *((boolean *)pBuff) = FALSE;
         *pnSize = sizeof(boolean);

         return(SUCCESS);
      }

      case AEE_DEVICESTATE_SPEAKER_ON:
      {
         if(!pnSize)
            return(EBADPARM);

         if(!pBuff || *pnSize < sizeof(boolean)) {
            *pnSize = sizeof(boolean);
            return(SUCCESS);
         }

         *((boolean *)pBuff) = FALSE;
         *pnSize = sizeof(boolean);

         return(SUCCESS);
      }

      case AEE_DEVICESTATE_VIBRATOR_ON:
      {
         if (!pnSize) {
            return(EBADPARM);
         }

         if(!pBuff || *pnSize < sizeof(boolean)) {
            *pnSize = sizeof(boolean);
            return(SUCCESS);
         }

         *((boolean *)pBuff) = OEMSound_IsVibratorON();
         *pnSize = sizeof(boolean);

         return(SUCCESS);
      }

      case AEE_DEVICEITEM_MANNER_MODE:
      {
         if (!pnSize)
            return EBADPARM;

         if (!pBuff || *pnSize < sizeof(uint32))
         {
            *pnSize = sizeof(uint32);
            return(SUCCESS);
         }
         *((uint32 *)pBuff) = (uint32)AEE_MANNER_MODE_NORMAL;
         *pnSize = sizeof(uint32);
         return SUCCESS;
      }

   case AEE_DEVICEITEM_KEY_SUPPORT:
      if (!pnSize)
         return EBADPARM;

      if (pBuff && *pnSize >= sizeof(KeySupportType))
         AEESIM_GetKeySupported((KeySupportType*)pBuff); 
      *pnSize = sizeof(KeySupportType);
      return SUCCESS;

   case AEE_DEVICEITEM_DOWNLOAD_HEADER:
      if (!pnSize)
         return EBADPARM;

      GetDownloadHeader((char *)pBuff, pnSize);

      return SUCCESS;
   
   case AEE_DEVICEITEM_ICCID:
      if (!pnSize) {
         return(EBADPARM);
      }

      if (!pBuff || *pnSize < (int)(STRLEN("Simulator") + 1)) {
         *pnSize = STRLEN("Simulator") + 1;
      } else {
         STRNCPY((char*)pBuff, "Simulator", *pnSize);
         *pnSize = (STRLEN("Simulator") + 1);
      }
      return(SUCCESS);

   default:
      return(EUNSUPPORTED);
   }
}


/*===========================================================================

===========================================================================*/
static uint32 GetDirSpace(const char * pszDir)
{
   IFileMgr *  pfm;
   uint32      dwTotal = 0;
   FileInfo    fi;

   ISHELL_CreateInstance(AEE_GetShell(), AEECLSID_FILEMGR, (void **)(&pfm));
   if(pfm){
      if(!IFILEMGR_EnumInit(pfm,pszDir,FALSE)){
         while(IFILEMGR_EnumNext(pfm,&fi)){
            if(!(fi.attrib & AEE_FA_CONST))
               dwTotal += fi.dwSize;
         }
      }                  
      IFILEMGR_Release(pfm);
   }
   return(dwTotal);
}

/*===========================================================================

===========================================================================*/
static void GetDownloadFSAvail(DLItemSize * pi)
{
   IFileMgr *  pfm;
   uint32      dwTotal = 0;
   FileInfo    fi;
   char *      psz;

#define DOWNLOAD_FS_SPACE     (1024l * 3000l)
   pi->dwFSSize = DOWNLOAD_FS_SPACE;

   AEESIM_GetEFSMax(&pi->dwFSSize, NULL);

   ISHELL_CreateInstance(AEE_GetShell(), AEECLSID_FILEMGR, (void **)(&pfm));
   if(pfm){
      if(!IFILEMGR_EnumInit(pfm,AEEFS_MOD_DIR,TRUE)){
         while(IFILEMGR_EnumNext(pfm,&fi)){
            psz = STRRCHR(fi.szName,'/');
            if(psz){
               psz++;
               if(STRTOUL(psz,NULL,10))
                  dwTotal += GetDirSpace(fi.szName);
            }
         }
      }                  
      IFILEMGR_Release(pfm);
   }

   if(dwTotal > pi->dwFSSize)
      pi->dwFSAvail = 0;
   else
      pi->dwFSAvail = pi->dwFSSize - dwTotal;
}


//Simulator Specific Functions. These are used on the BREW Simulator only. 
//These are provided here so that carriers can test the IDle App. Valid 
//values must be returned for the TimeOut and the IdleAppClass.  Then, 
//when the timeout expires, first a EVT_BUSY event is sent to the currently 
//running app. If that app returns FALSE, then the ScreenSaver is started. 
//When any key is pressed, control goes back to the currently running app.


//Return Idle App Timeout value in milliseconds
uint32 OEM_GetIdleAppTimeout()
{
   //Number of millisecons to wait before launching IdleApp. 
   //If you are using IdleApp in the Simulator, a non-zero value 
   // must be returned.
   
   // return(2000);
   
   return(0);
}

uint32 OEM_GetIdleAppCls()
{
   //If you are using IdleApp in the Simulator, please return
   //a valid classID of IdleApp to work
   
   //return(AEECLSID_IDLEAPP_BID);
   
   return(0);
}

void EnableCFGI_AUTOSTART(boolean bAutoStart)
{
   gbCFGI_AUTOSTART = bAutoStart;
}

boolean OEM_IsClsOKInSafeMode(uint32 clsid)
{
   // always need to be able to start the core app
   if (AEECLSID_APPMANAGER == clsid) {
      return TRUE;
   }

   return FALSE;
}

void SetCFGI_AUTOSTARTARGS(AECHAR * pArgs)
{
   gpCFGI_AUTOSTARTARGS = pArgs;
}

static int GetFirmwareVersion(byte *pVer, int *pnVerLen)
{
   OSVERSIONINFOEX osvi;
   BOOL            bOsVersionInfoEx;
   char            szFirmware[64];

   if(!pnVerLen)
      return EFAILED;

   MEMSET(&osvi, 0, sizeof(OSVERSIONINFOEX));
   MEMSET(szFirmware, '\0', 64);


   osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

   if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
   {
      // If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.
      osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
      if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) 
         SNPRINTF(szFirmware, 64, "1.2.3.4");
   }
   SNPRINTF(szFirmware, 64, "%d.%d.%d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber, osvi.dwPlatformId);

   if(!pVer)
      *pnVerLen = STRLEN(szFirmware) + 1;
   else
      STRLCPY(pVer, szFirmware, *pnVerLen);

   return SUCCESS;
}
