[Feature]Upload Modem source code

Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/service/nvram/src/nvram_interface.c b/mcu/service/nvram/src/nvram_interface.c
new file mode 100644
index 0000000..73a667f
--- /dev/null
+++ b/mcu/service/nvram/src/nvram_interface.c
@@ -0,0 +1,3753 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ * Filename:
+ * ---------
+ * nvram_interface.c
+ *
+ * Project:
+ * --------
+ *   MAUI
+ *
+ * Description:
+ * ------------
+ *   These are interface functions of NVRAM module.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+/*
+ * Include
+ */
+#include "string.h"
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+#include "kal_public_defs.h"
+#include "kal_trace.h"
+
+
+#include "kal_public_defs.h" //MSBB change #include "stack_config.h"
+#include "ex_item.h"
+#include "ex_public.h"
+#include "sysconf_statistics.h"
+
+#include "fs_type.h"
+#include "fs_errcode.h"
+#include "fs_func.h"
+//MSBB remove #include "fctycomp_config.h"
+
+#include "nvram_data_items.h"
+#include "nvram_group_def.h" //add for break group files from header file
+#include "nvram_main.h"
+#include "nvram_interface.h"
+
+#include "ul1_nvram_def.h"
+#include "audio_nvram_def.h"
+#include "ex_nvram_def.h"
+#include "nvram_msgid.h"
+
+#include "SST_secure.h"
+#include "svc_sap.h"
+#include "us_timer.h"
+#include "mcf_if.h"
+#include "cc_ex_item.h"
+#include "ex_public.h"
+
+/*
+ * Macro
+ */
+#define NVRAM_SPACE_MARGIN 10
+
+/*
+* used to check nvram ee memory info 
+*/
+kal_bool g_nvram_emm_query_info_result = KAL_TRUE;
+kal_uint32 g_nvram_emm_size = 0;
+kal_uint32 g_nvram_emm_addr = 0;
+
+/*
+ * Local Variable
+ */
+#if defined(__MTK_TARGET__) || defined(__OFFLINE_EX_LOG_PARSER__) 
+static EX_FULLLOG_T exception_full_log; 
+#endif
+
+static kal_uint8 nvram_exception_buffer[NVRAM_EF_SYS_EXCEPTION_SIZE];
+extern kal_uint32 BytesPerCluster;  /* will be set to exact value in nvram_get_disk_file_info */
+extern kal_bool stack_update_sys_statistics(stack_statistics_struct *prev_stats);
+
+extern nvram_shutdown_cb_struct nvram_shutdown_cb_table[];
+extern nvram_access_trace_information nvram_access_trace;
+extern kal_mutexid g_nvram_trace_mutex;
+extern module_type stack_get_active_module_id( void );
+
+extern nvram_ee_info_type* nvram_ee_info;
+extern kal_char nvram_trace_dump_temp_buffer[];
+extern kal_char nvram_trace_dump_buffer[];
+extern kal_mutexid g_nvram_dump_trace_mutex;
+extern kal_wchar nvram_trace_filename[];
+extern FS_HANDLE nvram_trace_file_hdl;
+extern kal_uint32 nvram_trace_dump_buffer_offset;
+
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_get_info
+ * DESCRIPTION
+ *  This is nvram_get_info() function of NVRAM module.
+ * PARAMETERS
+ *  LID         [IN]
+ *  total       [?]
+ *  size        [?]
+ * RETURNS
+ *  NVRAM_ERRNO_SUCCESS if succeed, NVRAM_ERRNO_INVALID otherwise (ie, invalid LID).
+ *****************************************************************************/
+nvram_errno_enum nvram_get_info(nvram_lid_enum LID, kal_uint16 *total, kal_uint16 *size)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi;
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    if ((nvram_ptr->state != NVRAM_STATE_READY) && !nvram_util_is_usbboot())
+    {
+        return NVRAM_ERRNO_FAIL;
+    }
+
+    nvram_pre_init();
+
+    if (!NVRAM_IS_LID_VALID(LID))
+    {
+        return NVRAM_IO_ERRNO_INVALID_LID;
+    }
+
+    nvram_util_get_data_item(&ldi, LID);
+
+    *total = ldi->total_records;
+    *size = ldi->size;
+
+    return NVRAM_ERRNO_SUCCESS;
+}   /* end of nvram_get_info function */
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_log_ota_info
+ * DESCRIPTION
+ *  show OTA version info in ELT log
+ *
+ * PARAMETERS
+ *  void
+ * RETURNS
+ *  void
+ *****************************************************************************/
+void nvram_log_ota_info(void)
+{
+    kal_wchar filename[NVRAM_MAX_PATH_LEN];
+    FS_HANDLE handle;
+    kal_char info[256];
+    kal_uint32 len = 0;
+    kal_int32 result = FS_NO_ERROR;
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    kal_wsprintf(filename, "%s", NVRAM_SWCHANGE_REPORT_FILE_TXT);
+    
+    NVRAM_FS_START_EX(FS_OP_OPEN,filename);
+    handle = FS_Open(filename, FS_READ_ONLY);
+    NVRAM_FS_END(FS_OP_OPEN,result);
+    if (handle < FS_NO_ERROR) {
+        return;
+    }
+    NVRAM_FS_START(FS_OP_READ);
+    result = FS_Read(handle, info, sizeof(info)-1, &len);
+    NVRAM_FS_END(FS_OP_READ,result);
+    NVRAM_FS_START(FS_OP_CLOSE);
+    result = FS_Close(handle);
+    NVRAM_FS_END(FS_OP_CLOSE,result);
+    if (len > 0) {
+        info[len] = '\0';
+        dhl_print(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_NIL, "[NVRAM] %s", info);  /* MOD_NIL will log to System trace */
+    }
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_write_exception
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ *  length:      [IN]   buffer length
+ *  ex_data:     [IN]   ex_data
+ *  ex_log:      [IN]   ex_log
+ * RETURNS
+ *  void
+ *****************************************************************************/
+void nvram_write_exception(kal_uint16 length, long *ex_data, long *ex_log)
+{
+    #if defined(__MTK_TARGET__) || defined(__OFFLINE_EX_LOG_PARSER__)
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    kal_uint16 i;
+    kal_uint16 prev_num = 0;
+
+    nvram_drv_status_enum result;
+    nvram_ltable_entry_struct *ldi;
+
+    EX_LOG_T *exception_ptr = (EX_LOG_T*) nvram_exception_buffer;    
+    EX_FULLLOG_T* exception_fulllog_ptr = (EX_FULLLOG_T*)ex_data;
+    
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"%s ====>\r\n",__FUNCTION__);
+    nvram_log_ota_info();
+    
+    if (ex_data == NULL)
+    {
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s \r\n",__FUNCTION__);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s <====\r\n",__FUNCTION__);
+        MD_TRC_FUNC_NVRAM_WRITE_EXCEPTION1();
+        return;
+    }
+    if (ex_log == NULL)
+    {
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s <====\r\n",__FUNCTION__);
+        MD_TRC_FUNC_NVRAM_WRITE_EXCEPTION1();
+        return;
+    }
+
+    /* Length must be equal to NVRAM_EF_SYS_EXCEPTION_SIZE */
+    if (length != NVRAM_EF_SYS_EXCEPTION_SIZE)
+    {
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s <====\r\n",__FUNCTION__);
+        MD_TRC_FUNC_NVRAM_WRITE_EXCEPTION2(length, NVRAM_EF_SYS_EXCEPTION_SIZE);
+        return;
+    }
+
+    /* Exception could happen even when no task is initialized */
+    if (nvram_ptr->state == NVRAM_STATE_NULL)
+    {
+        //nvram_init(INDX_NIL);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s <====\r\n",__FUNCTION__);
+        MD_TRC_FUNC_NVRAM_WRITE_EXCEPTION2(NVRAM_STATE_NULL, 1);
+        return;
+    }
+
+   /**
+    * Now linear searching for a free record such that ex_data could be
+    * written.
+    *
+    * Note that if value of ex_nvram field of a exception record
+    * is NOT 0xFF, then it is a valid record; otherwise it is a free
+    * record.
+    * Furthermore, update of exception records cannot exceeds
+    * the capacity, ie, number of exception records defined in NVRAM.
+    * Once the storage is full, no more exception record can be dumped.
+    * Hence, as long as a free record is found, then that record and
+    * other records after it could be all assumed to be free.
+    */
+
+    nvram_util_get_data_item(&ldi, NVRAM_EF_SYS_EXCEPTION_LID);
+
+    for (i = 1; i <= NVRAM_EF_SYS_EXCEPTION_TOTAL; ++i)
+    {
+        memset(&exception_full_log,0,sizeof(exception_full_log));
+        result = nvram_read_exception_data_item(ldi, i, (kal_uint8*) & exception_full_log, sizeof(exception_full_log));
+        /* Ok, now determine whether it is a free record */
+
+        MD_TRC_FUNC_NVRAM_WRITE_EXCEPTION2(i, result);
+        if ((result == NVRAM_DRV_OK))
+        {
+            if ((exception_full_log.mcu.ex_log.header.ex_nvram != KAL_TRUE) && (exception_full_log.mcu.ex_log.header.ex_serial_num < prev_num))  /* Found! */
+            {
+                break;
+            }
+            else
+            {
+                prev_num = exception_full_log.mcu.ex_log.header.ex_serial_num;
+            }
+        }
+        else if(result == NVRAM_DRV_EMPTY_RECORD)
+        {
+            if ((exception_full_log.mcu.ex_log.header.ex_nvram != KAL_TRUE))  /* Found! */
+            {
+                break;
+            }
+        }
+        else    /* Error, read fail!? How come?.....Dunno what to do.. */
+        {
+            MD_TRC_FUNC_NVRAM_WRITE_EXCEPTION2(i, result);
+            NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s <====\r\n",__FUNCTION__);
+            return;
+        }
+    }
+
+    MD_TRC_FUNC_NVRAM_WRITE_EXCEPTION2(0, 255);
+    if (i >= NVRAM_EF_SYS_EXCEPTION_TOTAL + 1)
+    {
+        i = 1;
+    }
+
+    prev_num += 1;
+    if (prev_num == 0xFFFF)
+    {
+        prev_num = 1;   /* wrap around to 1 if it reaches 65535 */
+    }
+
+   /**
+    *
+    * Hence the first record is the free record. Increment the serial number
+    * of the last record and take it as the new serial number for free record.
+    */
+    exception_ptr = (EX_LOG_T*) ex_log;
+    exception_ptr->header.ex_nvram = KAL_TRUE;
+    exception_ptr->header.ex_serial_num = prev_num;
+    
+    exception_fulllog_ptr->mcu.ex_log.header.ex_nvram = KAL_TRUE;
+    exception_fulllog_ptr->mcu.ex_log.header.ex_serial_num = prev_num;
+
+    MD_TRC_FUNC_NVRAM_WRITE_EXCEPTION2(1, prev_num);
+    
+     MD_TRC_FUNC_NVRAM_WRITE_EXCEPTION2(ldi->LID, i);
+    
+     nvram_write_exception_data_item(ldi, i, (kal_uint8*) ex_data);
+    
+     MD_TRC_FUNC_NVRAM_WRITE_EXCEPTION2(1, __LINE__);
+     NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"%s <====\r\n",__FUNCTION__);
+     #else
+     NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s ====>\r\n",__FUNCTION__);
+     NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"%s <====\r\n",__FUNCTION__);
+     return;
+     #endif
+}   /* end of nvram_write_exception function */
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_get_lid_num
+ * DESCRIPTION
+ *  To get the maxium LID
+ * PARAMETERS
+ *  void
+ * RETURNS
+ *  nvram_ptr->ltable.total_LID
+  *****************************************************************************/
+nvram_lid_enum nvram_get_lid_num(void)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    return nvram_ptr->ltable.total_LID;
+
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_check_backup
+ * DESCRIPTION
+ *  To tell given LID needs to backup or not
+ * PARAMETERS
+ *  LID         [IN]    LID of the file
+ *  prefix      [IN]    file prefix
+ * RETURNS
+ *  NVRAM_IO_ERRNO_OK: need to backup
+ *  NVRAM_IO_ERRNO_INVALID_LID: LID out of range or don't need to backup
+  *****************************************************************************/
+kal_uint8 nvram_check_backup(nvram_lid_enum LID, kal_char **prefix, kal_char **verno)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi = NULL;
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    if (!NVRAM_IS_LID_VALID(LID) || prefix == NULL)
+    {
+        return NVRAM_IO_ERRNO_INVALID_LID;
+    }
+
+    nvram_util_get_data_item(&ldi, LID);
+
+    if ((NVRAM_IS_CATEGORY_CALIBRAT(ldi->category) ||
+         NVRAM_IS_CATEGORY_IMPORTANT(ldi->category)||
+         NVRAM_IS_CATEGORY_IMPORTANT_L4(ldi->category)) &&
+        !NVRAM_IS_CATEGORY_OTP(ldi->category))
+    {
+    #ifdef __NVRAM_PSEUDO_MERGE__
+        if (NVRAM_IS_ATTR_PACKAGE(ldi->attr))
+        {
+            *prefix = "PACK";
+            *verno  = "LID";
+        }
+        else
+    #endif
+        {
+            *prefix = ldi->fileprefix;
+            *verno = ldi->fileverno;
+        }
+        return NVRAM_IO_ERRNO_OK;
+    }
+    else
+    {
+        *prefix = NULL;
+        *verno = NULL;
+        return NVRAM_IO_ERRNO_INVALID_LID;
+    }
+
+
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_validate_file
+ * DESCRIPTION
+ *  To validate integrity of  the given file
+ * PARAMETERS
+ *  LID         [IN]    LID of the file
+ *  path        [IN]    path to validate
+ * RETURNS
+ *  NVRAM_IO_ERRNO_OK: valid
+ *  NVRAM_IO_ERRNO_INVALID_LID: LID out of range
+ *  others: invalid
+  *****************************************************************************/
+nvram_errno_enum nvram_validate_file(nvram_lid_enum LID, kal_wchar *path)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi = NULL;
+    kal_uint8 *buffer = NULL;
+    kal_int32 result;
+    FS_HANDLE hFile = 0;
+    kal_uint32 nvram_chksum_size = 0;
+    nvram_drv_read_type_enum read_chksum_type = NVRAM_DRV_READ_TYPE_CHKSUM;
+    nvram_lid_chksum_info lid_chksum_info = {0};
+
+#ifdef __NVRAM_PSEUDO_MERGE__
+    kal_uint32 file_offset;
+#endif
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    if (!NVRAM_IS_LID_VALID(LID))
+    {
+        return NVRAM_IO_ERRNO_INVALID_LID;
+    }
+
+    nvram_util_get_data_item(&ldi, LID);
+
+
+#ifdef __NVRAM_PSEUDO_MERGE__
+    if (NVRAM_IS_ATTR_PACKAGE(ldi->attr))
+    {
+        file_offset = (kal_uint32) (ldi->description);
+    }
+    else
+    {
+        file_offset = (kal_uint32) 0;
+    }
+#endif
+
+    /* open NV_RCD.(RCD#) file */
+    NVRAM_FS_START_EX(FS_OP_OPEN,path);
+    hFile = FS_Open((const kal_wchar*)path, FS_READ_ONLY | FS_OPEN_NO_DIR | FS_OPEN_SHARED);
+    NVRAM_FS_END(FS_OP_OPEN,hFile);
+    if (FS_NO_ERROR > hFile)
+    {
+        return NVRAM_IO_ERRNO_INVALID_LID;
+    }
+
+#ifdef __NVRAM_PSEUDO_MERGE__
+    NVRAM_FS_START(FS_OP_SEEK);
+    result = FS_Seek(hFile, file_offset, FS_FILE_BEGIN);
+    NVRAM_FS_END(FS_OP_SEEK,result);
+    if (file_offset && FS_NO_ERROR > result)
+    {
+        NVRAM_FS_START(FS_OP_CLOSE);
+        result = FS_Close(hFile);
+        NVRAM_FS_END(FS_OP_CLOSE,result);
+        return NVRAM_IO_ERRNO_INVALID_LID;
+    }
+#endif
+
+    nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, KAL_FALSE, KAL_FALSE);
+    nvram_chksum_size = lid_chksum_info.algo_info.chksum_algo_length;
+    read_chksum_type = lid_chksum_info.read_chksum_type;
+
+
+    buffer = (kal_uint8 *)get_ctrl_buffer(nvram_chksum_size * ldi->total_records);
+
+    result = nvram_drv_fat_read_section(hFile, 1, ldi->total_records, ldi->size, buffer, read_chksum_type, ldi);
+
+    free_ctrl_buffer(buffer);
+
+    NVRAM_FS_START(FS_OP_CLOSE);
+    result = FS_Close(hFile);
+    NVRAM_FS_END(FS_OP_CLOSE,result);
+
+    if (result != NVRAM_DRV_OK)
+    {
+        return NVRAM_IO_ERRNO_INVALID_LID;
+    }
+
+    return NVRAM_IO_ERRNO_OK;
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_read_multi_record
+ * DESCRIPTION
+ *  This function is used to get data items for external modules.
+ * PARAMETERS
+ *  LID             [IN]
+ *  rec_index       [IN]
+ *  rec_amount    [IN]
+ *  buffer          [?]
+ *  buffer_size     [IN]
+ *  .(?)
+ * RETURNS
+ *  NVRAM_ERRNO_SUCCESS if succeed, NVRAM_ERRNO_INVALID otherwise (ie, invalid LID).
+ *****************************************************************************/
+kal_bool nvram_external_read_multi_record(nvram_lid_enum LID, kal_uint16 rec_index, kal_uint16 rec_amount, kal_uint8 *buffer, kal_uint32 buffer_size)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi = NULL;
+    nvram_errno_enum result = NVRAM_IO_ERRNO_OK;
+    kal_uint32 nvram_trace_index = 0;
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    
+    /*record nvram msg read access information to global struct*/
+    nvram_util_take_mutex(g_nvram_trace_mutex);
+    nvram_trace_index = nvram_access_trace.read_trace_index;
+    nvram_access_trace.read_trace_index = (nvram_access_trace.read_trace_index + 1) % MAX_TRACE_NUM;
+    nvram_util_give_mutex(g_nvram_trace_mutex);
+
+    kal_mem_set((void *)&(nvram_access_trace.read_trace[nvram_trace_index]), 0, sizeof(trace_info));
+    nvram_access_trace.read_trace[nvram_trace_index].access_way = NVRAM_ACCESS_BY_NORMAL_API;
+    nvram_access_trace.read_trace[nvram_trace_index].LID = LID;
+    nvram_access_trace.read_trace[nvram_trace_index].start_time = ust_get_current_time();
+
+    if (nvram_ptr->state != NVRAM_STATE_READY)
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_NOT_READY;        
+        kal_prompt_trace(MOD_NVRAM, "%s->LID 0x%x NVRAM_ERRNO_NOT_READY\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_ERRNO_NOT_READY\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+//    nvram_pre_init();
+
+    /**
+    * Invalid input paramters.
+    */
+    if (!NVRAM_IS_LID_VALID(LID))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_LID;
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+    nvram_util_get_data_item(&ldi, LID);
+    if(NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_WRONG_API_USE;
+        kal_prompt_trace(MOD_NVRAM,"%s->Raw LID 0x%x NVRAM_ERRNO_WRONG_API_USE\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Raw LID 0x%04X NVRAM_ERRNO_WRONG_API_USE\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+    
+    if(SST_NVRAM_Data_Access_Check(LID, 0, KAL_FALSE, NULL))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+#ifdef __NVRAM_READ_RESERVED_FILE__
+    if(ldi->LID == NVRAM_EF_READ_RESERVED_LID) {
+        nvram_ltable_entry_struct *ldi_r = (nvram_ltable_entry_struct*)ldi->default_value;
+        if(SST_NVRAM_Data_Access_Check(ldi_r->LID, 0, KAL_FALSE, NULL))
+        {
+            nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+            nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;            
+            kal_prompt_trace(MOD_NVRAM,"%s->Reserve LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,ldi_r->LID);
+            NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Reserve LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,ldi_r->LID);
+            return KAL_FALSE;
+        }    
+    }
+#endif
+
+#if defined(__NVRAM_CUSTOM_SENSITIVE__) || defined(__NVRAM_CUSTOM_DISK__)
+    /* In Meta mode, we cannot access the data belongs to custom sensitve area */
+    if (NVRAM_IS_CATEGORY_CUSTOM_SENSITIVE(ldi->category) || NVRAM_IS_CATEGORY_CUSTOM_DISK(ldi->category))
+    {
+    #ifdef __TC01__
+        if (FACTORY_BOOT == kal_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #else
+        if (FACTORY_BOOT == stack_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #endif
+        {
+            nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+            nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;            
+            kal_prompt_trace(MOD_NVRAM,"%s->Custom LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Custom LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            return KAL_FALSE;
+        }
+    }
+#endif
+
+    if ((rec_index < 1) ||(rec_index > ldi->total_records))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_RECORD;                
+        kal_prompt_trace(MOD_NVRAM,"[Error]%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_RECORD:rec_index(%d) total_records(%d)\r\n",__FUNCTION__,LID,rec_index,ldi->total_records);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_RECORD\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]rec_index(%d) total_records(%d)\r\n",rec_index,ldi->total_records);
+        return KAL_FALSE;
+    }
+
+    if (rec_index+rec_amount-1 > ldi->total_records)
+    {
+        rec_amount = ldi->total_records-rec_index+1;
+    }
+
+
+    /* handle by nvram_io layer */
+    result = nvram_read_data_item(ldi, rec_index, rec_amount, buffer, buffer_size);
+    nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+    nvram_access_trace.read_trace[nvram_trace_index].ret_value = result;
+
+    if (result != NVRAM_IO_ERRNO_OK)
+    {                
+        kal_prompt_trace(MOD_NVRAM,"%s->LID(0x%x) nvram_read_data_item return %d\r\n",__FUNCTION__,LID,result);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X nvram_read_data_item return %d\r\n",__FUNCTION__,LID,result);
+        return KAL_FALSE;
+    }
+    else
+    {
+        return KAL_TRUE;
+    }
+
+}
+
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_read_data
+ * DESCRIPTION
+ *  This function is used to get data items for external modules.
+ * PARAMETERS
+ *  LID             [IN]
+ *  rec_index       [IN]
+ *  buffer          [?]
+ *  buffer_size     [IN]
+ *  .(?)
+ * RETURNS
+ *  NVRAM_ERRNO_SUCCESS if succeed, NVRAM_ERRNO_INVALID otherwise (ie, invalid LID).
+ *****************************************************************************/
+kal_bool nvram_external_read_data(nvram_lid_enum LID, kal_uint16 rec_index, kal_uint8 *buffer, kal_uint32 buffer_size)
+{
+    return nvram_external_read_multi_record(LID, rec_index, 1, buffer, buffer_size);
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_read_raw_data
+ * DESCRIPTION
+ *  This function is used to get data items for external modules.
+ * PARAMETERS
+ *  LID             [IN]
+ *  offset          [IN]
+ *  buffer          [OUT]
+ *  buffer_size     [IN]
+ *  .(?)
+ * RETURNS
+ *  NVRAM_ERRNO_SUCCESS if succeed, NVRAM_ERRNO_INVALID otherwise (ie, invalid LID).
+ *****************************************************************************/
+kal_bool nvram_external_read_raw_data(nvram_lid_enum LID, kal_uint32 offset, kal_uint8 *buffer, kal_uint32 buffer_size)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi = NULL;
+    nvram_errno_enum result = NVRAM_IO_ERRNO_OK;
+    kal_uint32 nvram_trace_index  = 0;
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    
+    /*record nvram msg read access information to global struct*/
+    nvram_util_take_mutex(g_nvram_trace_mutex);
+    nvram_trace_index = nvram_access_trace.read_trace_index;
+    nvram_access_trace.read_trace_index = (nvram_access_trace.read_trace_index + 1) % MAX_TRACE_NUM;
+    nvram_util_give_mutex(g_nvram_trace_mutex);
+
+    kal_mem_set((void *)&(nvram_access_trace.read_trace[nvram_trace_index]), 0, sizeof(trace_info));
+    nvram_access_trace.read_trace[nvram_trace_index].access_way = NVRAM_ACCESS_BY_NORMAL_API;
+    nvram_access_trace.read_trace[nvram_trace_index].LID = LID;
+    nvram_access_trace.read_trace[nvram_trace_index].start_time = ust_get_current_time();
+    
+    if (nvram_ptr->state != NVRAM_STATE_READY) {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_NOT_READY;
+        
+        kal_prompt_trace(MOD_NVRAM, "%s->LID 0x%x NVRAM_ERRNO_NOT_READY\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_ERRNO_NOT_READY\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+    /**
+    * Invalid input paramters.
+    */
+    if(!nvram_util_get_data_item(&ldi, LID)) {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_LID;        
+        kal_prompt_trace(MOD_NVRAM, "%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_LID \r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_LID \r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+    if(!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_WRONG_API_USE;        
+        kal_prompt_trace(MOD_NVRAM,"%s->Raw LID 0x%x NVRAM_ERRNO_WRONG_API_USE\r\n\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Raw LID 0x%04X NVRAM_ERRNO_WRONG_API_USE\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+    if(SST_NVRAM_Data_Access_Check(LID, 0, KAL_FALSE, NULL))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+#if defined(__NVRAM_CUSTOM_SENSITIVE__) || defined(__NVRAM_CUSTOM_DISK__)
+    /* In Meta mode, we cannot access the data belongs to custom sensitve area */
+    if (NVRAM_IS_CATEGORY_CUSTOM_SENSITIVE(ldi->category) || NVRAM_IS_CATEGORY_CUSTOM_DISK(ldi->category))
+    {
+    #ifdef __TC01__
+        if (FACTORY_BOOT == kal_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #else
+        if (FACTORY_BOOT == stack_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #endif
+        {
+            nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+            nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;            
+            kal_prompt_trace(MOD_NVRAM,"%s->Custom LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Custom LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            return KAL_FALSE;
+        }
+    }
+#endif
+
+    /* handle by nvram_io layer */
+    result = nvram_read_data_item(ldi, offset, 1, buffer, buffer_size);
+    nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+    nvram_access_trace.read_trace[nvram_trace_index].ret_value = result;
+    if (result != NVRAM_IO_ERRNO_OK)
+    {        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x nvram_read_data_item return %d\r\n",__FUNCTION__,LID,result);        
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X nvram_read_data_item return %d\r\n",__FUNCTION__,LID,result);
+        return KAL_FALSE;
+    }
+    else
+    {
+        return KAL_TRUE;
+    }
+
+}
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_secure_read_data
+ * DESCRIPTION
+ *  This function is used to get data items for external modules with secure check.
+ * PARAMETERS
+ *  LID             [IN]
+ *  rec_index       [IN]
+ *  buffer          [?]
+ *  buffer_size     [IN]
+ *  .(?)
+ * RETURNS
+ *  NVRAM_ERRNO_SUCCESS if succeed, NVRAM_ERRNO_INVALID otherwise (ie, invalid LID).
+ *****************************************************************************/
+nvram_errno_enum nvram_external_secure_read_data(nvram_lid_enum LID, kal_uint16 rec_index, kal_uint8 *buffer, kal_uint32 buffer_size, void* reserved_ptr)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi = NULL;
+    nvram_errno_enum result = NVRAM_IO_ERRNO_OK;
+    kal_uint32 nvram_trace_index;
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    
+    /*record nvram msg read access information to global struct*/
+    nvram_util_take_mutex(g_nvram_trace_mutex);
+    nvram_trace_index = nvram_access_trace.read_trace_index;
+    nvram_access_trace.read_trace_index = (nvram_access_trace.read_trace_index + 1) % MAX_TRACE_NUM;
+    nvram_util_give_mutex(g_nvram_trace_mutex);
+
+    kal_mem_set((void *)&(nvram_access_trace.read_trace[nvram_trace_index]), 0, sizeof(trace_info));
+    nvram_access_trace.read_trace[nvram_trace_index].access_way = NVRAM_ACCESS_BY_SECURE_API;
+    nvram_access_trace.read_trace[nvram_trace_index].LID = LID;
+    nvram_access_trace.read_trace[nvram_trace_index].start_time = ust_get_current_time();
+
+    if (nvram_ptr->state != NVRAM_STATE_READY)
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_NOT_READY;        
+        kal_prompt_trace(MOD_NVRAM, "%s->LID 0x%x NVRAM_ERRNO_NOT_READY\r\n",__FUNCTION__);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_ERRNO_NOT_READY\r\n",__FUNCTION__,LID);
+        return NVRAM_ERRNO_NOT_READY;
+    }
+
+//    nvram_pre_init();
+
+    /**
+    * Invalid input paramters.
+    */
+    if (!NVRAM_IS_LID_VALID(LID))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_LID;                
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_LID \r\n",__FUNCTION__,LID);
+        return NVRAM_IO_ERRNO_INVALID_LID;
+    }
+
+    nvram_util_get_data_item(&ldi, LID);
+    if(NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_WRONG_API_USE;        
+        kal_prompt_trace(MOD_NVRAM,"%s->Raw LID 0x%x NVRAM_ERRNO_WRONG_API_USE\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Raw LID 0x%04X NVRAM_ERRNO_WRONG_API_USE\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+    if(SST_NVRAM_Data_Access_Check(LID, 0, KAL_TRUE, reserved_ptr))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,LID);
+        return NVRAM_IO_ERRNO_ACCESS_DENIED;
+    }
+#ifdef __NVRAM_READ_RESERVED_FILE__
+    if(ldi->LID == NVRAM_EF_READ_RESERVED_LID) {
+        nvram_ltable_entry_struct *ldi_r = (nvram_ltable_entry_struct*)ldi->default_value;
+        if(SST_NVRAM_Data_Access_Check(ldi_r->LID, 0, KAL_FALSE, NULL))
+        {
+            nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+            nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;                        
+            kal_prompt_trace(MOD_NVRAM,"%s->Reserve LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,LID);
+            NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Reserve LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,LID);
+            return KAL_FALSE;
+        }    
+    }
+#endif
+
+#if defined(__NVRAM_CUSTOM_SENSITIVE__) || defined(__NVRAM_CUSTOM_DISK__)
+    /* In Meta mode, we cannot access the data belongs to custom sensitve area */
+    if (NVRAM_IS_CATEGORY_CUSTOM_SENSITIVE(ldi->category) || NVRAM_IS_CATEGORY_CUSTOM_DISK(ldi->category))
+    {
+    #ifdef __TC01__
+        if (FACTORY_BOOT == kal_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #else
+        if (FACTORY_BOOT == stack_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #endif
+        {
+            nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+            nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;                        
+            kal_prompt_trace(MOD_NVRAM,"%s->Custom LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED for Meta mode\r\n",__FUNCTION__,ldi->LID);
+            NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Custom LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED for Meta mode\r\n",__FUNCTION__,ldi->LID);
+            return NVRAM_IO_ERRNO_ACCESS_DENIED;
+        }
+    }
+#endif
+
+    if ((rec_index < 1) ||(rec_index > ldi->total_records))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_RECORD;                
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_RECORD:rec_index(%d) total_records(%d)\r\n",__FUNCTION__,LID,rec_index,ldi->total_records);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_RECORD:\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]rec_index(%d) total_records(%d)\r\n",rec_index,ldi->total_records);
+        return NVRAM_IO_ERRNO_INVALID_RECORD;
+    }
+
+
+    /* handle by nvram_io layer */
+    result = nvram_read_data_item(ldi, rec_index, 1, buffer, buffer_size);
+    if (result != NVRAM_IO_ERRNO_OK)
+    {
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X nvram_read_data_item return %d\r\n",__FUNCTION__,LID,result);
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x nvram_read_data_item return %d\r\n",__FUNCTION__,LID,result);
+    }
+    nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+    nvram_access_trace.read_trace[nvram_trace_index].ret_value = result;
+    return result;
+}
+
+nvram_errno_enum nvram_external_get_lid_chksum_algo_info(nvram_lid_enum LID, nvram_lid_chksum_algo_info* lid_chksum_algo_info)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi = NULL;
+    nvram_errno_enum result = NVRAM_IO_ERRNO_OK;
+	kal_bool state = KAL_TRUE;
+    nvram_lid_chksum_info lid_chksum_info = {0};
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+
+    if(NULL == lid_chksum_algo_info)
+    {
+        return NVRAM_ERRNO_FAIL;
+    }
+
+    if (nvram_ptr->state != NVRAM_STATE_READY)
+    {     
+        kal_prompt_trace(MOD_NVRAM, "%s->LID 0x%x NVRAM_ERRNO_NOT_READY\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_ERRNO_NOT_READY\r\n",__FUNCTION__,LID);
+        return NVRAM_ERRNO_NOT_READY;
+    }
+
+    state = nvram_util_get_data_item(&ldi, LID);
+    if (!state)
+    {       
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        return NVRAM_ERRNO_INVALID;
+    }
+
+    result = nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, KAL_FALSE, KAL_FALSE);
+    if(result != NVRAM_IO_ERRNO_OK)
+    {
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_ERRNO_GET_CHKSUM_ALGO_INGO.\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_ERRNO_GET_CHKSUM_ALGO_INGO.\r\n",__FUNCTION__,LID);
+        return NVRAM_ERRNO_GET_CHKSUM_ALGO_INGO;
+    }
+
+    lid_chksum_algo_info->chksum_algo_length = lid_chksum_info.algo_info.chksum_algo_length;
+    lid_chksum_algo_info->chksum_algo_type = lid_chksum_info.algo_info.chksum_algo_type;
+
+    return NVRAM_IO_ERRNO_OK;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_read_chksum_value
+ * DESCRIPTION
+ *  This function is used to read the checksum of data item for external module.
+ *  Please must check with NVRAM owner before you use this API.
+ * PARAMETERS
+ *  LID:            [IN]    NVRAM LID
+ *  rec_index:      [IN]    record index
+ *  rec_amount:     [IN]    read how many record
+ *  buffer:         [OUT]   buffer pointer
+ *  buffer_size:    [IN]    buffer size
+ * RETURNS
+ *  a boolean value
+ * RETURN VALUES
+ *  KAL_FALSE:  fail
+ *  KAL_TRUE:   success
+ *****************************************************************************/
+nvram_errno_enum nvram_external_read_chksum_value(nvram_lid_enum LID, kal_uint16 rec_index, kal_uint16 rec_amount, kal_uint8 *buffer, kal_uint32 buffer_size, nvram_lid_read_type_enum read_chksum_type)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi = NULL;
+    nvram_errno_enum result = NVRAM_IO_ERRNO_OK;
+	kal_bool state = KAL_TRUE;
+    kal_uint32 nvram_trace_index  = 0;
+    kal_bool chksum_only = KAL_FALSE;
+    nvram_lid_chksum_info lid_chksum_info = {0};
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    
+    /*record nvram msg read access information to global struct*/
+    nvram_util_take_mutex(g_nvram_trace_mutex);
+    nvram_trace_index = nvram_access_trace.read_trace_index;
+    nvram_access_trace.read_trace_index = (nvram_access_trace.read_trace_index + 1) % MAX_TRACE_NUM;
+    nvram_util_give_mutex(g_nvram_trace_mutex);
+
+    kal_mem_set((void *)&(nvram_access_trace.read_trace[nvram_trace_index]), 0, sizeof(trace_info));
+    nvram_access_trace.read_trace[nvram_trace_index].access_way = NVRAM_ACCESS_BY_NORMAL_API;
+    nvram_access_trace.read_trace[nvram_trace_index].LID = LID;
+    nvram_access_trace.read_trace[nvram_trace_index].start_time = ust_get_current_time();
+    
+    if (nvram_ptr->state != NVRAM_STATE_READY)
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_NOT_READY;        
+        kal_prompt_trace(MOD_NVRAM, "%s->LID 0x%x NVRAM_ERRNO_NOT_READY\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_ERRNO_NOT_READY\r\n",__FUNCTION__,LID);
+        return NVRAM_ERRNO_NOT_READY;
+    }
+
+//    nvram_pre_init();
+
+    /**
+    * Invalid input paramters.
+    */
+    state = nvram_util_get_data_item(&ldi, LID);
+    if (!state)
+    {       
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        return NVRAM_ERRNO_INVALID;
+    }
+
+    if(((read_chksum_type == NVRAM_READ_TYPE_CHKSUM) || (read_chksum_type == NVRAM_READ_TYPE_CHKSUM_ONLY)))
+    {
+        chksum_only = (read_chksum_type == NVRAM_READ_TYPE_CHKSUM_ONLY)? KAL_TRUE : KAL_FALSE;
+        result = nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, chksum_only, KAL_FALSE);
+    }else
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_CHKSUM_TYPE_PARM;        
+        kal_prompt_trace(MOD_NVRAM, "[Error][NVRAM_ERRNO_CHKSUM_TYPE_PARM]%s->LID 0x%x, chceksum_type(%d)\r\n",__FUNCTION__,LID, read_chksum_type);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error][NVRAM_ERRNO_CHKSUM_TYPE_PARM]%s->LID 0x%04X, chceksum_type(%d)\r\n",__FUNCTION__,LID, read_chksum_type);
+        return NVRAM_ERRNO_CHKSUM_TYPE_PARM;
+    }
+
+    if (result != NVRAM_IO_ERRNO_OK)
+    {                
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_ERRNO_GET_CHKSUM_ALGO_INGO return %d\r\n",__FUNCTION__,LID,result);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_ERRNO_GET_CHKSUM_ALGO_INGO return %d\r\n",__FUNCTION__,LID,result);
+        return NVRAM_ERRNO_GET_CHKSUM_ALGO_INGO;
+    }
+
+    if (buffer_size < (lid_chksum_info.algo_info.chksum_algo_length * rec_amount))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_SIZE;        
+        kal_prompt_trace(MOD_NVRAM, "[Error][NVRAM_IO_ERRNO_INVALID_SIZE]%s->LID 0x%x.\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error][NVRAM_IO_ERRNO_INVALID_SIZE]%s->chksum_algo_type 0x%04X.\r\n",__FUNCTION__, lid_chksum_info.algo_info.chksum_algo_type);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error][NVRAM_IO_ERRNO_INVALID_SIZE]buffer_size(%d) < (chksum_algo_length*rec_amount: %d)\r\n",buffer_size,(lid_chksum_info.algo_info.chksum_algo_length * rec_amount));
+         return NVRAM_IO_ERRNO_INVALID_SIZE;
+    }
+#if defined(__NVRAM_CUSTOM_SENSITIVE__) || defined(__NVRAM_CUSTOM_DISK__)
+    /* In Meta mode, we cannot access the data belongs to custom sensitve area */
+    if (NVRAM_IS_CATEGORY_CUSTOM_SENSITIVE(ldi->category) || NVRAM_IS_CATEGORY_CUSTOM_DISK(ldi->category))
+    {
+    #ifdef __TC01__
+        if (FACTORY_BOOT == kal_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #else
+        if (FACTORY_BOOT == stack_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #endif
+        {
+            nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+            nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;            
+            kal_prompt_trace(MOD_NVRAM,"%s->Custom LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Custom LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            return NVRAM_IO_ERRNO_ACCESS_DENIED;
+        }
+    }
+#endif
+
+    if ((rec_index < 1) ||(rec_index > ldi->total_records))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_RECORD;        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_RECORD:rec_index(%d) total_records(%d)\r\n",__FUNCTION__,LID,rec_index,ldi->total_records);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_RECORD:\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]rec_index(%d) total_records(%d)\r\n",rec_index,ldi->total_records);
+        return NVRAM_IO_ERRNO_INVALID_RECORD;
+    }
+
+
+    /* handle by nvram_io layer */
+    result = nvram_read_data_item_chksum(ldi, rec_index, rec_amount, buffer, buffer_size, lid_chksum_info.read_chksum_type);
+    nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+    nvram_access_trace.read_trace[nvram_trace_index].ret_value = result;
+    
+    if (result != NVRAM_IO_ERRNO_OK)
+    {                
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x nvram_read_data_item_chksum return %d\r\n",__FUNCTION__,LID,result);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X nvram_read_data_item_chksum return %d\r\n",__FUNCTION__,LID,result);
+        return result;
+    }
+
+    return NVRAM_IO_ERRNO_OK;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_read_chksum
+ * DESCRIPTION
+ *  This function is used to read the checksum of data item for external module.
+ *  Please must check with NVRAM owner before you use this API.
+ * PARAMETERS
+ *  LID:            [IN]    NVRAM LID
+ *  rec_index:      [IN]    record index
+ *  rec_amount:     [IN]    read how many record
+ *  buffer:         [OUT]   buffer pointer
+ *  buffer_size:    [IN]    buffer size
+ * RETURNS
+ *  a boolean value
+ * RETURN VALUES
+ *  KAL_FALSE:  fail
+ *  KAL_TRUE:   success
+ *****************************************************************************/
+kal_bool nvram_external_read_chksum(nvram_lid_enum LID, kal_uint16 rec_index, kal_uint16 rec_amount, kal_uint8 *buffer, kal_uint32 buffer_size)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi = NULL;
+    nvram_errno_enum result = NVRAM_IO_ERRNO_OK;
+    kal_uint32 nvram_trace_index  = 0;
+    kal_uint32 nvram_chksum_size = 0;
+    nvram_drv_read_type_enum read_chksum_type = NVRAM_DRV_READ_TYPE_CHKSUM_2B;
+    nvram_lid_chksum_info lid_chksum_info = {0};
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    
+    /*record nvram msg read access information to global struct*/
+    nvram_util_take_mutex(g_nvram_trace_mutex);
+    nvram_trace_index = nvram_access_trace.read_trace_index;
+    nvram_access_trace.read_trace_index = (nvram_access_trace.read_trace_index + 1) % MAX_TRACE_NUM;
+    nvram_util_give_mutex(g_nvram_trace_mutex);
+
+    kal_mem_set((void *)&(nvram_access_trace.read_trace[nvram_trace_index]), 0, sizeof(trace_info));
+    nvram_access_trace.read_trace[nvram_trace_index].access_way = NVRAM_ACCESS_BY_NORMAL_API;
+    nvram_access_trace.read_trace[nvram_trace_index].LID = LID;
+    nvram_access_trace.read_trace[nvram_trace_index].start_time = ust_get_current_time();
+    
+    if (nvram_ptr->state != NVRAM_STATE_READY)
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_NOT_READY;        
+        kal_prompt_trace(MOD_NVRAM, "%s->LID 0x%x NVRAM_ERRNO_NOT_READY\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_ERRNO_NOT_READY\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+//    nvram_pre_init();
+
+    /**
+    * Invalid input paramters.
+    */
+    if (!NVRAM_IS_LID_VALID(LID))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_LID;        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+    nvram_util_get_data_item(&ldi, LID);
+    nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, KAL_FALSE, KAL_TRUE);
+    nvram_chksum_size = lid_chksum_info.algo_info.chksum_algo_length;
+    read_chksum_type = lid_chksum_info.read_chksum_type;
+
+    if (buffer_size < (nvram_chksum_size * rec_amount))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_SIZE;        
+        kal_prompt_trace(MOD_NVRAM, "[Error]%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_SIZE\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_SIZE\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]buffer_size(%d) < (nvram_chksum_size * rec_amount: %d)\r\n",buffer_size,(nvram_chksum_size * rec_amount));
+        return KAL_FALSE;
+    }
+
+#if defined(__NVRAM_CUSTOM_SENSITIVE__) || defined(__NVRAM_CUSTOM_DISK__)
+    /* In Meta mode, we cannot access the data belongs to custom sensitve area */
+    if (NVRAM_IS_CATEGORY_CUSTOM_SENSITIVE(ldi->category) || NVRAM_IS_CATEGORY_CUSTOM_DISK(ldi->category))
+    {
+    #ifdef __TC01__
+        if (FACTORY_BOOT == kal_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #else
+        if (FACTORY_BOOT == stack_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #endif
+        {
+            nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+            nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;            
+            kal_prompt_trace(MOD_NVRAM,"%s->Custom LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Custom LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            return KAL_FALSE;
+        }
+    }
+#endif
+
+    if ((rec_index < 1) ||(rec_index > ldi->total_records))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_RECORD;        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_RECORD:rec_index(%d) total_records(%d)\r\n",__FUNCTION__,LID,rec_index,ldi->total_records);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_RECORD:\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]rec_index(%d) total_records(%d)\r\n",rec_index,ldi->total_records);
+        return KAL_FALSE;
+    }
+
+
+    /* handle by nvram_io layer */
+    result = nvram_read_data_item_chksum(ldi, rec_index, rec_amount, buffer, buffer_size, read_chksum_type);
+    nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+    nvram_access_trace.read_trace[nvram_trace_index].ret_value = result;
+    
+    if (result != NVRAM_IO_ERRNO_OK)
+    {                
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x nvram_read_data_item_chksum return %d\r\n",__FUNCTION__,LID,result);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X nvram_read_data_item_chksum return %d\r\n",__FUNCTION__,LID,result);
+        return KAL_FALSE;
+    }
+    else
+    {
+        return KAL_TRUE;
+    }
+
+}
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_read_chksum_only
+ * DESCRIPTION
+ *  This function is used to read the checksum of data item for external module.
+ *  Please must check with NVRAM owner before you use this API.
+ * PARAMETERS
+ *  LID:            [IN]    NVRAM LID
+ *  rec_index:      [IN]    record index
+ *  rec_amount:     [IN]    read how many record
+ *  buffer:         [OUT]   buffer pointer
+ *  buffer_size:    [IN]    buffer size
+ * RETURNS
+ *  a boolean value
+ * RETURN VALUES
+ *  KAL_FALSE:  fail
+ *  KAL_TRUE:   success
+ *****************************************************************************/
+kal_bool nvram_external_read_chksum_only(nvram_lid_enum LID, kal_uint16 rec_index, kal_uint16 rec_amount, kal_uint8 *buffer, kal_uint32 buffer_size)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi = NULL;
+    nvram_errno_enum result = NVRAM_IO_ERRNO_OK;
+    kal_uint32 nvram_trace_index;
+    kal_uint32 nvram_chksum_size = 0;
+    nvram_drv_read_type_enum read_chksum_type = NVRAM_DRV_READ_TYPE_CHKSUM_ONLY_2B;
+    nvram_lid_chksum_info lid_chksum_info = {0};
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    
+    /*record nvram msg read access information to global struct*/
+    nvram_util_take_mutex(g_nvram_trace_mutex);
+    nvram_trace_index = nvram_access_trace.read_trace_index;
+    nvram_access_trace.read_trace_index = (nvram_access_trace.read_trace_index + 1) % MAX_TRACE_NUM;
+    nvram_util_give_mutex(g_nvram_trace_mutex);
+
+    kal_mem_set((void *)&(nvram_access_trace.read_trace[nvram_trace_index]), 0, sizeof(trace_info));
+    nvram_access_trace.read_trace[nvram_trace_index].access_way = NVRAM_ACCESS_BY_NORMAL_API;
+    nvram_access_trace.read_trace[nvram_trace_index].LID = LID;
+    nvram_access_trace.read_trace[nvram_trace_index].start_time = ust_get_current_time();
+    
+    if (nvram_ptr->state != NVRAM_STATE_READY)
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_NOT_READY;        
+        kal_prompt_trace(MOD_NVRAM, "%s->LID 0x%x NVRAM_ERRNO_NOT_READY \r\n",__FUNCTION__);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_ERRNO_NOT_READY \r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+//    nvram_pre_init();
+
+    /**
+    * Invalid input paramters.
+    */
+
+    
+    if (!NVRAM_IS_LID_VALID(LID))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_LID;        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+    nvram_util_get_data_item(&ldi, LID);
+    nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, KAL_TRUE, KAL_TRUE);
+    nvram_chksum_size = lid_chksum_info.algo_info.chksum_algo_length;
+    read_chksum_type = lid_chksum_info.read_chksum_type;
+    
+    if (buffer_size < (nvram_chksum_size * rec_amount))
+    {        
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_SIZE;        
+        kal_prompt_trace(MOD_NVRAM, "%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_SIZE buffer_size(%d) < (nvram_chksum_size * rec_amount: %d)\r\n",__FUNCTION__,LID,buffer_size,(nvram_chksum_size * rec_amount));
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_SIZE:\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]buffer_size(%d) < (nvram_chksum_size * rec_amount: %d)\r\n",buffer_size,(nvram_chksum_size * rec_amount));
+        return KAL_FALSE;
+    }
+
+#if defined(__NVRAM_CUSTOM_SENSITIVE__) || defined(__NVRAM_CUSTOM_DISK__)
+    /* In Meta mode, we cannot access the data belongs to custom sensitve area */
+    if (NVRAM_IS_CATEGORY_CUSTOM_SENSITIVE(ldi->category) || NVRAM_IS_CATEGORY_CUSTOM_DISK(ldi->category))
+    {
+    #ifdef __TC01__
+        if (FACTORY_BOOT == kal_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #else
+        if (FACTORY_BOOT == stack_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #endif
+        {        
+            nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+            nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;            
+            kal_prompt_trace(MOD_NVRAM,"%s->Custom LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,LID);
+            NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Custom LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,LID);
+            return KAL_FALSE;
+        }
+    }
+#endif
+
+    if ((rec_index < 1) ||(rec_index > ldi->total_records))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_RECORD;        
+        kal_prompt_trace(MOD_NVRAM,"[Error]%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_RECORD:rec_index(%d) total_records(%d)\r\n",__FUNCTION__,LID,rec_index,ldi->total_records);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_RECORD:\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]rec_index(%d) total_records(%d)\r\n",rec_index,ldi->total_records);
+        return KAL_FALSE;
+    }
+
+
+    /* handle by nvram_io layer */
+    result = nvram_read_data_item_chksum(ldi, rec_index, rec_amount, buffer, buffer_size, read_chksum_type);
+    nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+    nvram_access_trace.read_trace[nvram_trace_index].ret_value = result;
+    if (result != NVRAM_IO_ERRNO_OK)
+    {                
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x nvram_read_data_item_chksum return %d\r\n",__FUNCTION__,LID,result);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X nvram_read_data_item_chksum return %d\r\n",__FUNCTION__,LID,result);
+        return KAL_FALSE;
+    }
+    else
+    {
+        return KAL_TRUE;
+    }
+
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_read_chksum_8b
+ * DESCRIPTION
+ *  This function is used to read the checksum of data item for external module.
+ *  Please must check with NVRAM owner before you use this API.
+ * PARAMETERS
+ *  LID:            [IN]    NVRAM LID
+ *  rec_index:      [IN]    record index
+ *  rec_amount:     [IN]    read how many record
+ *  buffer:         [OUT]   md5 buffer pointer
+ *  buffer_size:    [IN]    md5 buffer size: must be 8-bytes length.
+ * RETURNS
+ *  a boolean value
+ * RETURN VALUES
+ *  KAL_FALSE:  fail
+ *  KAL_TRUE:   success
+ *****************************************************************************/
+kal_bool nvram_external_read_chksum_8b(nvram_lid_enum LID, kal_uint16 rec_index, kal_uint16 rec_amount, kal_uint8 *buffer, kal_uint32 buffer_size)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi = NULL;
+    nvram_errno_enum result = NVRAM_IO_ERRNO_OK;
+    kal_uint32 nvram_trace_index;
+    kal_uint32 nvram_chksum_size = 0;
+    nvram_drv_read_type_enum read_chksum_type = NVRAM_DRV_READ_TYPE_CHKSUM;
+    nvram_lid_chksum_info lid_chksum_info = {0};
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    
+    /*record nvram msg read access information to global struct*/
+    nvram_util_take_mutex(g_nvram_trace_mutex);
+    nvram_trace_index = nvram_access_trace.read_trace_index;
+    nvram_access_trace.read_trace_index = (nvram_access_trace.read_trace_index + 1) % MAX_TRACE_NUM;
+    nvram_util_give_mutex(g_nvram_trace_mutex);
+
+    kal_mem_set((void *)&(nvram_access_trace.read_trace[nvram_trace_index]), 0, sizeof(trace_info));
+    nvram_access_trace.read_trace[nvram_trace_index].access_way = NVRAM_ACCESS_BY_NORMAL_API;
+    nvram_access_trace.read_trace[nvram_trace_index].LID = LID;
+    nvram_access_trace.read_trace[nvram_trace_index].start_time = ust_get_current_time();
+    
+    if (nvram_ptr->state != NVRAM_STATE_READY)
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_NOT_READY;        
+        kal_prompt_trace(MOD_NVRAM, "%s->LID 0x%x NVRAM_ERRNO_NOT_READY \r\n",__FUNCTION__);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_ERRNO_NOT_READY \r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+//    nvram_pre_init();
+
+    /**
+    * Invalid input paramters.
+    */
+    if (!NVRAM_IS_LID_VALID(LID))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_LID;        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+    nvram_util_get_data_item(&ldi, LID);
+    nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, KAL_FALSE, KAL_FALSE);
+    nvram_chksum_size = lid_chksum_info.algo_info.chksum_algo_length;
+    read_chksum_type = lid_chksum_info.read_chksum_type;
+
+    if (buffer_size < (nvram_chksum_size * rec_amount))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_SIZE;        
+        kal_prompt_trace(MOD_NVRAM, "%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_SIZE: buffer_size(%d) < (nvram_chksum_size * rec_amount: %d)\r\n",__FUNCTION__,LID,buffer_size,(nvram_chksum_size * rec_amount));
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_SIZE:\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]buffer_size(%d) < (nvram_chksum_size * rec_amount: %d)\r\n",buffer_size,(nvram_chksum_size * rec_amount));
+        return KAL_FALSE;
+    }
+
+#if defined(__NVRAM_CUSTOM_SENSITIVE__) || defined(__NVRAM_CUSTOM_DISK__)
+    /* In Meta mode, we cannot access the data belongs to custom sensitve area */
+    if (NVRAM_IS_CATEGORY_CUSTOM_SENSITIVE(ldi->category) || NVRAM_IS_CATEGORY_CUSTOM_DISK(ldi->category))
+    {
+    #ifdef __TC01__
+        if (FACTORY_BOOT == kal_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #else
+        if (FACTORY_BOOT == stack_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #endif
+        {
+            nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+            nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;            
+            kal_prompt_trace(MOD_NVRAM,"%s->Custom LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Custom LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            return KAL_FALSE;
+        }
+    }
+#endif
+
+    if ((rec_index < 1) ||(rec_index > ldi->total_records))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_RECORD;        
+        kal_prompt_trace(MOD_NVRAM,"[Error]%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_RECORD:rec_index(%d) total_records(%d)\r\n",__FUNCTION__,LID,rec_index,ldi->total_records);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_RECORD:\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]rec_index(%d) total_records(%d)\r\n",rec_index,ldi->total_records);
+        return KAL_FALSE;
+    }
+
+
+    /* handle by nvram_io layer */
+    result = nvram_read_data_item_chksum_8b(ldi, rec_index, rec_amount, (kal_uint8*)buffer, buffer_size, read_chksum_type);
+    nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+    nvram_access_trace.read_trace[nvram_trace_index].ret_value = result;
+    if (result != NVRAM_IO_ERRNO_OK)
+    {        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x nvram_read_data_item_chksum_8b return %d\r\n",__FUNCTION__,LID,result);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X nvram_read_data_item_chksum_8b return %d\r\n",__FUNCTION__,LID,result);
+        return KAL_FALSE;
+    }
+    else
+    {
+        return KAL_TRUE;
+    }
+
+}
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_read_chksum_only_8b
+ * DESCRIPTION
+ *  This function is used to read the checksum of data item for external module.
+ *  Please must check with NVRAM owner before you use this API.
+ * PARAMETERS
+ *  LID:            [IN]    NVRAM LID
+ *  rec_index:      [IN]    record index
+ *  rec_amount:     [IN]    read how many record
+ *  buffer:         [OUT]   md5 buffer pointer
+ *  buffer_size:    [IN]    md5 buffer size: must be 8-bytes length.
+ * RETURNS
+ *  a boolean value
+ * RETURN VALUES
+ *  KAL_FALSE:  fail
+ *  KAL_TRUE:   success
+ *****************************************************************************/
+kal_bool nvram_external_read_chksum_only_8b(nvram_lid_enum LID, kal_uint16 rec_index, kal_uint16 rec_amount, kal_uint8 *buffer, kal_uint32 buffer_size)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi = NULL;
+    nvram_errno_enum result = NVRAM_IO_ERRNO_OK;
+    kal_uint32 nvram_trace_index  = 0;
+    kal_uint32 nvram_chksum_size = 0;
+    nvram_drv_read_type_enum read_chksum_type = NVRAM_DRV_READ_TYPE_CHKSUM_ONLY;
+    nvram_lid_chksum_info lid_chksum_info = {0};
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    
+    /*record nvram msg read access information to global struct*/
+    nvram_util_take_mutex(g_nvram_trace_mutex);
+    nvram_trace_index = nvram_access_trace.read_trace_index;
+    nvram_access_trace.read_trace_index = (nvram_access_trace.read_trace_index + 1) % MAX_TRACE_NUM;
+    nvram_util_give_mutex(g_nvram_trace_mutex);
+
+    kal_mem_set((void *)&(nvram_access_trace.read_trace[nvram_trace_index]), 0, sizeof(trace_info));
+    nvram_access_trace.read_trace[nvram_trace_index].access_way = NVRAM_ACCESS_BY_NORMAL_API;
+    nvram_access_trace.read_trace[nvram_trace_index].LID = LID;
+    nvram_access_trace.read_trace[nvram_trace_index].start_time = ust_get_current_time();    
+
+    if (nvram_ptr->state != NVRAM_STATE_READY)
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_NOT_READY;        
+        kal_prompt_trace(MOD_NVRAM, "%s->LID 0x%x NVRAM_ERRNO_NOT_READY \r\n",__FUNCTION__);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_ERRNO_NOT_READY \r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+//    nvram_pre_init();
+
+    /**
+    * Invalid input paramters.
+    */
+    if (!NVRAM_IS_LID_VALID(LID))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_LID;        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+    nvram_util_get_data_item(&ldi, LID);
+    nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, KAL_TRUE, KAL_FALSE);
+    nvram_chksum_size = lid_chksum_info.algo_info.chksum_algo_length;
+    read_chksum_type = lid_chksum_info.read_chksum_type;
+
+    if (buffer_size < (nvram_chksum_size * rec_amount))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_SIZE;        
+        kal_prompt_trace(MOD_NVRAM, "%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_SIZE: buffer_size(%d) < (nvram_chksum_size * rec_amount: %d)\r\n",__FUNCTION__,LID,buffer_size,(nvram_chksum_size * rec_amount));
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_SIZE:\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]buffer_size(%d) < (nvram_chksum_size * rec_amount: %d)\r\n",buffer_size,(nvram_chksum_size * rec_amount));
+        return KAL_FALSE;
+    }
+
+#if defined(__NVRAM_CUSTOM_SENSITIVE__) || defined(__NVRAM_CUSTOM_DISK__)
+    /* In Meta mode, we cannot access the data belongs to custom sensitve area */
+    if (NVRAM_IS_CATEGORY_CUSTOM_SENSITIVE(ldi->category) || NVRAM_IS_CATEGORY_CUSTOM_DISK(ldi->category))
+    {
+    #ifdef __TC01__
+        if (FACTORY_BOOT == kal_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #else
+        if (FACTORY_BOOT == stack_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #endif
+        {
+            nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+            nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;            
+            kal_prompt_trace(MOD_NVRAM,"%s->Custom LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Custom LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            return KAL_FALSE;
+        }
+    }
+#endif
+
+    if ((rec_index < 1) ||(rec_index > ldi->total_records))
+    {
+        nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.read_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_RECORD;        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_RECORD:rec_index(%d) total_records(%d)\r\n",__FUNCTION__,LID,rec_index,ldi->total_records);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_RECORD:\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]rec_index(%d) total_records(%d)\r\n",rec_index,ldi->total_records);
+        return KAL_FALSE;
+    }
+
+
+    /* handle by nvram_io layer */
+    result = nvram_read_data_item_chksum_8b(ldi, rec_index, rec_amount, (kal_uint8*)buffer, buffer_size, read_chksum_type);
+    nvram_access_trace.read_trace[nvram_trace_index].end_time = ust_get_current_time();
+    nvram_access_trace.read_trace[nvram_trace_index].ret_value = result;
+    if (result != NVRAM_IO_ERRNO_OK)
+    {        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x nvram_read_data_item_chksum_8b return %d\r\n",__FUNCTION__,LID,result);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X nvram_read_data_item_chksum_8b return %d\r\n",__FUNCTION__,LID,result);
+        return KAL_FALSE;
+    }
+    else
+    {
+        return KAL_TRUE;
+    }
+
+}
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_write_data
+ * DESCRIPTION
+ *  This function is used to write data items for external modules.
+ * PARAMETERS
+ *  LID:            [IN]    NVRAM LID
+ *  rec_index:      [IN]    record index
+ *  buffer:         [IN]    buffer pointer
+ *  buffer_size:    [IN]    buffer size
+ * RETURNS
+ *  a boolean value
+ * RETURN VALUES
+ *  KAL_FALSE:  fail
+ *  KAL_TRUE:   success
+ *****************************************************************************/
+kal_bool nvram_external_write_data(nvram_lid_enum LID, kal_uint16 rec_index, kal_uint8 *buffer, kal_uint32 buffer_size)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi = NULL;
+    nvram_errno_enum result = NVRAM_IO_ERRNO_OK;
+    kal_uint32 nvram_trace_index  = 0;
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    
+    /*record nvram msg read access information to global struct*/
+    nvram_util_take_mutex(g_nvram_trace_mutex);
+    nvram_trace_index = nvram_access_trace.write_trace_index;
+    nvram_access_trace.write_trace_index = (nvram_access_trace.write_trace_index + 1) % MAX_TRACE_NUM;
+    nvram_util_give_mutex(g_nvram_trace_mutex);
+
+    kal_mem_set((void *)&(nvram_access_trace.write_trace[nvram_trace_index]), 0, sizeof(trace_info));
+    nvram_access_trace.write_trace[nvram_trace_index].access_way = NVRAM_ACCESS_BY_NORMAL_API;
+    nvram_access_trace.write_trace[nvram_trace_index].LID = LID;
+    nvram_access_trace.write_trace[nvram_trace_index].start_time = ust_get_current_time();
+
+    if (nvram_ptr->state != NVRAM_STATE_READY)
+    {
+        nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_NOT_READY;        
+        kal_prompt_trace(MOD_NVRAM, "%s->LID 0x%x NVRAM_ERRNO_NOT_READY\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_ERRNO_NOT_READY\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+//    nvram_pre_init();
+
+    if (!NVRAM_IS_LID_VALID(LID))
+    {
+        nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_LID;        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+    nvram_util_get_data_item(&ldi, LID);
+    if(NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) {
+        nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_WRONG_API_USE;        
+        kal_prompt_trace(MOD_NVRAM,"%s->Raw LID 0x%x NVRAM_ERRNO_WRONG_API_USE\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Raw LID 0x%04X NVRAM_ERRNO_WRONG_API_USE\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+    if(SST_NVRAM_Data_Access_Check(LID, 1, KAL_FALSE, NULL))
+    {
+        nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+#if defined(__NVRAM_CUSTOM_SENSITIVE__) || defined(__NVRAM_CUSTOM_DISK__)
+    /* In Meta mode, we cannot access the data belongs to custom sensitve area */
+    if (NVRAM_IS_CATEGORY_CUSTOM_SENSITIVE(ldi->category) || NVRAM_IS_CATEGORY_CUSTOM_DISK(ldi->category))
+    {
+    #ifdef __TC01__
+        if (FACTORY_BOOT == kal_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #else
+        if (FACTORY_BOOT == stack_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #endif
+        {
+            nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+            nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;            
+            kal_prompt_trace(MOD_NVRAM,"%s->Custom LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Custom LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            return KAL_FALSE;
+        }
+    }
+#endif
+
+    if ((rec_index < 1) ||
+        (rec_index > ldi->total_records))
+    {
+        nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_RECORD;        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_RECORD:rec_index(%d) total_records(%d)\r\n",__FUNCTION__,LID,rec_index,ldi->total_records);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_RECORD:\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]rec_index(%d) total_records(%d)\r\n",rec_index,ldi->total_records);
+        return KAL_FALSE;
+    }
+
+    if (buffer_size < ldi->size)
+    {
+        nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_SIZE;        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_SIZE:buffer size(%d)< record_size(%d)\r\n",__FUNCTION__,LID,buffer_size,ldi->size);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_SIZE:\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]buffer size(%d)< record_size(%d)\r\n",buffer_size,ldi->size);
+        return KAL_FALSE;
+    }
+
+    result = nvram_write_data_item(ldi, rec_index, buffer, KAL_FALSE);
+    nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+    nvram_access_trace.write_trace[nvram_trace_index].ret_value = result;
+
+    if (result != NVRAM_IO_ERRNO_OK)
+    {        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x nvram_write_data_item return %d\r\n",__FUNCTION__,LID,result);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X nvram_write_data_item return %d\r\n",__FUNCTION__,LID,result);
+        return KAL_FALSE;
+    }
+    else
+    {
+        return KAL_TRUE;
+    }
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_write_raw_data
+ * DESCRIPTION
+ *  This function is used to write data items for external modules.
+ * PARAMETERS
+ *  LID:            [IN]    NVRAM LID
+ *  offset:         [IN]    file offset
+ *  buffer:         [IN]    buffer pointer
+ *  buffer_size:    [IN]    buffer size
+ * RETURNS
+ *  a boolean value
+ * RETURN VALUES
+ *  KAL_FALSE:  fail
+ *  KAL_TRUE:   success
+ *****************************************************************************/
+kal_bool nvram_external_write_raw_data(nvram_lid_enum LID, kal_uint32 offset, kal_uint8 *buffer, kal_uint32 buffer_size)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi = NULL;
+    nvram_errno_enum result = NVRAM_IO_ERRNO_OK;
+    kal_uint32 nvram_trace_index  = 0;
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    
+    /*record nvram msg read access information to global struct*/
+    nvram_util_take_mutex(g_nvram_trace_mutex);
+    nvram_trace_index = nvram_access_trace.write_trace_index;
+    nvram_access_trace.write_trace_index = (nvram_access_trace.write_trace_index + 1) % MAX_TRACE_NUM;
+    nvram_util_give_mutex(g_nvram_trace_mutex);
+
+    kal_mem_set((void *)&(nvram_access_trace.write_trace[nvram_trace_index]), 0, sizeof(trace_info));
+    nvram_access_trace.write_trace[nvram_trace_index].access_way = NVRAM_ACCESS_BY_NORMAL_API;
+    nvram_access_trace.write_trace[nvram_trace_index].LID = LID;
+    nvram_access_trace.write_trace[nvram_trace_index].start_time = ust_get_current_time();
+    
+    if (nvram_ptr->state != NVRAM_STATE_READY)
+    {
+        nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_NOT_READY;        
+        kal_prompt_trace(MOD_NVRAM, "%s->LID 0x%x NVRAM_ERRNO_NOT_READY \r\n",__FUNCTION__);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_ERRNO_NOT_READY \r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+    /**
+    * Invalid input paramters.
+    */
+    if(!nvram_util_get_data_item(&ldi, LID)) {
+        nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_LID;        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+    if(!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) {
+        nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_WRONG_API_USE;        
+        kal_prompt_trace(MOD_NVRAM,"%s->Raw LID 0x%x NVRAM_ERRNO_WRONG_API_USE\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Raw LID 0x%04X NVRAM_ERRNO_WRONG_API_USE\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+    if(SST_NVRAM_Data_Access_Check(LID, 1, KAL_FALSE, NULL))
+    {
+        nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+#if defined(__NVRAM_CUSTOM_SENSITIVE__) || defined(__NVRAM_CUSTOM_DISK__)
+    /* In Meta mode, we cannot access the data belongs to custom sensitve area */
+    if (NVRAM_IS_CATEGORY_CUSTOM_SENSITIVE(ldi->category) || NVRAM_IS_CATEGORY_CUSTOM_DISK(ldi->category))
+    {
+    #ifdef __TC01__
+        if (FACTORY_BOOT == kal_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #else
+        if (FACTORY_BOOT == stack_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #endif
+        {
+            nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+            nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;            
+            kal_prompt_trace(MOD_NVRAM,"%s->Custom LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Custom LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            return KAL_FALSE;
+        }
+    }
+#endif
+
+    ldi->size = buffer_size;
+    result = nvram_write_data_item(ldi, offset, buffer, KAL_FALSE);
+    nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+    nvram_access_trace.write_trace[nvram_trace_index].ret_value = result;
+    if (result != NVRAM_IO_ERRNO_OK)
+    {        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x nvram_write_data_item return %d\r\n",__FUNCTION__,LID,result);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X nvram_write_data_item return %d\r\n",__FUNCTION__,LID,result);
+        return KAL_FALSE;
+    }
+    else
+    {
+        return KAL_TRUE;
+    }
+}
+
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_secure_write_data
+ * DESCRIPTION
+ *  This function is used to write data items for external modules with secure check.
+ * PARAMETERS
+ *  LID:            [IN]    NVRAM LID
+ *  rec_index:      [IN]    record index
+ *  buffer:         [IN]    buffer pointer
+ *  buffer_size:    [IN]    buffer size
+ * RETURNS
+ *  a boolean value
+ * RETURN VALUES
+ *  KAL_FALSE:  fail
+ *  KAL_TRUE:   success
+ *****************************************************************************/
+nvram_errno_enum nvram_external_secure_write_data(nvram_lid_enum LID, kal_uint16 rec_index, kal_uint8 *buffer, kal_uint32 buffer_size, void* reserved_ptr)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi = NULL;
+    nvram_errno_enum result = NVRAM_IO_ERRNO_OK;
+    kal_uint32 nvram_trace_index  = 0;
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    
+    /*record nvram msg read access information to global struct*/
+    nvram_util_take_mutex(g_nvram_trace_mutex);
+    nvram_trace_index = nvram_access_trace.write_trace_index;
+    nvram_access_trace.write_trace_index = (nvram_access_trace.write_trace_index + 1) % MAX_TRACE_NUM;
+    nvram_util_give_mutex(g_nvram_trace_mutex);
+
+    kal_mem_set((void *)&(nvram_access_trace.write_trace[nvram_trace_index]), 0, sizeof(trace_info));
+    nvram_access_trace.write_trace[nvram_trace_index].access_way = NVRAM_ACCESS_BY_SECURE_API;
+    nvram_access_trace.write_trace[nvram_trace_index].LID = LID;
+    nvram_access_trace.write_trace[nvram_trace_index].start_time = ust_get_current_time();
+
+    if (nvram_ptr->state != NVRAM_STATE_READY)
+    {
+        nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_NOT_READY;
+        kal_prompt_trace(MOD_NVRAM, "%s->LID 0x%x NVRAM_ERRNO_NOT_READY\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_ERRNO_NOT_READY\r\n",__FUNCTION__,LID);
+        return NVRAM_ERRNO_NOT_READY;
+    }
+
+//    nvram_pre_init();
+
+    if (!NVRAM_IS_LID_VALID(LID))
+    {
+        nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_LID;        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        return NVRAM_IO_ERRNO_INVALID_LID;
+    }
+
+    nvram_util_get_data_item(&ldi, LID);
+    if(NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) {
+        nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_WRONG_API_USE;
+        kal_prompt_trace(MOD_NVRAM,"%s->Raw LID 0x%x NVRAM_ERRNO_WRONG_API_USE\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Raw LID 0x%04X NVRAM_ERRNO_WRONG_API_USE\r\n",__FUNCTION__,LID);
+        return KAL_FALSE;
+    }
+
+    if(SST_NVRAM_Data_Access_Check(LID, 1, KAL_TRUE, reserved_ptr))
+    {
+        nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED\r\n",__FUNCTION__,LID);
+        return NVRAM_IO_ERRNO_ACCESS_DENIED;
+    }
+
+#if defined(__NVRAM_CUSTOM_SENSITIVE__) || defined(__NVRAM_CUSTOM_DISK__)
+    /* In Meta mode, we cannot access the data belongs to custom sensitve area */
+    if (NVRAM_IS_CATEGORY_CUSTOM_SENSITIVE(ldi->category) || NVRAM_IS_CATEGORY_CUSTOM_DISK(ldi->category))
+    {
+    #ifdef __TC01__
+        if (FACTORY_BOOT == kal_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #else
+        if (FACTORY_BOOT == stack_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #endif
+        {
+            nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+            nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;
+            kal_prompt_trace(MOD_NVRAM,"%s->Custom LID 0x%x NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->Custom LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            return NVRAM_IO_ERRNO_ACCESS_DENIED;
+        }
+    }
+#endif
+
+    if ((rec_index < 1) ||
+        (rec_index > ldi->total_records))
+    {
+        nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_RECORD;
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_RECORD:rec_index(%d) total_records(%d)\r\n",__FUNCTION__,LID,rec_index,ldi->total_records);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_RECORD:\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]rec_index(%d) total_records(%d)\r\n",rec_index,ldi->total_records);
+        return NVRAM_IO_ERRNO_INVALID_RECORD;
+    }
+
+    if (buffer_size < ldi->size)
+    {
+        nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.write_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_SIZE;
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x NVRAM_IO_ERRNO_INVALID_SIZE:buffer size(%d)< record_size(%d)\r\n",__FUNCTION__,LID,buffer_size,ldi->size);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_SIZE:\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]buffer size(%d)< record_size(%d)\r\n",buffer_size,ldi->size);
+        return NVRAM_IO_ERRNO_INVALID_SIZE;
+    }
+
+    result = nvram_write_data_item(ldi, rec_index, buffer, KAL_FALSE);
+    nvram_access_trace.write_trace[nvram_trace_index].end_time = ust_get_current_time();
+    nvram_access_trace.write_trace[nvram_trace_index].ret_value = result;
+    if (result != NVRAM_IO_ERRNO_OK)
+    {        
+        kal_prompt_trace(MOD_NVRAM,"%s->LID 0x%x nvram_write_data_item return %d\r\n",__FUNCTION__,LID,result);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X nvram_write_data_item return %d\r\n",__FUNCTION__,LID,result);
+        return KAL_FALSE;
+    }
+    return result;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_reset_data
+ * DESCRIPTION
+ *  This function is used to reset data items for external modules.
+ * PARAMETERS
+ *  LID:            [IN]    NVRAM LID
+ *  rec_index:      [IN]    record index
+ *  buffer:         [IN]    buffer pointer
+ * RETURNS
+ *  a boolean value
+ * RETURN VALUES
+ *  KAL_FALSE:  fail
+ *  KAL_TRUE:   success
+ *****************************************************************************/
+kal_bool nvram_external_reset_data(nvram_lid_enum LID, kal_uint16 rec_index, kal_uint16 rec_amount)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi = NULL;
+    nvram_ltable_entry_struct tmp_ldi = {0};
+    kal_bool result = KAL_FALSE;
+    kal_uint32 nvram_trace_index  = 0;
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"%s ====>\r\n",__FUNCTION__);
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"LID:0x%04X rec_index=%d,rec_amount=%d\r\n",LID,rec_index,rec_amount);
+    /*record nvram msg read access information to global struct*/
+    nvram_util_take_mutex(g_nvram_trace_mutex);
+    nvram_trace_index = nvram_access_trace.reset_trace_index;
+    nvram_access_trace.reset_trace_index = (nvram_access_trace.reset_trace_index + 1) % MAX_TRACE_NUM;
+    nvram_util_give_mutex(g_nvram_trace_mutex);
+
+    kal_mem_set((void *)&(nvram_access_trace.reset_trace[nvram_trace_index]), 0, sizeof(trace_info));
+    nvram_access_trace.reset_trace[nvram_trace_index].access_way = NVRAM_ACCESS_BY_NORMAL_API;
+    nvram_access_trace.reset_trace[nvram_trace_index].LID = LID;
+    nvram_access_trace.reset_trace[nvram_trace_index].start_time = ust_get_current_time();
+    
+    if (nvram_ptr->state != NVRAM_STATE_READY)
+    {
+        nvram_access_trace.reset_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.reset_trace[nvram_trace_index].ret_value = NVRAM_ERRNO_NOT_READY;
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_ERRNO_NOT_READY\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s <====\r\n",__FUNCTION__);
+        return KAL_FALSE;
+    }
+
+//    nvram_pre_init();
+
+    if (!NVRAM_IS_LID_VALID(LID))
+    {
+        nvram_access_trace.reset_trace[nvram_trace_index].end_time = ust_get_current_time();
+        nvram_access_trace.reset_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_INVALID_LID;
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s <====\r\n",__FUNCTION__);
+        return KAL_FALSE;
+    }
+
+    nvram_util_get_data_item(&ldi, LID);
+
+    /* In Meta mode, we cannot access the data belongs to custom sensitve area
+       we also cannot reset the important data to prevent security problem */
+    if (NVRAM_IS_CATEGORY_IMPORTANT(ldi->category)
+        || NVRAM_IS_CATEGORY_IMPORTANT_L4(ldi->category)
+        #if defined(__NVRAM_CUSTOM_SENSITIVE__) || defined(__NVRAM_CUSTOM_DISK__)
+        || NVRAM_IS_CATEGORY_CUSTOM_SENSITIVE(ldi->category)
+        || NVRAM_IS_CATEGORY_CUSTOM_DISK(ldi->category)
+        #endif
+       )
+    {
+    #ifdef __TC01__
+        if (FACTORY_BOOT == kal_query_boot_mode() && stack_get_active_module_id() == MOD_FT)
+    #else
+        if (FACTORY_BOOT == kal_query_boot_mode() && kal_get_active_module_id() == MOD_FT)
+    #endif
+        {
+            nvram_access_trace.reset_trace[nvram_trace_index].end_time = ust_get_current_time();
+            nvram_access_trace.reset_trace[nvram_trace_index].ret_value = NVRAM_IO_ERRNO_ACCESS_DENIED;
+            NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_ACCESS_DENIED for Meta Mode\r\n",__FUNCTION__,LID);
+            NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s <====\r\n",__FUNCTION__);
+            return KAL_FALSE;
+        }
+    }
+
+    NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[collection]%s -> LID:0x%04X index=%d\r\n",__FUNCTION__, ldi->LID, ldi->size);
+    NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[collection]rec_amount=%d,rec_index=%d\r\n", rec_amount, rec_index);
+
+    result = nvram_reset_data_items(NVRAM_RESET_CERTAIN, NVRAM_APP_RESERVED, ldi, rec_index, rec_amount);
+    memcpy(&tmp_ldi,ldi,sizeof(nvram_ltable_entry_struct));
+    mcf_do_ota_by_lid(LID,rec_index, rec_amount,&tmp_ldi);
+    
+    NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"%s <====\r\n",__FUNCTION__);
+    nvram_access_trace.reset_trace[nvram_trace_index].end_time = ust_get_current_time();
+    nvram_access_trace.reset_trace[nvram_trace_index].ret_value = result;
+    
+    return result;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_get_default_value
+ * DESCRIPTION
+ *  This function is used to get default value for external modules.
+ * PARAMETERS
+ *  LID             [IN]
+ *  rec_index       [IN]
+ *  p_buffer        [IN/OUT]
+ *
+ * RETURNS
+ *  NVRAM_DEFAULT_VALUE_FAIL : get default value fail
+ *  NVRAM_DEFAULT_VALUE_FF   : p_buffer is invalid, default value is FF
+ *  NVRAM_DEFAULT_VALUE_ZERO : p_buffer is invalid, default value is zero
+ *  NVRAM_DEFAULT_VALUE_POINT: p_buffer is valid, use p_buffer to get default value
+ *****************************************************************************/
+nvram_default_value_enum nvram_get_default_value(nvram_lid_enum LID, kal_uint16 rec_index, kal_uint8 **p_buffer)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi = NULL;
+    nvram_default_value_enum result = NVRAM_DEFAULT_VALUE_SUCCESS;
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    
+    if (!NVRAM_IS_LID_VALID(LID))
+    {        
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_LID\r\n",__FUNCTION__,LID);
+        return NVRAM_DEFAULT_VALUE_FAIL;
+    }
+
+    nvram_util_get_data_item(&ldi, LID);
+
+    if ((rec_index < 1) || (rec_index > ldi->total_records))
+    {
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->LID 0x%04X NVRAM_IO_ERRNO_INVALID_RECORD:\r\n",__FUNCTION__,LID);
+        NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]rec_index(%d) total_records(%d)\r\n",rec_index,ldi->total_records);
+        return NVRAM_DEFAULT_VALUE_FAIL;
+    }
+
+
+    /* Multi default value */
+    if ((ldi->attr & NVRAM_ATTR_MULTI_DEFAULT))
+    {
+        rec_index--;
+    }
+    else
+    {
+        rec_index = 0;
+    }
+
+    if ((ldi->LID >= NVRAM_EF_L1_START && ldi->LID <= NVRAM_EF_L1_END)
+        || (ldi->LID >= NVRAM_EF_UL1_START && ldi->LID <= NVRAM_EF_UL1_END)
+    #if defined(__WIFI_SUPPORT__)&&(__CUSTOM_WIFI_FEATURES_SWITCH__)
+        || (ldi->LID >= NVRAM_EF_WNDRV_START && ldi->LID <= NVRAM_EF_WNDRV_END)
+    #endif
+#if !defined(MED_NOT_PRESENT)
+#ifdef __AMRWB_LINK_SUPPORT__
+        || (ldi->LID == NVRAM_EF_AUDIO_WB_SPEECH_INPUT_FIR_LID) || (ldi->LID == NVRAM_EF_AUDIO_WB_SPEECH_OUTPUT_FIR_LID) || (ldi->LID == NVRAM_EF_AUDIO_WB_SPEECH_MODE_PARAM_LID)
+#endif
+#ifdef __AUDIO_COMPENSATION_SW_VERSION__
+        || (ldi->LID == NVRAM_EF_AUDIO_SWFIR_LID)
+#endif
+#ifdef __BES_LOUDNESS_SUPPORT__
+        || (ldi->LID == NVRAM_EF_AUDIO_BESLOUDNESS_LID)
+#endif
+        || (ldi->LID == NVRAM_EF_AUDIO_DC_CALIBRATION_LID)
+
+        || (ldi->LID == NVRAM_EF_AUDIO_PARAM_LID)
+#endif
+        )
+    {
+        result = NVRAM_DEFAULT_VALUE_APPLICATION;
+    }
+#ifdef __NVRAM_COMPRESS_SUPPORT__
+    else if (NVRAM_IS_ATTR_ZIP_DEFAULT(ldi->attr))
+    {
+        result = NVRAM_DEFAULT_VALUE_FF;
+    }
+#endif
+    else
+    {
+        /* No default value supplied. Fill the buffer with 0xFF. */
+        if (ldi->default_value == NULL || ldi->default_value == (kal_uint8 const*)NVRAM_EF_FF_DEFAULT)
+        {
+            result = NVRAM_DEFAULT_VALUE_FF;
+        }     /* Default value is all the same value (0x00) Fill it as well. */
+        else if (ldi->default_value == (kal_uint8 const*)NVRAM_EF_ZERO_DEFAULT)
+        {
+            result = NVRAM_DEFAULT_VALUE_ZERO;
+        }
+        else
+        {
+            *p_buffer = (void*)(ldi->default_value + ldi->size * rec_index);
+            result = NVRAM_DEFAULT_VALUE_POINT;
+        }
+    }
+//#ifdef __NVRAM_PSEUDO_MERGE__
+    MD_TRC_FUNC_NVRAM_GET_DEFAULT_VALUE(ldi->LID, result, ldi->size, ldi->fileprefix);
+//#else
+//    nvram_trace(TRACE_FUNC, FUNC_NVRAM_GET_DEFAULT_VALUE, ldi->LID, result, ldi->size);
+//#endif
+    return result;
+}
+
+
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_shutdown_handler
+ * DESCRIPTION
+ *  Disable all interrupts, change NVRAM state, change FS command mode, and flush
+ * PARAMETERS
+ *  void
+ * RETURNS
+ *  void
+ *****************************************************************************/
+void nvram_shutdown_handler(void)
+{
+
+#ifdef __MMI_FMI__    
+#if !defined(__L1_STANDALONE__)
+
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    kal_uint32 i;
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    /* to handle shutdown callback */
+    for (i = 0; ;i++)
+    {
+        if (nvram_shutdown_cb_table[i].LID == 0 && nvram_shutdown_cb_table[i].get_data == NULL)
+        {
+            break;
+        }
+
+        if (NVRAM_IS_LID_VALID(nvram_shutdown_cb_table[i].LID) && nvram_shutdown_cb_table[i].get_data)
+        {
+            kal_uint8 *data;
+            nvram_ltable_entry_struct *ldi;
+
+            nvram_util_get_data_item(&ldi, nvram_shutdown_cb_table[i].LID);
+            data = (kal_uint8 *)get_ctrl_buffer(ldi->size);
+            if (nvram_shutdown_cb_table[i].get_data(data, ldi->size))
+            {
+                /* doesn't support linear-fix */
+                nvram_write_data_item(ldi, 1, data, KAL_FALSE);
+            }
+            free_ctrl_buffer(data);
+        }
+    }
+#endif /* !__L1_STANDALONE__ */
+#endif /* __MMI_FMI__ */
+}
+
+#ifdef __NVRAM_DISK_SIZE_CHECK__
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_space_reserve
+ * DESCRIPTION
+ *  To perform software upgrade.
+ * PARAMETERS
+ *  SpecialName         [?]
+ *  StillNeed           [?]
+ *  sysrecord(?)        [IN]        Sysrecord
+ * RETURNS
+ *  Success or Fail(?)
+ *****************************************************************************/
+void nvram_space_reserve(kal_uint32 *size_from_code)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    kal_uint32 CodeFileSize;
+    kal_uint32 clusterSize;
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    NVRAM_FS_START_EX(FS_OP_GETCLUSTERSIZE,'Z');
+    clusterSize = FS_GetClusterSize('Z');
+    NVRAM_FS_END(FS_OP_GETCLUSTERSIZE,clusterSize);
+
+    nvram_pre_init();
+
+    nvram_get_code_file_size(&CodeFileSize);
+
+    *size_from_code = (CodeFileSize / clusterSize) + ((CodeFileSize / clusterSize)? 1 : 0) + NVRAM_SPACE_MARGIN;
+}
+#endif
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_get_folder_name
+ * DESCRIPTION
+ *  To get NVRAM folder name.
+ * PARAMETERS
+ *  void
+ * RETURNS
+ *  NVRAM folder name.
+ *****************************************************************************/
+void nvram_get_folder_name(WCHAR *nvram_folder_name)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    kal_wstrcpy(nvram_folder_name, NVRAM_FS_FOLDER_NAME);
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_get_work_path
+ * DESCRIPTION
+ *  To get NVRAM working directory.
+ * PARAMETERS
+ *  folder_idx  : Which folder
+ * RETURNS
+ *  NVRAM working directory.
+ *****************************************************************************/
+kal_char *nvram_get_work_path(kal_uint8 folder_idx)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+
+    return nvram_query_work_path((nvram_folder_enum)folder_idx);
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_get_folder_idx
+ * DESCRIPTION
+ *  To get the index of nvram folder.
+ * PARAMETERS
+ *  LID  :
+ * RETURNS
+ *  index of folder.
+ *****************************************************************************/
+kal_uint8 nvram_get_folder_idx(nvram_lid_enum LID)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi;
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    if (!NVRAM_IS_LID_VALID(LID))
+    {
+        return NVRAM_IO_ERRNO_INVALID_LID;
+    }
+
+    nvram_util_get_data_item(&ldi, LID);
+
+    return nvram_query_folder_index(ldi->category);
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_get_file_fullname
+ * DESCRIPTION
+ *  To get the full name of nvram file.
+ * PARAMETERS
+ *  folder_idx : [In]
+ *  nvramname  : [In]
+ *  filename   : [Out]
+ * RETURNS
+ *  index of folder.
+ *****************************************************************************/
+kal_wchar * nvram_get_file_fullname(kal_uint8 folder_idx, kal_char *nvramname, kal_wchar *filename)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+
+    return nvram_query_file_name((nvram_folder_enum)folder_idx, nvramname, filename);
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_get_folder_total_amount
+ * DESCRIPTION
+ *  To get the full name of nvram file.
+ * PARAMETERS
+ *  void
+ * RETURNS
+ *  number of folders
+ *****************************************************************************/
+kal_uint8 nvram_get_folder_total_amount(void)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+
+    return NVRAM_FOLDER_TOTAL;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_check_hidden_files
+ * DESCRIPTION
+ *  Check if the files or folder is hidden or not in Meta FAT Editor.
+ *  1. Any LID with NVRAM_CATEGORY_IMPORTANT will not appear in meta FAT Editor. ex: IMEI and SML
+ *  2. Important Folder will not appear in meta FAT Editor.
+ *  3. Customer sensitive data.
+ *  Exception 1: During backup/restore, we can see IMEI and SML
+ *  Exception 2: When NVRAM is locked. All the files and folder are hidden.
+ *
+ * PARAMETERS
+ *  filename    [IN]    the filename
+ *  backup      [IN]    During backup/restore the hidden file is different from normal
+ *                      Please set this as true during backup/restore
+ * RETURNS
+ *  a boolean value
+ * RETURN VALUES
+ *  KAL_TRUE:   hidden
+ *  KAL_FALSE:  not hidden
+ *****************************************************************************/
+kal_bool nvram_check_hidden_file(const kal_wchar* filename, kal_bool backup)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    kal_wchar buf[NVRAM_MAX_PATH_LEN];
+    nvram_ltable_entry_struct *ldi;
+#ifdef __NVRAM_MULTI_FOLDERS__
+    nvram_folder_enum i;
+#endif
+    kal_wchar *starter;
+    kal_char *temp_strrchr = NULL;
+
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+
+    starter = kal_wstrchr(filename, '\\');
+
+    if (starter == NULL)
+    {
+        return KAL_FALSE;
+    }
+
+    if (kal_wstrncmp(starter + 1, NVRAM_FS_FOLDER_NAME, kal_wstrlen(NVRAM_FS_FOLDER_NAME)) !=0 )
+    {
+        /* Not belongs to NVRAM folder */
+        return KAL_FALSE;
+    }
+
+    if (nvram_test_lock() && backup == KAL_FALSE)
+    {
+        return KAL_TRUE;
+    }
+    
+    starter = kal_wstrrchr(filename, '\\') + 1;
+
+#ifdef __NVRAM_MULTI_FOLDERS__
+    for (i = NVRAM_FOLDER_BEGIN; i < NVRAM_FOLDER_TOTAL ; i++)
+    {
+        temp_strrchr = strrchr(nvram_query_work_path(i), '\\');
+        if(temp_strrchr == NULL)
+        {
+            continue;
+        }
+        kal_wsprintf(buf, "%s", temp_strrchr+1);
+        if (kal_wstrcmp(buf, starter) == 0)
+        {
+            if ((i == NVRAM_NVD_IMPT && backup == KAL_FALSE)
+                #ifdef __NVRAM_CUSTOM_SENSITIVE__
+                || i == NVRAM_NVD_CUST
+                #endif
+                )
+            {
+                return KAL_TRUE;
+            }
+            else
+            {
+                return KAL_FALSE;
+            }
+        }
+    }
+#endif
+
+    ldi = &logical_data_item_table[0];
+    do
+    {
+
+        if (( NVRAM_IS_CATEGORY_IMPORTANT(ldi->category) && backup == KAL_FALSE)
+            || (NVRAM_IS_CATEGORY_IMPORTANT_L4(ldi->category) && backup == KAL_FALSE)
+        #ifdef __NVRAM_CUSTOM_SENSITIVE__
+            || NVRAM_IS_CATEGORY_CUSTOM_SENSITIVE(ldi->category)
+        #endif
+        #ifdef __NVRAM_CUSTOM_DISK__
+            || NVRAM_IS_CATEGORY_CUSTOM_DISK(ldi->category)
+        #endif
+            )
+        {
+
+            kal_wsprintf(buf, "%s", ldi->fileprefix);
+
+            if (kal_wstrncmp(buf, starter, FILE_PREFIX_LEN)== 0)
+            {
+                return KAL_TRUE;
+            }
+        }
+    }while(nvram_util_next_data_item(&ldi));
+
+    return KAL_FALSE;
+}
+
+
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_compare_to_default_value
+ * DESCRIPTION
+ *  This function is used to compare the value in nvram file to default value
+ * PARAMETERS
+ *  LID:            [IN]    NVRAM LID
+ *  rec_index:      [IN]    record index, start from 1, but if the value is 0,
+ *                          this function will compare all record to default value
+ * RETURNS
+ *  nvram_errno_enum
+ * RETURN VALUES
+ *  NVRAM_ERRNO_SUCCESS:            no error
+ *  NVRAM_ERRNO_FAIL:   at least one record is different to default value
+ *****************************************************************************/
+kal_int32 nvram_compare_to_default_value(nvram_lid_enum LID, kal_uint16 rec_index)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi;
+    int i;
+    kal_uint8 *default_value = NULL;
+    kal_uint8 *buffer = NULL;
+    kal_int32 compare_result = 1;
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+
+    nvram_util_get_data_item(&ldi, LID);
+
+    if (!NVRAM_IS_LID_VALID(LID))
+    {
+        return NVRAM_IO_ERRNO_INVALID_LID;
+    }
+
+    if (rec_index > ldi->total_records)
+    {
+        return NVRAM_IO_ERRNO_INVALID_RECORD;
+    }
+
+    if (ldi->size <= MAX_NVRAM_RECORD_SIZE)
+    {
+        /* this function doesn't support the size over 2K now */
+        buffer = (kal_uint8*) get_ctrl_buffer(ldi->size);
+
+
+        for (i = (rec_index == 0?0:rec_index-1); i < ldi->total_records ; i++)
+        {
+            nvram_read_data_item(ldi, i + 1, 1, buffer, ldi->size);
+
+            default_value = (kal_uint8 *)nvram_get_default_value_to_write(ldi, i + 1, NULL, 0);
+
+            if (default_value == NULL || default_value == NVRAM_EF_FF_DEFAULT || default_value == NVRAM_EF_ZERO_DEFAULT)
+            {
+                default_value = (kal_uint8*)get_ctrl_buffer(ldi->size);
+                nvram_get_default_value_to_write(ldi, i + 1, default_value, ldi->size);
+                compare_result = memcmp(default_value, buffer, ldi->size);
+                free_ctrl_buffer(default_value);
+            }
+            else
+            {
+                compare_result = memcmp(default_value, buffer, ldi->size);
+            }
+
+            if (rec_index != 0)
+            {
+                break;
+            }
+        }
+
+        free_ctrl_buffer(buffer);
+    }
+    else
+    {
+        kal_uint8 *chksum2 = NULL;
+        kal_uint8 *chksum1 = NULL;
+        kal_uint32 nvram_chksum_size = 0;
+        nvram_drv_read_type_enum read_chksum_type = NVRAM_DRV_READ_TYPE_CHKSUM;
+        nvram_lid_chksum_info lid_chksum_info = {0};
+
+        nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, KAL_FALSE, KAL_FALSE);
+        nvram_chksum_size = lid_chksum_info.algo_info.chksum_algo_length;
+        read_chksum_type = lid_chksum_info.read_chksum_type;
+
+        buffer = (kal_uint8*) get_ctrl_buffer(ldi->total_records * nvram_chksum_size);
+        chksum1 = (kal_uint8*) get_ctrl_buffer(nvram_chksum_size);
+
+        /* this is temp solution, should implement full solution in drv layer in the future */
+        nvram_read_data_item_chksum(ldi, 1, ldi->total_records, buffer, ldi->total_records * nvram_chksum_size, read_chksum_type);
+
+        for (i = (rec_index == 0?0:rec_index-1); i < ldi->total_records ; i++)
+        {
+            default_value = (kal_uint8 *)nvram_get_default_value_to_write(ldi, i + 1, NULL, 0);
+
+            /* not support special default_value now */
+            if(default_value == NULL)
+            {
+                if(buffer)
+                {
+                    free_ctrl_buffer(buffer);
+                    buffer = NULL;
+                }
+                if (chksum1)
+                {
+                    free_ctrl_buffer(chksum1);
+                    chksum1 = NULL;
+                }
+                NVRAM_EXT_ASSERT(KAL_FALSE,0, NVRAM_LOC_GET_DEFAULT_VALUE_IS_NULL_1, 0, __LINE__);
+            }
+
+            kal_mem_set(chksum1, 0, nvram_chksum_size);
+            nvram_util_caculate_checksum(ldi, default_value, ldi->size, chksum1);
+            chksum2 = buffer + (nvram_chksum_size * i);
+
+            compare_result = memcmp(chksum1, chksum2, nvram_chksum_size);
+            if(compare_result != 0)
+            {
+                compare_result = 1;
+            }
+
+            if (rec_index != 0)
+            {
+                break;
+            }
+        }
+
+        if(buffer)
+        {
+            free_ctrl_buffer(buffer);
+            buffer = NULL;
+        }
+        if (chksum1)
+        {
+            free_ctrl_buffer(chksum1);
+            chksum1 = NULL;
+        }
+    }
+
+    if (compare_result == 0)
+    {
+        return NVRAM_ERRNO_SUCCESS;
+    }
+    else
+    {
+        return NVRAM_ERRNO_FAIL;
+    }
+}
+
+kal_uint8 *nvram_get_custpack_version(void)
+{
+    return nvram_ptr->custpack_version;
+}
+void nvram_dummy(void)
+{
+}
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_set_restore_factory_flag
+ * DESCRIPTION
+ * PARAMETERS
+ * RETURNS
+ *****************************************************************************/
+kal_bool nvram_set_restore_factory_flag(nvram_restore_flag_enum restore_flag)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi;
+    kal_uint8 sys_cache[NVRAM_EF_SYS_CACHE_OCTET_SIZE];
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s ====>\r\n",__FUNCTION__);
+    nvram_util_get_data_item(&ldi, NVRAM_EF_SYS_CACHE_OCTET_LID);
+
+    /*
+     * if current record just record NVRAM_SYS_FACTORY_FLAG
+     *  1. please use memory set
+     *  2. else read out first.
+     */
+    memset(sys_cache, 0, NVRAM_EF_SYS_CACHE_OCTET_SIZE);
+
+    sys_cache[0] = (kal_uint8) restore_flag;
+
+    nvram_write_data_item(ldi, NVRAM_SYS_FACTORY_FLAG, sys_cache, KAL_FALSE);
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s <====\r\n",__FUNCTION__);
+    return KAL_TRUE;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_check_restore_factory_flag
+ * DESCRIPTION
+ * PARAMETERS
+ * RETURNS
+ *****************************************************************************/
+kal_bool nvram_check_restore_factory_flag(void)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *ldi;
+    kal_uint8 sys_cache[NVRAM_EF_SYS_CACHE_OCTET_SIZE];
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s ====>\r\n",__FUNCTION__);
+    nvram_util_get_data_item(&ldi, NVRAM_EF_SYS_CACHE_OCTET_LID);
+
+    nvram_read_data_item(ldi, NVRAM_SYS_FACTORY_FLAG, 1, sys_cache, NVRAM_EF_SYS_CACHE_OCTET_SIZE);
+
+    if (NVRAM_RESTORE_TRUE == sys_cache[0])
+    {
+        return KAL_TRUE;
+    }
+    else
+    {
+        return KAL_FALSE;
+    }
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s <====\r\n",__FUNCTION__);
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_msg_read_req
+ * DESCRIPTION
+ *  This function issues MSG_ID_NVRAM_READ_REQ  to nvram.
+ * PARAMETERS
+ *  file_idx            [IN]        
+ *  record_index        [IN]        
+ *  access_id           [IN]        
+ *  rec_amount          [IN]        
+ * RETURNS
+ *  void
+ *****************************************************************************/
+void nvram_external_msg_read_req(
+                kal_uint16 file_idx,
+                kal_uint16 record_index,
+                kal_uint8 access_id,
+                kal_uint16 rec_amount)
+{
+
+    nvram_read_req_struct *nvram_read_req;
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s ====>\r\n",__FUNCTION__);
+    nvram_read_req = (nvram_read_req_struct*) construct_local_para(sizeof(nvram_read_req_struct), TD_CTRL);
+    nvram_read_req->file_idx = (nvram_lid_enum) file_idx;
+    nvram_read_req->para = record_index;
+    nvram_read_req->access_id = (kal_uint16) access_id;
+    nvram_read_req->rec_amount = rec_amount;
+	
+    msg_send6(stack_get_active_module_id(), MOD_NVRAM, PS_NVRAM_SAP, MSG_ID_NVRAM_READ_REQ, (local_para_struct *)nvram_read_req,NULL);
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s <====\r\n",__FUNCTION__);
+}   /* end of nvram_msg_read_req */
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_msg_write_req
+ * DESCRIPTION
+ *  This function issues NVRAM_WRITE_REQ to nvram.
+ * PARAMETERS
+ *  file_idx            [IN]        
+ *  record_index        [IN]        
+ *  access_id           [IN]        
+ *  peer_buf_ptr        [?]         
+ *  ilm_ptr(?)          [IN]        The primitives
+ * RETURNS
+ *  void
+ *****************************************************************************/
+void nvram_external_msg_write_req(
+                kal_uint16 file_idx,
+                kal_uint16 record_index,
+                kal_uint8 access_id,
+                peer_buff_struct *peer_buf_ptr)
+{
+
+    nvram_write_req_struct *nvram_write_req;
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s ====>\r\n",__FUNCTION__);
+    
+    nvram_write_req = (nvram_write_req_struct*) construct_local_para(sizeof(nvram_write_req_struct), TD_CTRL);
+    nvram_write_req->file_idx = (nvram_lid_enum) file_idx;
+    nvram_write_req->para = record_index;
+    nvram_write_req->access_id = (kal_uint16) access_id;
+
+    msg_send6(stack_get_active_module_id(), MOD_NVRAM, PS_NVRAM_SAP, MSG_ID_NVRAM_WRITE_REQ, (local_para_struct *)nvram_write_req, peer_buf_ptr);
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s <====\r\n",__FUNCTION__);
+}   /* end of nvram_msg_write_req */
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_msg_reset_req
+ * DESCRIPTION
+ *  
+ * PARAMETERS
+ *  src_id              [IN]        
+ *  reset_category      [IN]        
+ *  lid                 [IN]        
+ *  rec_index           [IN]        
+ *  rec_amount          [IN]        
+ * RETURNS
+ *  void
+ *****************************************************************************/
+void nvram_external_msg_reset_req(
+	     kal_uint16 file_idx,
+            kal_uint16 record_index,
+            kal_uint16 rec_amount,
+            kal_uint8 access_id)
+{
+    nvram_reset_req_struct *nvram_reset_req;
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s ====>\r\n",__FUNCTION__);
+    
+    nvram_reset_req = (nvram_reset_req_struct*) construct_local_para((kal_uint16) sizeof(nvram_reset_req_struct), TD_RESET);
+
+    nvram_reset_req->reset_category = NVRAM_RESET_CERTAIN;
+    nvram_reset_req->LID = file_idx;
+    nvram_reset_req->access_id = access_id;
+    nvram_reset_req->rec_index = record_index;
+    nvram_reset_req->rec_amount = rec_amount;
+
+    msg_send6(stack_get_active_module_id(), MOD_NVRAM, PS_NVRAM_SAP, MSG_ID_NVRAM_RESET_REQ, (local_para_struct *)nvram_reset_req, NULL);
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s <====\r\n",__FUNCTION__);
+}
+
+
+extern void nvram_set_ltable(nvram_ltable_entry_struct *table);
+extern nvram_ltable_entry_struct *nvram_get_ltable(void);
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_ltable_register
+ * DESCRIPTION
+ * PARAMETERS
+ * RETURNS
+ *****************************************************************************/
+void nvram_ltable_register(nvram_ltable_entry_struct *table)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+
+
+    /*----------------------------------------------------------------*/
+    /* Code Body                                                      */
+    /*----------------------------------------------------------------*/
+
+    
+    nvram_set_ltable(table);
+}
+
+// The return value not used now, always return KAL_TRUE
+kal_bool nvram_register_read_req(nvram_read_callback_struct *entry)
+{
+    nvram_callback_req_struct *local_data;
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s ====>\r\n",__FUNCTION__);
+    
+    entry->processed = KAL_FALSE;
+    /*send a message to NVRAM to wakeup NVRAM task*/
+    local_data = (nvram_callback_req_struct*) construct_local_para(sizeof(nvram_callback_req_struct), TD_CTRL);
+    local_data->ref_count = 1;
+    local_data->access_id = 0;
+    local_data->cfun_addr = (void*)(entry->callback);
+    nvram_send_ilm(MOD_NVRAM, MSG_ID_NVRAM_CALLBACK_REQ, local_data, NULL);
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s <====\r\n",__FUNCTION__);
+    return KAL_TRUE;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_msg_reg_req
+ * DESCRIPTION
+ *  file_idx               [IN]  
+ *  rec_index           [IN]        
+ *  rec_amount          [IN]        
+ * RETURNS
+ *  void
+ *****************************************************************************/
+void nvram_external_msg_reg_req(
+            kal_uint16 file_idx,
+            kal_uint16 record_index,
+            kal_uint16 rec_amount)
+{
+    nvram_reg_notify_req_struct *nvram_read_req;
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s ====>\r\n",__FUNCTION__);
+    
+    nvram_read_req = (nvram_reg_notify_req_struct*) construct_local_para(sizeof(nvram_reg_notify_req_struct), TD_CTRL);
+    nvram_read_req->file_idx = (nvram_lid_enum) file_idx;
+    nvram_read_req->para = record_index;
+    nvram_read_req->access_id = 0;
+    nvram_read_req->rec_amount = rec_amount;
+    
+    msg_send6(stack_get_active_module_id(), MOD_NVRAM, PS_NVRAM_SAP, MSG_ID_NVRAM_REG_NOTIFY_REQ, (local_para_struct *)nvram_read_req,NULL);
+}
+
+void nvram_external_msg_dereg_req(
+            kal_uint16 file_idx,
+            kal_uint16 record_index,
+            kal_uint16 rec_amount)
+{
+    nvram_dereg_notify_req_struct *nvram_read_req;
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s ====>\r\n",__FUNCTION__);
+    
+    nvram_read_req = (nvram_dereg_notify_req_struct*) construct_local_para(sizeof(nvram_dereg_notify_req_struct), TD_CTRL);
+    nvram_read_req->file_idx = (nvram_lid_enum) file_idx;
+    nvram_read_req->para = record_index;
+    nvram_read_req->access_id = 0;
+    nvram_read_req->rec_amount = rec_amount;
+    
+    msg_send6(stack_get_active_module_id(), MOD_NVRAM, PS_NVRAM_SAP, MSG_ID_NVRAM_DEREG_NOTIFY_REQ, (local_para_struct *)nvram_read_req,NULL);
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s <====\r\n",__FUNCTION__);
+}
+
+#ifdef __NVRAM_READ_RESERVED_FILE__
+kal_bool nvram_external_search_reserved_lid(nvram_lid_enum LID, kal_char *verno, kal_uint16 total_records, kal_uint16 size)
+{
+    nvram_ltable_entry_struct *ldi, *ldi_r;
+    kal_char filename[NVRAM_MAX_PATH_LEN];
+    NVRAM_FULL_PATH r_filename;
+    nvram_ldi_ota_header ota_hdr;
+    kal_int32 result = 0;
+
+    nvram_util_get_data_item(&ldi, LID);
+    if (!ldi) {
+        return KAL_FALSE;
+    }
+
+    //search file
+    sprintf(filename, "%s?%s_", ldi->fileprefix, verno);
+    if(total_records) {
+        sprintf((filename + NVRAM_FILE_LEN + 1), "%04X", total_records);
+    }
+    else {
+        strcat(filename, "????");
+    }
+
+    if(size) {
+       result = sprintf((filename + NVRAM_FILE_LEN + 5), "%04X", size);
+       if(result < 0)
+       {
+            return KAL_FALSE;
+       }
+    }
+    else {
+        strcat(filename, "????");
+    }
+    
+    if(!nvram_ota_search_backup_file(filename, (NVRAM_FULL_PATH *)r_filename)) {
+        return KAL_FALSE;
+    }
+
+    //check file header
+    if(!nvram_read_data_header(r_filename, LDI_HEADER_OTA_SECTION, (void*)&ota_hdr, NVRAM_LDI_OTA_HEADER_SIZE)) {
+        return KAL_FALSE;
+    }
+
+    //Prepare NVRAM_EF_READ_RESERVED_LID_VERNO
+    nvram_util_get_data_item(&ldi_r, NVRAM_EF_READ_RESERVED_LID);
+    if (!ldi_r) {
+        return KAL_FALSE;
+    }
+    ldi_r->attr = ota_hdr.ldi_attr;
+    ldi_r->total_records = ota_hdr.total_records;
+    ldi_r->size = ota_hdr.record_size;
+    ldi_r->default_value = (kal_uint8*)ldi;
+    strncpy(ldi_r->fileprefix, ldi->fileprefix, FILE_PREFIX_LEN);
+    ldi_r->fileprefix[FILE_PREFIX_LEN] = '\0';
+    strncpy(ldi_r->fileverno, verno, FILE_VERNO_LEN);
+    ldi_r->fileverno[FILE_VERNO_LEN] = '\0';
+    
+    return KAL_TRUE;
+}
+#endif
+
+/*****************************************************************************
+ * FUNCTION
+ *  nvram_external_get_lid_info
+ * DESCRIPTION
+ *  This function is used to get the LID info
+ * PARAMETERS
+ *  LID:            [IN]    NVRAM LID
+ *  ldi:            [OUT]   LID info buffer pointer,store the LID info 
+ * RETURNS
+ *  nvram_errno_enum
+ * RETURN VALUES
+ *  NVRAM_ERRNO_SUCCESS:            no error
+ *  NVRAM_IO_ERRNO_INVALID_LID:     invalid LID
+ *  NVRAM_ERRNO_INVALID:            lid pointer is NULL
+ *****************************************************************************/
+
+
+nvram_errno_enum nvram_external_get_lid_info(nvram_lid_enum LID,nvram_ltable_entry_struct *ldi)
+{
+    /*----------------------------------------------------------------*/
+    /* Local Variables                                                */
+    /*----------------------------------------------------------------*/
+    nvram_ltable_entry_struct *tmp_ldi = NULL;
+    kal_bool ret = KAL_TRUE;
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s ====>\r\n",__FUNCTION__);
+    
+    if(ldi == NULL)
+    {
+        return NVRAM_ERRNO_INVALID;
+    }
+    ret = nvram_util_get_data_item(&tmp_ldi, LID);
+    
+    if (!ret)
+    {
+        return NVRAM_IO_ERRNO_INVALID_LID;
+    }
+    memcpy(ldi,tmp_ldi,sizeof(nvram_ltable_entry_struct));
+    NVRAM_DEBUG_DUMP(NVRAM_WARNING_DUMP,"%s <====\r\n",__FUNCTION__);
+    return NVRAM_ERRNO_SUCCESS;
+}
+
+kal_bool nvram_debug_info_init(kal_uint32 **share_mem,kal_uint32 *length_ptr)
+{
+    #if defined(__CCCIFS_SUPPORT__) && defined(__MTK_TARGET__)
+    if(nvram_ee_info == NULL)
+    {
+        g_nvram_emm_query_info_result = EMM_DirInfo_Query(EMM_DIRECT_WRITE_NVRAM, &g_nvram_emm_addr, &g_nvram_emm_size);
+        if((g_nvram_emm_size < sizeof(nvram_ee_info_type)) || !g_nvram_emm_query_info_result)
+        {
+            share_mem = NULL;
+            nvram_ee_info = NULL;
+            *length_ptr = 0;
+            return KAL_FALSE;
+        }        
+        nvram_ee_info = (nvram_ee_info_type *)g_nvram_emm_addr;
+        kal_mem_set(nvram_ee_info,0,sizeof(nvram_ee_info_type));
+        *share_mem =(kal_uint32 *)(&(nvram_ee_info->md_ccci_debug_info[0]));
+        *length_ptr = MD_CCCI_INFO_SIZE * sizeof(nvram_ee_info->md_ccci_debug_info[0]);
+    }
+    return KAL_TRUE;
+    #else
+    return KAL_FALSE;
+    #endif
+}
+