/*===========================================================================
                              OEMSVC.c

  OEM REFERENCE SUPERVISOR MODE FUNCTIONS SUPPORTING 
  USER MODE APPLICATION CONTROL ROUTINES
  
  This file contains a reference implementation of Supervisor mode services that
  OEMs need to provide in order to support BREW. Most functions defined here are
  called from OEM porting layers such as OEMAppFuncs, OEMNotify, etc. The functions
  specified in this file are not all mandatory. The OEM can add, delete, or modify
  functions in this file to support the functions in OEMAppFuncs and OEMNotify. 
  The file bridle_oemsvc.c must be modified accordingly and the new functions added
  must follow the rules for implementing BRIDLE interfaces as specified in the
  'How to BRIDLE' document. The files bridle_oemsvc.h and bridle_oemsvc.c may be used
  as reference.
    
        Copyright © 1999-2003 QUALCOMM Incorporated.
               All Rights Reserved.
            QUALCOMM Proprietary/GTDR
============================================================================*/

#include "dsiface.h"
#include "dssocket.h"
#include "target.h"
#include "customer.h"
#if !defined(AEE_SIMULATOR)
#include "bit.h"
#include "ui.h"
#include "voc.h"
#endif

#include "OEMFeatures.h"
#include "OEMDisp.h"
#include "AEEComdef.h"

#if defined(OEMAPPFUNCS)

#include "OEMConfig.h"
#include "OEMNotify.h"
#include "AEE_OEMDispatch.h"
#include "AEEShell.h"
#include "AEEStdLib.h"
#include "AEEPhone.h"
#include "AEEFile.h"

#ifdef FEATURE_UI_CORE
#include "CoreApp.h"
#endif /* FEATURE_UI_CORE */

#include "AEEDownload.h"
#ifdef FEATURE_PROVISION
#include "OEMProvisionItems.h"
#endif // FEATURE_PROVISION

#include "nv.h"
#include "nvi.h"

#ifdef FEATURE_UIM_RUIM
#include "rex.h"
#include "uim.h"
#include "nvruimi.h"
extern nvruim_esn_usage_type nvruim_esn_usage;
#endif

#ifdef FEATURE_DYNAMIC_CLOCK_FREQUENCY_CHANGING
#include "clkregim.h"
#endif

#include "OEMSMS.h"
#include "AEESMS.h"

#if defined(FEATURE_UIM_RUIM)
#define UI_RUIM_SIG  0x2000
#define CARD_ID_SIZE    ((word)(sizeof(((nv_item_type *) 0)-> esn.esn )))

void OEM_IssueRUIMCmd(uim_cmd_type *uim_cmd_ptr);
static void UIM_Report(uim_rpt_type *report);

#endif

typedef struct _NVMap
{
   AEEConfigItem        cfgi;
   nv_items_enum_type   nvi;
} NVMap;

#if defined(FEATURE_UIM_RUIM)
static uim_cmd_type        gUimCmd;
static uim_rpt_type        gCallBack;
#endif

static AEECallback   gCBReset;   
static boolean       gbReset = FALSE;
static AEECallback   gCBStartCoreApp;

static void GetMobileInfo(AEEMobileInfo * pmi);
static void WaitNV(void);

//
// Used for OEM_SetDataNetwork (below) 
//
#if 0
extern byte ds_atcop_pkt_orig_str[NV_MAX_PKT_ORIG_DIGITS];
extern byte ds_atcop_pkt_orig_str_len;
#endif

extern int OEMDisp_GetDispInfo(AEEDeviceInfo* pi);

#ifdef FEATURE_PROVISION
static int ReadNV(AEEConfigItem i, ProvisionItem * pi,int nSize);

static const NVMap   gNVMap[] = {{CFGI_MIN2,             NV_MIN2_I},
                                 {CFGI_ROAMING_LIST,     NV_ROAMING_LIST_683_I},
                                 {CFGI_BANNER,           NV_BANNER_I},
                                 {CFGI_NAME_NAM,         NV_NAME_NAM_I},
                                 {CFGI_ANALOG_FIRSTCHP,  NV_ANALOG_FIRSTCHP_I},
                                 {CFGI_ANALOG_REG,       NV_ANALOG_REG_I},
                                 {CFGI_ANALOG_HOME_SID,  NV_ANALOG_HOME_SID_I},
                                 {CFGI_PCDMACH,          NV_PCDMACH_I},
                                 {CFGI_SCDMACH,          NV_SCDMACH_I},
                                 {CFGI_SYSTEM_PREF,      NV_SYSTEM_PREF_I},
                                 {CFGI_PREF_MODE,        NV_PREF_MODE_I},
                                 {CFGI_HOME_SID_NID,     NV_HOME_SID_NID_I},
                                 {CFGI_MIN_CHKSUM,       NV_MIN_CHKSUM_I},
                                 {(AEEConfigItem)0,      (nv_items_enum_type)0}};
#endif // FEATURE_PROVISION


#if defined(FEATURE_UIM_RUIM)
/*===========================================================================

Function: OEMCard_Report

===========================================================================*/
static void UIM_Report(uim_rpt_type *report)
{
   MEMCPY(&gCallBack, report, sizeof(uim_rpt_type));
   rex_set_sigs( &ui_tcb, UI_RUIM_SIG);
}
#endif

/*==================================================================
Function: OEM_SVCGetConfig

Description: Retrieves configuration information from the OEM

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

Parameter(s):

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

==================================================================*/
int OEM_SVCGetConfig(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.
   //

   // Make sure we have a valid buffer
   if(!pBuff)
      return EBADPARM;

   switch(i){


   //
   // DNS Addresses - Used by the HTTP layer, etc.
   //

      case CFGI_DNS_IP1:
         if( nSize != sizeof( uint32 ) ) {
            return EBADPARM;
         }
         {
            nv_item_type nvItem;
            if(NV_DONE_S == ui_get_nv(NV_PRIMARY_DNS_I, &nvItem))
         {
               *(uint32*)pBuff = dss_htonl(nvItem.primary_dns);
               return SUCCESS;
            }
            else
               return EFAILED;
         }

      case CFGI_DNS_IP2:
         if( nSize != sizeof( uint32 ) ) {
            return EBADPARM;
         }
         {
            nv_item_type nvItem;
            if(NV_DONE_S == ui_get_nv(NV_SECONDARY_DNS_I, &nvItem))
            {
               *(uint32*)pBuff = dss_htonl(nvItem.secondary_dns);
               return SUCCESS;
            }
            else
               return EFAILED;
         }

   // 
   // Download information - specific to the carrier/handset
   //

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

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

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

      	 //bBKey -- Leave as 0s?
         //bAKey -- Leave as 0s?
         pdi->dwCarrierID  = 2;
      	 pdi->dwPlatformID = 4000;//500;
      	 STRCPY(pdi->szServer,"internaldemo.qualcomm.com");
      	 pdi->wFlags       = DIF_TEST_ALLOWED|DIF_MIN_FOR_SID;
         pdi->nAuth        = APOLICY_NONE;
         pdi->nPolicy      = PPOLICY_BREW_OR_CARRIER;
      	 return SUCCESS;
         }

   //
   // Subscriber ID -- 32-byte Subscriber ID in ASCII
   //
      
      case CFGI_SUBSCRIBERID:
         return(EUNSUPPORTED);

   //
   // Mobile ID information - generally, this is the MIN
   //
      case CFGI_MOBILEINFO:
        if (nSize != sizeof(AEEMobileInfo))
           return(EBADPARM);
         GetMobileInfo((AEEMobileInfo *) pBuff);

         return SUCCESS;

   //
   // AutoStart Application - This app will be started by BREW after AEE_Init
   // completes and the next time AEE_Dispatch is called.
   //

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

         if(nSize != sizeof(AEECLSID))
            return(EBADPARM);
#ifdef FEATURE_UI_CORE
         *pc = AEECLSID_CORE_APP;  
#else
         *pc = 0;
#endif /* FEATURE_UI_CORE */
         return SUCCESS;
         }

      case CFGI_BUSY_CURSOR_OFFSET:
      case CFGI_DOWNLOAD_BUFFER:
      case CFGI_HTTP_BUFFER:           
      case CFGI_NET_CONNTIMEOUT:       
      case CFGI_SUBSCRIBERID_LEN:      
      case CFGI_MAX_DISPATCH_TIME:     
      case CFGI_MIN_IDLE_TIME:         
      case CFGI_SLEEP_TIMER_RESOLUTION:
      case CFGI_SYSMEM_SIZE:           
      case CFGI_DOWNLOAD_FS_INFO:      
      case CFGI_SCREEN_SAVER:         
      case CFGI_CLOSE_KEYS:           
      case CFGI_FILE_CACHE_INFO:      
      case CFGI_GPSONE_TRANSPORT:     
      case CFGI_GPSONE_SVRIP:         
      case CFGI_GPSONE_SVRPORT:       
      case CFGI_GPSONE_LOCK:
         return EUNSUPPORTED;

   //
   // Default file system limits for apps.
   //

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

         if (nSize < sizeof(MIFFSLimit))
            return EBADPARM;

#if !defined(AEE_SIMULATOR)
         //
         // NOTE: OEMs can enforce their (per module) defaults here...
         //
         pfsLimit->wMaxFiles = MAX_FILES_UNLIMITED;
         pfsLimit->dwMaxSpace = MAX_SPACE_UNLIMITED;
#else
#error Simulator CFGI_MODULE_FSLIMIT code is located in a different file
#endif // !defined(AEE_SIMULATOR)

         return SUCCESS;
      }

   //
   // Card ID (RUIM/SIM) support
   //
#if defined (FEATURE_UIM_RUIM)
      case CFGI_CARDID_LEN:
      case CFGI_CARDID:
      {
         int   nErr = SUCCESS;
         byte *buffer;

         buffer = MALLOC(CARD_ID_SIZE);
         if(!buffer){
           return(EFAILED);
         }
            
         // Prepare to read the id EF.
         gUimCmd.access_uim.hdr.command            = UIM_ACCESS_F;
         gUimCmd.access_uim.hdr.cmd_hdr.task_ptr   = NULL;
         gUimCmd.access_uim.hdr.cmd_hdr.sigs       = 0;
         gUimCmd.access_uim.hdr.cmd_hdr.done_q_ptr = NULL;
         gUimCmd.access_uim.hdr.options            = UIM_OPTION_ALWAYS_RPT;
         gUimCmd.access_uim.hdr.protocol           = UIM_CDMA;
         gUimCmd.access_uim.hdr.rpt_function       = UIM_Report;
            
         gUimCmd.access_uim.item      = UIM_CDMA_RUIM_ID;
         gUimCmd.access_uim.access    = UIM_READ_F;
         gUimCmd.access_uim.rec_mode  = UIM_ABSOLUTE;
         gUimCmd.access_uim.num_bytes = CARD_ID_SIZE;
         gUimCmd.access_uim.offset    = 1;
         gUimCmd.access_uim.data_ptr  = buffer;
            
         // From nvruim_access():  Access an EF, do not signal any task, use no
         // signal, no done queue, use a callback, always report status.
            
         // Send the command to the R-UIM:
         (void) rex_clr_sigs(&ui_tcb, UI_RUIM_SIG);
         uim_cmd(&gUimCmd);
         (void) rex_wait(UI_RUIM_SIG);

         if ((gCallBack.rpt_type   != UIM_ACCESS_R) ||
            (gCallBack.rpt_status != UIM_PASS)) {
            FREE(buffer);
            return(EFAILED);
         }
            
         if(i == CFGI_CARDID_LEN){
            if(nSize == sizeof(int)){
               *((int*)pBuff) = gUimCmd.access_uim.num_bytes_rsp;
            }else{
               nErr = EBADPARM;
            }
         }else{
            nSize = MIN(nSize, gUimCmd.access_uim.num_bytes_rsp);
            MEMCPY(pBuff, buffer, nSize);
         }
         FREE(buffer);
         return(nErr);
      }
#endif  

      case CFGI_DEBUG_KEY:          
         return EUNSUPPORTED;

      case CFGI_ALLOW_3G_2G_FAILOVER:
         if(nSize != sizeof(boolean))
            return EBADPARM;
         // Allow failover
         *(boolean*)pBuff = TRUE;
         return SUCCESS;

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

      case CFGI_SMS_EMAIL_DEST:           
         if(nSize < (STRLEN("6245") + 1))
            return EBADPARM;
         STRNCPY((char*)pBuff, "6245", STRLEN("6245"));
         return SUCCESS;
         
      case CFGI_SMS_EMAIL_DEST_LENGTH:           
         if(nSize < sizeof(uint32))
            return EBADPARM;         
         *(uint32*)pBuff = STRLEN("6245") + 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 = GetLngCode();
         return SUCCESS;

      case CFGI_SMS_GW_DOMAIN_PREF:
         if(nSize < sizeof(uint32))
            return EBADPARM;
         return OEMSMS_GetDomainPref((int*)pBuff);
     
      default:
#ifdef FEATURE_PROVISION
         if((i >= CFGI_PROVISION_FIRST) && (i <= CFGI_PROVISION_LAST))
         return(ReadNV(i,(ProvisionItem *)pBuff,nSize));
         else
            return EUNSUPPORTED;
#else 
         return(EUNSUPPORTED);
#endif // FEATURE_PROVISION


   }
   return(EBADPARM);
}

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

===========================================================================*/
#ifdef FEATURE_PROVISION
static int ReadNV(AEEConfigItem i, ProvisionItem * pi,int nSize)
{
   int      nErr;
   byte *   pnv;
   NVMap *  pm;

   if(nSize < sizeof(ProvisionItem))
      return(EUNSUPPORTED);

   for(pm = (NVMap *)gNVMap; pm->cfgi; pm++){
      if(pm->cfgi == i){
         pnv = (byte *)MALLOC(sizeof(nv_item_type));
         if(!pnv)
            return(ENOMEMORY);
         *pnv = (byte)pi->nNAM;
         if(ui_get_nv(pm->nvi, (nv_item_type *)pnv) == NV_DONE_S){
            MEMCPY((void *)pi->pDest,pnv,pi->nSize);
            nErr = 0;
         }
         else
            nErr = EFAILED;
         FREE(pnv);
         return(nErr);
      }
   }      
   return(EUNSUPPORTED);
}

#endif // FEATURE_PROVISION


/*==================================================================
Function: OEM_SVCSetConfig

Description: Sets configuration information from the OEM

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

Parameter(s):

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

==================================================================*/
int OEM_SVCSetConfig(AEEConfigItem i, void * pBuff, int nSize)
{
   if(!pBuff)
      return(EBADPARM);

#ifdef FEATURE_PROVISION
 {
    NVMap * pm;
    
    for(pm = (NVMap *)gNVMap; pm->cfgi; pm++){
       if(pm->cfgi == i){
          if(ui_put_nv(pm->nvi,(nv_item_type *)pBuff) == NV_DONE_S)
             return(0);
          return(EFAILED);
       }
    }
 }
#endif // FEATURE_PROVISION

   switch(i) {

      case CFGI_DOWNLOAD:
//#error OEM must save the download settings and return the same in OEM_GetConfig() for CFGI_DOWNLOAD
         break;

      case CFGI_LNG:
         if(nSize < sizeof(uint32))
            return EBADPARM;
         return SetLngCode(*(uint32*)pBuff);

      case CFGI_SMS_GW_DOMAIN_PREF:
         if(nSize < sizeof(uint32))
            return EBADPARM;
         return OEMSMS_SetDomainPref(*(int*)pBuff);

      default:
         break;
   }

   return(EUNSUPPORTED);
}


boolean OEM_SVCIsVocCapable(voc_capability_type vocCap)
{
return voc_capability_supported(vocCap);

}



/*==================================================================
Function: OEM_SimpleBeep

Description:
   This function plays a standard OEM beep tone and vibration given
the duration, and returns TRUE if successful.

Prototype:
   boolean OEM_SimpleBeep(BeepType nBeepType, boolean bLoud);

Parameters:
   nBeepType: beep type which can be one of the following:
      - BEEP_OFF: stop playback of the current beep or vibration
      - BEEP_ALERT: alert beep tone
      - BEEP_REMINDER: reminder beep tone
      - BEEP_MSG: message beep tone
      - BEEP_ERROR: error beep tone
      - BEEP_VIBRATE_ALERT: alert vibration
      - BEEP_VIBRATE_REMIND: reminder vibration
   bLoud: boolean flag that sets the playback volume high or low

Return Value:
   TRUE if successfuly played or stopped the tone or vibration;
   FALSE otherwise/unsupported.

Comments:
   None

Side Effects:
   None

See Also:
   None
==================================================================*/
boolean OEM_SVCSimpleBeep(BeepType nBeepType, boolean bLoud)
{
   switch( nBeepType )
   {
   case BEEP_OFF:
      // Turn current BEEP sound off
      uisnd_snd_stop();
      return TRUE;
   case BEEP_ALERT:
      // Use Alert Beep sound
      uisnd_snd(UI_MSG_SND, SND_ALERT);
      return TRUE;
   case BEEP_REMINDER:
      // Use Reminder Beep sound
      uisnd_tone(UI_MSG_SND, SND_WARN, 300);
      return TRUE;
   case BEEP_MSG:
      // Use New Message Beep Sound
      uisnd_tone(UI_MSG_SND, SND_MSG_WAITING, 300);
      return TRUE;
   case BEEP_ERROR:
      // Use Errpor Beep sound
      uisnd_tone(UI_MSG_SND, SND_ERR, 300);
      return TRUE;
   case BEEP_VIBRATE_ALERT:
      // Use Alert Sound
      return TRUE;
   case BEEP_VIBRATE_REMIND:
      // Use Vibrate Reminder
      return TRUE;
   default:
      break;
   }
   return FALSE;
}

#if 0
/*==============================================================
Function: OEM_GetDefaultNetInfo


 Fill the dial, username and password strings for the default
 data network.

==============================================================*/
static void OEM_GetDefaultNetInfo(DataNetworkInfo * pi)
{
   STRCPY(pi->szDial,"#777");
}

/*==============================================================
Function: OEM_GetDataNetInfo


 Fill the dial, username and password strings for the default
 data network.

==============================================================*/
static void OEM_GetDataNetInfo(DataNetworkInfo * pi)
{
   STRCPY(pi->szDial,"#777");
}

/*==============================================================
Function: OEM_GetDownloadNetInfo


 Fill the dial, username and password strings for the default
 data network.

==============================================================*/
static void OEM_GetDownloadNetInfo(DataNetworkInfo * pi)
{
   STRCPY(pi->szDial,"#777");
}
#endif


/*===========================================================================
            Local Functions
==========================================================================*/
static void GetMobileInfo(AEEMobileInfo * pmi)
{
   nv_cmd_type   nv_item;   // To get mobile information from NV
   static uint32 me_esn;
   static uint8 cur_nam;
   static nv_mob_dir_data_type mobile_dir; 
   static char mobile_number[NV_DIR_NUMB_PCS_SIZ+1];
   int i;
#ifdef FEATURE_UIM_RUIM
   nvruim_esn_usage_type nv_esn_type;
#endif

   if(!pmi)
      return;
   memset(pmi, 0, sizeof(AEEMobileInfo));

#ifdef FEATURE_UIM_RUIM
   nv_esn_type = nvruim_esn_usage;
   nvruim_set_esn_usage(NV_RUIM_USE_ESN);
#endif /* FEATURE_UIM_RUIM */ 

   nv_item.tcb_ptr = rex_self();    /* Notify this task when done */
   nv_item.sigs = UI_NV_SIG;
   nv_item.done_q_ptr = NULL;
   nv_item.item = NV_ESN_I;
   nv_item.cmd = NV_READ_F;
   nv_item.data_ptr = (nv_item_type *)&(me_esn);

   /* Clear the return signal, call NV, and wait for a response */
   (void) rex_clr_sigs( rex_self(), UI_NV_SIG );
   nv_cmd( &nv_item );
   WaitNV();

#ifdef FEATURE_UIM_RUIM
   nvruim_set_esn_usage(nv_esn_type);
#endif /* FEATURE_UIM_RUIM */ 

   /* Read the current NAM */
   nv_item.item = NV_CURR_NAM_I;
   nv_item.data_ptr = (nv_item_type *) &(cur_nam);
   /* Clear the return signal, call NV, and wait for a response */
   (void) rex_clr_sigs( rex_self(), UI_NV_SIG );
   nv_cmd( &nv_item );
   WaitNV();

   nv_item.item = NV_DIR_NUMBER_PCS_I;
   mobile_dir.nam = cur_nam;
   nv_item.data_ptr = (nv_item_type *) &(mobile_dir);
   /* Clear the return signal, call NV, and wait for a response */
   (void) rex_clr_sigs( rex_self(), UI_NV_SIG );
   nv_cmd( &nv_item);
   WaitNV();

   {
      int ZeroFillCount = 15 - mobile_dir.n_digits;
      // Fill in 0s in the first few spaces
      for(i = 0; i < ZeroFillCount; i++)
      {
         mobile_number[i] = '0';
      }
      
      for (i = ZeroFillCount; i < 15; i++)
      {
         // If the digit is 10... it should really be 0.
         if(mobile_dir.digitn[i - ZeroFillCount] == 10)
            mobile_number[i] = '0';       
         else
            mobile_number[i] =  ((char) (mobile_dir.digitn[i-ZeroFillCount])) + '0'; 
      }
   }
   mobile_number[15] = '\0';
   // Ignore the mobile id for now */

   pmi->dwESN = me_esn;
   pmi->nCurrNAM = cur_nam;
   strcpy(pmi->szMobileID, mobile_number);

   return;
}  /* GetMobileInfo */

/*===========================================================================
FUNCTION WaitNV

DESCRIPTION
  Wait on NV actions.  Handle signals as they come in just in case NV
  takes a while.  Only time critical watchdog signals are 
  acknowledged.

DEPENDENCIES
  There is a command sent to NV, and this task will be signalled.  

RETURN VALUE
  None

SIDE EFFECT
  Some signals are ignored till we're done with NV

===========================================================================*/
static void WaitNV( void )
{
  rex_sigs_type sigs;             /* hold signals from rex_wait() */

  for( ;; ) 
  {                     /* until signal back from NV */
    sigs = rex_wait(UI_NV_SIG);
  
    /* The NV is done.  Exit this routine. */
    if( sigs & UI_NV_SIG )
    {
      return;
    }
  }
} /* End WaitNV */

static uint32 GetLngCode(void)
{
   uint32 lang = LNG_ENGLISH;
   IShell * shell_ptr = 0;
   
   shell_ptr = AEE_GetShell();

   if (shell_ptr)
   {
      IFileMgr * pfm = 0;
      ISHELL_CreateInstance(shell_ptr, AEECLSID_FILEMGR, (void **) (&pfm));
      if (pfm)
      {
         IFile * pf = 0;
         pf = IFILEMGR_OpenFile(pfm, AEEFS_SYS_DIR"lang.dat", _OFM_READ);
         if (pf)
         {
            char lan_str[11];
            int32 count = IFILE_Read(pf, lan_str, 11);
            if (count)
            {
               char * endptr;
               unsigned long val = STRTOUL(lan_str, &endptr, 16);
               if (val)
                  lang = val;
            }
            IFILE_Release(pf);
         }
         else
         {
            int ferr = IFILEMGR_GetLastError(pfm);
            DBGPRINTF("GetLngCode : open file error = %d", ferr);
         }
         IFILEMGR_Release(pfm);
      }
   }

   return lang;
}

static int SetLngCode(uint32 dwLngCode)
{
   int nErr = EFAILED;
   IShell * shell_ptr = 0;
   
   shell_ptr = AEE_GetShell();

   if (shell_ptr)
   {
      IFileMgr * pfm = 0;
      ISHELL_CreateInstance(shell_ptr, AEECLSID_FILEMGR, (void **) (&pfm));
      if (pfm)
      {
         IFile * pf = 0;
         if (IFILEMGR_Test(pfm, AEEFS_SYS_DIR"lang.dat") == SUCCESS)
         {
            pf = IFILEMGR_OpenFile(pfm, AEEFS_SYS_DIR"lang.dat", _OFM_READWRITE);
         }
         else
         {
            pf = IFILEMGR_OpenFile(pfm, AEEFS_SYS_DIR"lang.dat", _OFM_CREATE);
         }
         if (pf)
         {
            char lan_str[11];
            MEMSET(lan_str, 0, sizeof(lan_str));
            SNPRINTF(lan_str, sizeof(lan_str), "0x%.8x", dwLngCode);
            if (IFILE_Write(pf, lan_str, 11))
            {
               nErr = SUCCESS;
            }
            IFILE_Release(pf);
         }
         else
         {
            nErr = IFILEMGR_GetLastError(pfm);
            DBGPRINTF("SetLngCode : open file error = %d", nErr);
         }
         IFILEMGR_Release(pfm);
      }
   }

   return nErr;
}
#endif
