--- /dev/null
+/*===========================================================================\r
+\r
+ N V I T E M M A N A G E R T A S K\r
+DESCRIPTION\r
+ All the declarations and definitions necessary to support the table \r
+ lookup of mapping between an NV item and the Flash File System files\r
+ which simulate storage in an EEPROM. External tasks queue requests for\r
+ this task for NV EEPROM read and write operations. This tasks then \r
+ performs the necessary internal operations to read, write\r
+ and control access to the Flash File System files which simulate storage\r
+ in an EEPROM. \r
+ This task includes the following files:\r
+ nv.h - NVM Item Manager task services\r
+ nvim.h, nvim.c - NVM Item Manager item services\r
+ nvio.h, nvio.c - NVM Item Manager read/write services\r
+ nvi.h - Common definitions\r
+\r
+EXTERNALIZED FUNCTIONS\r
+ nv_write_err_log\r
+ Write an error log without requiring any tasking services.\r
+ nv_read_err_log\r
+ Read an error log without requiring any tasking services.\r
+ nv_cmd\r
+ This is the applications read and write interface to this task.\r
+ nv_task\r
+ This is the nv task initialization entry, started up with rex_def_task.\r
+ \r
+INITIALIZATION AND SEQUENCING REQUIREMENTS\r
+ This task should be started up with rex_def_task. Caution must be\r
+ taken when invoking error services from this task. These services invoke\r
+ this task again (to log errors) and could cause an infinite loop.\r
+ \r
+\r
+Copyright (c) 2005-2010 by QUALCOMM, Incorporated.\r
+All Rights Reserved.\r
+Qualcomm Confidential and Proprietary\r
+\r
+===========================================================================*/\r
+\r
+\r
+/*===========================================================================\r
+\r
+ EDIT HISTORY FOR FILE\r
+\r
+$Header: //source/qcom/qct/core/pkg/2H09/halcyon_modem/rel/LA2.0/AMSS/products/7x30/core/services/nv/src/nvim.c#1 $ $DateTime: 2010/10/20 22:41:15 $ $Author: cbirch $\r
+ \r
+when who what, where, why\r
+-------- --- ---------------------------------------------------------\r
+10/12/09 as Moved nvdiag_init call in to NVIM task \r
+09/25/09 pc Dual SIM/Dual Standby support for LCU\r
+07/23/09 sri UMTS build support for remoted functions: nv_rtre_control,\r
+ nv_rtre_polling_for_nam and nv_rtre_polling_control\r
+07/08/09 sri Moved function implementations from nv.h and removed inline\r
+05/27/09 sri Adding "default" case in nvim_remove_item and the function\r
+ nv_cmd_remote() modified to protect some NV items remote\r
+ read/write access under FEATURE_NV_ACCESS_FILTER\r
+03/18/09 sri NV task priority is kept unchanged.\r
+01/08/08 pc Ensured mutex initialization for synchronous calls.\r
+12/13/07 pc Introduced kxmutexes around NV access.\r
+06/08/07 pc Added support for mdn based nai\r
+12/15/06 ck Include the header file fs_diag_access.h\r
+06/05/05 pc Created NV-2.\r
+===========================================================================*/\r
+\r
+/* ======================================================================\r
+\r
+ INCLUDE FILES FOR MODULE\r
+\r
+========================================================================*/\r
+\r
+#include "target.h"\r
+#include "comdef.h"\r
+#include "AEEstd.h"\r
+#ifdef FEATURE_NV_ITEM_MGR\r
+\r
+#include "nvim.h"\r
+#include "msg.h"\r
+#include "nvio.h"\r
+#include "err.h"\r
+#include "task.h"\r
+#include "dog.h"\r
+#include "crc.h"\r
+#include "memory.h"\r
+#include "fs_public.h"\r
+#include "nv_items.h"\r
+#include "fs_diag_access.h"\r
+\r
+#ifdef FEATURE_CDMA1X\r
+ #include "mc.h"\r
+#else\r
+ #include "tmc.h"\r
+#endif\r
+\r
+#ifdef FEATURE_TREX\r
+#error code not present\r
+#endif\r
+#include "nvim_items.h"\r
+#ifdef FEATURE_TREX\r
+#error code not present\r
+#endif\r
+\r
+#ifdef FEATURE_NV_RUIM\r
+#include "nvruimi.h"\r
+#endif\r
+\r
+#ifdef FEATURE_NV_CNV\r
+#include "fs_public.h"\r
+#include "nv_cnv.h"\r
+#endif\r
+\r
+#ifdef FEATURE_MDN_BASED_NAI\r
+#define PS_NAI_DFLT_DOMAIN "@default.com"\r
+#include "dsmip.h"\r
+#endif /* FEATURE_MDN_BASED_NAI */\r
+\r
+#ifdef FEATURE_WINCE\r
+#error code not present\r
+#else\r
+ #ifdef FEATURE_QUARTZ_135\r
+ #include "quartz/KxMutex.h"\r
+ #else\r
+ #include <KxMutex.h>\r
+ #endif\r
+#endif\r
+\r
+#include <stdlib.h> \r
+\r
+\f \r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+/* */\r
+/* DATA DEFINITIONS */\r
+/* */\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+\r
+static KxMutex nv_access_op_cs;\r
+\r
+extern rex_crit_sect_type nv_crit_sect;\r
+extern const nvim_item_info_type nvim_item_info_table[];\r
+extern nv_rtre_control_type nv_rtre_control_value;\r
+extern nv_rtre_polling_control_type nv_rtre_polling_control_value;\r
+\r
+#ifdef FEATURE_NV_CNV\r
+/* File to back up the data into */\r
+const char *cnv_file = "/nvm/nv_cnv.bin";\r
+#endif\r
+\r
+boolean nvi_task_running=FALSE;\r
+\r
+/* Contains the roaming list "valid" indicator */\r
+boolean nv_prl_valid_data[NV_MAX_NAMS];\r
+\r
+/* Contains the roaming list "prl_version" field */\r
+word nv_prl_version_data[NV_MAX_NAMS];\r
+\r
+/* Buffer holding the union of all internal NVM storage types. Use as */\r
+/* a working buffer when reading or writing data from or to NVM and the */\r
+/* data requires translation between internal format and external format. */\r
+nvi_item_type nvi_item;\r
+\r
+/* Data buffer for individual writes/reads issued internally. */ \r
+nv_item_type local_item; \r
+\r
+/* Command buffer for individual writes/reads issued internally. */\r
+nv_cmd_type local_cmd; \r
+\r
+#ifdef NV_FEATURE_PRL_ITEMS\r
+/* Globally used buffer to contain the roaming list read-from */ \r
+/* or written-to NV memory. */\r
+nv_roaming_list_type nv_pr_list; \r
+#endif\r
+\r
+#ifdef NV_FEATURE_RENTAL_ITEMS\r
+#error code not present\r
+#endif\r
+\r
+/* Dynamic pool available in EFS */\r
+word nvi_memavail_data=0;\r
+\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+/* */\r
+/* REX Timers and Queues */\r
+/* */\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+\r
+rex_timer_type nv_rpt_timer; /* NV watchdog report timer. */\r
+rex_timer_type nv_write_timer; /* NVM write timer. */\r
+LOCAL q_type nv_cmd_q; /* NV task command queue. */\r
+\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+/* */\r
+/* Local Data */\r
+/* */\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+\r
+\r
+/* Flag to determine if EEPROM initialization has occurred */\r
+static boolean nvi_initialized = FALSE;\r
+\r
+/* Flag to determine if kxmutex initialization has occured */\r
+static boolean nv_cs_init_flag = FALSE;\r
+\r
+/* The total factory data block cache for peek/poke access */\r
+byte fact_data[NVIM_FACTORY_DATA_SIZE];\r
+\r
+static boolean nverr_init( void );\r
+static void nverr_update_log( void );\r
+\r
+extern void nvdiag_init (void);\r
+\r
+/* Structure used to essentially double buffer the error log */\r
+struct \r
+{\r
+ nv_err_log_type external[NV_MAX_ERR_LOG];\r
+ nv_err_log_type internal[NV_MAX_ERR_LOG];\r
+ boolean update_required[NV_MAX_ERR_LOG];\r
+ boolean update_in_progress[NV_MAX_ERR_LOG];\r
+ boolean processing_required;\r
+} nverr_log;\r
+\r
+#if defined( FEATURE_UIM_RUN_TIME_ENABLE )\r
+/* Run Time R-UIM Enable control. Default: do not use the R-UIM */\r
+#ifdef FEATURE_RTRE_DEFAULT_IS_NV\r
+nv_rtre_control_type nv_rtre_control_value = NV_RTRE_CONTROL_NO_RUIM;\r
+#else\r
+nv_rtre_control_type nv_rtre_control_value = NV_RTRE_CONTROL_USE_RUIM;\r
+#endif\r
+/* Run Time R-UIM Enable polling control. Default: do not poll */\r
+nv_rtre_polling_control_type nv_rtre_polling_control_value = \r
+ NV_RTRE_POLLING_CONTROL_NO_POLL;\r
+#endif /* FEATURE_UIM_RUN_TIME_ENABLE */\r
+\r
+#ifdef FEATURE_DIAG_FS_ACCESS_VALIDATION\r
+ #ifdef FEATURE_EFS2\r
+ #include "fs_diag.h"\r
+ #else\r
+ #include "fsdiag.h"\r
+ #endif\r
+\r
+static const char *nv_access_dirs[] = {\r
+ "nvm"\r
+};\r
+\r
+#endif\r
+\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+/* */\r
+/* Debug Data */\r
+/* */\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+/* */\r
+/* Macros */\r
+/* */\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+\r
+\r
+#ifdef FEATURE_DIAG_FS_ACCESS_VALIDATION\r
+\r
+/*==================================================================\r
+Function: NV_CHECK_REMOTE_ACCESS\r
+\r
+Description: This functions returns access permissions for \r
+ directories specified by input parameter "path".\r
+==================================================================*/\r
+static boolean\r
+nv_check_remote_access (char *path, uint32 op_type)\r
+{\r
+ (void) path;\r
+ (void) op_type;\r
+ #ifdef FEATURE_TECHNICS_DIAG\r
+ return TRUE;\r
+#else\r
+ return FALSE;\r
+#endif\r
+\r
+}\r
+\r
+/*====================================================================\r
+Function: NV_REGISTER_REMOTE_ACCESS_CHECK\r
+\r
+Description: Registers callback function nv_check_remote_access()\r
+ with directory listed in nv_access_dirs. On any access to\r
+ nv_access_dirs directories, nv_check_remote_access will \r
+ be called to determine access permissions.\r
+=====================================================================*/\r
+void\r
+nv_register_remote_access_check (void)\r
+{\r
+ diag_fs_register_access_check (nv_access_dirs, 1, nv_check_remote_access);\r
+}\r
+#endif /* FEATURE_DIAG_FS_ACCESS_VALIDATION */\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NV_READ_ERR_LOG\r
+\r
+DESCRIPTION\r
+ This function reads an error log from NVM.\r
+\r
+DEPENDENCIES\r
+ The function MUST NOT USE ANY TASK SERVICES, so that it can be\r
+ called when tasks are not initialized. The function MUST NOT\r
+ USE ERROR SERVICES. It returns status to the caller if there\r
+ is a failure.\r
+\r
+RETURN VALUE\r
+ NV_DONE_S if it worked\r
+ NV_NOT_ACTIVE_S if item was not active\r
+ NV_FAIL_S if item could not be read\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+nv_stat_enum_type \r
+nv_read_err_log (\r
+ nv_err_log_type *nv_err_log_ptr /* Pointer where to return read data */\r
+)\r
+{\r
+ word isave; /* Save processor flags */\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+\r
+ if(!nvi_initialized) {\r
+ return NV_DONE_S; /* can not read errors before nv built */\r
+ }\r
+\r
+ /* check and reject illegal request. */\r
+ if (nv_err_log_ptr->address >= NV_MAX_ERR_LOG) {\r
+ return NV_FAIL_S;\r
+ }\r
+\r
+ /* copy the shadow copy of the error log */\r
+ INTLOCK_SAV( isave ); /* Disable interrupts and save PSW */\r
+ nv_err_log_ptr->err_count = nverr_log.external[nv_err_log_ptr->address].err_count;\r
+ std_strlcpy((char *)nv_err_log_ptr->file_name,\r
+ (char *)nverr_log.external[nv_err_log_ptr->address].file_name,\r
+ sizeof(nv_err_log_ptr->file_name));\r
+ nv_err_log_ptr->line_num = nverr_log.external[nv_err_log_ptr->address].line_num;\r
+ nv_err_log_ptr->fatal = nverr_log.external[nv_err_log_ptr->address].fatal;\r
+ INTFREE_SAV( isave ); /* Restore interrupts (PSW) */\r
+\r
+ return NV_DONE_S;\r
+} /* nv_read_err_log */\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NV_WRITE_ERR_LOG\r
+\r
+DESCRIPTION\r
+ This function writes the boot error log to NVM.\r
+\r
+DEPENDENCIES\r
+ The function MUST NOT USE ANY TASK SERVICES, so that it can be\r
+ called when tasks are not initialized. The function MUST NOT\r
+ USE ERROR SERVICES. It returns status to the caller if there\r
+ is a failure.\r
+\r
+RETURN VALUE\r
+ NV_DONE_S - if it worked\r
+ NV_FAIL_S - if item could not be written\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+nv_stat_enum_type \r
+nv_write_err_log(\r
+ nv_err_log_type *nv_err_log_ptr /* Pointer where to get write data */\r
+)\r
+{\r
+ static boolean nv_err_fataling = FALSE;\r
+ nv_stat_enum_type status; /* NV read status */\r
+ word isave;\r
+ \r
+ /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+ if (nv_err_fataling) return NV_FAIL_S;\r
+\r
+ if (!nvi_initialized) {\r
+ return NV_DONE_S; /* can not write errors before nv built */\r
+ }\r
+\r
+ /* Check if file system is error fataling */\r
+ if ((rex_self() == &fs_tcb) && (nv_err_log_ptr->fatal)) {\r
+ nv_err_fataling = TRUE; /* NV is not usable once FS err fatals */\r
+ return NV_DONE_S; /* can not write this error */\r
+ }\r
+ \r
+ /* check and reject illegal request. */\r
+\r
+ if (nv_err_log_ptr->address >= NV_MAX_ERR_LOG) {\r
+ return NV_FAIL_S;\r
+ }\r
+ /* If the task is running we queue the write to the nv part as to not\r
+ * interrupt a write in progress. This is a somewhat device dependend\r
+ * concept in that we assume a write can not be safely interrupted during\r
+ * a write, which is not true of all nv devices. \r
+ * Note that error_fatals always take the direct route.\r
+ */\r
+ if (nvi_task_running && !(nv_err_log_ptr->fatal)) {\r
+ /* put error into shadow copy of nv error record */\r
+ INTLOCK_SAV(isave);\r
+ nverr_log.processing_required = TRUE;\r
+ (void) memcpy((void *)&(nverr_log.external[nv_err_log_ptr->address]), \r
+ (void *)nv_err_log_ptr,\r
+ sizeof(nv_err_log_type)); /* data buffer size */\r
+ nverr_log.update_required[nv_err_log_ptr->address] = TRUE;\r
+ INTFREE_SAV(isave);\r
+\r
+ /* Signal the nv task that there is a buffer to process */\r
+ (void) rex_set_sigs(&nv_tcb, NV_ERR_LOG_SIG);\r
+ return NV_DONE_S;\r
+ }\r
+ else {\r
+ if ((nv_err_log_ptr->fatal)) {\r
+ nv_err_fataling = TRUE;\r
+ /* allow lower levels to run with ints disabled */\r
+ nvi_task_running = FALSE; \r
+ }\r
+\r
+ status = nvio_write_item\r
+ ( NV_ERR_LOG_I, \r
+ nv_err_log_ptr->address, /* Item index within its array */\r
+ (void *)&nv_err_log_ptr->err_count, /* data buffer */ \r
+ nvim_op_get_size(NV_ERR_LOG_I),\r
+ 0 /* context=0 implies no context is defined */\r
+ );\r
+\r
+ INTLOCK_SAV(isave);\r
+ if (!(nv_err_log_ptr->fatal)) {\r
+ (void) memcpy((void *)&(nverr_log.external[nv_err_log_ptr->address]), \r
+ (void *)nv_err_log_ptr,\r
+ sizeof(nv_err_log_type)); /* data buffer size */\r
+ }\r
+ INTFREE_SAV(isave);\r
+\r
+ return status;\r
+ }\r
+} /* nv_write_err_log */\r
+\r
+/*===========================================================================\r
+\r
+FUNCTION NVIM_OP_GET_PRESENCE\r
+\r
+DESCRIPTION\r
+ This function determines whether an entry is present.\r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ 0 : NVIM_NOT_PRESENT : Not present\r
+ 1 : NVIM_PRESENT : Present\r
+ 2 : NVIM_WRITE_ONCE : Present and write once only\r
+\r
+SIDE EFFECTS\r
+\r
+===========================================================================*/\r
+boolean \r
+nvim_op_get_presence (\r
+ nv_items_enum_type item /* Item ID */\r
+)\r
+{\r
+ if (item < NVIM_ITEM_INFO_TABLE_SIZE)\r
+ {\r
+ return nvim_item_info_table[item].is_present;\r
+ }\r
+ else\r
+ {\r
+ ERR("Item code %d out of range", item, 0, 0);\r
+ return 0;\r
+ }\r
+\r
+} /* nvim_op_get_presence */\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NVIM_OP_GET_ARRAY_SIZE\r
+\r
+DESCRIPTION\r
+ This function returns the array size of an item, given its ID (item code).\r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ Array size.\r
+\r
+SIDE EFFECTS\r
+ Only a meaningful return value if the entry is valid which is determined\r
+ by calling nv_op_is_valid_entry\r
+\r
+===========================================================================*/\r
+uint16 \r
+nvim_op_get_array_size (\r
+ nv_items_enum_type item /* Item ID */\r
+)\r
+{\r
+ if (item < NVIM_ITEM_INFO_TABLE_SIZE) {\r
+ return nvim_item_info_table[item].array_size;\r
+ }\r
+ else {\r
+ ERR("Item %d out of range", item, 0, 0);\r
+ return 0;\r
+ }\r
+} /* nvim_op_get_array_size */\r
+\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NVIM_OP_GET_SIZE\r
+\r
+DESCRIPTION\r
+ This function returns the size of an item, given its ID (item code).\r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ Item size.\r
+\r
+SIDE EFFECTS\r
+ Only a meaningful return value if the entry is valid which is determined\r
+ by calling nv_op_is_valid_entry\r
+\r
+===========================================================================*/\r
+uint32 \r
+nvim_op_get_size (\r
+ nv_items_enum_type item /* Item ID */\r
+)\r
+{\r
+ if (item < NVIM_ITEM_INFO_TABLE_SIZE)\r
+ {\r
+ return (nvim_item_info_table[item].item_size);\r
+ }\r
+ else\r
+ {\r
+ ERR("Item %d out of range", item, 0, 0);\r
+ return 0;\r
+ }\r
+} /* nvim_op_get_size */\r
+\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NV_DETERMINE_ESN_VALIDITY\r
+\r
+DESCRIPTION\r
+ This function is determines if the current ESN has been programmed with the\r
+ status of this check returned.\r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ TRUE if the current ESN is non-zero with proper checksums, else FALSE\r
+\r
+SIDE EFFECTS\r
+\r
+===========================================================================*/\r
+\r
+boolean \r
+nv_determine_esn_validity( void)\r
+{\r
+ /* This is gross, but there is not enough stack space\r
+ * for these next two items so we declare them as the appear in the enum\r
+ */\r
+ dword nv_item1_esn; /* tmp buffer for esn */\r
+ dword nv_item2_esn_chksum; /* tmp buffer for esn checksum */\r
+ nv_stat_enum_type status; /* to get status of NV operations */\r
+\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+\r
+ /* Start by reading the ESN and returning FALSE if it is now -1 */\r
+\r
+ status = nvio_read_item(NV_ESN_I,/* file handle */\r
+ 0, /* file position */\r
+ &nv_item1_esn, /* data ptr */\r
+ sizeof(nv_item1_esn), /* data count */\r
+ 0); /* context=0 implies no context is defined */\r
+\r
+ if( (status != NV_DONE_S) ||\r
+ (nv_item1_esn == 0xFFFFFFFF) ) {\r
+ /* ------------------------- */\r
+ /* The ESN has not been set, */\r
+ /* return FALSE */\r
+ /* ------------------------- */\r
+ ERR( "ESN has not been set", 0, 0, 0);\r
+ return FALSE;\r
+ }\r
+\r
+ if( nv_item1_esn == 0 ) {\r
+ QSR_MSG_HIGH( 1495149522ULL, "ESN is zero for factory test",0,0,0);//auto-gen, to change remove 'QSR_' and first param\r
+ }\r
+\r
+ /* --------------------------------------------------------------------- */\r
+ /* To get here the ESN has been set. Determine if the checksums are */\r
+ /* valid. Do this be comparing calculated checksums against stored sums */\r
+ /* --------------------------------------------------------------------- */\r
+ \r
+ status = nvio_read_item(NV_ESN_CHKSUM_I,/* file handle */\r
+ 0, /* file position */\r
+ &nv_item2_esn_chksum, /* data ptr */\r
+ sizeof(nv_item2_esn_chksum), /* data count */\r
+ 0); /* context=0 implies no context is defined */\r
+\r
+ /* --------------------------------------------------------------------- */\r
+ /* To get here the ESN is valid and this is not a pre-Version 5. */\r
+ /* Check for proper checksums and return TRUE if so, else return FALSE */\r
+ /* --------------------------------------------------------------------- */\r
+\r
+ if( crc_30_calc( (byte *)&nv_item1_esn, sizeof(nv_item1_esn) * 8) !=\r
+ nv_item2_esn_chksum) {\r
+ /* ------------------------- */\r
+ /* The ESN checksum is not */\r
+ /* valid, return FALSE */\r
+ /* ------------------------- */\r
+ ERR( "Stored ESN CHKSUM bad: %u", nv_item2_esn_chksum, 0, 0);\r
+ return FALSE;\r
+ } else {\r
+ return TRUE;\r
+ }\r
+}\r
+\r
+\f\r
+#ifdef FEATURE_NV_CNV\r
+/*======================================================================\r
+FUNCTION NVI_CNV_CHECK\r
+\r
+DESCRIPTION\r
+ This function checks for the presence of a CNV file in EFS.\r
+ If it is found, the items are inserted into the current nv.\r
+\r
+DEPENDENCIES\r
+ EFS must be initialized. The item manager must also have completed\r
+ nv_init. This routine expects to be called at the end of NV_INIT.\r
+\r
+RETURN VALUE\r
+ None\r
+\r
+SIDE EFFECTS\r
+ NV items could be updated if a valid CNV fileis present.\r
+\r
+======================================================================*/\r
+void nvim_cnv_check(void)\r
+{\r
+ int file_handle = NULL;\r
+ struct fs_stat sbuf;\r
+ fs_off_t offset;\r
+ fs_size_t size;\r
+ word crc16;\r
+ static byte buffer[32];\r
+ uint32 count;\r
+ uint32 size_left;\r
+ uint8 pad_size;\r
+\r
+\r
+ cnv_item_hdr_type item_head;\r
+ static nv_item_type item;\r
+ nv_cmd_type cmd;\r
+ nv_cmd_ext_type cmd_ext;\r
+\r
+ /* Open the file */\r
+ file_handle = efs_open(cnv_file, O_RDWR);\r
+ if (file_handle < 0)\r
+ {\r
+ QSR_MSG_HIGH ( 1964571546ULL, "Cannot open CNV file", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ return;\r
+ }\r
+\r
+ /* Stat to get the file size */\r
+ if (efs_fstat(file_handle, &sbuf) < 0)\r
+ {\r
+ QSR_MSG_HIGH ( 945998922ULL, "Error on fstat of CNV file",0,0,0);//auto-gen, to change remove 'QSR_' and first param\r
+ return;\r
+ }\r
+\r
+ /* Cycle thru the contents to check CRC */\r
+ crc16 = (word) CRC_16_STEP_SEED;\r
+\r
+ size_left = sbuf.st_size;\r
+ while (size_left > 0) {\r
+ count = size_left;\r
+ if (count > sizeof (buffer))\r
+ count = sizeof (buffer);\r
+\r
+ size = efs_read(file_handle, buffer, count);\r
+ if (size != count)\r
+ {\r
+ QSR_MSG_MED ( 2881874282ULL, "Unable to read CNV data", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ return;\r
+ }\r
+\r
+ crc16 = crc_16_step (crc16, buffer, count);\r
+ size_left -= count;\r
+ }\r
+\r
+ if (crc16 != CRC_16_OK) {\r
+ QSR_MSG_HIGH ( 2303037548ULL, "Invalid CRC for CNV data", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ return;\r
+ }\r
+\r
+ QSR_MSG_MED ( 2373619479ULL, "Valid CNV file detected", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+\r
+ /* Rewind the file back to the first item and ignore the header\r
+ for now */\r
+ offset = efs_lseek (file_handle, sizeof(cnv_header_type), SEEK_SET);\r
+\r
+ if (offset < 0)\r
+ {\r
+ QSR_MSG_HIGH ( 1998497732ULL, "Cannot seek to the beginning of the file",0,0,0);//auto-gen, to change remove 'QSR_' and first param\r
+ return;\r
+ }\r
+\r
+ size_left = sbuf.st_size - (sizeof(cnv_header_type) + sizeof(crc16)\r
+ + sizeof(cnv_item_hdr_type));\r
+\r
+ while (size_left > 0)\r
+ {\r
+ /* Read in an item. */\r
+ size = efs_read (file_handle, (void *) &item_head, sizeof (item_head));\r
+ if (size != sizeof (item_head))\r
+ {\r
+ QSR_MSG_MED ( 1772854668ULL, "Unable to read handover item header", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ return;\r
+ }\r
+\r
+ size_left -= sizeof (item_head);\r
+\r
+ QSR_MSG_MED ( 852213282ULL, "CNV item: %d, size %d", item_head.nv_item_number,\r
+ item_head.nv_item_size, 0);//auto-gen, to change remove 'QSR_' and first param\r
+\r
+ /* Read in the raw data. */\r
+ size = efs_read (file_handle, (void *) &item, item_head.nv_item_size);\r
+ if (size != item_head.nv_item_size)\r
+ {\r
+ QSR_MSG_MED ( 267230007ULL, "Unable to read CNV item", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ return;\r
+ }\r
+\r
+ /* Write the item to NV. */\r
+ cmd.item = (nv_items_enum_type) item_head.nv_item_number;\r
+ cmd.cmd = NV_WRITE_F;\r
+ cmd.data_ptr = &item;\r
+\r
+ cmd_ext.nvcmd = &cmd;\r
+ cmd_ext.context = 0;\r
+\r
+ if (nvio_write (&cmd_ext) != NV_DONE_S)\r
+ {\r
+ QSR_MSG_HIGH ( 1264321974ULL, "Unable to write handover item: %d, size %d",\r
+ item_head.nv_item_number, item_head.nv_item_size, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ }\r
+\r
+ pad_size = 0;\r
+ if ((item_head.nv_item_size % 4) != 0)\r
+ {\r
+ pad_size = 4 - (item_head.nv_item_size % 4);\r
+\r
+ offset = efs_lseek(file_handle, pad_size, SEEK_CUR);\r
+ if (offset < 0)\r
+ {\r
+ QSR_MSG_HIGH ( 1039740364ULL, "Cannot seek forward to the next item",0,0,0);//auto-gen, to change remove 'QSR_' and first param\r
+ return;\r
+ }\r
+ }\r
+ size_left -= (item_head.nv_item_size + pad_size);\r
+ }\r
+\r
+ /* Close the file */\r
+ efs_close (file_handle);\r
+\r
+ /* Remove the file since we are done updating the NV items */\r
+ if (efs_unlink (cnv_file) < 0)\r
+ {\r
+ QSR_MSG_HIGH ( 2406613708ULL, "Unable to remove CNV file", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ }\r
+} /* nvi_cnv_check */\r
+\r
+#endif /*FEATURE_NV_CNV*/\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NVIM_BUILD_SEC\r
+\r
+DESCRIPTION\r
+ This function builds all NVM variables.\r
+\r
+DEPENDENCIES\r
+\r
+RETURN VALUE\r
+ NV_DONE_S if it worked\r
+ NV_FAIL_S if a variable could not be initialized.\r
+\r
+SIDE EFFECTS\r
+\r
+===========================================================================*/\r
+\r
+static nv_stat_enum_type \r
+nvim_build_sec(void)\r
+{\r
+ nv_stat_enum_type status; /* Status to return to calling procedure */\r
+ word cnt; /* Counter for attempts to write variable */\r
+ nv_cmd_ext_type local_cmd_ext;\r
+ \r
+ /* Initialize the lock code to the default value (0000) */\r
+ for( cnt=0; cnt<NV_LOCK_CODE_SIZE; cnt++) {\r
+ local_item.lock_code.digits[ cnt] = '0';\r
+ }\r
+ \r
+ local_cmd.item = NV_LOCK_CODE_I;\r
+ local_cmd.tcb_ptr = NULL;\r
+ local_cmd.sigs = 0;\r
+ local_cmd.done_q_ptr = NULL;\r
+ local_cmd.cmd = NV_WRITE_F;\r
+ local_cmd.data_ptr = &local_item;\r
+ \r
+ local_cmd_ext.nvcmd = &local_cmd;\r
+ local_cmd_ext.context = 0; /* No context is defined */\r
+\r
+ status = nvio_write(&local_cmd_ext);\r
+ if(status != NV_DONE_S)\r
+ {\r
+ return status;\r
+ }\r
+ \r
+ /* Initialize the sec code to the default value (0000) */\r
+ for( cnt=0; cnt<NV_SEC_CODE_SIZE; cnt++) {\r
+ local_item.sec_code.digits[ cnt] = '0';\r
+ }\r
+ local_cmd.item = NV_SEC_CODE_I;\r
+ local_cmd.tcb_ptr = NULL;\r
+ local_cmd.sigs = 0;\r
+ local_cmd.done_q_ptr = NULL;\r
+ local_cmd.cmd = NV_WRITE_F;\r
+ local_cmd.data_ptr = &local_item;\r
+ \r
+ local_cmd_ext.nvcmd = &local_cmd;\r
+ local_cmd_ext.context = 0; /* No context is defined */\r
+\r
+ status = nvio_write(&local_cmd_ext);\r
+\r
+ return status;\r
+}\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NVIM_CLEAR_CRCS\r
+\r
+DESCRIPTION\r
+ This function is called to clear CRCs in NV when the NV is built. The function \r
+ clears the NAM checksums, the MIN checksums within each NAM, and, if \r
+ the ESN and IMEI have not already been written (assigned), the ESN, the IMEI,\r
+ the ESN checksum, the IMEI checksum. This action lets higher level tasks \r
+ know that these parameters are not valid and that service programming is \r
+ required.\r
+\r
+DEPENDENCIES\r
+ NVM must have been built.\r
+\r
+RETURN VALUE\r
+ NV_DONE_S if it worked\r
+ NV_FAIL_S if the EEPROM access has failed\r
+\r
+SIDE EFFECTS\r
+ NV parameters identified above are zeroed.\r
+\r
+===========================================================================*/\r
+\r
+LOCAL nv_stat_enum_type \r
+nvim_clear_crcs (void)\r
+{\r
+ byte nam_idx; /* NAM counter */\r
+ byte min_idx; /* MIN counter */\r
+ nv_cmd_ext_type local_cmd_ext;\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+\r
+ /* Setup command buffer parameters. */\r
+\r
+ local_cmd.cmd = NV_WRITE_F;\r
+ local_cmd.tcb_ptr = NULL;\r
+ local_cmd.sigs = 0;\r
+ local_cmd.done_q_ptr = NULL;\r
+ local_cmd.data_ptr = &local_item;\r
+\r
+ /* Clear all NAMs checksums and the MIN checksums for each NAM. */\r
+ \r
+ for (nam_idx = 0; nam_idx < NV_MAX_NAMS; nam_idx++) { \r
+ local_item.nam_chksum.nam = nam_idx;\r
+ local_item.nam_chksum.chksum = 0;\r
+ local_cmd.item = NV_NAM_CHKSUM_I;\r
+\r
+ local_cmd_ext.nvcmd = &local_cmd;\r
+ local_cmd_ext.context = 0; /* No context is defined */\r
+\r
+ local_cmd.status = nvio_write(&local_cmd_ext);\r
+\r
+ QSR_MSG_LOW( 705624602ULL, "NAM %d NAM checksum zero status %d", nam_idx, local_cmd.status, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ if (local_cmd.status != NV_DONE_S) {\r
+ return (local_cmd.status);\r
+ }\r
+ \r
+ local_item.min_chksum.nam = nam_idx;\r
+ for (min_idx = 0; min_idx < NV_MAX_MINS; min_idx++) {\r
+ local_item.min_chksum.chksum[min_idx] = 0;\r
+ }\r
+ local_cmd.item = NV_MIN_CHKSUM_I;\r
+\r
+ local_cmd_ext.nvcmd = &local_cmd;\r
+ local_cmd_ext.context = 0; /* No context is defined */\r
+\r
+ local_cmd.status = nvio_write(&local_cmd_ext);\r
+\r
+ QSR_MSG_LOW( 1811374263ULL, "NAM %d MIN checksum zero status %d", nam_idx, local_cmd.status, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ if (local_cmd.status != NV_DONE_S) {\r
+ return (local_cmd.status);\r
+ }\r
+ } /* for */\r
+\r
+ /* --------------------------------------------------------------------- */\r
+ /* Next we determine if the ESN is now proper and if not then clear the */\r
+ /* ESN,the ESN checksum, and the ESN valid flag. */\r
+ /* --------------------------------------------------------------------- */\r
+ if( nv_determine_esn_validity() == FALSE) {\r
+ /* ------------------------------------------------------------------- */\r
+ /* The ESN has not yet been assigned/written. Zero associated items */\r
+ /* Note that to get here status == NV_DONE_S */\r
+ /* ------------------------------------------------------------------- */\r
+ local_item.esn.esn = 0;\r
+ local_cmd.item = NV_ESN_I;\r
+\r
+ local_cmd_ext.nvcmd = &local_cmd;\r
+ local_cmd_ext.context = 0; /* No context is defined */\r
+\r
+ local_cmd.status = nvio_write(&local_cmd_ext);\r
+ \r
+ QSR_MSG_LOW( 983002661ULL, "ESN zero status %d", local_cmd.status, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ if (local_cmd.status != NV_DONE_S) {\r
+ return local_cmd.status;\r
+ }\r
+ }\r
+ return local_cmd.status;\r
+} /* nvim_clear_crcs */\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NVIM_INIT_RENTAL_TIMER\r
+\r
+DESCRIPTION\r
+ This function reads the rental timer item structure out of NVRAM and\r
+ initializes the "nv_rental_item_image" state data item. It also\r
+ validates the data structure and recovers from a previous bad powerdown.\r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ NV_DONE_S if it worked\r
+ NV_FAIL_S if the EEPROM access has failed\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+LOCAL nv_stat_enum_type \r
+nvim_init_rental_timer (void) \r
+{\r
+\r
+#ifdef NV_FEATURE_RENTAL_ITEMS\r
+#error code not present\r
+#endif\r
+ return NV_DONE_S;\r
+}\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NVIM_INIT_RENTAL_CNT\r
+\r
+DESCRIPTION\r
+ This function reads the rental count item from NV and initializes \r
+ the "nv_rental_cnt_image" state data item. \r
+ \r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ NV_DONE_S if it worked\r
+ NV_FAIL_S if the EEPROM access has failed\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+LOCAL nv_stat_enum_type \r
+nvim_init_rental_cnt (void) {\r
+#ifdef NV_FEATURE_RENTAL_ITEMS\r
+#error code not present\r
+#else\r
+ return NV_DONE_S;\r
+#endif\r
+}\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NVIM_INIT_PRL_DATA\r
+\r
+DESCRIPTION\r
+ This function initializes the "prl_valid_data" and "prl_version_data"\r
+ state data items. These are maintained as NV state data so the functions\r
+ "nv_prl_is_valid()" and "nvim_prl_version()" can return an immediate \r
+ response. \r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ NV_DONE_S if it worked\r
+ NV_FAIL_S if failed\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+LOCAL void\r
+nvim_init_prl_data (void) \r
+{\r
+ byte nam;\r
+ nv_roaming_list_header_type prl_header;\r
+ nv_stat_enum_type status;\r
+\r
+ prl_header.nam = FALSE;\r
+ prl_header.prl_version = 0;\r
+ prl_header.valid = FALSE;\r
+\r
+ for (nam=0; nam<NV_MAX_NAMS; nam++) {\r
+ /* For each nam, read the prl header */\r
+ status = nvio_read_prl_item(nam,\r
+ (void *)&prl_header, /* data ptr */\r
+ NV_ROAMING_LIST_HEADER_SIZE);/* data count */\r
+ /* Set state data items -- note that the item's active flag */\r
+ /* occupies the "nam" field in the external type. */\r
+ if (status == NV_DONE_S) {\r
+ nv_prl_version_data[nam] = prl_header.prl_version;\r
+ nv_prl_valid_data[nam] = prl_header.valid;\r
+ }\r
+ else {\r
+ nv_prl_version_data[nam] = NV_PRL_VERSION_INVALID;\r
+ nv_prl_valid_data[nam] = FALSE;\r
+ }\r
+ }\r
+ return;\r
+}\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NVIM_REMOVE_ITEM\r
+\r
+DESCRIPTION\r
+ This procedure processes NVM remove requests for a particular item.\r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ Status of read operation.\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+nv_stat_enum_type \r
+nvim_remove_item (\r
+ nv_cmd_ext_type *cmd_ext_ptr /* Pointer to Command block */\r
+)\r
+{\r
+ //Filename size is incremented from 20 to 28 to account for context\r
+ char file_name[28];\r
+ nv_stat_enum_type status;\r
+\r
+ if ((cmd_ext_ptr->nvcmd->item != NV_SMS_I) && (cmd_ext_ptr->nvcmd->item != NV_SMS_GW_I)) \r
+ return NV_BADPARM_S;\r
+\r
+#ifdef FEATURE_NV_RUIM\r
+ if (cmd_ext_ptr->context == 0) {\r
+ if ( nvruim_free(cmd_ext_ptr->nvcmd, &status) == NV_RUIM_SUPPORTS_ITEM )\r
+ return status;\r
+ }\r
+#ifdef FEATURE_DUAL_STANDBY\r
+ else {\r
+ if ( nvruim_free_ext(cmd_ext_ptr, &status) == NV_RUIM_SUPPORTS_ITEM )\r
+ return status;\r
+ }\r
+#endif\r
+#endif\r
+ status = NV_DONE_S;\r
+\r
+ if (cmd_ext_ptr->nvcmd->item >= NV_MAX_I) {\r
+ status = NV_BADPARM_S;\r
+ }\r
+ else {\r
+ switch(cmd_ext_ptr->nvcmd->item) {\r
+ case NV_SMS_I:\r
+ case NV_SMS_DM_I:\r
+ if(cmd_ext_ptr->nvcmd->data_ptr->sms.address >= NVI_MAX_SMS_ADDR)\r
+ status = NV_BADPARM_S;\r
+ else{\r
+ //If context is not defined, use the old path\r
+ if (cmd_ext_ptr->context == 0)\r
+ (void) snprintf(file_name, sizeof(file_name), "/nvm/sms_%05d",\r
+ cmd_ext_ptr->nvcmd->data_ptr->sms.address);\r
+ else //Else, context is defined, use context for path\r
+ (void) snprintf(file_name, sizeof(file_name), "/nvm/context%d/sms_%05d",\r
+ cmd_ext_ptr->context,cmd_ext_ptr->nvcmd->data_ptr->sms.address);\r
+ efs_unlink(file_name);\r
+ }\r
+ break;\r
+ case NV_SMS_GW_I:\r
+ if(cmd_ext_ptr->nvcmd->data_ptr->sms_gw.address >= NVI_MAX_SMS_ADDR) \r
+ status = NV_BADPARM_S;\r
+ else {\r
+ //If context is not defined, use the old path\r
+ if (cmd_ext_ptr->context == 0)\r
+ (void) snprintf(file_name, sizeof(file_name), "/nvm/sms_gw_%05d",\r
+ cmd_ext_ptr->nvcmd->data_ptr->sms_gw.address);\r
+ else //Else, context is defined, use context for path\r
+ (void) snprintf(file_name, sizeof(file_name), "/nvm/context%d/sms_gw_%05d",\r
+ cmd_ext_ptr->context,cmd_ext_ptr->nvcmd->data_ptr->sms_gw.address);\r
+ efs_unlink(file_name);\r
+ }\r
+ break;\r
+ default:\r
+ status = NV_BADPARM_S;\r
+ }/*switch*/\r
+ }/* else */\r
+ return status;\r
+}/*nvim_remove_item*/\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NVIM_REMOVE_ALL\r
+\r
+DESCRIPTION\r
+ This removes all files under the NVM directory\r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ Status of read operation.\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+nv_stat_enum_type \r
+nvim_remove_all ( void )\r
+{\r
+ struct fs_dirent *dirent;\r
+ EFSDIR *dir;\r
+\r
+ dir = efs_opendir("nvm/sms");\r
+ while((dirent = efs_readdir(dir))!= NULL){\r
+ efs_unlink( dirent->d_name );\r
+ }\r
+ efs_closedir (dir);\r
+ efs_rmdir("/nvm/sms");\r
+\r
+ dir = efs_opendir("nvm/prl");\r
+ while((dirent = efs_readdir(dir))!= NULL){\r
+ efs_unlink( dirent->d_name );\r
+ }\r
+ efs_closedir (dir);\r
+ efs_rmdir("/nvm/prl");\r
+\r
+ dir = efs_opendir("nvm/nvm");\r
+ while((dirent = efs_readdir(dir))!= NULL){\r
+ efs_unlink( dirent->d_name );\r
+ }\r
+ efs_closedir (dir);\r
+ efs_rmdir("/nvm/nvm");\r
+\r
+ dir = efs_opendir("nvm");\r
+ while((dirent = efs_readdir(dir))!= NULL){\r
+ efs_unlink( dirent->d_name );\r
+ }\r
+ efs_closedir (dir);\r
+\r
+ return NV_DONE_S;\r
+}/*nvim_remove_all*/\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NVIM_MIGRATION_NEEDED\r
+\r
+DESCRIPTION\r
+ This function will decide if there is a need to unlink the nvm directory \r
+ during a transition of older NV services to NV-2\r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ 0 if migration is not required\r
+ 1 if migratuion is required\r
+ \r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+LOCAL int \r
+nvim_migration_needed(void) \r
+{\r
+ struct fs_stat temp_buf;\r
+ /* Make sure that the change to efs_get is made so that it returns \r
+ correct value */\r
+ if(efs_stat("nvm/num/0",&temp_buf) == -1)\r
+ return 1;\r
+ else \r
+ return 0;\r
+}\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NV_INIT\r
+\r
+DESCRIPTION\r
+ This function checks the major version number of the the NV task\r
+ as stored at edit time, against the major version number of the\r
+ NV EEPROM as read from NVM. If the numbers are different then the\r
+ function completely rebuilds the NV EEPROM. If the major version\r
+ number has not changed then the function checks if the number of\r
+ items defined in NVI.H has increased from the internal NVM stored\r
+ items count. If so then only those new items are built. Once the\r
+ NV EEPROM has been initialized the function updates the stored\r
+ major version number to the one contained in NVI.H.\r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ NV_DONE_S if it worked\r
+ NV_FAIL_S if the EEPROM access has failed\r
+\r
+SIDE EFFECTS\r
+ Rebuilding the NVM takes a significant amount of time, measured in\r
+ seconds on serial eeprom devices, if NVM is rebuilt. Startup time \r
+ will vary with the type of EEPROM.\r
+\r
+===========================================================================*/\r
+\r
+LOCAL nv_stat_enum_type \r
+nv_init (void)\r
+{\r
+ nv_stat_enum_type status; /* Status to return to caller */\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+\r
+ if(!nv_cs_init_flag)\r
+ nv_access_op_cs_init();\r
+\r
+ NV_GLOBAL_LOCK_INIT();\r
+ if (nvim_migration_needed()) {\r
+ status = nvim_remove_all();\r
+ if ((status = nvim_build_sec()) == NV_DONE_S) {\r
+ status = nvim_clear_crcs();\r
+ }\r
+ } \r
+ else {\r
+ status = NV_DONE_S;\r
+ }\r
+\r
+#ifdef FEATURE_NV_CNV\r
+ /* If the file was dropped in as part of a CEFS image, then restore\r
+ the NV items */\r
+ nvim_cnv_check();\r
+\r
+ /* Remove the file since we are done updating the NV items and just\r
+ in case the file is left hanging around because of error conditions */\r
+ if (efs_unlink (cnv_file) < 0) {\r
+ QSR_MSG_HIGH ( 2406613708ULL, "Unable to remove CNV file", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ }\r
+#endif\r
+\r
+ (void)nverr_init(); /* cannot init err logging until nv is built */\r
+ (void)nvim_init_rental_timer(); /* validate the rental timer item */\r
+ (void)nvim_init_rental_cnt(); /* validate the rental count item */\r
+\r
+#if !defined( FEATURE_NV_RUIM ) || defined( FEATURE_UIM_RUN_TIME_ENABLE )\r
+ nvim_init_prl_data(); /* initialize prl state data items */\r
+#endif /* FEATURE_RUIM */\r
+\r
+#ifdef FEATURE_DIAG_FS_ACCESS_VALIDATION\r
+ nv_register_remote_access_check();\r
+#endif\r
+\r
+ return status;\r
+} /* nv_init */\r
+\r
+#ifdef FEATURE_MDN_BASED_NAI\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NV_BCD_TO_CHAR\r
+\r
+DESCRIPTION\r
+ Functions to convert MDN (BCD form) into ASCII characters.\r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ Returns the characters for the numeric values between 1 - 9.\r
+ Returns 0 for 10, * for 11 and # for 12.\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+char nv_bcd_to_char\r
+(\r
+ word num_to_convert\r
+)\r
+{\r
+ switch(num_to_convert)\r
+ {\r
+ case 1:\r
+ case 2:\r
+ case 3:\r
+ case 4:\r
+ case 5:\r
+ case 6:\r
+ case 7:\r
+ case 8:\r
+ case 9:\r
+ return '0' + num_to_convert;\r
+ case 10:\r
+ return '0';\r
+ case 11:\r
+ return '*';\r
+ case 12:\r
+ return '#';\r
+ default:\r
+ QSR_MSG_ERROR ( 2574375817ULL, "Invalid BCD digit (%d)", num_to_convert, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ return ' ';\r
+ }\r
+} /* nv_bcd_to_char */\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NV_NAI_FROM_MDN\r
+\r
+DESCRIPTION\r
+ Functions form NAI based on given MDN and domain .\r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ TRUE if it worked\r
+ FALSE Failure\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+boolean nv_nai_from_mdn\r
+(\r
+ char * nai_to_write,\r
+ word * len, // len should be set to MAX_NAI_LENGTH\r
+ nv_mob_dir_data_type * mob_dir,\r
+ char * domain // must be null terminated\r
+)\r
+{\r
+ int i, cpylen;\r
+\r
+ ASSERT (nai_to_write);\r
+ ASSERT (len);\r
+ ASSERT (mob_dir);\r
+ ASSERT (domain);\r
+\r
+ if (*len < mob_dir->n_digits + 1)\r
+ {\r
+ QSR_MSG_ERROR ( 2878414871ULL, "Output nai buffer too small for MDN",0,0,0);//auto-gen, to change remove 'QSR_' and first param\r
+ return FALSE;\r
+ }\r
+\r
+ for (i = 0; i < mob_dir->n_digits; i++)\r
+ {\r
+ nai_to_write[i] = nv_bcd_to_char(mob_dir->digitn[i]);\r
+ if (nai_to_write[i] == ' ')\r
+ {\r
+ QSR_MSG_ERROR ( 3975514337ULL, "Invalid MDN when converting to NAI",0,0,0);//auto-gen, to change remove 'QSR_' and first param\r
+ return FALSE; // item_to_be_written = FALSE;\r
+ }\r
+ }\r
+\r
+ nai_to_write[i] = 0;\r
+ \r
+ cpylen = strlen(domain);\r
+ if (cpylen > *len - i - 1)\r
+ {\r
+ QSR_MSG_ERROR ( 4243638384ULL, "Output nai buffer too small for domain",0,0,0);//auto-gen, to change remove 'QSR_' and first param\r
+ return FALSE; // item_to_be_written = FALSE;\r
+ }\r
+\r
+ std_strlcat(&(nai_to_write[i]), domain, *len - i - 1);\r
+ nai_to_write[i+cpylen] = 0; // NULL terminate\r
+ *len = i + cpylen;\r
+ return TRUE;\r
+} /* nv_nai_from_mdn */\r
+\r
+/*===========================================================================\r
+\r
+FUNCTION NV_GET_DFLT_MIP_PROFILE\r
+\r
+DESCRIPTION\r
+ Sets the current profile with the parameters for the default MIP profile.\r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ None.\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+LOCAL void nv_get_dflt_mip_profile\r
+(\r
+ nv_ds_mip_gen_user_prof_type * prof\r
+)\r
+{\r
+ ASSERT (prof);\r
+\r
+ prof->index = MIP_DLFT_PROFILE_NUM;\r
+ prof->nai_length = 0;\r
+ prof->nai[0] = 0;\r
+ prof->mn_ha_spi_set = TRUE;\r
+ prof->mn_ha_spi = MIP_MD5_SPI;\r
+ prof->mn_aaa_spi_set = TRUE;\r
+ prof->mn_aaa_spi = MIP_CHAP_SPI;\r
+ prof->rev_tun_pref = FALSE;\r
+ prof->home_addr = DYNAMIC_HOME_ADDR;\r
+ prof->primary_ha_addr = DYNAMIC_HA_ADDR;\r
+ prof->secondary_ha_addr = UNSET_HA_ADDR;\r
+} /* nv_get_dflt_mip_profile */\r
+#endif /* FEATURE_MDN_BASED_NAI */\r
+\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NV_OTASP_COMMIT\r
+\r
+DESCRIPTION\r
+ This function performs the OTASP "commit" operation, which updates\r
+ a number of OTASP-related nv items at once. \r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ NV_DONE_S if it worked\r
+ Others Failure for internal call\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+LOCAL nv_stat_enum_type \r
+nv_otasp_commit (\r
+ nv_cmd_ext_type *cmd_ext_ptr /* Command block */\r
+)\r
+{\r
+ nv_cmd_ext_type local_cmd_ext;\r
+\r
+#ifdef FEATURE_NV_OTASP\r
+\r
+/* Define constants for the switch statement below */\r
+#define NV_COMMIT_DIR_NUM 0\r
+#define NV_COMMIT_IMSI_ADDR 1\r
+#define NV_COMMIT_IMSI_MCC 2\r
+#define NV_COMMIT_IMSI_11_12 3\r
+#define NV_COMMIT_MIN1 4\r
+#define NV_COMMIT_MIN2 5\r
+#define NV_COMMIT_ACCOLC 6\r
+#define NV_COMMIT_MOB_HOME 7\r
+#define NV_COMMIT_MOB_SID 8\r
+#define NV_COMMIT_MOB_NID 9\r
+#define NV_COMMIT_SID_NID 10\r
+#define NV_COMMIT_FIRSTCHP 11\r
+#define NV_COMMIT_HOME_SID 12\r
+#define NV_COMMIT_ROAM_LIST 13\r
+#define NV_COMMIT_SPC 14\r
+#define NV_COMMIT_IMSI_T_S1 15\r
+#define NV_COMMIT_IMSI_T_S2 16\r
+#define NV_COMMIT_IMSI_T_11_12 17\r
+#define NV_COMMIT_IMSI_T_MCC 18\r
+#define NV_COMMIT_IMSI_T_ADDR_NUM 19\r
+#define NV_COMMIT_NAM_LOCK 20\r
+#define NV_COMMIT_PRIMARY_MIP_NAI_AFTER_MDN 21\r
+#define NV_COMMIT_PRIMARY_SIP_NAI_AFTER_MDN 22\r
+#define NV_COMMIT_AN_NAI_AFTER_MDN 23\r
+\r
+#define NV_COMMIT_DONE 255\r
+\r
+ boolean item_to_be_written; /* Flag controls whether write occurs */\r
+ byte i, commit_state=0; /* Index variables */\r
+\r
+#ifdef FEATURE_MDN_BASED_NAI\r
+\r
+/* use the largest of the source nai fields (MIP, SIP, AN) */\r
+#define MAX_NAI_LENGTH NV_MAX_PPP_USER_ID_LENGTH\r
+\r
+ char nai_to_write[MAX_NAI_LENGTH]; // max for MIP, check SIP\r
+ char domain[MAX_NAI_LENGTH + 1];\r
+ char * domain_ptr;\r
+ word nai_length;\r
+#endif /* FEATURE_MDN_BASED_NAI */\r
+\r
+ QSR_MSG_HIGH ( 771664511ULL, "NV Starting OTASP commit", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+\r
+ /* Raise NV task priority for OTASP commit operation (and save */\r
+ /* original priority so it can be restored at end of commit) */\r
+\r
+ QSR_MSG_HIGH ( 3779412989ULL, "NV Priority raised for OTASP", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ /* Set up generic command buffer parameters */\r
+ local_cmd.cmd = NV_WRITE_F;\r
+ local_cmd.tcb_ptr = NULL;\r
+ local_cmd.sigs = 0;\r
+ local_cmd.done_q_ptr = NULL;\r
+ local_cmd.data_ptr = &local_item;\r
+ local_cmd.status = NV_DONE_S;\r
+\r
+ while (commit_state != NV_COMMIT_DONE) { \r
+\r
+ item_to_be_written = FALSE;\r
+ switch (commit_state) {\r
+ \r
+ case NV_COMMIT_DIR_NUM:\r
+ \r
+ /* Read control flag to determine if item should be written */\r
+ if (cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->commit_mob_dir) {\r
+\r
+ /* Write NV_DIR_NUMBER_PCS_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.mob_dir_number.nam = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.mob_dir_number.n_digits = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->mob_dir.n_digits;\r
+ for (i=0; i < NV_DIR_NUMB_PCS_SIZ; ++i) {\r
+ local_item.mob_dir_number.digitn[i] = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->mob_dir.digitn[i];\r
+ } \r
+ local_cmd.item = NV_DIR_NUMBER_PCS_I;\r
+ }\r
+\r
+ /* Set next state */\r
+#ifdef FEATURE_MDN_BASED_NAI\r
+ if (item_to_be_written) \r
+ {\r
+ commit_state = NV_COMMIT_PRIMARY_MIP_NAI_AFTER_MDN;\r
+ break;\r
+ }\r
+#endif /* FEATURE_MDN_BASED_NAI */\r
+ commit_state = NV_COMMIT_IMSI_ADDR;\r
+ break;\r
+\r
+ case NV_COMMIT_IMSI_ADDR:\r
+\r
+ /* Read control flag to determine if items should be written */\r
+ if (cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->commit_ftc_cdma) {\r
+ \r
+ /* Write NV_IMSI_ADDR_NUM_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.imsi_addr_num.nam = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.imsi_addr_num.num = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->ftc_cdma.imsi_addr_num;\r
+ local_cmd.item = NV_IMSI_ADDR_NUM_I;\r
+ /* Set commit_state to write the additional items of this group */\r
+ commit_state = NV_COMMIT_IMSI_MCC;\r
+ }\r
+ else {\r
+ /* Control flag indicates no items from this group should */\r
+ /* be written, so set commit_state to bypass them all */\r
+ commit_state = NV_COMMIT_FIRSTCHP;\r
+ }\r
+ break;\r
+\r
+ case NV_COMMIT_IMSI_MCC:\r
+\r
+ /* Write NV_IMSI_MCC_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.imsi_mcc.nam = cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.imsi_mcc.imsi_mcc = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->ftc_cdma.mcc;\r
+ local_cmd.item = NV_IMSI_MCC_I;\r
+ /* Set commit_state to write the next item of this group */\r
+ commit_state++;\r
+ break;\r
+\r
+ case NV_COMMIT_IMSI_11_12:\r
+\r
+ /* Write NV_IMSI_11_12_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.imsi_11_12.nam = cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.imsi_11_12.imsi_11_12 = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->ftc_cdma.imsi_11_12;\r
+ local_cmd.item = NV_IMSI_11_12_I;\r
+ /* Set commit_state to write the next item of this group */\r
+ commit_state++;\r
+ break;\r
+\r
+ case NV_COMMIT_MIN1:\r
+\r
+ /* Write NV_MIN1_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.min1.nam = cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.min1.min1[NV_CDMA_MIN_INDEX] = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->ftc_cdma.imsi_s1;\r
+ /* Set both the CDMA min and the analog min to this same value */\r
+ local_item.min1.min1[NV_ANALOG_MIN_INDEX] = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->ftc_cdma.imsi_s1;\r
+ local_cmd.item = NV_MIN1_I;\r
+ /* Set commit_state to write the next item of this group */\r
+ commit_state++;\r
+ break;\r
+\r
+ case NV_COMMIT_MIN2:\r
+\r
+ /* Write NV_MIN2_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.min2.nam = cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.min2.min2[NV_CDMA_MIN_INDEX] = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->ftc_cdma.imsi_s2;\r
+ /* Set both the CDMA min and the analog min to this same value */\r
+ local_item.min2.min2[NV_ANALOG_MIN_INDEX] = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->ftc_cdma.imsi_s2;\r
+ local_cmd.item = NV_MIN2_I;\r
+ /* Set commit_state to write the next item of this group */\r
+ commit_state++;\r
+ break;\r
+\r
+ case NV_COMMIT_ACCOLC:\r
+\r
+ /* Write NV_ACCOLC_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.accolc.nam = cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.accolc.ACCOLCpClass[NV_CDMA_MIN_INDEX] = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->ftc_cdma.accolc;\r
+ local_cmd.item = NV_ACCOLC_I;\r
+ /* Set commit_state to write the next item of this group */\r
+ commit_state++;\r
+ break;\r
+\r
+ case NV_COMMIT_MOB_HOME:\r
+\r
+ /* Write NV_MOB_TERM_HOME_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.mob_term_home.nam = cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.mob_term_home.enabled[NV_CDMA_MIN_INDEX] = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->ftc_cdma.mob_term_home;\r
+ local_cmd.item = NV_MOB_TERM_HOME_I;\r
+ /* Set commit_state to write the next item of this group */\r
+ commit_state++;\r
+ break;\r
+\r
+ case NV_COMMIT_MOB_SID:\r
+\r
+ /* Write NV_MOB_TERM_FOR_SID_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.mob_term_for_sid.nam = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.mob_term_for_sid.enabled[NV_CDMA_MIN_INDEX] = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->ftc_cdma.mob_term_for_sid;\r
+ local_cmd.item = NV_MOB_TERM_FOR_SID_I;\r
+ /* Set commit_state to write the next item of this group */\r
+ commit_state++;\r
+ break;\r
+\r
+ case NV_COMMIT_MOB_NID:\r
+\r
+ /* Write NV_MOB_TERM_FOR_NID_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.mob_term_for_nid.nam = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.mob_term_for_nid.enabled[NV_CDMA_MIN_INDEX] = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->ftc_cdma.mob_term_for_nid;\r
+ local_cmd.item = NV_MOB_TERM_FOR_NID_I;\r
+ /* Set commit_state to write the next item of this group */\r
+ commit_state++;\r
+ break;\r
+\r
+ case NV_COMMIT_SID_NID:\r
+\r
+ /* Write NV_SID_NID_I */\r
+ item_to_be_written = TRUE;\r
+ /* All the targets which have SSPR Enhancements use NV item HOME SID-NID */\r
+#if (defined (NV_FEATURE_SSPR_ENHANCEMENTS) || defined (NV_FEATURE_TRIMODE_ITEMS))\r
+ local_item.home_sid_nid.nam = cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ for(i=0;i<NV_MAX_HOME_SID_NID;i++)\r
+ {\r
+ local_item.home_sid_nid.pair[i].sid = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->ftc_cdma.pair[i].sid;\r
+ local_item.home_sid_nid.pair[i].nid = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->ftc_cdma.pair[i].nid;\r
+ } \r
+ local_cmd.item = NV_HOME_SID_NID_I;\r
+#else\r
+ local_item.sid_nid.nam = cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ for(i=0;i<NV_MAX_SID_NID;i++)\r
+ {\r
+ local_item.sid_nid.pair[NV_CDMA_MIN_INDEX][i].sid = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->ftc_cdma.pair[i].sid;\r
+ local_item.sid_nid.pair[NV_CDMA_MIN_INDEX][i].nid = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->ftc_cdma.pair[i].nid;\r
+ }\r
+ local_cmd.item = NV_SID_NID_I;\r
+#endif\r
+ /* Set next state */\r
+ commit_state = NV_COMMIT_FIRSTCHP;\r
+ break;\r
+\r
+ case NV_COMMIT_FIRSTCHP:\r
+\r
+ /* Read control flag to determine if items should be written */\r
+ if (cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->commit_ftc_amps) {\r
+\r
+ /* Write NV_ANALOG_FIRSTCHP_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.analog_firstchp.nam = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.analog_firstchp.channel = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->ftc_amps.firstchp;\r
+ local_cmd.item = NV_ANALOG_FIRSTCHP_I;\r
+ /* Set commit_state to write the next item of this group */\r
+ commit_state = NV_COMMIT_HOME_SID;\r
+ }\r
+ else {\r
+ /* Control flag indicates no items from this group should */\r
+ /* be written, so set commit_state to bypass them all */\r
+ commit_state = NV_COMMIT_SPC;\r
+ }\r
+ break;\r
+\r
+ case NV_COMMIT_HOME_SID:\r
+\r
+ /* Write NV_ANALOG_HOME_SID_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.analog_home_sid.nam = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.analog_home_sid.sid = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->ftc_amps.home_sid;\r
+ local_cmd.item = NV_ANALOG_HOME_SID_I;\r
+ /* Set next state */\r
+ commit_state = NV_COMMIT_SPC;\r
+ break;\r
+\r
+ case NV_COMMIT_SPC:\r
+\r
+ /* Read control flag to determine if item should be written */\r
+ if (cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->commit_spc) {\r
+\r
+ /* Write NV_SEC_CODE_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.sec_code = cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->spc;\r
+ local_cmd.item = NV_SEC_CODE_I;\r
+ }\r
+ /* Set next state */\r
+ commit_state = NV_COMMIT_IMSI_T_S1;\r
+ break;\r
+\r
+ case NV_COMMIT_IMSI_T_S1:\r
+\r
+ /* Read control flag to determine if items should be written */\r
+ if (cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->commit_imsi_t) {\r
+\r
+ /* Write NV_IMSI_T_S1 */\r
+ item_to_be_written = TRUE;\r
+ local_item.imsi_t_s1.nam = cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.imsi_t_s1.min1[NV_CDMA_MIN_INDEX] = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->imsi_t.s1;\r
+ local_cmd.item = NV_IMSI_T_S1_I;\r
+ /* Set commit_state to write the next item of this group */\r
+ commit_state++;\r
+ }\r
+ else\r
+ {\r
+ /* Control flag indicates no items from this group should */\r
+ /* be written, so set commit_state to bypass them all */\r
+ commit_state = NV_COMMIT_ROAM_LIST;\r
+ }\r
+ break;\r
+\r
+ case NV_COMMIT_IMSI_T_S2:\r
+\r
+ /* Write NV_IMSI_T_S2_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.imsi_t_s2.nam = cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.imsi_t_s2.min2[NV_CDMA_MIN_INDEX] = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->imsi_t.s2;\r
+ local_cmd.item = NV_IMSI_T_S2_I;\r
+ /* Set commit_state to write the next item of this group */\r
+ commit_state++;\r
+ break;\r
+\r
+ case NV_COMMIT_IMSI_T_11_12:\r
+\r
+ /* Write NV_IMSI_T_11_12_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.imsi_t_11_12.nam = cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.imsi_t_11_12.imsi_11_12 = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->imsi_t.imsi_t_11_12;\r
+ local_cmd.item = NV_IMSI_T_11_12_I;\r
+ /* Set commit_state to write the next item of this group */\r
+ commit_state++;\r
+ break;\r
+ \r
+ case NV_COMMIT_IMSI_T_MCC:\r
+\r
+ /* Write NV_IMSI_T_MCC_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.imsi_t_mcc.nam = cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.imsi_t_mcc.imsi_mcc = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->imsi_t.mcc;\r
+ local_cmd.item = NV_IMSI_T_MCC_I;\r
+ /* Set commit_state to write the next item of this group */\r
+ commit_state++;\r
+ break;\r
+\r
+ case NV_COMMIT_IMSI_T_ADDR_NUM:\r
+\r
+ /* Write NV_IMSI_T_MCC_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.imsi_t_addr_num.nam = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.imsi_t_addr_num.num = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->imsi_t.addr_num;\r
+ local_cmd.item = NV_IMSI_T_ADDR_NUM_I;\r
+ /* Set next state */\r
+ commit_state = NV_COMMIT_ROAM_LIST;\r
+ break;\r
+\r
+ case NV_COMMIT_ROAM_LIST:\r
+\r
+ /* Commit to the Roaming List MUST be the last commit to be performed */\r
+ /* This is, because the local_cmd.data_ptr gets assigned to pointer to */\r
+ /* nv_pr_list during this sequence of operations. If one must add any */\r
+ /* other NV item in the commit switch after Roaming List at all, then */\r
+ /* (s)he should make sure to reassign this to local_item */ \r
+\r
+ /* Read control flag to determine if item should be written */\r
+ if (cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->commit_roam_list) {\r
+\r
+ /* Write NV_ROAMING_LIST_I */\r
+ item_to_be_written = TRUE;\r
+ local_cmd.data_ptr = (nv_item_type *)&nv_pr_list;\r
+ #ifdef NV_FEATURE_IS683A_PRL\r
+ local_cmd.item = NV_ROAMING_LIST_683_I;\r
+ #else\r
+ local_cmd.item = NV_ROAMING_LIST_I;\r
+ #endif\r
+ }\r
+ /* Set next state */\r
+ commit_state = NV_COMMIT_NAM_LOCK;\r
+ break;\r
+\r
+ case NV_COMMIT_NAM_LOCK:\r
+ /* Read control flag to determine if items should be written */\r
+ if (cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->commit_nam_lock) \r
+ {\r
+ #ifdef FEATURE_OTASP_OTAPA\r
+ /* Write NV_NAM_LOCK_I */\r
+ item_to_be_written = TRUE;\r
+ local_item.nam_lock.nam = cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam;\r
+ local_item.nam_lock.enabled = \r
+ cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->nam_lock.enabled;\r
+ local_cmd.item = NV_NAM_LOCK_I;\r
+ #else\r
+ ERR("Attempted to write NV_NAM_LOCK_I when FEATURE_OTASP_OTAPA not on",\r
+ 0, 0, 0);\r
+ #endif\r
+ }\r
+ /* Set commit_state to signify we've finished committing */\r
+ commit_state = NV_COMMIT_DONE;\r
+ \r
+ break;\r
+\r
+#ifdef FEATURE_MDN_BASED_NAI\r
+ case NV_COMMIT_PRIMARY_MIP_NAI_AFTER_MDN:\r
+\r
+ /*-------------------------------------------------------------------\r
+ Note: this defaults to read/write profile at index 0.\r
+ Customer should use whichever index they assign\r
+ to the active MIP profile.\r
+ -------------------------------------------------------------------*/\r
+ local_item.ds_mip_gen_user_prof.index = MIP_DLFT_PROFILE_NUM;\r
+ local_cmd.cmd = NV_READ_F;\r
+ local_cmd.item = NV_DS_MIP_GEN_USER_PROF_I;\r
+\r
+ local_cmd_ext.nvcmd = &local_cmd;\r
+ local_cmd_ext.context = 0; /* No context is defined */\r
+\r
+ local_cmd.status = nvio_read(&local_cmd_ext);\r
+ if (local_cmd.status == NV_NOTACTIVE_S)\r
+ {\r
+ nv_get_dflt_mip_profile( &(local_item.ds_mip_gen_user_prof) );\r
+ }\r
+ else if (local_cmd.status != NV_DONE_S)\r
+ {\r
+ QSR_MSG_ERROR ( 1094358265ULL, "Error %d reading NV",local_cmd.status,0,0);//auto-gen, to change remove 'QSR_' and first param\r
+ commit_state = NV_COMMIT_PRIMARY_SIP_NAI_AFTER_MDN;\r
+ break;\r
+ }\r
+\r
+ if(local_item.ds_mip_gen_user_prof.nai_length < NV_MAX_NAI_LENGTH)\r
+ local_item.ds_mip_gen_user_prof.nai[\r
+ local_item.ds_mip_gen_user_prof.nai_length] = 0;\r
+ domain_ptr =\r
+ std_strchr( (char*) local_item.ds_mip_gen_user_prof.nai, '@' );\r
+ if (domain_ptr == NULL)\r
+ {\r
+ QSR_MSG_HIGH( 437141575ULL, "Using default domain",0,0,0);//auto-gen, to change remove 'QSR_' and first param\r
+ domain_ptr = PS_NAI_DFLT_DOMAIN;\r
+ }\r
+ std_strlcpy(domain,domain_ptr,NV_MAX_NAI_LENGTH);\r
+ domain[NV_MAX_NAI_LENGTH] = 0; // NULL terminate\r
+\r
+ nai_length = NV_MAX_NAI_LENGTH; // max bytes to write\r
+ if( !nv_nai_from_mdn( nai_to_write,\r
+ &nai_length,\r
+ &(cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->mob_dir),\r
+ domain ) )\r
+ {\r
+ ERR("Couldn't convert MDN and domain to NAI!",0,0,0);\r
+ commit_state = NV_COMMIT_PRIMARY_SIP_NAI_AFTER_MDN;\r
+ break;\r
+ }\r
+\r
+ item_to_be_written = TRUE;\r
+ local_cmd.cmd = NV_WRITE_F;\r
+ local_item.ds_mip_gen_user_prof.nai_length = nai_length;\r
+ memcpy( (char*) local_item.ds_mip_gen_user_prof.nai,\r
+ nai_to_write,\r
+ nai_length );\r
+ commit_state = NV_COMMIT_PRIMARY_SIP_NAI_AFTER_MDN;\r
+ break;\r
+\r
+ case NV_COMMIT_PRIMARY_SIP_NAI_AFTER_MDN:\r
+\r
+ local_cmd.cmd = NV_READ_F;\r
+ local_cmd.item = NV_PPP_USER_ID_I;\r
+\r
+ local_cmd_ext.nvcmd = &local_cmd;\r
+ local_cmd_ext.context = 0; /* No context is defined */\r
+\r
+ local_cmd.status = nvio_read(&local_cmd_ext);\r
+ if (local_cmd.status == NV_NOTACTIVE_S)\r
+ {\r
+ local_item.ppp_user_id.user_id_len = 0;\r
+ }\r
+ else if (local_cmd.status != NV_DONE_S)\r
+ {\r
+ QSR_MSG_ERROR ( 1094358265ULL, "Error %d reading NV",local_cmd.status,0,0);//auto-gen, to change remove 'QSR_' and first param\r
+ commit_state = NV_COMMIT_AN_NAI_AFTER_MDN;\r
+ break;\r
+ }\r
+\r
+ // copy the old domain from the user profile, or the default domain\r
+ local_item.ppp_user_id.user_id[local_item.ppp_user_id.user_id_len] = 0;\r
+ domain_ptr = std_strchr( (char*) local_item.ppp_user_id.user_id, '@' );\r
+ if (domain_ptr == NULL)\r
+ {\r
+ QSR_MSG_HIGH( 1009080534ULL, "Using default domain for SIP nai",0,0,0);//auto-gen, to change remove 'QSR_' and first param\r
+ domain_ptr = PS_NAI_DFLT_DOMAIN;\r
+ }\r
+ std_strlcpy(domain,domain_ptr,NV_MAX_PPP_USER_ID_LENGTH);\r
+ domain[NV_MAX_PPP_USER_ID_LENGTH] = 0; // NULL terminate\r
+\r
+ nai_length = NV_MAX_PPP_USER_ID_LENGTH; // max bytes to write\r
+ if( !nv_nai_from_mdn( nai_to_write,\r
+ &nai_length,\r
+ &(cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->mob_dir),\r
+ domain ) )\r
+ {\r
+ ERR("Couldn't convert MDN and domain to NAI!",0,0,0);\r
+ commit_state = NV_COMMIT_AN_NAI_AFTER_MDN;\r
+ break;\r
+ }\r
+\r
+ item_to_be_written = TRUE;\r
+ local_cmd.cmd = NV_WRITE_F;\r
+ local_cmd.item = NV_PPP_USER_ID_I;\r
+ local_item.ppp_user_id.user_id_len = nai_length;\r
+ memcpy( (char*) local_item.ppp_user_id.user_id,\r
+ nai_to_write,\r
+ nai_length );\r
+ commit_state = NV_COMMIT_AN_NAI_AFTER_MDN;\r
+ break;\r
+\r
+ case NV_COMMIT_AN_NAI_AFTER_MDN:\r
+ \r
+ local_cmd.cmd = NV_READ_F;\r
+ local_cmd.item = NV_HDR_AN_AUTH_USER_ID_LONG_I;\r
+\r
+ local_cmd_ext.nvcmd = &local_cmd;\r
+ local_cmd_ext.context = 0; /* No context is defined */\r
+\r
+ local_cmd.status = nvio_read(&local_cmd_ext);\r
+ if (local_cmd.status == NV_NOTACTIVE_S)\r
+ {\r
+ local_item.hdr_an_ppp_user_id.user_id_len = 0;\r
+ }\r
+ else if (local_cmd.status != NV_DONE_S)\r
+ {\r
+ QSR_MSG_ERROR ( 1094358265ULL, "Error %d reading NV",local_cmd.status,0,0);//auto-gen, to change remove 'QSR_' and first param\r
+ commit_state = NV_COMMIT_IMSI_ADDR;\r
+ break;\r
+ }\r
+ \r
+ // copy the old domain from the user profile, or the default domain\r
+ local_item.hdr_an_ppp_user_id.user_id[\r
+ local_item.hdr_an_ppp_user_id.user_id_len] = 0;\r
+ domain_ptr =\r
+ std_strchr( (char*) local_item.hdr_an_ppp_user_id.user_id, '@' );\r
+ if (domain_ptr == NULL)\r
+ {\r
+ QSR_MSG_HIGH( 4198565724ULL, "Using default domain for AN nai",0,0,0);//auto-gen, to change remove 'QSR_' and first param\r
+ domain_ptr = PS_NAI_DFLT_DOMAIN;\r
+ }\r
+ std_strlcpy(domain,domain_ptr,NV_MAX_AN_PPP_USER_ID_LENGTH);\r
+ domain[NV_MAX_AN_PPP_USER_ID_LENGTH] = 0; // NULL terminate\r
+ \r
+ nai_length = NV_MAX_AN_PPP_USER_ID_LENGTH; // max bytes to write\r
+ if( !nv_nai_from_mdn( nai_to_write,\r
+ &nai_length,\r
+ &(cmd_ext_ptr->nvcmd->data_ptr->otasp_commit->mob_dir),\r
+ domain ) )\r
+ {\r
+ ERR("Couldn't convert MDN and domain to NAI!",0,0,0);\r
+ commit_state = NV_COMMIT_IMSI_ADDR;\r
+ break;\r
+ }\r
+ \r
+ item_to_be_written = TRUE;\r
+ local_cmd.cmd = NV_WRITE_F;\r
+ local_cmd.item = NV_HDR_AN_AUTH_USER_ID_LONG_I;\r
+ local_item.hdr_an_ppp_user_id.user_id_len = nai_length;\r
+ memcpy( (char*) local_item.hdr_an_ppp_user_id.user_id,\r
+ nai_to_write,\r
+ nai_length );\r
+ commit_state = NV_COMMIT_IMSI_ADDR;\r
+ break;\r
+#endif /* FEATURE_MDN_BASED_NAI */ \r
+\r
+\r
+ default:\r
+ /* Restore original NV task priority before returning */\r
+ \r
+ QSR_MSG_HIGH ( 3773457423ULL, "NV Priority Returned to NORMAL", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ return(cmd_ext_ptr->nvcmd->status = NV_BADCMD_S);\r
+ \r
+ } /* switch */\r
+\r
+ if (item_to_be_written == TRUE) {\r
+ local_cmd_ext.nvcmd = &local_cmd;\r
+ local_cmd_ext.context = 0; /* No context is defined */\r
+\r
+ local_cmd.status = nvio_write(&local_cmd_ext);\r
+\r
+ if (local_cmd.status != NV_DONE_S) {\r
+ /* Restore original NV task priority before returning */\r
+ \r
+ QSR_MSG_HIGH ( 3773457423ULL, "NV Priority Returned to NORMAL", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ return (local_cmd.status);\r
+ }\r
+ }\r
+\r
+ /* Reset data_ptr for next item */\r
+ local_cmd.data_ptr = &local_item;\r
+ } /* while */ \r
+\r
+ /* Restore original NV task priority before returning */\r
+\r
+ QSR_MSG_HIGH ( 3773457423ULL, "NV Priority Returned to NORMAL", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ return (local_cmd.status);\r
+\r
+#else\r
+ return NV_BADTG_S;\r
+\r
+#endif /* FEATURE_NV_OTASP */\r
+} /* nv_otasp_commit */\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NV_PRL_IS_VALID\r
+\r
+DESCRIPTION\r
+ This function returns the "valid" indicator from the specified NAM's\r
+ roaming list. \r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ TRUE if the roaming list "valid" field is TRUE \r
+ FALSE if the roaming list "valid" field is FALSE or if the\r
+ specified NAM is invalid or if the roaming list\r
+ is currently NOT_ACTIVE\r
+\r
+SIDE EFFECTS\r
+ None. \r
+ \r
+===========================================================================*/\r
+\r
+boolean nv_prl_is_valid\r
+(\r
+ byte nam /* Which NAM the request is for */\r
+)\r
+{\r
+ /* Check for illegal NAM */\r
+ if (nam >= NV_MAX_NAMS) return FALSE;\r
+\r
+ /* Note that valid field is set FALSE if prl is NOT_ACTIVE */\r
+ return nv_prl_valid_data[nam];\r
+}\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NV_PRL_VERSION\r
+\r
+DESCRIPTION\r
+ This function returns the "prl_version" indicator from the specified NAM's\r
+ roaming list. \r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ prl_version if the roaming list for the specified NAM is\r
+ currently ACTIVE \r
+ NV_PRL_VERSION_INVALID if the specified NAM is invalid or if the \r
+ roaming list for the specified NAM is \r
+ currently NOT_ACTIVE\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+word nv_prl_version\r
+(\r
+ byte nam /* Which NAM the request is for */\r
+)\r
+{\r
+ /* Check for illegal NAM */\r
+ if (nam >= NV_MAX_NAMS) return NV_PRL_VERSION_INVALID;\r
+\r
+ /* Note that prl_version field is set to NV_PRL_VERSION_INVALID if */\r
+ /* the roaming list is NOT_ACTIVE */\r
+ return nv_prl_version_data[nam];\r
+}\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NVIMNV_TASK_START\r
+\r
+DESCRIPTION\r
+ This function performs NV task initialization. The function\r
+ first sets the acknowledge signal back to MC to acknowledge that it has\r
+ been created. It then waits for the start signal back to it. While\r
+ waiting for the start signal and keeps kicking the watchdog timer\r
+ everytime its interval timer has expired. When it gets the start\r
+ signal it then performs file initialization.\r
+ Once initialization completes, it then acknowledges it back to MC \r
+ and returns to the caller.\r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ None.\r
+\r
+SIDE EFFECTS\r
+ The calling task stays here until it receives the START signal.\r
+\r
+===========================================================================*/\r
+\r
+static void nvimnv_task_start\r
+(\r
+ rex_sigs_type rpt_sig, /* report timer signal for task */\r
+ dog_report_type dog_rpt, /* Watchdog report for the task */\r
+ rex_timer_type *rpt_timer_ptr /* pointer to report timer */\r
+)\r
+{\r
+\r
+ rex_sigs_type sigs; /* Signals returned by rex_timed_wait. */\r
+\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+\r
+ /* Acknowledge task creation. */\r
+\r
+ (void) rex_set_sigs(&tmc_tcb, TMC_ACK_SIG);\r
+\r
+ /* Continue to set watchdog timer while waiting for start signal from MC. */\r
+\r
+ for (;;)\r
+ {\r
+ /* Set a timed wait for OR of signals and a watchdog report timer. */\r
+\r
+ sigs = rex_timed_wait(TASK_START_SIG | rpt_sig, rpt_timer_ptr, DOG_MC_RPT_TIME);\r
+\r
+ /* If start signal is set then perform file initialization and \r
+ signal back to MC. */\r
+\r
+ if ((sigs & TASK_START_SIG) != 0)\r
+ {\r
+ (void) rex_clr_sigs(&nv_tcb, TASK_START_SIG);\r
+ \r
+ /* Initialize the EFS files. */\r
+ if (nv_init() != NV_DONE_S) \r
+ {\r
+ ERR_FATAL("Failed NVIM EFS initialization", 0, 0, 0);\r
+ }\r
+ \r
+ QSR_MSG_MED( 1502779829ULL, "NVIM initialization successfull", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ nvi_initialized = TRUE;\r
+ \r
+ nvdiag_init();\r
+ \r
+ /* Signal back to TMC acknowledgement. */\r
+ (void) rex_set_sigs(&tmc_tcb, TMC_ACK_SIG);\r
+ break;\r
+ }\r
+ /* Otherwise timer has expired. Kick the watchdog and loop. */\r
+ else\r
+ {\r
+ (void) rex_clr_sigs(&nv_tcb, rpt_sig);\r
+ dog_report(dog_rpt);\r
+ }\r
+ } /* for */\r
+} /* nvimnv_task_start */\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NV_FRONT_OP\r
+\r
+DESCRIPTION\r
+ This is the function called by both nv_cmd and nv_task. This is required\r
+ in order to use kxmutexes for both synchronous and asynchronous accesses via\r
+ NV.\r
+\r
+DEPENDENCIES\r
+ The NV task must have been started up already. All of the items in\r
+ the nv_cmd_block must be already set.\r
+\r
+RETURN VALUE\r
+ None directly. The status variable of the nv_cmd_type will be updated\r
+ to reflect the current status of this command as it is processed.\r
+\r
+SIDE EFFECTS\r
+ The nv_cmd_type is placed on the NV command queue. It must not be\r
+ modified until the command has been processed.\r
+\r
+===========================================================================*/\r
+\r
+\r
+void nv_front_op(\r
+ nv_cmd_ext_type *cmd_ext_ptr /* Pointer to NV command buffer */\r
+ )\r
+{\r
+ nv_cmd_type *cmd_ptr = cmd_ext_ptr->nvcmd;\r
+ uint16 context = cmd_ext_ptr->context;\r
+\r
+ if (context > MAX_NV_CONTEXT) {\r
+ cmd_ptr->status = NV_FAIL_S;\r
+ QSR_MSG_HIGH( 3451605573ULL, "NV context out of bounds", 0, 0, 0); //auto-gen, to change remove 'QSR_' and first param\r
+ }\r
+ else {\r
+\r
+ (void)KxMutex_Lock(&nv_access_op_cs); \r
+\r
+ switch (cmd_ptr->cmd) {\r
+ case NV_READ_F:\r
+ cmd_ptr->status = nvio_read(cmd_ext_ptr);\r
+ break;\r
+\r
+ case NV_WRITE_F:\r
+ cmd_ptr->status = nvio_write(cmd_ext_ptr);\r
+ break;\r
+\r
+ case NV_PEEK_F:\r
+ cmd_ptr->status = NV_FAIL_S;\r
+ break;\r
+\r
+ case NV_POKE_F:\r
+ cmd_ptr->status = NV_FAIL_S;\r
+ break;\r
+\r
+ case NV_FREE_F:\r
+ cmd_ptr->status = nvim_remove_item(cmd_ext_ptr);\r
+ break;\r
+\r
+ case NV_CHKPNT_ENA_F:\r
+ break;\r
+\r
+ case NV_CHKPNT_DIS_F:\r
+ break;\r
+\r
+ case NV_OTASP_COMMIT_F:\r
+ cmd_ptr->status = nv_otasp_commit(cmd_ext_ptr);\r
+ break;\r
+\r
+ case NV_REPLACE_F:\r
+ cmd_ptr->status = nvio_write(cmd_ext_ptr);\r
+ break;\r
+\r
+ case NV_INCREMENT_F:\r
+ cmd_ptr->status = nvim_increment(cmd_ext_ptr);\r
+ break;\r
+ \r
+#ifdef FEATURE_UIM_RUN_TIME_ENABLE\r
+ case NV_RTRE_OP_CONFIG_F:\r
+ /* The function nvruim_process_rtre_configuration doesnot have any\r
+ dependency on context. However creating new function to take input\r
+ parameter cmd_ext_ptr */\r
+ cmd_ptr->status = \r
+ (nv_stat_enum_type)nvruim_process_rtre_configuration(cmd_ext_ptr->nvcmd, \r
+ &nv_rtre_control_value,\r
+ &nv_rtre_polling_control_value);\r
+ break;\r
+#endif \r
+\r
+ default:\r
+ cmd_ptr->status = NV_BADCMD_S;\r
+ break;\r
+\r
+ }/*switch*/\r
+\r
+ (void)KxMutex_Unlock(&nv_access_op_cs);\r
+}\r
+\r
+ /* Free memory allocated for cmd_ext_ptr */\r
+ free(cmd_ext_ptr);\r
+\r
+} /* nv_front_op_ext */\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NV_TASK\r
+\r
+DESCRIPTION\r
+ This is the NV task, created via rex_def_task from the Main Control task.\r
+ The NV task sets MC_ACK_SIG when it is done with initialization and it\r
+ then waits for NV_START_SIG before starting its normal operations. The\r
+ NV task then enters a main loop, awaiting for commands received on its\r
+ input queue. Each command received is processed and the loop continues.\r
+ While in the main loop the task kicks the watchdog periodically.\r
+\r
+ *MODIFIED to handle new parameter nv_cmd_ext_type\r
+\r
+DEPENDENCIES\r
+ None.\r
+\r
+RETURN VALUE\r
+ None.\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+void nv_task\r
+( \r
+ dword parm /* from REX - ignored */\r
+)\r
+{\r
+ nv_cmd_ext_type *cmd_ext_ptr; /* Pointer to command received on nv_cmd_q */\r
+ nv_cmd_type *cmd_ptr;\r
+ rex_sigs_type rex_sigs; /* REX signals word */\r
+ rex_tcb_type *task_ptr; /* Task to signal back on request completion. */\r
+ rex_sigs_type task_sigs; /* Signals to set back to requesting task */\r
+\r
+/*-------------------------------------------------------------------------*/\r
+\r
+/* Keep Lint happy */\r
+\r
+#ifdef _lint\r
+ parm = parm;\r
+#endif\r
+\r
+ QSR_MSG_MED( 3850502563ULL, "NV task created", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ \r
+ /* Initialize the watchdog report timer and NV write timer. */\r
+\r
+ rex_def_timer(&nv_rpt_timer, &nv_tcb, NV_RPT_TIMER_SIG);\r
+\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+\r
+ /* Initialize the NV command queue. */\r
+ (void) q_init(&nv_cmd_q);\r
+\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+\r
+\r
+ /* Wait for start signal. */\r
+\r
+ nvimnv_task_start (NV_RPT_TIMER_SIG, DOG_NV_RPT, &nv_rpt_timer);\r
+\r
+\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+ /* Kick the wathcdog and start task operations. */\r
+\r
+ KICK_WATCHDOG();\r
+\r
+ /* signal nv err log operations to queue writes to nv */\r
+ nvi_task_running = TRUE; \r
+\r
+ for (;;) { /* while (TRUE) and Lint happy */\r
+\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+\r
+ /* Set REX wait with mask of all possible input signals. */\r
+\r
+ rex_sigs = rex_wait( NV_RPT_TIMER_SIG /* Watchdog timer elapsed */\r
+ | NV_CMD_Q_SIG /* Input of command queue */\r
+ | NV_ERR_LOG_SIG /* Process the nverr record */\r
+ | TASK_STOP_SIG /* Stop the NV task */\r
+ | TASK_OFFLINE_SIG); /* Go offline */\r
+\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+\r
+ /* Kick watchdog and start the watchdog report timer. */\r
+ /* Note that the watchdog is kicked after every wakeup, */\r
+ /* following input of any signal to the NV task. */\r
+\r
+ KICK_WATCHDOG();\r
+\r
+\f\r
+/*-------------------------------------------------------------------------*/\r
+/* */\r
+/* COMMAND QUEUE SIGNAL */\r
+/* */\r
+/*-------------------------------------------------------------------------*/\r
+\r
+ if ((rex_sigs & NV_RPT_TIMER_SIG) != 0) {\r
+ QSR_MSG_LOW( 252695986ULL, "NV_RPT_TIMER_SIG received", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ /* write out any old ERR() if required */\r
+ nverr_update_log();\r
+ }\r
+\r
+ if ((rex_sigs & NV_ERR_LOG_SIG) != 0) {\r
+ QSR_MSG_LOW( 180449550ULL, "NV_ERR_LOG_SIG received", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ (void) rex_clr_sigs(&nv_tcb, NV_ERR_LOG_SIG);\r
+ /* write out any old ERR() if required */\r
+ nverr_update_log();\r
+ }\r
+ /* Check if command queue signal was set. */\r
+ /* If set then clear signal and proceeed. */\r
+\r
+ if ((rex_sigs & NV_CMD_Q_SIG) != 0) {\r
+ QSR_MSG_LOW( 3275661280ULL, "NV_CMD_Q_SIG received", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ (void) rex_clr_sigs(&nv_tcb, NV_CMD_Q_SIG);\r
+\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+ /* Enter a loop where the command queue is checked and */\r
+ while ((cmd_ext_ptr = (nv_cmd_ext_type *) q_get(&nv_cmd_q)) != NULL) \r
+ {\r
+ cmd_ptr = cmd_ext_ptr->nvcmd;\r
+\r
+ nv_front_op(cmd_ext_ptr); \r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+\r
+ /* Save for a moment the requesting task TCB and signal to set. */\r
+ \r
+ task_ptr = cmd_ptr->tcb_ptr;\r
+ task_sigs = cmd_ptr->sigs;\r
+\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+ \r
+ /* If specified in request then return buffer to specified queue. */\r
+\r
+ if (cmd_ptr->done_q_ptr != NULL)\r
+ q_put(cmd_ptr->done_q_ptr, &cmd_ptr->link);\r
+ \r
+ /* If specified in request then signal the requesting task. */\r
+ \r
+ if (task_ptr != NULL)\r
+ (void) rex_set_sigs(task_ptr, task_sigs);\r
+ \r
+ /* At the end of the loop kick the watchdog timer. */\r
+ \r
+ KICK_WATCHDOG();\r
+ \r
+ } /* while */\r
+ } /* if command queue signal */\r
+\r
+/*-------------------------------------------------------------------------*/\r
+/* */\r
+/* OFFLINE COMMAND SIGNAL */\r
+/* */\r
+/*-------------------------------------------------------------------------*/\r
+\r
+ /* Check if offline command signal was set. If set then clear signal, */\r
+ /* send ack back to MC, and proceeed. */\r
+\r
+ if ((rex_sigs & TASK_OFFLINE_SIG) != 0) {\r
+ QSR_MSG_MED( 1000812593ULL, "TASK_OFFLINE_SIG received", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ (void) rex_clr_sigs(&nv_tcb, TASK_OFFLINE_SIG);\r
+ (void) rex_set_sigs(&tmc_tcb, TMC_ACK_SIG);\r
+ /* write out any old ERR() if required */\r
+ nverr_update_log();\r
+ } /* if offline command signal */\r
+\r
+/*-------------------------------------------------------------------------*/\r
+/* */\r
+/* POWERDOWN (STOP) COMMAND SIGNAL */\r
+/* */\r
+/*-------------------------------------------------------------------------*/\r
+\r
+ /* Check if powerdown command signal was set. */\r
+ /* If set then clear signal and proceeed. */\r
+\r
+ if ((rex_sigs & TASK_STOP_SIG) != 0) {\r
+ /* write out any old ERR() if required */\r
+ nverr_update_log();\r
+ QSR_MSG_MED( 2124372139ULL, "TASK_STOP_SIG received", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ (void) rex_clr_sigs(&nv_tcb, TASK_STOP_SIG);\r
+\r
+ nvi_task_running=FALSE;\r
+\r
+ task_stop ();\r
+ /* Send ack back to MC. */\r
+ /* (void) rex_set_sigs(&tmc_tcb, TMC_ACK_SIG); */\r
+ } /* if stop command signal */\r
+\r
+/*-------------------------------------------------------------------------*/\r
+/* */\r
+/* WATCHDOG REPORT TIMER SIGNAL */\r
+/* */\r
+/*-------------------------------------------------------------------------*/\r
+\r
+/* PC debug only. */\r
+\r
+#ifdef FEATURE_NV_UNIT_TEST\r
+ if ((rex_sigs & NV_RPT_TIMER_SIG) != 0) {\r
+ (void) rex_clr_sigs(&nv_tcb, NV_RPT_TIMER_SIG);\r
+ QSR_MSG_LOW( 252695986ULL, "NV_RPT_TIMER_SIG received", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ }\r
+#endif\r
+\r
+/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
+ } /* for (;;) */\r
+} /* nv_task */\r
+\r
+\r
+\f\r
+/*===========================================================================\r
+FUNCTION NVERR_INIT\r
+\r
+DESCRIPTION\r
+ Initialize nv error queue for external tasks\r
+ \r
+DEPENDENCIES\r
+ Called once, by NV.C to init buffers\r
+\r
+RETURN VALUE\r
+ False if init conflict.\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+boolean \r
+nverr_init( void ) {\r
+ int i;\r
+ static boolean nv_error_initialized = FALSE;\r
+ static boolean nv_error_init_in_progress = FALSE;\r
+\r
+ /* We have allready visited this routine */\r
+ if(nv_error_initialized) {\r
+ nv_error_init_in_progress = FALSE;\r
+ return TRUE;\r
+ }\r
+\r
+ /* Flag incase multiple paths initing nv at same time. */\r
+ if(nv_error_init_in_progress) return FALSE;\r
+ nv_error_init_in_progress = TRUE;\r
+\r
+ /* read up shadow copy of error log */\r
+ for(i=0; i< NV_MAX_ERR_LOG; i++) {\r
+ (void) nvio_read_item (\r
+ NV_ERR_LOG_I,\r
+ (byte) i, /* Item index within its array */\r
+ (byte*)&(nverr_log.external[i].err_count), /* data buffer */\r
+ nvim_op_get_size(NV_ERR_LOG_I),\r
+ 0 /* context=0 implies no context is defined */\r
+ );\r
+ nverr_log.update_required[i] = FALSE;\r
+ }\r
+ nverr_log.processing_required = FALSE;\r
+\r
+ nv_error_initialized = TRUE;\r
+ nv_error_init_in_progress = FALSE;\r
+ return TRUE;\r
+}\r
+\r
+\f\r
+/*===========================================================================\r
+FUNCTION NVERR_UPDATE_LOG\r
+\r
+DESCRIPTION\r
+ write dirty error log items out to nv.\r
+ \r
+DEPENDENCIES\r
+ nverr_init must have been called.\r
+\r
+RETURN VALUE\r
+ None.\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+void \r
+nverr_update_log( void ) {\r
+ int i; /* loop counter */\r
+ word isave; /* save flags for interrupt diasble/enable */\r
+\r
+ /* If no errors waiting to be saved, get out of here */\r
+ if(!nverr_log.processing_required) return;\r
+\r
+ KICK_WATCHDOG();\r
+\r
+ /* update internal copy of err_log to write out from */\r
+ INTLOCK_SAV( isave ); /* Disable interrupts and save PSW */\r
+ (void) memcpy((void *) nverr_log.internal,\r
+ (void *) nverr_log.external, \r
+ sizeof(nverr_log.internal)); /* data buffer size */\r
+\r
+ (void) memcpy((void *) nverr_log.update_in_progress,\r
+ (void *) nverr_log.update_required, \r
+ sizeof(nverr_log.update_in_progress)); /* data buffer size */\r
+\r
+ for(i=0; i< NV_MAX_ERR_LOG; i++) {\r
+ nverr_log.update_required[i] = FALSE;\r
+ }\r
+ nverr_log.processing_required = FALSE;\r
+ INTFREE_SAV( isave ); /* Restore interrupts (PSW) */\r
+\r
+ /* write out internal shadow copy of error log */\r
+ for(i=0; i< NV_MAX_ERR_LOG; i++) {\r
+ if(nverr_log.update_in_progress[i]) {\r
+ QSR_MSG_MED( 427085943ULL, "nverr_log entry %d update in progress ", i, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ KICK_WATCHDOG();\r
+ nvio_write_item\r
+ (\r
+ NV_ERR_LOG_I,\r
+ (byte) i, /* Item index within its array */\r
+ (byte *)&(nverr_log.internal[i].err_count), /* data buffer */ \r
+ nvim_op_get_size(NV_ERR_LOG_I),\r
+ 0 /* context=0 implies no context is defined */\r
+ );\r
+ }\r
+ }\r
+}\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NV_MAX_SIZE_OF_ROAMING_LIST\r
+\r
+DESCRIPTION\r
+ This function returns the maximum number of bytes available for\r
+ storage of a roaming list (per NAM). The value returned depends \r
+ on the total amount of NVRAM installed in the phone and the total \r
+ number of NAMs defined. \r
+\r
+DEPENDENCIES\r
+ The function cannot be called until NV is initialized. A\r
+ premature call will raise err_fatal.\r
+\r
+RETURN VALUE\r
+ The maximum number of bytes available for storage of a roaming list\r
+ (per NAM).\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+word \r
+nv_max_size_of_roaming_list( void ) {\r
+ if (!nvi_initialized)\r
+ {\r
+ ERR_FATAL("Illegal task start-up order", 0, 0, 0);\r
+ }\r
+\r
+ #if !defined( FEATURE_NV_RUIM ) || defined( FEATURE_UIM_RUN_TIME_ENABLE )\r
+ #if defined( FEATURE_UIM_RUN_TIME_ENABLE )\r
+ /* Determine if the R-UIM is available */\r
+ if (NV_RTRE_CONTROL_USE_RUIM != nv_rtre_control())\r
+ #endif /* FEATURE_UIM_RUN_TIME_ENABLE */\r
+ {\r
+ #ifdef NV_FEATURE_PRL_ITEMS\r
+ return NV_ROAMING_LIST_MAX_SIZE;\r
+ #else\r
+ return (word)0;\r
+ #endif\r
+ }\r
+ #if defined( FEATURE_UIM_RUN_TIME_ENABLE )\r
+ else {\r
+ #if defined( FEATURE_NVRUIM_ADM_ACCESS ) || defined( FEATURE_BUILD_JCDMA )\r
+ /* Return a max number here and check the size in nvruim before writing */\r
+ return NV_ROAMING_LIST_MAX_SIZE;\r
+ #else\r
+ return (word)0;\r
+ #endif /* FEATURE_RUIM_ADM_ACCESS */\r
+ }\r
+ #endif /*( FEATURE_UIM_RUN_TIME_ENABLE ) */\r
+\r
+ #else\r
+ return (word)0;\r
+ #endif /* !FEATURE_NV_RUIM || FEATURE_UIM_RUN_TIME_ENABLE */\r
+\r
+} /* nv_max_size_of_roaming_list */\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NV_MAX_SIZE_OF_WEB_CACHE\r
+\r
+DESCRIPTION\r
+ This function returns the maximum number of bytes currently available \r
+ for storage of the Unwired Planet cache. At this time, the cache\r
+ size is always zero (it is not currently used).\r
+ \r
+DEPENDENCIES\r
+ The function cannot be called until NV is initialized. A\r
+ premature call will raise err_fatal.\r
+\r
+RETURN VALUE\r
+ The maximum number of bytes currently available for storage of the\r
+ Unwired Planet cache.\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+word \r
+nv_max_size_of_web_cache( void ) {\r
+ if (!nvi_initialized) {\r
+ ERR_FATAL("Illegal task start-up order", 0, 0, 0);\r
+ }\r
+ return (word)0;\r
+} /* nv_max_size_of_web_cache */\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NV_BUILT\r
+\r
+DESCRIPTION\r
+ This function will return TRUE once the files are available that simulate\r
+ NV storage.\r
+\r
+DEPENDENCIES\r
+ This is a special use function, normally called by error services\r
+ to allow early access to NV, and before the NV task has been started.\r
+ The NV Item Manager allows access once file initialization is complete.\r
+\r
+RETURN VALUE\r
+ TRUE - The NV has been built and direct read/write is allowed\r
+ FALSE - The NV has not been built and access is not allowed\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+boolean nv_built (void)\r
+\r
+{\r
+ return nvi_initialized;\r
+ \r
+} /* nv_built */\r
+\r
+\f\r
+/*===========================================================================\r
+\r
+FUNCTION NV_CMD\r
+\r
+DESCRIPTION\r
+ This is the outside world's interface to the non volatile memory task\r
+ this function takes an already filled out nv_cmd_type and place it on\r
+ the nv queue. The function returns to the caller after setting the\r
+ status to busy indicaton. This does _not_ mean that the command has\r
+ been executed yet, just that it is waiting to be executed.\r
+\r
+DEPENDENCIES\r
+ The NV task must have been started up already. All of the items in\r
+ the nv_cmd_block must be already set.\r
+\r
+RETURN VALUE\r
+ None directly. The status variable of the nv_cmd_type will be updated\r
+ to reflect the current status of this command as it is processed.\r
+\r
+SIDE EFFECTS\r
+ The nv_cmd_type is placed on the NV command queue. It must not be\r
+ modified until the command has been processed.\r
+\r
+===========================================================================*/\r
+\r
+void \r
+nv_cmd (\r
+ nv_cmd_type *cmd_ptr /* Pointer to NV command buffer */\r
+)\r
+{\r
+\r
+ nv_cmd_ext_type *cmd_ext_ptr = (nv_cmd_ext_type *) malloc (sizeof(nv_cmd_ext_type));\r
+\r
+ if (cmd_ext_ptr != NULL)\r
+ { \r
+\r
+ /* Converting nv_cmd_type to nv_cmd_ext_type by setting context to 0 */\r
+ cmd_ext_ptr->nvcmd = cmd_ptr;\r
+ cmd_ext_ptr->context = 0;\r
+ \r
+ /* Set the request status to busy. initialize and link the command */\r
+ /* onto the NV command queue, set a signal to the NV task and exit. */\r
+ if (cmd_ext_ptr->nvcmd->tcb_ptr != NULL) \r
+ {\r
+ cmd_ext_ptr->nvcmd->status = NV_BUSY_S;\r
+ (void) q_link(cmd_ext_ptr, &cmd_ext_ptr->link);\r
+ q_put(&nv_cmd_q, &cmd_ext_ptr->link);\r
+ (void) rex_set_sigs(&nv_tcb, NV_CMD_Q_SIG);\r
+ }\r
+ \r
+ else\r
+ {\r
+\r
+ /* For synchronous calls, we need to ensure mutexes are initiliazed */\r
+ if(!nv_cs_init_flag)\r
+ nv_access_op_cs_init();\r
+ \r
+ nv_front_op(cmd_ext_ptr);\r
+ } /* if command has no tcb */\r
+ }\r
+ else \r
+ QSR_MSG_HIGH ( 3639666217ULL, "Could not allocate memory for variable of type nv_cmd_ext_type", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ \r
+} /* nv_cmd */\r
+\r
+\r
+/*===========================================================================\r
+\r
+FUNCTION NV_CMD_EXT\r
+\r
+DESCRIPTION\r
+ This is the outside world's interface to the non volatile memory task\r
+ this function takes an already filled out nv_cmd_type and place it on\r
+ the nv queue. The function returns to the caller after setting the\r
+ status to busy indicaton. This does _not_ mean that the command has\r
+ been executed yet, just that it is waiting to be executed.\r
+\r
+DEPENDENCIES\r
+ The NV task must have been started up already. All of the items in\r
+ the nv_cmd_block must be already set. This function allows items across\r
+ multiple SIMs to be accessed.\r
+\r
+RETURN VALUE\r
+ None directly. The status variable of the nv_cmd_ext_type will be updated\r
+ to reflect the current status of this command as it is processed.\r
+\r
+SIDE EFFECTS\r
+ The nv_cmd_ext_type is placed on the NV command queue. It must not be\r
+ modified until the command has been processed.\r
+\r
+===========================================================================*/\r
+\r
+void \r
+nv_cmd_ext (\r
+ nv_cmd_ext_type *cmd_ext_ptr /* Pointer to NV command buffer */\r
+)\r
+{\r
+ nv_cmd_ext_type *lcmd_ext_ptr = (nv_cmd_ext_type *) malloc (sizeof(nv_cmd_ext_type));\r
+\r
+ if (lcmd_ext_ptr != NULL)\r
+ { \r
+ /* copy the parameters into the allocated momory */\r
+ lcmd_ext_ptr->nvcmd = cmd_ext_ptr->nvcmd;\r
+ lcmd_ext_ptr->context = cmd_ext_ptr->context;\r
+ } else {\r
+ QSR_MSG_HIGH ( 3639666217ULL, "Could not allocate memory for variable of type nv_cmd_ext_type", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+ return;\r
+ }\r
+\r
+ /* Set the request status to busy. initialize and link the command */\r
+ /* onto the NV command queue, set a signal to the NV task and exit. */\r
+ if (lcmd_ext_ptr->nvcmd->tcb_ptr != NULL) \r
+ {\r
+ lcmd_ext_ptr->nvcmd->status = NV_BUSY_S;\r
+ (void) q_link(lcmd_ext_ptr, &lcmd_ext_ptr->link);\r
+ q_put(&nv_cmd_q, &lcmd_ext_ptr->link);\r
+ (void) rex_set_sigs(&nv_tcb, NV_CMD_Q_SIG);\r
+ }\r
+ else\r
+ {\r
+\r
+ /* For synchronous calls, we need to ensure mutexes are initiliazed */\r
+ if(!nv_cs_init_flag)\r
+ nv_access_op_cs_init();\r
+ \r
+ nv_front_op(lcmd_ext_ptr);\r
+ } /* if command has no tcb */\r
+} /* nv_cmd_ext */\r
+\r
+\r
+\r
+/*===========================================================================\r
+\r
+FUNCTION NV_CMD_R\r
+\r
+DESCRIPTION\r
+ This is same as nv_cmd but it waits till NV finishes its operation.\r
+\r
+DEPENDENCIES\r
+ The NV task must have been started up already. All of the items in\r
+ the nv_cmd_block must be already set.\r
+\r
+RETURN VALUE\r
+ None directly. The status variable of the nv_cmd_type will be updated\r
+ to reflect the current status of this command as it is processed.\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+void \r
+nv_cmd_r (\r
+ nv_cmd_type *cmd_ptr, /* Pointer to NV command buffer */\r
+ nv_item_type *data_ptr /* Pointer to structure that contains item data */\r
+)\r
+{\r
+#ifdef FEATURE_RPC\r
+ nv_cmd_ext_type *cmd_ext_ptr = (nv_cmd_ext_type *) malloc (sizeof(nv_cmd_ext_type));\r
+ \r
+ /* Save params */\r
+ rex_tcb_type *client_tcb = cmd_ptr->tcb_ptr;\r
+ nv_item_type *client_data = cmd_ptr->data_ptr;\r
+\r
+ /* Set the request status to busy. initialize and link the command */\r
+ /* onto the NV command queue, set a signal to the NV task and exit. */\r
+\r
+ cmd_ptr->tcb_ptr = rex_self();\r
+ cmd_ptr->data_ptr = data_ptr;\r
+\r
+ cmd_ptr->status = NV_BUSY_S;\r
+\r
+ /* Converting nv_cmd_type to nv_cmd_ext_type by setting context to 0 */\r
+ if (cmd_ext_ptr != NULL) \r
+ {\r
+ cmd_ext_ptr->nvcmd = cmd_ptr;\r
+ cmd_ext_ptr->context = 0;\r
+ \r
+ /* Putting nv_cmd_ext on queue */\r
+ (void) q_link(cmd_ext_ptr, &cmd_ext_ptr->link);\r
+ q_put(&nv_cmd_q, &cmd_ext_ptr->link);\r
+ (void) rex_set_sigs(&nv_tcb, NV_CMD_Q_SIG);\r
+\r
+ rex_wait( cmd_ptr->sigs );\r
+ rex_clr_sigs( cmd_ptr->tcb_ptr, cmd_ptr->sigs );\r
+\r
+ }\r
+ else\r
+ QSR_MSG_HIGH ( 3639666217ULL, "Could not allocate memory for variable of type nv_cmd_ext_type", 0, 0, 0);//auto-gen, to change remove 'QSR_' and first param\r
+\r
+ /* Restore params */\r
+\r
+ cmd_ptr->tcb_ptr = client_tcb;\r
+ cmd_ptr->data_ptr = client_data;\r
+#else\r
+ QSR_MSG_HIGH( 3143198573ULL, "nv_cmd_r():FEATURE_RPC not defined",0,0,0);//auto-gen, to change remove 'QSR_' and first param\r
+#endif\r
+} /* nv_cmd_r */\r
+\r
+/*===========================================================================\r
+\r
+FUNCTION NV_CMD_EXT_R\r
+\r
+DESCRIPTION\r
+ This is same as nv_cmd but it waits till NV finishes its operation.\r
+\r
+DEPENDENCIES\r
+ The NV task must have been started up already. All of the items in\r
+ the nv_cmd_block must be already set.\r
+\r
+RETURN VALUE\r
+ None directly. The status variable of the nv_cmd_type will be updated\r
+ to reflect the current status of this command as it is processed.\r
+\r
+SIDE EFFECTS\r
+ None.\r
+\r
+===========================================================================*/\r
+\r
+void \r
+nv_cmd_ext_r (\r
+ nv_cmd_ext_type *cmd_ext_ptr, /* Pointer to NV command buffer */\r
+ nv_item_type *data_ptr /* Pointer to structure that contains item data */\r
+)\r
+{\r
+#ifdef FEATURE_RPC\r
+ /* Save params */\r
+ rex_tcb_type *client_tcb = cmd_ext_ptr->nvcmd->tcb_ptr;\r
+ nv_item_type *client_data = cmd_ext_ptr->nvcmd->data_ptr;\r
+\r
+ /* Set the request status to busy. initialize and link the command */\r
+ /* onto the NV command queue, set a signal to the NV task and exit. */\r
+\r
+ cmd_ext_ptr->nvcmd->tcb_ptr = rex_self();\r
+ cmd_ext_ptr->nvcmd->data_ptr = data_ptr;\r
+\r
+ cmd_ext_ptr->nvcmd->status = NV_BUSY_S;\r
+\r
+ /* Putting nv_cmd_ext on queue */\r
+ (void) q_link(cmd_ext_ptr, &cmd_ext_ptr->link);\r
+ q_put(&nv_cmd_q, &cmd_ext_ptr->link);\r
+ (void) rex_set_sigs(&nv_tcb, NV_CMD_Q_SIG);\r
+ \r
+ rex_wait( cmd_ptr->sigs );\r
+ rex_clr_sigs( cmd_ptr->tcb_ptr, cmd_ptr->sigs );\r
+ \r
+ /* Restore params */\r
+ cmd_ext_ptr->nvcmd->tcb_ptr = client_tcb;\r
+ cmd_ext_ptr->nvcmd->data_ptr = client_data;\r
+#else\r
+ QSR_MSG_HIGH( 2675320387ULL, "nv_cmd_ext_r():FEATURE_RPC not defined",0,0,0);//auto-gen, to change remove 'QSR_' and first param\r
+#endif\r
+ \r
+} /* nv_cmd_ext_r */\r
+\r
+\r
+/*===========================================================================\r
+\r
+FUNCTION NV_CMD_REMOTE\r
+\r
+DESCRIPTION\r
+ This is the outside world's interface to the non volatile memory task.\r
+\r
+DEPENDENCIES\r
+ The NV task must have been started up already. All of the items in\r
+ the nv_cmd_type must be already set.\r
+\r
+RETURN VALUE\r
+\r
+ NV_DONE_S, - Request completed okay\r
+ NV_BUSY_S, - Request is queued\r
+ NV_BADCMD_S, - Unrecognizable command field\r
+ NV_FULL_S, - The NVM is full\r
+ NV_FAIL_S, - Command failed, reason other than NVM was full\r
+ NV_NOTACTIVE_S, - Variable was not active\r
+ NV_BADPARM_S, - Bad parameter in command block\r
+ NV_READONLY_S, - Parameter is write-protected and thus read only\r
+ NV_BADTG_S, - Item not valid for Target\r
+ NV_NOMEM_S, - free memory exhausted\r
+ NV_NOTALLOC_S - address is not a valid allocation\r
+\r
+SIDE EFFECTS\r
+ The nv_cmd_type is placed on the NV command queue. It must not be\r
+ modified until the command has been processed!\r
+\r
+===========================================================================*/\r
+\r
+nv_stat_enum_type \r
+nv_cmd_remote (\r
+ nv_func_enum_type cmd,\r
+ nv_items_enum_type item,\r
+ nv_item_type *data_ptr\r
+)\r
+{\r
+ nv_cmd_type nv_rpc_cmd;\r
+#ifdef FEATURE_NV_RPC_SUPPORT\r
+\r
+#ifdef FEATURE_NV_ACCESS_FILTER\r
+ if(cmd == NV_READ_F)\r
+ {\r
+ if(unreadable_nv_item(item))\r
+ {\r
+ return NV_BADPARM_S; \r
+ }\r
+ }\r
+ else \r
+ { \r
+ if((cmd == NV_WRITE_F)||(cmd == NV_REPLACE_F))\r
+ {\r
+ if(unwritable_nv_item(item))\r
+ {\r
+ return NV_BADPARM_S; \r
+ }\r
+ }\r
+ }\r
+#endif\r
+\r
+ nv_rpc_cmd.status = NV_BUSY_S;\r
+ (void) q_link(&nv_rpc_cmd, &nv_rpc_cmd.link);\r
+ nv_rpc_cmd.tcb_ptr = rex_self();\r
+ nv_rpc_cmd.sigs = NV_QIDS_RPC_SIG;\r
+ nv_rpc_cmd.cmd = cmd;\r
+ nv_rpc_cmd.item = item;\r
+ nv_rpc_cmd.data_ptr = data_ptr;\r
+ nv_rpc_cmd.done_q_ptr = NULL;\r
+\r
+ nv_cmd( &nv_rpc_cmd );\r
+ rex_wait( NV_QIDS_RPC_SIG ); /* this signal needs to be reserved for all worker task*/\r
+\r
+ rex_clr_sigs( nv_rpc_cmd.tcb_ptr, NV_QIDS_RPC_SIG );\r
+\r
+#else\r
+ QSR_MSG_HIGH( 2469021251ULL, "nv_stat_enum_type(): FEATURE_NV_RPC_SUPPORT not defined",0,0,0);//auto-gen, to change remove 'QSR_' and first param\r
+ nv_rpc_cmd.status = NV_FAIL_S;\r
+#endif\r
+ return nv_rpc_cmd.status;\r
+\r
+}\r
+\r
+/*===========================================================================\r
+\r
+FUNCTION NV_CMD_EXT_REMOTE\r
+\r
+DESCRIPTION\r
+ This is the outside world's interface to the non volatile memory task.\r
+\r
+DEPENDENCIES\r
+ The NV task must have been started up already. All of the items in\r
+ the nv_cmd_ext_type must be already set.\r
+\r
+RETURN VALUE\r
+\r
+ NV_DONE_S, - Request completed okay\r
+ NV_BUSY_S, - Request is queued\r
+ NV_BADCMD_S, - Unrecognizable command field\r
+ NV_FULL_S, - The NVM is full\r
+ NV_FAIL_S, - Command failed, reason other than NVM was full\r
+ NV_NOTACTIVE_S, - Variable was not active\r
+ NV_BADPARM_S, - Bad parameter in command block\r
+ NV_READONLY_S, - Parameter is write-protected and thus read only\r
+ NV_BADTG_S, - Item not valid for Target\r
+ NV_NOMEM_S, - free memory exhausted\r
+ NV_NOTALLOC_S - address is not a valid allocation\r
+\r
+SIDE EFFECTS\r
+ The nv_cmd_ext_type is placed on the NV command queue. It must not be\r
+ modified until the command has been processed!\r
+\r
+===========================================================================*/\r
+\r
+nv_stat_enum_type \r
+nv_cmd_ext_remote (\r
+ nv_func_enum_type cmd,\r
+ nv_items_enum_type item,\r
+ nv_item_type *data_ptr,\r
+ uint16 context\r
+)\r
+{\r
+ nv_cmd_type nv_rpc_cmd;\r
+#ifdef FEATURE_NV_RPC_SUPPORT\r
+ nv_cmd_ext_type nv_rpc_cmd_ext;\r
+\r
+#ifdef FEATURE_NV_ACCESS_FILTER\r
+ if(cmd == NV_READ_F)\r
+ {\r
+ if(unreadable_nv_item(item))\r
+ {\r
+ return NV_BADPARM_S; \r
+ }\r
+ }\r
+ else \r
+ { \r
+ if((cmd == NV_WRITE_F)||(cmd == NV_REPLACE_F))\r
+ {\r
+ if(unwritable_nv_item(item))\r
+ {\r
+ return NV_BADPARM_S; \r
+ }\r
+ }\r
+ }\r
+#endif\r
+\r
+ nv_rpc_cmd.status = NV_BUSY_S;\r
+ (void) q_link(&nv_rpc_cmd, &nv_rpc_cmd.link);\r
+ nv_rpc_cmd.tcb_ptr = rex_self();\r
+ nv_rpc_cmd.sigs = NV_QIDS_RPC_SIG;\r
+ nv_rpc_cmd.cmd = cmd;\r
+ nv_rpc_cmd.item = item;\r
+ nv_rpc_cmd.data_ptr = data_ptr;\r
+ nv_rpc_cmd.done_q_ptr = NULL;\r
+ \r
+ nv_rpc_cmd_ext.nvcmd = &nv_rpc_cmd;\r
+ nv_rpc_cmd_ext.context = context;\r
+ (void) q_link(&nv_rpc_cmd_ext, &nv_rpc_cmd_ext.link);\r
+ \r
+ nv_cmd_ext( &nv_rpc_cmd_ext );\r
+ rex_wait( NV_QIDS_RPC_SIG ); /* this signal needs to be reserved for all worker task*/\r
+\r
+ rex_clr_sigs( nv_rpc_cmd.tcb_ptr, NV_QIDS_RPC_SIG );\r
+\r
+#else\r
+ QSR_MSG_HIGH( 2201780199ULL, "nv_cmd_ext_remote(): FEATURE_NV_RPC_SUPPORT not defined",0,0,0);//auto-gen, to change remove 'QSR_' and first param\r
+ nv_rpc_cmd.status = NV_FAIL_S;\r
+#endif\r
+\r
+ return nv_rpc_cmd.status;\r
+\r
+}\r
+\r
+/*===========================================================================\r
+\r
+FUNCTION NV_RTRE_USE_RUIM_FOR_NAM\r
+\r
+DESCRIPTION\r
+ This function determines if the R-UIM is to be used (based on RTRE control)\r
+ and the NAM is the R-UIM NAM.\r
+ \r
+DEPENDENCIES\r
+ The return value has a default setting and is updated when NV receives\r
+ a NV_RTRE_OP_CONFIG_F command.\r
+\r
+RETURN VALUE\r
+ The RTRE control indicates to use the R-UIM and the NAM matches the R-UIM \r
+ NAM.\r
+\r
+SIDE EFFECTS\r
+ This function uses the current value of the RTRE control. It may\r
+ change.\r
+\r
+===========================================================================*/\r
+\r
+boolean \r
+nv_rtre_use_ruim_for_nam (\r
+ byte nam\r
+)\r
+{\r
+ #ifdef FEATURE_UIM_RUN_TIME_ENABLE\r
+ /* Determine if the current RTRE control is for the R-UIM */\r
+ return ((NV_RTRE_CONTROL_USE_RUIM == nv_rtre_control()) &&\r
+ /* and the NAM matches the R-UIM NAM */\r
+ (NV_RUIM_NAM == nam));\r
+ #else\r
+ (void)nam;\r
+ return FALSE;\r
+ #endif /*FEATURE_UIM_RUN_TIME_ENABLE*/\r
+}\r
+\r
+/*==================================================================\r
+Function: NV_ACCESS_OP_CS_INIT\r
+\r
+Description: This functions initialises kxmutex.\r
+==================================================================*/\r
+\r
+void nv_access_op_cs_init(void)\r
+{\r
+ if (!(KxMutex_Init(&nv_access_op_cs,"KXMUTEX_NV_ACCESS_OP_CS"))) \r
+ {\r
+ ERR_FATAL("nv_access_op_cs KxMutex_Alloc Failed",0,0,0);\r
+ }\r
+ nv_cs_init_flag = TRUE;\r
+}\r
+\r
+/*===========================================================================\r
+\r
+FUNCTION NV_RTRE_CONTROL\r
+\r
+DESCRIPTION\r
+ This function provides the current RTRE control. The control indicates \r
+ whether the use the R-UIM in an operation or not.\r
+\r
+DEPENDENCIES\r
+ The return value has a default setting and is updated when NV receives\r
+ a NV_RTRE_OP_CONFIG_F command.\r
+\r
+RETURN VALUE\r
+ The RTRE control\r
+\r
+SIDE EFFECTS\r
+ This function returns the current value of the RTRE control. It may\r
+ change.\r
+\r
+===========================================================================*/\r
+\r
+nv_rtre_control_type \r
+nv_rtre_control( void ) \r
+{\r
+#ifdef FEATURE_UIM_RUN_TIME_ENABLE\r
+ /* Retrieve the current RTRE control value */\r
+ return (nv_rtre_control_value);\r
+#else\r
+ return NV_RTRE_CONTROL_NO_RUIM;\r
+ #endif /*FEATURE_UIM_RUN_TIME_ENABLE*/\r
+\r
+}\r
+\r
+/*===========================================================================\r
+\r
+FUNCTION NV_RTRE_POLLING_CONTROL\r
+\r
+DESCRIPTION\r
+ This function provides the current RTRE polling control. The polling control\r
+ indicates whether to poll the UIM card when originating a call or while on \r
+ the traffic channel.\r
+\r
+DEPENDENCIES\r
+ The return value has a default setting and is updated when NV receives\r
+ a NV_RTRE_OP_CONFIG_F command.\r
+\r
+RETURN VALUE\r
+ The RTRE polling control\r
+\r
+SIDE EFFECTS\r
+ This function returns the current value of the RTRE polling control. It may\r
+ change.\r
+\r
+===========================================================================*/\r
+\r
+nv_rtre_polling_control_type \r
+nv_rtre_polling_control( void ) {\r
+#ifdef FEATURE_UIM_RUN_TIME_ENABLE\r
+ /* Retrieve the current RTRE control value */\r
+ return (nv_rtre_polling_control_value);\r
+#else\r
+ return NV_RTRE_POLLING_CONTROL_NO_POLL;\r
+ #endif /*FEATURE_UIM_RUN_TIME_ENABLE*/\r
+}\r
+\r
+/*===========================================================================\r
+\r
+FUNCTION NV_RTRE_POLLING_FOR_NAM\r
+\r
+DESCRIPTION\r
+ This function provides the current RTRE polling control when the NAM is the \r
+ R_UIM NAM. The polling control indicates whether to poll the UIM card when \r
+ originating a call or while on the traffic channel.\r
+\r
+DEPENDENCIES\r
+ The return value has a default setting and is updated when NV receives\r
+ a NV_RTRE_OP_CONFIG_F command.\r
+\r
+RETURN VALUE\r
+ The RTRE polling control indicates whether to poll and the NAM matches the\r
+ R-UIM NAM.\r
+\r
+SIDE EFFECTS\r
+ This function returns the current value of the RTRE polling control. It may\r
+ change.\r
+\r
+===========================================================================*/\r
+\r
+boolean \r
+nv_rtre_polling_for_nam ( \r
+ byte nam\r
+)\r
+{\r
+#ifdef FEATURE_UIM_RUN_TIME_ENABLE\r
+ /* Retrieve the current RTRE control value */\r
+ return ((NV_RTRE_POLLING_CONTROL_POLL == nv_rtre_polling_control_value) &&\r
+ /* and the NAM matches the R-UIM NAM */\r
+ (NV_RUIM_NAM == nam));\r
+#else\r
+ (void)nam;\r
+ return FALSE;\r
+ #endif /*FEATURE_UIM_RUN_TIME_ENABLE*/\r
+}\r
+\r
+\r
+#endif /* FEATURE_NV_ITEM_MGR */\r