#include "stdafx.h"
#include "Calibration.h"

#include "Calibration_Struct.h"

const CString szErrDescTable[] = 
{
    "Can not find calibration parameter in NV file!",
    "Can not find calibration parameter in module!",
    "Length of calibration parameters does not match in module and NV file!",
    "Unknown or unsurpport version in Module!",
    "Use a older version of calibration parameters to Update a new one is not permitted!",
    "Unknown version in NV file!"        
};

enum
{
    ERR_NOT_FIND_PARAM_IN_FILE,
    ERR_NOT_FIND_PARAM_IN_MODULE,
    ERR_PARAM_LEN_NOT_MATCH,
    ERR_UNKNOWN_VER_IN_MODULE,
    ERR_OLD_VERSION,
    ERR_UNKNOWN_VER_IN_FILE,    
};

#define NV_L1_CALIBRATION_PARAMETER 0x2
#define NV_IMEI                     0x5
#define ADC_ITEM                    0x190

 
CString GetErrorDesc( UINT dwID  )
{
    if( (int)dwID < 0 )
        return "";

    return szErrDescTable[ dwID ];
}

#define PRESERVE_CALIBRATION(lpSrc,nSrc,lpDst,nDst,nSize,nLen)  memcpy(lpSrc + nSrc,lpDst + nDst,nSize);    \
                                                                nSrc += nSize;                              \
                                                                nDst += nSize;                              \
                                                                nLen += nSize;

#define SKIP_UNUSED(nOffset,nSize,nLen)    nOffset += nSize;   \
                                           nLen += nSize;

BOOL FindNVOffset(WORD wId,LPBYTE lpCode,DWORD dwCodeSize,
                  DWORD& dwOffset,DWORD& dwLength)
{
    if(lpCode == NULL || (int)dwCodeSize < 0)
    {
        return FALSE;
    }
    
    dwOffset = 4;     // Skip first four bytes,that is time stamp
    DWORD dwId;
    dwLength = 0;
    BYTE* pTemp = lpCode + dwOffset;
    
    while(dwOffset < dwCodeSize)
    {
        dwId = ( *pTemp << 8 ) + *(pTemp + 1);
        pTemp += 2;
        dwLength = ( *pTemp << 8 ) + *(pTemp + 1);
        pTemp += 2;
        dwOffset += 4;
        // Must be four byte aligned
        BYTE bRet = (BYTE)(dwLength % 4);
        if(bRet != 0)
        {
            dwLength += 4 - bRet;
        }
        
        if(dwId == wId)
        {
            return TRUE;
        }
        else
        {
            dwOffset += dwLength;
            pTemp += dwLength;
        }
    }
    
    return FALSE;
}

void Ver4To4( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    int nOffset = dwOffset;
    int nOffsetFile = dwOffsetFile;
    int nLen = 0;
    
    //Preserve from start to end of RF_ramppwr_step_factor for GSM
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x1AC,nLen );
    
    //Skip RF_ramp_delta_timing for GSM
    SKIP_UNUSED( nOffsetFile,0x20,nLen );
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration for GSM to RF_ramppwr_step_factor for DCS
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x262,nLen );
    
    //Skip RF_ramp_delta_timing for DCS
    SKIP_UNUSED( nOffsetFile,0x20,nLen );
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration for DCS to RF_ramppwr_step_factor for PCS
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x262,nLen );
    
    //Skip RF_ramp_delta_timing for PCS
    SKIP_UNUSED(nOffsetFile,0x20,nLen);
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration for PCS to RF_ramppwr_step_factor for GSM850
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x262,nLen );
    
    //Skip RF_ramp_delta_timing for GSM850
    SKIP_UNUSED(nOffsetFile,0x20,nLen);
    nOffset += 0x20;
    
    //Preserve rest
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x1DE,nLen );
}

void Ver4To4m( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    int nOffset = dwOffset;
    int nOffsetFile = dwOffsetFile;
    int nLen = 0;
    
    //Preserve from start to end of RF_ramppwr_step_factor for GSM
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x1B6,nLen );
    
    //Skip RF_ramp_delta_timing for GSM
    SKIP_UNUSED( nOffsetFile,0x20,nLen );
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration for GSM to RF_ramppwr_step_factor for DCS
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x262,nLen );
    
    //Skip RF_ramp_delta_timing for DCS
    SKIP_UNUSED( nOffsetFile,0x20,nLen );
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration for DCS to RF_ramppwr_step_factor for PCS
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x262,nLen );
    
    //Skip RF_ramp_delta_timing for PCS
    SKIP_UNUSED(nOffsetFile,0x20,nLen);
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration for PCS to RF_ramppwr_step_factor for GSM850
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x262,nLen );
    
    //Skip RF_ramp_delta_timing for GSM850
    SKIP_UNUSED(nOffsetFile,0x20,nLen);
    nOffset += 0x20;
    
    //Preserve rest
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x1DE,nLen );
}

void Ver3To4( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    int nOffset = dwOffset + 2;
    int nOffsetFile = dwOffsetFile + 2;
    int nLen = 2;
    
    //Preserve from start to end of osci_temp_comp_in_dac
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x12,nLen );
    
    // Skip aero2_RF_AFC_STRUCT
    SKIP_UNUSED( nOffsetFile,0x70,nLen );
    
    // Preserve from RF_ramp_up_table_stage0 to end of RF_ramppwr_step_factor for GSM
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x128,nLen );
    
    //Skip RF_ramp_delta_timing for GSM
    SKIP_UNUSED( nOffsetFile,0x20,nLen );
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration for GSM to RF_ramppwr_step_factor for DCS
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x262,nLen );
    
    //Skip RF_ramp_delta_timing for DCS
    SKIP_UNUSED( nOffsetFile,0x20,nLen );
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration for DCS to RF_ramppwr_step_factor for PCS
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x262,nLen );
    
    //Skip RF_ramp_delta_timing for PCS
    SKIP_UNUSED(nOffsetFile,0x20,nLen);
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration for PCS to RF_ramppwr_step_factor for GSM850
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x262,nLen );
    
    //Skip RF_ramp_delta_timing for GSM850
    SKIP_UNUSED(nOffsetFile,0x20,nLen);
    nOffset += 0x20;
    
    //Preserve rest
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x1DE,nLen );
}

void Ver3To3( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    int nOffset = dwOffset;
    int nOffsetFile = dwOffsetFile;
    int nLen = 0;
    
    //Preserve from start to end of RF_ramppwr_step_factor for GSM
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x13c,nLen );
    
    //Skip RF_ramp_delta_timing for GSM
    SKIP_UNUSED( nOffsetFile,0x20,nLen );
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration for GSM to RF_ramppwr_step_factor for DCS
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x262,nLen );
    
    //Skip RF_ramp_delta_timing for DCS
    SKIP_UNUSED( nOffsetFile,0x20,nLen );
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration for DCS to RF_ramppwr_step_factor for PCS
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x262,nLen );
    
    //Skip RF_ramp_delta_timing for PCS
    SKIP_UNUSED(nOffsetFile,0x20,nLen);
    nOffset += 0x20;         
    
    //Preserve rest
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x460,nLen );
}

void Ver4To3( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    int nOffset = dwOffset + 2;
    int nOffsetFile = dwOffsetFile + 2;
    int nLen = 2;
    
    //Preserve from start to end of osci_temp_comp_in_dac
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x12,nLen );
    
    // Skip aero2_RF_AFC_STRUCT
    SKIP_UNUSED( nOffset,0x70,nLen );
    
    // Preserve from RF_ramp_up_table_stage0 to end of RF_ramppwr_step_factor for GSM
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x128,nLen );
    
    //Skip RF_ramp_delta_timing for GSM
    SKIP_UNUSED( nOffsetFile,0x20,nLen );
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration for GSM to RF_ramppwr_step_factor for DCS
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x262,nLen );
    
    //Skip RF_ramp_delta_timing for DCS
    SKIP_UNUSED( nOffsetFile,0x20,nLen );
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration for DCS to RF_ramppwr_step_factor for PCS
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x262,nLen );
    
    //Skip RF_ramp_delta_timing for PCS
    SKIP_UNUSED(nOffsetFile,0x20,nLen);
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration for PCS to RF_ramppwr_step_factor for GSM850
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x262,nLen );
    
    //Skip RF_ramp_delta_timing for GSM850
    SKIP_UNUSED(nOffsetFile,0x20,nLen);
    nOffset += 0x20;
    
    //Preserve rest
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x1DE,nLen );
}

void Ver2To3( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    int nOffset = 2 + dwOffset;
    int nOffsetFile = 2 + dwOffsetFile;
    int nLen = 2;
    
    //Preserve RF_commom_dsp_use
    nOffset = 0x554 + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x8,nLen );
    
    //Preserve osci_temp_comp_in_dac
    nOffset = 0x562 + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0xA,nLen );
    
    //Preserve from RF_ramp_up_table_stage0 to RF_ramp_step_factor
    nOffset = 0x2 + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x128,nLen );
    
    //Skip RF_ramp_delta_timing for GSM
    SKIP_UNUSED( nOffsetFile,0x20,nLen );
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration to temperature_TX_rampwr_step_factor
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x56,nLen );
    
    //Preserve ramp_switch_level
    nOffset = 0x794 + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,2,nLen );
    
    //Preserve afc_alg_bias
    nOffset = 0x55c + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,2,nLen );
    
    //Preserve agc_ctrl_word and max_rf_gain_index
    nOffset = 0x56c + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0xB8,nLen );
    
    //Skip reserved area            
    SKIP_UNUSED( nOffsetFile,0x28,nLen );
    
    
    
    //Preserve from RF_ramp_up_table_stage0 to RF_ramp_step_factor
    nOffset = 0x1C8 + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x128,nLen );
    
    //Skip RF_ramp_delta_timing for DCS
    SKIP_UNUSED( nOffsetFile,0x20,nLen );
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration to temperature_TX_rampwr_step_factor
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x56,nLen );
    
    //Preserve ramp_switch_level
    nOffset = 0x796 + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,2,nLen );
    
    //Preserve afc_alg_bias
    nOffset = 0x55e + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,2,nLen );
    
    //Preserve agc_ctrl_word and max_rf_gain_index
    nOffset = 0x624 + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0xB8,nLen );
    
    //Skip reserved area            
    SKIP_UNUSED( nOffsetFile,0x28,nLen );
    
    
    //Preserve from RF_ramp_up_table_stage0 to RF_ramp_step_factor
    nOffset = 0x38E + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x128,nLen );
    
    //Skip RF_ramp_delta_timing for PCS
    SKIP_UNUSED( nOffsetFile,0x20,nLen );
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration to temperature_TX_rampwr_step_factor
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x56,nLen );
    
    //Preserve ramp_switch_level
    nOffset = 0x798 + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,2,nLen );
    
    //Preserve afc_alg_bias
    nOffset = 0x560 + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,2,nLen );
    
    //Preserve agc_ctrl_word and max_rf_gain_index
    nOffset = 0x6DC + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0xB8,nLen );
    
    //Skip reserved area            
    SKIP_UNUSED( nOffsetFile,0x28,nLen );
    
    //Skip RF_gsm850_param_dsp_use
    SKIP_UNUSED( nOffsetFile,0x282,nLen );
    
    
    //Preserve from rx_whole_band_comp_gsm to rx_whole_band_comp_pcs
    nOffset = 0x79A + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x15,nLen );
    
    //Skip rx_whole_band_comp_gsm850
    SKIP_UNUSED( nOffsetFile,0x6,nLen );
    
    //Preserve from pa_gsm_temp_comp to pa_pcs_temp_comp
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0xF,nLen );
    
    //Skip pa_gsm850_temp_comp
    SKIP_UNUSED( nOffsetFile,0x5,nLen );
    
    //Preserve from rxlev_GSM_temp_comp to rxlev_PCS_temp_comp
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0xF,nLen );
    
    //Skip rxlev_GSM850_temp_comp
    SKIP_UNUSED( nOffsetFile,0x5,nLen );
    
    //Preserve from pa_GSM_vcc_comp_threshold to pa_PCS_vcc_comp_step
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x6,nLen );
    
    //Skip pa_GSM850_vcc_comp_threshold and pa_GSM850_vcc_comp_step
    SKIP_UNUSED( nOffsetFile,0x2,nLen );
    
    // For alignment 
    SKIP_UNUSED( nOffsetFile,0x1,nLen );
    nOffset += 0x1;
    
    //Preserve rest
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x58,nLen );
}

void Ver1To3( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    int nOffset = 2 + dwOffset;
    int nOffsetFile = 2 + dwOffsetFile;
    int nLen = 2;
    
    //Preserve RF_commom_dsp_use
    nOffset = 0x2a2 + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x8,nLen );
    
    //Preserve osci_temp_comp_in_dac
    nOffset = 0x2b0 + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0xA,nLen );
    
    // Preserve from start to end of RF_ramp_down_table_stage1
    nOffset = 2 + dwOffset;
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x80,nLen);
    
    // Skip TX_compensate_boundary_arfcn_index
    SKIP_UNUSED(nOffsetFile,0x8,nLen);
    
    // Preserve RF_ramppwr_step_factor[0]
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // Skip RF_ramppwr_step_factor[1] ----- RF_ramppwr_step_factor[4]
    // Use RF_ramppwr_step_factor[0] to overwrite the rest of the array
    memcpy(pSrc + nOffsetFile       ,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x20,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x40,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x60,lpReadBuffer + nOffset - 0x20,0x20);
    SKIP_UNUSED(nOffsetFile,0x80,nLen);
    
    //Skip RF_ramp_delta_timing for GSM
    SKIP_UNUSED( nOffsetFile,0x20,nLen );
    nOffset += 0x20;
    
    // Preserve RF_ramp_PA_power_on_duration
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // Skip from RX_compensate_boundary_arfcn_index to temperature_TX_rampwr_step_factor
    SKIP_UNUSED(nOffsetFile,0x36,nLen);
    
    //Preserve ramp_switch_level
    nOffset = 0x4e2 + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,2,nLen );
    
    //Preserve afc_alg_bias
    nOffset = 0x2aa + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,2,nLen );
    
    //Preserve agc_ctrl_word and max_rf_gain_index
    nOffset = 0x2ba + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0xB8,nLen );
    
    //Skip reserved area            
    SKIP_UNUSED( nOffsetFile,0x28,nLen );
    
    
    
    // Preserve from start to end of RF_ramp_down_table_stage1
    nOffset = 0xe2 + dwOffset;
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x80,nLen);
    
    // Skip TX_compensate_boundary_arfcn_index
    SKIP_UNUSED(nOffsetFile,0x8,nLen);
    
    // Preserve RF_ramppwr_step_factor[0]
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // Skip RF_ramppwr_step_factor[1] ----- RF_ramppwr_step_factor[4]
    // Use RF_ramppwr_step_factor[0] to overwrite the rest of the array
    memcpy(pSrc + nOffsetFile       ,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x20,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x40,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x60,lpReadBuffer + nOffset - 0x20,0x20);
    SKIP_UNUSED(nOffsetFile,0x80,nLen);
    
    //Skip RF_ramp_delta_timing for GSM
    SKIP_UNUSED( nOffsetFile,0x20,nLen );
    nOffset += 0x20;
    
    // Preserve RF_ramp_PA_power_on_duration
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // Skip from RX_compensate_boundary_arfcn_index to temperature_TX_rampwr_step_factor
    SKIP_UNUSED(nOffsetFile,0x36,nLen);
    
    //Preserve ramp_switch_level
    nOffset = 0x4e4 + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,2,nLen );
    
    //Preserve afc_alg_bias
    nOffset = 0x2ac + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,2,nLen );
    
    //Preserve agc_ctrl_word and max_rf_gain_index
    nOffset = 0x372 + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0xB8,nLen );
    
    //Skip reserved area            
    SKIP_UNUSED( nOffsetFile,0x28,nLen );
    
    
    
    // Preserve from start to end of RF_ramp_down_table_stage1
    nOffset = 0x1c2 + dwOffset;
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x80,nLen);
    
    // Skip TX_compensate_boundary_arfcn_index
    SKIP_UNUSED(nOffsetFile,0x8,nLen);
    
    // Preserve RF_ramppwr_step_factor[0]
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // Skip RF_ramppwr_step_factor[1] ----- RF_ramppwr_step_factor[4]
    // Use RF_ramppwr_step_factor[0] to overwrite the rest of the array
    memcpy(pSrc + nOffsetFile       ,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x20,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x40,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x60,lpReadBuffer + nOffset - 0x20,0x20);
    SKIP_UNUSED(nOffsetFile,0x80,nLen);
    
    //Skip RF_ramp_delta_timing for GSM
    SKIP_UNUSED( nOffsetFile,0x20,nLen );
    nOffset += 0x20;
    
    // Preserve RF_ramp_PA_power_on_duration
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // Skip from RX_compensate_boundary_arfcn_index to temperature_TX_rampwr_step_factor
    SKIP_UNUSED(nOffsetFile,0x36,nLen);
    
    //Preserve ramp_switch_level
    nOffset = 0x4e6 + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,2,nLen );
    
    //Preserve afc_alg_bias
    nOffset = 0x2ae + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,2,nLen );
    
    //Preserve agc_ctrl_word and max_rf_gain_index
    nOffset = 0x42a + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0xB8,nLen );
    
    //Skip reserved area            
    SKIP_UNUSED( nOffsetFile,0x28,nLen );
    
    //Skip RF_gsm850_param_dsp_use
    SKIP_UNUSED( nOffsetFile,0x282,nLen );
    
    
    //Preserve from rx_whole_band_comp_gsm to rx_whole_band_comp_pcs
    nOffset = 0x4e8 + dwOffset;
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x15,nLen );
    
    //Skip rx_whole_band_comp_gsm850
    SKIP_UNUSED( nOffsetFile,0x6,nLen );
    
    //Preserve from pa_gsm_temp_comp to pa_pcs_temp_comp
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0xF,nLen );
    
    //Skip pa_gsm850_temp_comp
    SKIP_UNUSED( nOffsetFile,0x5,nLen );
    
    //Preserve from rxlev_GSM_temp_comp to rxlev_PCS_temp_comp
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0xF,nLen );
    
    //Skip rxlev_GSM850_temp_comp
    SKIP_UNUSED( nOffsetFile,0x5,nLen );
    
    //Preserve from pa_GSM_vcc_comp_threshold to pa_PCS_vcc_comp_step
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x6,nLen );
    
    //Skip pa_GSM850_vcc_comp_threshold and pa_GSM850_vcc_comp_step
    SKIP_UNUSED( nOffsetFile,0x2,nLen );
    
    // For alignment 
    SKIP_UNUSED( nOffsetFile,0x1,nLen );
    nOffset += 0x1;
    
    //Preserve rest
    PRESERVE_CALIBRATION( pSrc,nOffsetFile,lpReadBuffer,nOffset,0x58,nLen );
}

void Ver2To2( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset,DWORD dwLength )
{
    int nOffset = dwOffset;
    int nOffsetFile = dwOffsetFile;
    int nLen = 0;
    
    //Preserver from start to end of RF_ramppwr_step_factor_GSM
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x12a,nLen);
    
    //Skip RF_ramp_delta_timing_GSM
    SKIP_UNUSED(nOffsetFile,0x20,nLen);
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration_GSM to RF_ramppwr_step_factor_DCS
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x1a6,nLen);
    
    //Skip RF_ramp_delta_timing_DCS
    SKIP_UNUSED(nOffsetFile,0x20,nLen);
    nOffset += 0x20;
    
    //Preserve from RF_ramp_PA_power_on_duration_DCS to RF_ramppwr_step_factor_PCS
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x1a6,nLen);
    
    //Skip RF_ramp_delta_timing_PCS
    SKIP_UNUSED(nOffsetFile,0x20,nLen);
    nOffset += 0x20;            
    
    //Preserve rest
    memcpy(pSrc + nOffsetFile,lpReadBuffer + nOffset,dwLength - nLen);
}

void Ver1To2( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset,DWORD dwLengthFile )
{
    // Skip version field
    int nOffset = 2 + dwOffset;
    int nOffsetFile = 2 + dwOffsetFile;
    int nLen = 2;
    
    // Preserve from start to end of RF_ramp_down_table_GSM_stage1
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x80,nLen);
    
    // Skip TX_compensate_boundary_arfcn_index_GSM
    SKIP_UNUSED(nOffsetFile,0x8,nLen);
    
    // Preserve RF_ramppwr_step_factor_GSM[0]
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // Skip RF_ramppwr_step_factor_GSM[1] ----- RF_ramppwr_step_factor_GSM[4]
    // Use RF_ramppwr_step_factor_GSM[0] to overwrite the rest of the array
    //@ Liu Kai 2004-6-23 CR10011
    memcpy(pSrc + nOffsetFile       ,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x20,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x40,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x60,lpReadBuffer + nOffset - 0x20,0x20);
    SKIP_UNUSED(nOffsetFile,0x80,nLen);
    
    //@ Liu Kai 2004-8-25 CR12644
    // Skip RF_ramp_delta_timing_GSM
    SKIP_UNUSED(nOffsetFile,0x20,nLen);
    nOffset += 0x20;
    
    // Preserve RF_ramp_PA_power_on_duration_GSM
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // Skip from RX_compensate_boundary_arfcn_index_GSM to reserve_for_future_GSM
    SKIP_UNUSED(nOffsetFile,0x5e,nLen);
    
    // Preserve from RF_ramp_up_table_DCS_stage0 to RF_ramp_down_table_DCS_stage1
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x80,nLen);
    
    // Skip TX_compensate_boundary_arfcn_index_DCS
    SKIP_UNUSED(nOffsetFile,0x8,nLen);
    
    // Preserve RF_ramppwr_step_factor_DCS[0]
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // Skip from RF_ramppwr_step_factor_DCS[1] to RF_ramppwr_step_factor_DCS[4]
    // Use RF_ramppwr_step_factor_DCS[0] to overwrite the rest of the array
    //@ Liu Kai 2004-6-23 CR10011
    memcpy(pSrc + nOffsetFile       ,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x20,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x40,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x60,lpReadBuffer + nOffset - 0x20,0x20);
    
    SKIP_UNUSED(nOffsetFile,0x80,nLen);
    
    //@ Liu Kai 2004-8-25 CR12644
    // Skip RF_ramp_delta_timing_DCS
    SKIP_UNUSED(nOffsetFile,0x20,nLen);
    nOffset += 0x20;
    
    // Preserve RF_ramp_PA_power_on_duration_DCS
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // Skip from RX_compensate_boundary_arfcn_index_DCS to reserve_for_future_DCS
    SKIP_UNUSED(nOffsetFile,0x5e,nLen);
    
    // Preserve from RF_ramp_up_table_PCS_stage0 to RF_ramp_down_table_PCS_stage1
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x80,nLen);
    
    // Skip TX_compensate_boundary_arfcn_index_PCS
    SKIP_UNUSED(nOffsetFile,0x8,nLen);
    
    // Preserve RF_ramppwr_step_factor_PCS[0]
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // SKip from RF_ramppwr_step_factor_PCS[1] to RF_ramppwr_step_factor_PCS[4]
    // Use RF_ramppwr_step_factor_PCS[0] to overwrite the rest of the array
    //@ Liu Kai 2004-6-23 CR10011
    memcpy(pSrc + nOffsetFile       ,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x20,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x40,lpReadBuffer + nOffset - 0x20,0x20);
    memcpy(pSrc + nOffsetFile + 0x60,lpReadBuffer + nOffset - 0x20,0x20);
    
    SKIP_UNUSED(nOffsetFile,0x80,nLen);
    
    //@ Liu Kai 2004-8-25 CR12644
    // Skip RF_ramp_delta_timing_PCS
    SKIP_UNUSED(nOffsetFile,0x20,nLen);
    nOffset += 0x20;
    
    // Preserve RF_ramp_PA_power_on_duration_PCS
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // Skip from RX_compensate_boundary_arfcn_index_PCS to reserve_for_future_PCS
    SKIP_UNUSED(nOffsetFile,0x5e,nLen);
    
    // Preserve from is_using_si4134 to ramp_switch_level_PCS
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x27f,nLen);
    
    // Alignment
    SKIP_UNUSED(nOffsetFile,1,nLen);
    nOffset += 3;
    
    // Preserve rest
    memcpy(pSrc + nOffsetFile,lpReadBuffer + nOffset,dwLengthFile - nLen);
}


void Ver2To1( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset,DWORD dwLength )
{
    // Skip version field
    int nOffset = 2 + dwOffset;
    int nOffsetFile = 2 + dwOffsetFile;
    int nLen = 2;
    
    // Preserve from start to end of RF_ramp_down_table_GSM_stage1
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x80,nLen);
    
    // Skip TX_compensate_boundary_arfcn_index_GSM
    SKIP_UNUSED(nOffset,0x8,nLen);
    
    // Preserve RF_ramppwr_step_factor_GSM[0]
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // Skip RF_ramppwr_step_factor_GSM[1] ----- RF_ramppwr_step_factor_GSM[4]
    SKIP_UNUSED(nOffset,0x80,nLen);
    
    // Skip RF_ramp_delta_timing_GSM
    SKIP_UNUSED(nOffset,0x20,nLen);
    nOffsetFile += 0x20;
    
    // Preserve RF_ramp_PA_power_on_duration_GSM
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // Skip from RX_compensate_boundary_arfcn_index_GSM to reserve_for_future_GSM
    SKIP_UNUSED(nOffset,0x5e,nLen);
    
    // Preserve from RF_ramp_up_table_DCS_stage0 to RF_ramp_down_table_DCS_stage1
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x80,nLen);
    
    // Skip TX_compensate_boundary_arfcn_index_DCS
    SKIP_UNUSED(nOffset,0x8,nLen);
    
    // Preserve RF_ramppwr_step_factor_DCS[0]
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // Skip from RF_ramppwr_step_factor_DCS[1] to RF_ramppwr_step_factor_DCS[4]
    SKIP_UNUSED(nOffset,0x80,nLen);
    
    // Skip RF_ramp_delta_timing_DCS
    SKIP_UNUSED(nOffset,0x20,nLen);
    nOffsetFile += 0x20;
    
    // Preserve RF_ramp_PA_power_on_duration_DCS
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // Skip from RX_compensate_boundary_arfcn_index_DCS to reserve_for_future_DCS
    SKIP_UNUSED(nOffset,0x5e,nLen);
    
    // Preserve from RF_ramp_up_table_PCS_stage0 to RF_ramp_down_table_PCS_stage1
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x80,nLen);
    
    // Skip TX_compensate_boundary_arfcn_index_PCS
    SKIP_UNUSED(nOffset,0x8,nLen);
    
    // Preserve RF_ramppwr_step_factor_PCS[0]
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // SKip from RF_ramppwr_step_factor_PCS[1] to RF_ramppwr_step_factor_PCS[4]
    SKIP_UNUSED(nOffset,0x80,nLen);
    
    // Skip RF_ramp_delta_timing_PCS
    SKIP_UNUSED(nOffset,0x20,nLen);
    nOffsetFile += 0x20;
    
    // Preserve RF_ramp_PA_power_on_duration_PCS
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x20,nLen);
    
    // Skip from RX_compensate_boundary_arfcn_index_PCS to reserve_for_future_PCS
    SKIP_UNUSED(nOffset,0x5e,nLen);
    
    // Preserve from is_using_si4134 to ramp_switch_level_PCS
    PRESERVE_CALIBRATION(pSrc,nOffsetFile,lpReadBuffer,nOffset,0x27f,nLen);
    
    // Alignment
    SKIP_UNUSED(nOffset,1,nLen);
    nOffsetFile += 3;
    
    // Preserve rest
    memcpy(pSrc + nOffsetFile,lpReadBuffer + nOffset,dwLength - nLen);
}

void Ver0To1( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    // Skip version info
    int nOffset = 2 + dwOffset;
    int nOffsetFile = 2 + dwOffsetFile;
    
    // Preserve from start to end of RF_ramp_PA_power_on_duration_DCS
    memcpy(pSrc + nOffsetFile,lpReadBuffer+nOffset,0x1c0);
    nOffsetFile += 0x1c0;
    nOffset += 0x1c0;
    // skip items list below
    // RF_ramp_up_table_PCS_stage0[NUM_RAMP_POINTS];
    // RF_ramp_up_table_PCS_stage1[NUM_RAMP_POINTS];
    // RF_ramp_down_table_PCS_stage0[NUM_RAMP_POINTS];
    // RF_ramp_down_table_PCS_stage1[NUM_RAMP_POINTS];
    // RF_ramppwr_step_factor_PCS[NUM_TX_LEVEL];
    // RF_ramp_delta_timing_PCS[NUM_TX_LEVEL];
    // RF_ramp_PA_power_on_duration_PCS[NUM_TX_LEVEL];
    nOffsetFile += 0xe0;
    
    // Preserve from is_using_si4134 to afc_alg_bias_dcs
    memcpy(pSrc + nOffsetFile,lpReadBuffer+nOffset,0xc);
    nOffsetFile += 0xc;
    nOffset += 0xc;
    // Skip afc_alg_bias_pcs
    nOffsetFile += 0x2;
    
    // Preserve from  osci_temp_comp_in_dac to dcs_max_rf_gain_index
    memcpy(pSrc + nOffsetFile,lpReadBuffer+nOffset,0x17a);
    nOffsetFile += 0x17a;
    nOffset += 0x17a;
    // Skip agc_ctrl_word_PCS and pcs_max_rf_gain_index
    nOffsetFile += 0xb8;
    
    // Preserve ramp_switch_level_GSM and ramp_switch_level_DCS
    memcpy(pSrc + nOffsetFile,lpReadBuffer + nOffset,0x4);
    nOffsetFile += 0x4;
    nOffset += 0x4;
    // Skip ramp_switch_level_PCS
    nOffsetFile += 0x2;
    
    // Alignment 
    nOffsetFile += 2;
    nOffset += 2;
    
    // Preserve  rx_whole_band_comp_gsm and  rx_whole_band_comp_dcs
    memcpy(pSrc + nOffsetFile,lpReadBuffer + nOffset,0xe);
    nOffsetFile += 0xe;
    nOffset += 0xe;
    // Skip  rx_whole_band_comp_pcs
    nOffsetFile += 0x7;
    
    // Preserve from pa_GSM_temp_comp to pa_DCS_vcc_comp_step
    memcpy(pSrc + nOffsetFile,lpReadBuffer + nOffset,0x22);
    nOffsetFile += 0x22;
    nOffset += 0x22;
    // Skip pa_PCS_vcc_comp_threshold and pa_PCS_vcc_comp_step
    nOffsetFile += 0x2;
    
    // Alignment
    nOffsetFile += 0x3;
    
    // Preserve from Misc_cal_MCU_use_T to PM_VERSION
    memcpy(pSrc + nOffsetFile,lpReadBuffer + nOffset,0xe);
}

void Ver1To0( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    int nOffset = 2 + dwOffset;
    int nOffsetFile = 2 + dwOffsetFile;
    
    // Preserve from start to end of RF_ramp_PA_power_on_duration_DCS
    memcpy(pSrc + nOffsetFile,lpReadBuffer+nOffset,0x1c0);
    nOffsetFile += 0x1c0;
    nOffset += 0x1c0;
    // skip items list below
    // RF_ramp_up_table_PCS_stage0[NUM_RAMP_POINTS];
    // RF_ramp_up_table_PCS_stage1[NUM_RAMP_POINTS];
    // RF_ramp_down_table_PCS_stage0[NUM_RAMP_POINTS];
    // RF_ramp_down_table_PCS_stage1[NUM_RAMP_POINTS];
    // RF_ramppwr_step_factor_PCS[NUM_TX_LEVEL];
    // RF_ramp_delta_timing_PCS[NUM_TX_LEVEL];
    // RF_ramp_PA_power_on_duration_PCS[NUM_TX_LEVEL];
    nOffset += 0xe0;
    
    // Preserve from is_using_si4134 to afc_alg_bias_dcs
    memcpy(pSrc + nOffsetFile,lpReadBuffer+nOffset,0xc);
    nOffsetFile += 0xc;
    nOffset += 0xc;
    // Skip afc_alg_bias_pcs
    nOffset += 0x2;
    
    // Preserve from  osci_temp_comp_in_dac to dcs_max_rf_gain_index
    memcpy(pSrc + nOffsetFile,lpReadBuffer+nOffset,0x17a);
    nOffsetFile += 0x17a;
    nOffset += 0x17a;
    // Skip agc_ctrl_word_PCS and pcs_max_rf_gain_index
    nOffset += 0xb8;
    
    // Preserve ramp_switch_level_GSM and ramp_switch_level_DCS
    memcpy(pSrc + nOffsetFile,lpReadBuffer + nOffset,0x4);
    nOffsetFile += 0x4;
    nOffset += 0x4;
    // Skip ramp_switch_level_PCS
    nOffset += 0x2;
    
    // Alignment 
    nOffsetFile += 2;
    nOffset += 2;
    
    // Preserve  rx_whole_band_comp_gsm and  rx_whole_band_comp_dcs
    memcpy(pSrc + nOffsetFile,lpReadBuffer + nOffset,0xe);
    nOffsetFile += 0xe;
    nOffset += 0xe;
    // Skip  rx_whole_band_comp_pcs
    nOffset += 0x7;
    
    // Preserve from pa_GSM_temp_comp to pa_DCS_vcc_comp_step
    memcpy(pSrc + nOffsetFile,lpReadBuffer + nOffset,0x22);
    nOffsetFile += 0x22;
    nOffset += 0x22;
    // Skip pa_PCS_vcc_comp_threshold and pa_PCS_vcc_comp_step
    nOffset += 0x2;
    
    // Alignment
    nOffset += 0x3;
    
    // Preserve from Misc_cal_MCU_use_T to PM_VERSION
    memcpy(pSrc + nOffsetFile,lpReadBuffer + nOffset,0xe);
}

void Ver5To5( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    Ver4To4( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
}

void Ver5To5M(LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    Ver4To4m( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
}

void Ver4To5( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    Ver4To4( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
    pSrc[ dwOffsetFile + 1] = 0x05;
}

void Ver3To5( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    Ver3To4( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
}

void Ver5To4( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    Ver4To4( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
    pSrc[ dwOffsetFile + 1] = 0x04;
}

void Ver5To3( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    Ver4To3( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
}

void Ver6To6( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    calibration_struct_v6::calibration_param_T para,para_file;
    memcpy( &para,lpReadBuffer+dwOffset,sizeof( para ) );
    memcpy( &para_file,pSrc+dwOffsetFile,sizeof( para_file ) );

    for( int i=0;i<calibration_struct_v6::NUM_TX_LEVEL;i++ )
    {
        para.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_delta_timing[i];
    }

    memcpy( pSrc + dwOffsetFile,&para,sizeof( para ) );
}

void Ver6To6M( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    calibration_struct_v6_m::calibration_param_T para,para_file;
    memcpy( &para,lpReadBuffer+dwOffset,sizeof( para ) );
    memcpy( &para_file,pSrc+dwOffsetFile,sizeof( para_file ) );
    
    for( int i=0;i<calibration_struct_v6::NUM_TX_LEVEL;i++ )
    {
        para.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_delta_timing[i];
    }
    
    memcpy( pSrc + dwOffsetFile,&para,sizeof( para ) );
}

void Ver5To6_RF_param_band_DSP_use_T( calibration_struct_v6::RF_param_band_DSP_use_T* pV6,
                                     calibration_struct_v5::RF_param_band_DSP_use_T* pV5
                                     )
{
    BYTE* p1 = (BYTE*)&( pV6->TX_compensate_boundary_arfcn_index );
    BYTE* p2 = (BYTE*)&( pV6->RF_ramp_delta_timing );
    
    memcpy( &(pV6->TX_compensate_boundary_arfcn_index),&(pV5->TX_compensate_boundary_arfcn_index),p2 - p1 ); //lint !e422
    
    p1 = (BYTE*)&( pV6->RF_ramp_PA_power_on_duration );
    p2 = (BYTE*)&( pV6->RF_ramp_table );
    memcpy( &(pV6->RF_ramp_PA_power_on_duration),&(pV5->RF_ramp_PA_power_on_duration),p2 - p1 );//lint !e422
    
    for( int i=0;i<11;i++)
    {
        pV6->RF_ramp_table.stage8[i] = pV5->RF_ramp_up_table_stage0[i+5];
        pV6->RF_ramp_table.stage9[i] = pV5->RF_ramp_up_table_stage0[i+5];
        pV6->RF_ramp_table.stage10[i] = pV5->RF_ramp_up_table_stage0[i+5];
        pV6->RF_ramp_table.stage11[i] = pV5->RF_ramp_up_table_stage0[i+5];
        pV6->RF_ramp_table.stage12[i] = pV5->RF_ramp_up_table_stage0[i+5];
        pV6->RF_ramp_table.stage13[i] = pV5->RF_ramp_up_table_stage0[i+5];
        pV6->RF_ramp_table.stage14[i] = pV5->RF_ramp_up_table_stage0[i+5];
        pV6->RF_ramp_table.stage15[i] = pV5->RF_ramp_up_table_stage0[i+5];
    }
    
    for( i=0;i<11;i++)
    {
        pV6->RF_ramp_table.stage0[i] = pV5->RF_ramp_up_table_stage1[i+5];
        pV6->RF_ramp_table.stage1[i] = pV5->RF_ramp_up_table_stage1[i+5];
        pV6->RF_ramp_table.stage2[i] = pV5->RF_ramp_up_table_stage1[i+5];
        pV6->RF_ramp_table.stage3[i] = pV5->RF_ramp_up_table_stage1[i+5];
        pV6->RF_ramp_table.stage4[i] = pV5->RF_ramp_up_table_stage1[i+5];
        pV6->RF_ramp_table.stage5[i] = pV5->RF_ramp_up_table_stage1[i+5];
        pV6->RF_ramp_table.stage6[i] = pV5->RF_ramp_up_table_stage1[i+5];
        pV6->RF_ramp_table.stage7[i] = pV5->RF_ramp_up_table_stage1[i+5];
    }
    
    for( i=0;i<9;i++ )
    {
        pV6->RF_ramp_table.stage8[i+11] = pV5->RF_ramp_down_table_stage0[i];
        pV6->RF_ramp_table.stage9[i+11] = pV5->RF_ramp_down_table_stage0[i];
        pV6->RF_ramp_table.stage10[i+11] = pV5->RF_ramp_down_table_stage0[i];
        pV6->RF_ramp_table.stage11[i+11] = pV5->RF_ramp_down_table_stage0[i];
        pV6->RF_ramp_table.stage12[i+11] = pV5->RF_ramp_down_table_stage0[i];
        pV6->RF_ramp_table.stage13[i+11] = pV5->RF_ramp_down_table_stage0[i];
        pV6->RF_ramp_table.stage14[i+11] = pV5->RF_ramp_down_table_stage0[i];
        pV6->RF_ramp_table.stage15[i+11] = pV5->RF_ramp_down_table_stage0[i];
    }
    
    for( i=0;i<9;i++ )
    {
        pV6->RF_ramp_table.stage0[i+11] = pV5->RF_ramp_down_table_stage1[i];
        pV6->RF_ramp_table.stage1[i+11] = pV5->RF_ramp_down_table_stage1[i];
        pV6->RF_ramp_table.stage2[i+11] = pV5->RF_ramp_down_table_stage1[i];
        pV6->RF_ramp_table.stage3[i+11] = pV5->RF_ramp_down_table_stage1[i];
        pV6->RF_ramp_table.stage4[i+11] = pV5->RF_ramp_down_table_stage1[i];
        pV6->RF_ramp_table.stage5[i+11] = pV5->RF_ramp_down_table_stage1[i];
        pV6->RF_ramp_table.stage6[i+11] = pV5->RF_ramp_down_table_stage1[i];
        pV6->RF_ramp_table.stage7[i+11] = pV5->RF_ramp_down_table_stage1[i];
    }
    
    for( i=0;i<8;i++ )
    {
        pV6->rf_ramp_param_constant_up[i] = pV5->RF_ramp_up_table_stage0[0];
        pV6->rf_ramp_param_constant_up[i+8] = pV5->RF_ramp_up_table_stage1[0];
        pV6->rf_ramp_param_constant_down[i] = pV5->RF_ramp_down_table_stage0[15];
        pV6->rf_ramp_param_constant_down[i+8] = pV5->RF_ramp_down_table_stage1[15];
    }
}

void Ver5To6_RF_param_band_DSP_use_T_M( calibration_struct_v6_m::RF_param_band_DSP_use_T* pV6,
                                     calibration_struct_v5_m::RF_param_band_DSP_use_T* pV5
                                     )
{
    BYTE* p1 = (BYTE*)&( pV6->TX_compensate_boundary_arfcn_index );
    BYTE* p2 = (BYTE*)&( pV6->RF_ramp_delta_timing );
    
    memcpy( &(pV6->TX_compensate_boundary_arfcn_index),&(pV5->TX_compensate_boundary_arfcn_index),p2 - p1 );//lint !e422
    
    p1 = (BYTE*)&( pV6->RF_ramp_PA_power_on_duration );
    p2 = (BYTE*)&( pV6->RF_ramp_table );
    memcpy( &(pV6->RF_ramp_PA_power_on_duration),&(pV5->RF_ramp_PA_power_on_duration),p2 - p1 );//lint !e422
    
    for( int i=0;i<11;i++)
    {
        pV6->RF_ramp_table.stage8[i] = pV5->RF_ramp_up_table_stage0[i+5];
        pV6->RF_ramp_table.stage9[i] = pV5->RF_ramp_up_table_stage0[i+5];
        pV6->RF_ramp_table.stage10[i] = pV5->RF_ramp_up_table_stage0[i+5];
        pV6->RF_ramp_table.stage11[i] = pV5->RF_ramp_up_table_stage0[i+5];
        pV6->RF_ramp_table.stage12[i] = pV5->RF_ramp_up_table_stage0[i+5];
        pV6->RF_ramp_table.stage13[i] = pV5->RF_ramp_up_table_stage0[i+5];
        pV6->RF_ramp_table.stage14[i] = pV5->RF_ramp_up_table_stage0[i+5];
        pV6->RF_ramp_table.stage15[i] = pV5->RF_ramp_up_table_stage0[i+5];
    }
    
    for( i=0;i<11;i++)
    {
        pV6->RF_ramp_table.stage0[i] = pV5->RF_ramp_up_table_stage1[i+5];
        pV6->RF_ramp_table.stage1[i] = pV5->RF_ramp_up_table_stage1[i+5];
        pV6->RF_ramp_table.stage2[i] = pV5->RF_ramp_up_table_stage1[i+5];
        pV6->RF_ramp_table.stage3[i] = pV5->RF_ramp_up_table_stage1[i+5];
        pV6->RF_ramp_table.stage4[i] = pV5->RF_ramp_up_table_stage1[i+5];
        pV6->RF_ramp_table.stage5[i] = pV5->RF_ramp_up_table_stage1[i+5];
        pV6->RF_ramp_table.stage6[i] = pV5->RF_ramp_up_table_stage1[i+5];
        pV6->RF_ramp_table.stage7[i] = pV5->RF_ramp_up_table_stage1[i+5];
    }
    
    for( i=0;i<9;i++ )
    {
        pV6->RF_ramp_table.stage8[i+11] = pV5->RF_ramp_down_table_stage0[i];
        pV6->RF_ramp_table.stage9[i+11] = pV5->RF_ramp_down_table_stage0[i];
        pV6->RF_ramp_table.stage10[i+11] = pV5->RF_ramp_down_table_stage0[i];
        pV6->RF_ramp_table.stage11[i+11] = pV5->RF_ramp_down_table_stage0[i];
        pV6->RF_ramp_table.stage12[i+11] = pV5->RF_ramp_down_table_stage0[i];
        pV6->RF_ramp_table.stage13[i+11] = pV5->RF_ramp_down_table_stage0[i];
        pV6->RF_ramp_table.stage14[i+11] = pV5->RF_ramp_down_table_stage0[i];
        pV6->RF_ramp_table.stage15[i+11] = pV5->RF_ramp_down_table_stage0[i];
    }
    
    for( i=0;i<9;i++ )
    {
        pV6->RF_ramp_table.stage0[i+11] = pV5->RF_ramp_down_table_stage1[i];
        pV6->RF_ramp_table.stage1[i+11] = pV5->RF_ramp_down_table_stage1[i];
        pV6->RF_ramp_table.stage2[i+11] = pV5->RF_ramp_down_table_stage1[i];
        pV6->RF_ramp_table.stage3[i+11] = pV5->RF_ramp_down_table_stage1[i];
        pV6->RF_ramp_table.stage4[i+11] = pV5->RF_ramp_down_table_stage1[i];
        pV6->RF_ramp_table.stage5[i+11] = pV5->RF_ramp_down_table_stage1[i];
        pV6->RF_ramp_table.stage6[i+11] = pV5->RF_ramp_down_table_stage1[i];
        pV6->RF_ramp_table.stage7[i+11] = pV5->RF_ramp_down_table_stage1[i];
    }
    
    for( i=0;i<8;i++ )
    {
        pV6->rf_ramp_param_constant_up[i] = pV5->RF_ramp_up_table_stage0[0];
        pV6->rf_ramp_param_constant_up[i+8] = pV5->RF_ramp_up_table_stage1[0];
        pV6->rf_ramp_param_constant_down[i] = pV5->RF_ramp_down_table_stage0[15];
        pV6->rf_ramp_param_constant_down[i+8] = pV5->RF_ramp_down_table_stage1[15];
    }
}

void Ver6To5_RF_param_band_DSP_use_T( calibration_struct_v5::RF_param_band_DSP_use_T* pV5,
                                     calibration_struct_v6::RF_param_band_DSP_use_T* pV6
                                     )
{
    BYTE* p1 = (BYTE*)&( pV6->TX_compensate_boundary_arfcn_index );
    BYTE* p2 = (BYTE*)&( pV6->RF_ramp_delta_timing );
    
    memcpy( &(pV5->TX_compensate_boundary_arfcn_index),&(pV6->TX_compensate_boundary_arfcn_index),p2 - p1 );//lint !e422
    
    p1 = (BYTE*)&( pV6->RF_ramp_PA_power_on_duration );
    p2 = (BYTE*)&( pV6->RF_ramp_table );
    memcpy( &(pV5->RF_ramp_PA_power_on_duration),&(pV6->RF_ramp_PA_power_on_duration),p2 - p1 );//lint !e422

    for( int i=0;i<5;i++ )
    {
        pV5->RF_ramp_up_table_stage0[i] = pV6->rf_ramp_param_constant_up[0];
        pV5->RF_ramp_up_table_stage1[i] = pV6->rf_ramp_param_constant_up[8];
    }

    for( i=9;i<16;i++ )
    {
        pV5->RF_ramp_down_table_stage0[i] = pV6->rf_ramp_param_constant_down[0];
        pV5->RF_ramp_down_table_stage1[i] = pV6->rf_ramp_param_constant_down[8];
    }
    
    for( i=0;i<11;i++ )
    {
        pV5->RF_ramp_up_table_stage0[i+5] = pV6->RF_ramp_table.stage8[i];
        pV5->RF_ramp_up_table_stage1[i+5] = pV6->RF_ramp_table.stage0[i];
    }

    for( i=0;i<9;i++ )
    {
        pV5->RF_ramp_down_table_stage0[i] = pV6->RF_ramp_table.stage8[i+11];
        pV5->RF_ramp_down_table_stage1[i] = pV6->RF_ramp_table.stage0[i+11];
    }
}

void Ver6To5_RF_param_band_DSP_use_T_M( calibration_struct_v5_m::RF_param_band_DSP_use_T* pV5,
                                     calibration_struct_v6_m::RF_param_band_DSP_use_T* pV6
                                     )
{
    BYTE* p1 = (BYTE*)&( pV6->TX_compensate_boundary_arfcn_index );
    BYTE* p2 = (BYTE*)&( pV6->RF_ramp_delta_timing );
    
    memcpy( &(pV5->TX_compensate_boundary_arfcn_index),&(pV6->TX_compensate_boundary_arfcn_index),p2 - p1 );//lint !e422
    
    p1 = (BYTE*)&( pV6->RF_ramp_PA_power_on_duration );
    p2 = (BYTE*)&( pV6->RF_ramp_table );
    memcpy( &(pV5->RF_ramp_PA_power_on_duration),&(pV6->RF_ramp_PA_power_on_duration),p2 - p1 );//lint !e422
    
    for( int i=0;i<5;i++ )
    {
        pV5->RF_ramp_up_table_stage0[i] = pV6->rf_ramp_param_constant_up[0];
        pV5->RF_ramp_up_table_stage1[i] = pV6->rf_ramp_param_constant_up[8];
    }
    
    for( i=9;i<16;i++ )
    {
        pV5->RF_ramp_down_table_stage0[i] = pV6->rf_ramp_param_constant_down[0];
        pV5->RF_ramp_down_table_stage1[i] = pV6->rf_ramp_param_constant_down[8];
    }
    
    for( i=0;i<11;i++ )
    {
        pV5->RF_ramp_up_table_stage0[i+5] = pV6->RF_ramp_table.stage8[i];
        pV5->RF_ramp_up_table_stage1[i+5] = pV6->RF_ramp_table.stage0[i];
    }
    
    for( i=0;i<9;i++ )
    {
        pV5->RF_ramp_down_table_stage0[i] = pV6->RF_ramp_table.stage8[i+11];
        pV5->RF_ramp_down_table_stage1[i] = pV6->RF_ramp_table.stage0[i+11];
    }
}

void Ver5To6( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    calibration_struct_v6::calibration_param_T* lp_para_v6 = (calibration_struct_v6::calibration_param_T*)(pSrc + dwOffsetFile);
    calibration_struct_v5::calibration_param_T* lp_para_v5 = (calibration_struct_v5::calibration_param_T*)(lpReadBuffer+dwOffset);

    memcpy( &(lp_para_v6->rf_param_dsp_use.rf_common_param_dsp_use),&(lp_para_v5->rf_param_dsp_use.rf_common_param_dsp_use),sizeof( lp_para_v6->rf_param_dsp_use.rf_common_param_dsp_use ) );
    BYTE* p1 = (BYTE*)&(lp_para_v6->adc.reserved[7]);
    BYTE* p2 = (BYTE*)&(lp_para_v6->rf_param_mcu_use);

    memcpy( &(lp_para_v6->rf_param_mcu_use),&(lp_para_v5->rf_param_mcu_use),p1 - p2 + 2 );

    Ver5To6_RF_param_band_DSP_use_T( &lp_para_v6->rf_param_dsp_use.rf_gsm_param_dsp_use,&lp_para_v5->rf_param_dsp_use.rf_gsm_param_dsp_use );
    Ver5To6_RF_param_band_DSP_use_T( &lp_para_v6->rf_param_dsp_use.rf_dcs_param_dsp_use,&lp_para_v5->rf_param_dsp_use.rf_dcs_param_dsp_use );
    Ver5To6_RF_param_band_DSP_use_T( &lp_para_v6->rf_param_dsp_use.rf_pcs_param_dsp_use,&lp_para_v5->rf_param_dsp_use.rf_pcs_param_dsp_use );
    Ver5To6_RF_param_band_DSP_use_T( &lp_para_v6->rf_param_dsp_use.rf_gsm850_param_dsp_use,&lp_para_v5->rf_param_dsp_use.rf_gsm850_param_dsp_use );
}

void Ver5To6M( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    calibration_struct_v6_m::calibration_param_T* lp_para_v6 = (calibration_struct_v6_m::calibration_param_T*)(pSrc + dwOffsetFile);
    calibration_struct_v5_m::calibration_param_T* lp_para_v5 = (calibration_struct_v5_m::calibration_param_T*)(lpReadBuffer+dwOffset);
    
    memcpy( &(lp_para_v6->rf_param_dsp_use.rf_common_param_dsp_use),&(lp_para_v5->rf_param_dsp_use.rf_common_param_dsp_use),sizeof( lp_para_v6->rf_param_dsp_use.rf_common_param_dsp_use ) );
    BYTE* p1 = (BYTE*)&(lp_para_v6->adc.reserved[7]);
    BYTE* p2 = (BYTE*)&(lp_para_v6->rf_param_mcu_use);
    
    memcpy( &(lp_para_v6->rf_param_mcu_use),&(lp_para_v5->rf_param_mcu_use),p1 - p2 + 2 );
    
    Ver5To6_RF_param_band_DSP_use_T_M( &lp_para_v6->rf_param_dsp_use.rf_gsm_param_dsp_use,&lp_para_v5->rf_param_dsp_use.rf_gsm_param_dsp_use );
    Ver5To6_RF_param_band_DSP_use_T_M( &lp_para_v6->rf_param_dsp_use.rf_dcs_param_dsp_use,&lp_para_v5->rf_param_dsp_use.rf_dcs_param_dsp_use );
    Ver5To6_RF_param_band_DSP_use_T_M( &lp_para_v6->rf_param_dsp_use.rf_pcs_param_dsp_use,&lp_para_v5->rf_param_dsp_use.rf_pcs_param_dsp_use );
    Ver5To6_RF_param_band_DSP_use_T_M( &lp_para_v6->rf_param_dsp_use.rf_gsm850_param_dsp_use,&lp_para_v5->rf_param_dsp_use.rf_gsm850_param_dsp_use );
}

void Ver6To5( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    calibration_struct_v5::calibration_param_T* lp_para_v5 = (calibration_struct_v5::calibration_param_T*)(pSrc + dwOffsetFile);
    calibration_struct_v6::calibration_param_T* lp_para_v6 = (calibration_struct_v6::calibration_param_T*)(lpReadBuffer+dwOffset);
    
    memcpy( &(lp_para_v5->rf_param_dsp_use.rf_common_param_dsp_use),&(lp_para_v6->rf_param_dsp_use.rf_common_param_dsp_use),sizeof( lp_para_v5->rf_param_dsp_use.rf_common_param_dsp_use ) );

    BYTE* p1 = (BYTE*)&(lp_para_v6->adc.reserved[7]);
    BYTE* p2 = (BYTE*)&(lp_para_v6->rf_param_mcu_use);
    
    memcpy( &(lp_para_v5->rf_param_mcu_use),&(lp_para_v6->rf_param_mcu_use),p1 - p2 + 2 );
    
    Ver6To5_RF_param_band_DSP_use_T( &lp_para_v5->rf_param_dsp_use.rf_gsm_param_dsp_use,&lp_para_v6->rf_param_dsp_use.rf_gsm_param_dsp_use );
    Ver6To5_RF_param_band_DSP_use_T( &lp_para_v5->rf_param_dsp_use.rf_dcs_param_dsp_use,&lp_para_v6->rf_param_dsp_use.rf_dcs_param_dsp_use );
    Ver6To5_RF_param_band_DSP_use_T( &lp_para_v5->rf_param_dsp_use.rf_pcs_param_dsp_use,&lp_para_v6->rf_param_dsp_use.rf_pcs_param_dsp_use );
    Ver6To5_RF_param_band_DSP_use_T( &lp_para_v5->rf_param_dsp_use.rf_gsm850_param_dsp_use,&lp_para_v6->rf_param_dsp_use.rf_gsm850_param_dsp_use );
}

void Ver6To5M( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    calibration_struct_v5_m::calibration_param_T* lp_para_v5 = (calibration_struct_v5_m::calibration_param_T*)(pSrc + dwOffsetFile);
    calibration_struct_v6_m::calibration_param_T* lp_para_v6 = (calibration_struct_v6_m::calibration_param_T*)(lpReadBuffer+dwOffset);
    
    memcpy( &(lp_para_v5->rf_param_dsp_use.rf_common_param_dsp_use),&(lp_para_v6->rf_param_dsp_use.rf_common_param_dsp_use),sizeof( lp_para_v5->rf_param_dsp_use.rf_common_param_dsp_use ) );
    
    BYTE* p1 = (BYTE*)&(lp_para_v6->adc.reserved[7]);
    BYTE* p2 = (BYTE*)&(lp_para_v6->rf_param_mcu_use);
    
    memcpy( &(lp_para_v5->rf_param_mcu_use),&(lp_para_v6->rf_param_mcu_use),p1 - p2 + 2 );
    
    Ver6To5_RF_param_band_DSP_use_T_M( &lp_para_v5->rf_param_dsp_use.rf_gsm_param_dsp_use,&lp_para_v6->rf_param_dsp_use.rf_gsm_param_dsp_use );
    Ver6To5_RF_param_band_DSP_use_T_M( &lp_para_v5->rf_param_dsp_use.rf_dcs_param_dsp_use,&lp_para_v6->rf_param_dsp_use.rf_dcs_param_dsp_use );
    Ver6To5_RF_param_band_DSP_use_T_M( &lp_para_v5->rf_param_dsp_use.rf_pcs_param_dsp_use,&lp_para_v6->rf_param_dsp_use.rf_pcs_param_dsp_use );
    Ver6To5_RF_param_band_DSP_use_T_M( &lp_para_v5->rf_param_dsp_use.rf_gsm850_param_dsp_use,&lp_para_v6->rf_param_dsp_use.rf_gsm850_param_dsp_use );
}

void Ver9To9( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    calibration_struct_v9::calibration_param_T para,para_file;
    memcpy( &para,lpReadBuffer+dwOffset,sizeof( para ) );
    memcpy( &para_file,pSrc+dwOffsetFile,sizeof( para_file ) );
    
    for( int i=0;i<calibration_struct_v6::NUM_TX_LEVEL;i++ )
    {
        para.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_delta_timing[i];
    }
    
    memcpy( pSrc + dwOffsetFile,&para,sizeof( para ) );
}

void Ver9To6( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    calibration_struct_v9::calibration_param_T para;
    calibration_struct_v6_m::calibration_param_T para_file;

    memcpy( &para,lpReadBuffer+dwOffset,sizeof( para ) );
    memcpy( &para_file,pSrc+dwOffsetFile,sizeof( para_file ) );
    
    for( int i=0;i<calibration_struct_v6::NUM_TX_LEVEL;i++ )
    {
        para.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_delta_timing[i];
    }
    
    memcpy( &(para_file.rf_param_dsp_use.rf_common_param_dsp_use.rf_aero1_afc_struct),
        &(para.rf_param_dsp_use.rf_common_param_dsp_use.rf_aero1_afc_struct),
        (LPBYTE)&(para.misc_cal_mcu_use) - (LPBYTE)&(para.rf_param_dsp_use.rf_common_param_dsp_use.rf_aero1_afc_struct)
        );
    
    memcpy( &( para_file.misc_cal_mcu_use ),
        &( para.misc_cal_mcu_use ),
        sizeof( para ) - ( (LPBYTE)&(para.misc_cal_mcu_use) - (LPBYTE)&( para ) ) 
        );
    
    /*
    memcpy( &(para_file.rf_param_dsp_use.rf_common_param_dsp_use.rf_aero1_afc_struct),
            &(para.rf_param_dsp_use.rf_common_param_dsp_use.rf_aero1_afc_struct ),
            sizeof( para ) - sizeof( para.calibration_param_version ) 
          );
    */
        
    memcpy( pSrc + dwOffsetFile ,
            &para_file,
            sizeof( para_file )
          );
}

void Ver6To9( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    calibration_struct_v9::calibration_param_T para_file;
    calibration_struct_v6_m::calibration_param_T para;
    
    memcpy( &para,lpReadBuffer+dwOffset,sizeof( para ) );
    memcpy( &para_file,pSrc+dwOffsetFile,sizeof( para_file ) );
    
    for( int i=0;i<calibration_struct_v6::NUM_TX_LEVEL;i++ )
    {
        para.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_delta_timing[i];
    }

    memcpy( &(para_file.rf_param_dsp_use.rf_common_param_dsp_use.rf_aero1_afc_struct),
            &(para.rf_param_dsp_use.rf_common_param_dsp_use.rf_aero1_afc_struct),
            (LPBYTE)&(para_file.misc_cal_mcu_use) - (LPBYTE)&(para_file.rf_param_dsp_use.rf_common_param_dsp_use.rf_aero1_afc_struct)
          );

    memcpy( &( para_file.misc_cal_mcu_use ),
            &( para.misc_cal_mcu_use ),
            sizeof( para_file ) - ( (LPBYTE)&(para_file.misc_cal_mcu_use) - (LPBYTE)&( para_file ) ) 
          );

/*
    memcpy( &(para_file.rf_param_dsp_use.rf_common_param_dsp_use.rf_aero1_afc_struct),
            &(para.rf_param_dsp_use.rf_common_param_dsp_use.rf_aero1_afc_struct),
            sizeof( para_file ) - sizeof( para_file.calibration_param_version )
          );
*/    
    memcpy( pSrc + dwOffsetFile,
        &para_file,
        sizeof( para_file )
        );
}

void VeraToa( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    calibration_struct_va::calibration_param_T para,para_file;
    memcpy( &para,lpReadBuffer+dwOffset,sizeof( para ) );
    memcpy( &para_file,pSrc+dwOffsetFile,sizeof( para_file ) );
    
    for( int i=0;i<calibration_struct_va::NUM_TX_LEVEL;i++ )
    {
        para.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_delta_timing[i];
    }
    
    memcpy( pSrc + dwOffsetFile,&para,sizeof( para ) );
}

void Ver9Toa( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    calibration_struct_va::calibration_param_T para_file;
    calibration_struct_v9::calibration_param_T para;

    memcpy( &para,lpReadBuffer+dwOffset,sizeof( para ) );
    memcpy( &para_file,pSrc+dwOffsetFile,sizeof( para_file ) );

    memcpy( &(para_file.rf_param_dsp_use),
            &(para.rf_param_dsp_use),
            (BYTE*)&(para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.RX_compensate_value)-(BYTE*)&(para_file.rf_param_dsp_use) ); //lint !e420

    memcpy( &(para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_table),
            &(para.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_table),
            (BYTE*)&(para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.RX_compensate_value)-(BYTE*)&(para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_table) );

    memcpy( &(para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_table),
        &(para.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_table),
        (BYTE*)&(para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.RX_compensate_value)-(BYTE*)&(para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_table) );
    
    memcpy( &(para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_table),
        &(para.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_table),
        (BYTE*)&(para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.RX_compensate_value)-(BYTE*)&(para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_table) );
    
    memcpy( &(para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_table),
        &(para.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_table),
        (BYTE*)&(para_file.adc.reserved[7])-(BYTE*)&(para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_table) + 4);
    
    memcpy( pSrc + dwOffsetFile,&para_file,sizeof( para_file ) );
}

void VeraTo9( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    calibration_struct_v9::calibration_param_T para_file;
    calibration_struct_va::calibration_param_T para;
    
    memcpy( &para,lpReadBuffer+dwOffset,sizeof( para ) );
    memcpy( &para_file,pSrc+dwOffsetFile,sizeof( para_file ) );
    
    memcpy( &(para_file.rf_param_dsp_use),
        &(para.rf_param_dsp_use),
        (BYTE*)&(para.rf_param_dsp_use.rf_gsm_param_dsp_use.RX_compensate_value)-(BYTE*)&(para.rf_param_dsp_use) );
    
    memcpy( &(para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_table),
        &(para.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_table),
        (BYTE*)&(para.rf_param_dsp_use.rf_dcs_param_dsp_use.RX_compensate_value)-(BYTE*)&(para.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_table) );
    
    memcpy( &(para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_table),
        &(para.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_table),
        (BYTE*)&(para.rf_param_dsp_use.rf_pcs_param_dsp_use.RX_compensate_value)-(BYTE*)&(para.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_table) );
    
    memcpy( &(para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_table),
        &(para.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_table),
        (BYTE*)&(para.rf_param_dsp_use.rf_gsm850_param_dsp_use.RX_compensate_value)-(BYTE*)&(para.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_table) );
    
    memcpy( &(para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_table),
        &(para.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_table),
        (BYTE*)&(para.adc.reserved[7])-(BYTE*)&(para.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_table) + 4);
    
    memcpy( pSrc + dwOffsetFile,&para_file,sizeof( para_file ) );
}

void Ver7To7( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    calibration_struct_v7::calibration_param_T para,para_file;
    memcpy( &para,lpReadBuffer+dwOffset,sizeof( para ) );
    memcpy( &para_file,pSrc+dwOffsetFile,sizeof( para_file ) );
    
    for( int i=0;i<calibration_struct_v7::NUM_TX_LEVEL;i++ )
    {
        para.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_delta_timing[i];
        para.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_delta_timing[i] = para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_delta_timing[i];
    }
    
    memcpy( pSrc + dwOffsetFile,&para,sizeof( para ) );
}

void Ver6To7( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    calibration_struct_v7::calibration_param_T para_file;
    calibration_struct_v6::calibration_param_T para;
    
    memcpy( &para,lpReadBuffer+dwOffset,sizeof( para ) );
    memcpy( &para_file,pSrc+dwOffsetFile,sizeof( para_file ) );
    
    memcpy( &(para_file.rf_param_dsp_use),
        &(para.rf_param_dsp_use),
        (BYTE*)&(para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.RX_compensate_value)-(BYTE*)&(para_file.rf_param_dsp_use) );//lint !e420
    
    memcpy( &(para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_table),
        &(para.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_table),
        (BYTE*)&(para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.RX_compensate_value)-(BYTE*)&(para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_table) );
    
    memcpy( &(para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_table),
        &(para.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_table),
        (BYTE*)&(para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.RX_compensate_value)-(BYTE*)&(para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_table) );
    
    memcpy( &(para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_table),
        &(para.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_table),
        (BYTE*)&(para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.RX_compensate_value)-(BYTE*)&(para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_table) );
    
    memcpy( &(para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_table),
        &(para.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_table),
        (BYTE*)&(para_file.adc.reserved[7])-(BYTE*)&(para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_table) + 4);
    
    memcpy( pSrc + dwOffsetFile,&para_file,sizeof( para_file ) );
}

void Ver7To6( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    calibration_struct_v6::calibration_param_T para_file;
    calibration_struct_v7::calibration_param_T para;
    
    memcpy( &para,lpReadBuffer+dwOffset,sizeof( para ) );
    memcpy( &para_file,pSrc+dwOffsetFile,sizeof( para_file ) );
    
    memcpy( &(para_file.rf_param_dsp_use),
        &(para.rf_param_dsp_use),
        (BYTE*)&(para.rf_param_dsp_use.rf_gsm_param_dsp_use.RX_compensate_value)-(BYTE*)&(para.rf_param_dsp_use) );
    
    memcpy( &(para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_table),
        &(para.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_table),
        (BYTE*)&(para.rf_param_dsp_use.rf_dcs_param_dsp_use.RX_compensate_value)-(BYTE*)&(para.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_table) );
    
    memcpy( &(para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_table),
        &(para.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_table),
        (BYTE*)&(para.rf_param_dsp_use.rf_pcs_param_dsp_use.RX_compensate_value)-(BYTE*)&(para.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_table) );
    
    memcpy( &(para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_table),
        &(para.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_table),
        (BYTE*)&(para.rf_param_dsp_use.rf_gsm850_param_dsp_use.RX_compensate_value)-(BYTE*)&(para.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_table) );
    
    memcpy( &(para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_table),
        &(para.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_table),
        (BYTE*)&(para.adc.reserved[7])-(BYTE*)&(para.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_table) + 4);
    
    memcpy( pSrc + dwOffsetFile,&para_file,sizeof( para_file ) );
}
void Ver7To5( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    calibration_struct_v5::calibration_param_T para_file;
    calibration_struct_v7::calibration_param_T para;
    
    memcpy( &para,lpReadBuffer+dwOffset,sizeof( para ) );
    memcpy( &para_file,pSrc+dwOffsetFile,sizeof( para_file ) );
    
    memcpy( &(para_file.rf_param_dsp_use),
        &(para.rf_param_dsp_use),
        (BYTE*)&(para.rf_param_dsp_use.rf_gsm_param_dsp_use.RX_compensate_value)-(BYTE*)&(para.rf_param_dsp_use) );
    
    memcpy( &(para_file.rf_param_dsp_use.rf_dcs_param_dsp_use),
        &(para.rf_param_dsp_use.rf_dcs_param_dsp_use),
        (BYTE*)&(para.rf_param_dsp_use.rf_dcs_param_dsp_use.RX_compensate_value)-(BYTE*)&(para.rf_param_dsp_use.rf_dcs_param_dsp_use) );
    
    memcpy( &(para_file.rf_param_dsp_use.rf_pcs_param_dsp_use),
        &(para.rf_param_dsp_use.rf_pcs_param_dsp_use),
        (BYTE*)&(para.rf_param_dsp_use.rf_pcs_param_dsp_use.RX_compensate_value)-(BYTE*)&(para.rf_param_dsp_use.rf_pcs_param_dsp_use) );
    
    memcpy( &(para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use),
        &(para.rf_param_dsp_use.rf_gsm850_param_dsp_use),
        (BYTE*)&(para.rf_param_dsp_use.rf_gsm850_param_dsp_use.RX_compensate_value)-(BYTE*)&(para.rf_param_dsp_use.rf_gsm850_param_dsp_use) );
    
    memcpy( &(para_file.rf_param_mcu_use),
        &(para.rf_param_mcu_use),
        (BYTE*)&(para.adc.reserved[7])-(BYTE*)&(para.rf_param_mcu_use) + 4);
    
    memcpy( pSrc + dwOffsetFile,&para_file,sizeof( para_file ) );
}
DWORD  PreserveCalibration( LPBYTE lpCode, DWORD dwCodeSize, 
                         LPBYTE lpReadBuffer, DWORD dwReadSize,
                         BOOL bOldReplaceNew , BOOL bContinue )
{
    DWORD dwOffsetFile,dwLengthFile;
    BYTE* pSrc = lpCode;

    if(!FindNVOffset( NV_L1_CALIBRATION_PARAMETER,
                    pSrc,dwCodeSize,dwOffsetFile,dwLengthFile))
    {
        return ERR_NOT_FIND_PARAM_IN_FILE;
    }

    int wVerFile = *(pSrc + dwOffsetFile);
    wVerFile = wVerFile << 8;
    wVerFile += *(pSrc + dwOffsetFile + 1);

    // Find calibration
    DWORD dwOffset,dwLength;
    if(!FindNVOffset(NV_L1_CALIBRATION_PARAMETER,
                    lpReadBuffer,dwReadSize,dwOffset,dwLength)  )
    {
        if( bContinue )
        {
            return 0;
        }
        else
        {
            return ERR_NOT_FIND_PARAM_IN_MODULE;
        }
    }

    int wVer = (*(lpReadBuffer + dwOffset)<< 8) + *(lpReadBuffer + dwOffset + 1);
    DWORD OFFSET_AFX_SLOPE_HZ_PER_6BITS_900M = 0;
    DWORD OFFSET_RF_RAMPPWR_STEP_FACTOR_GSM = 0;
    DWORD OFFSET_RF_RAMPPWR_STEP_FACTOR_DCS = 0;

#define VER0            0x2903
#define VER1            0xff01
//@ Liu kai 2004-4-27 CR9004
#define VER2            0xff02
//@ Liu Kai 2004-11-17 CR16686
#define VER3            0xff03
//@ Liu Kai 2005-4-13 CR21463
#define VER4            0xff04
//@ Liu Kai 2005-6-23   CF26981
#define VER5            0xff05

#define VER6            0xff06

#define VER9            0xff09
    
#define VERA            0xff0a

#define VER7            0xff07
    
#define DEFAULT_LENGTH   0x390

#define DEFAULT_OFFSET_AFX_SLOPE_HZ_PER_6BITS_900M  0x1c8
#define DEFAULT_OFFSET_RF_RAMPPWR_STEP_FACTOR_GSM   0x82
#define DEFAULT_OFFSET_RF_RAMPPWR_STEP_FACTOR_DCS   0x162
#define NV_PRESERVE_OFFSET      0x2

    BOOL bAdjust = FALSE;

    if(wVer == VER0)
    {
        OFFSET_AFX_SLOPE_HZ_PER_6BITS_900M = DEFAULT_OFFSET_AFX_SLOPE_HZ_PER_6BITS_900M;
        OFFSET_RF_RAMPPWR_STEP_FACTOR_GSM = DEFAULT_OFFSET_RF_RAMPPWR_STEP_FACTOR_GSM;
        OFFSET_RF_RAMPPWR_STEP_FACTOR_DCS = DEFAULT_OFFSET_RF_RAMPPWR_STEP_FACTOR_DCS;
        bAdjust = TRUE;
    }
    else if(dwLength <= DEFAULT_LENGTH - 2)
    {
        // No version field
        OFFSET_AFX_SLOPE_HZ_PER_6BITS_900M = DEFAULT_OFFSET_AFX_SLOPE_HZ_PER_6BITS_900M - 2;
        OFFSET_RF_RAMPPWR_STEP_FACTOR_GSM = DEFAULT_OFFSET_RF_RAMPPWR_STEP_FACTOR_GSM - 2;
        OFFSET_RF_RAMPPWR_STEP_FACTOR_DCS = DEFAULT_OFFSET_RF_RAMPPWR_STEP_FACTOR_DCS - 2;
        bAdjust = TRUE;
    }

    // Preprocess nv parameters in module
    if(bAdjust)
    {
        // Check value of item afx_slope_hz_per_6bits_900M
        // the offset of this item is 0x1c8
        // If the value is not between 1600 and 2000,then change
        // it to 1800
#define MIN_AFX_SLOPE_HZ_PER_6BITS_900M     1600
#define MAX_AFX_SLOPE_HZ_PER_6BITS_900M     2000
#define DEF_AFX_SLOPE_HZ_PER_6BITS_900M     1800
        int dValue = (lpReadBuffer[dwOffset + OFFSET_AFX_SLOPE_HZ_PER_6BITS_900M] << 8) 
            + lpReadBuffer[dwOffset + OFFSET_AFX_SLOPE_HZ_PER_6BITS_900M + 1];
        if(dValue < MIN_AFX_SLOPE_HZ_PER_6BITS_900M || 
            dValue > MAX_AFX_SLOPE_HZ_PER_6BITS_900M)
        {
            lpReadBuffer[dwOffset + OFFSET_AFX_SLOPE_HZ_PER_6BITS_900M] = (DEF_AFX_SLOPE_HZ_PER_6BITS_900M >> 8);
            lpReadBuffer[dwOffset + OFFSET_AFX_SLOPE_HZ_PER_6BITS_900M + 1] = DEF_AFX_SLOPE_HZ_PER_6BITS_900M % 256;
        }
        
        //Check the difference of item rf_param_dsp_use.RF_ramppwr_step_factor_GSM[8],[9]
        //if the diffrence is less than 
        //then set the value of the rf_param_dsp_use.RF_ramppwr_step_factor_GSM[9] to the average
        //of the rf_param_dsp_use.RF_ramppwr_step_factor_GSM[8], [10]
#define DIFF_RF_RAMPPWR_STEP_FACTOR_GSM     0x100
        
        int dStepFactorGSM8 = (lpReadBuffer[dwOffset + OFFSET_RF_RAMPPWR_STEP_FACTOR_GSM + sizeof(USHORT) * 8] << 8) 
            + lpReadBuffer[dwOffset + OFFSET_RF_RAMPPWR_STEP_FACTOR_GSM + sizeof(USHORT) * 8 + 1];
        
        int dStepFactorGSM9 = (lpReadBuffer[dwOffset + OFFSET_RF_RAMPPWR_STEP_FACTOR_GSM + sizeof(USHORT) * 9] << 8) 
            + lpReadBuffer[dwOffset + OFFSET_RF_RAMPPWR_STEP_FACTOR_GSM + sizeof(USHORT) * 9 + 1];
        
        int dStepFactorGSM10 = (lpReadBuffer[dwOffset + OFFSET_RF_RAMPPWR_STEP_FACTOR_GSM + sizeof(USHORT) * 10] << 8) 
            + lpReadBuffer[dwOffset + OFFSET_RF_RAMPPWR_STEP_FACTOR_GSM + sizeof(USHORT) * 10 + 1];
        
        if(DIFF_RF_RAMPPWR_STEP_FACTOR_GSM > (dStepFactorGSM8 - dStepFactorGSM9))
        {
            dStepFactorGSM9 = (dStepFactorGSM8 + dStepFactorGSM10) / 2;
            
            lpReadBuffer[dwOffset + OFFSET_RF_RAMPPWR_STEP_FACTOR_GSM + sizeof(USHORT) * 9] = (BYTE)(dStepFactorGSM9 >> 8);
            lpReadBuffer[dwOffset + OFFSET_RF_RAMPPWR_STEP_FACTOR_GSM + sizeof(USHORT) * 9 + 1] = (BYTE)(dStepFactorGSM9 % 256);
        }
        
        //Check the difference of item rf_param_dsp_use.RF_ramppwr_step_factor_DCS[7],[8]
        //if the diffrence is less than 
        //then set the value of the rf_param_dsp_use.RF_ramppwr_step_factor_DCS[8] to the average
        //of the rf_param_dsp_use.RF_ramppwr_step_factor_DCS[7], [9]
#define DIFF_RF_RAMPPWR_STEP_FACTOR_DCS     0x100
        
        int dStepFactorDCS7 = (lpReadBuffer[dwOffset + OFFSET_RF_RAMPPWR_STEP_FACTOR_DCS + sizeof(USHORT) * 7] << 8) 
            + lpReadBuffer[dwOffset + OFFSET_RF_RAMPPWR_STEP_FACTOR_DCS + sizeof(USHORT) * 7 + 1];
        
        int dStepFactorDCS8 = (lpReadBuffer[dwOffset + OFFSET_RF_RAMPPWR_STEP_FACTOR_DCS + sizeof(USHORT) * 8] << 8) 
            + lpReadBuffer[dwOffset + OFFSET_RF_RAMPPWR_STEP_FACTOR_DCS + sizeof(USHORT) * 8 + 1];
        
        int dStepFactorDCS9 = (lpReadBuffer[dwOffset + OFFSET_RF_RAMPPWR_STEP_FACTOR_DCS + sizeof(USHORT) * 9] << 8) 
            + lpReadBuffer[dwOffset + OFFSET_RF_RAMPPWR_STEP_FACTOR_DCS + sizeof(USHORT) * 9 + 1];
        
        if(DIFF_RF_RAMPPWR_STEP_FACTOR_DCS > (dStepFactorDCS7 - dStepFactorDCS8))
        {
            dStepFactorDCS8 = (dStepFactorDCS7 + dStepFactorDCS9) / 2;
            
            lpReadBuffer[dwOffset + OFFSET_RF_RAMPPWR_STEP_FACTOR_DCS + sizeof(USHORT) * 8] = (BYTE)(dStepFactorDCS8 >> 8);
            lpReadBuffer[dwOffset + OFFSET_RF_RAMPPWR_STEP_FACTOR_DCS + sizeof(USHORT) * 8 + 1] = (BYTE)(dStepFactorDCS8 % 256);
        }
    }

    if( VERA == wVerFile )
    {
        if( dwLengthFile != sizeof( calibration_struct_va::calibration_param_T ) )
        {
            return ERR_PARAM_LEN_NOT_MATCH;
        }

        if( VERA == wVer )
        {
            if( dwLength != dwLengthFile )
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
            
            VeraToa( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
        }
        else if( VER9 == wVer )
        {
            if( dwLength != sizeof( calibration_struct_v9::calibration_param_T ) )
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
            Ver9Toa( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
        }
    }
    else if( VER7 == wVerFile )
    {
        if( dwLengthFile != sizeof( calibration_struct_v7::calibration_param_T ) )
        {
            return ERR_PARAM_LEN_NOT_MATCH;
        }

        if( VER7 == wVer )
        {
            if( dwLength != dwLengthFile )
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
            
            if( dwLength == sizeof( calibration_struct_v7::calibration_param_T ) )
            {
                Ver7To7( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
        }
        else if( VER6 == wVer )
        {
            if( dwLength == sizeof( calibration_struct_v6::calibration_param_T ) )
            {
                Ver6To7( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
        }        
    }
    else if( VER9 == wVerFile )
    {
        if( dwLengthFile != sizeof( calibration_struct_v9::calibration_param_T ) )
        {
            return ERR_PARAM_LEN_NOT_MATCH;
        }

        if( VERA == wVer )
        {
            if( !bOldReplaceNew )
            {
                return ERR_OLD_VERSION;
            }

            VeraTo9( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );                
        }
        else if( VER9 == wVer )
        {
            if( dwLength != dwLengthFile )
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }

            if( dwLength == sizeof( calibration_struct_v9::calibration_param_T ) )
            {
                Ver9To9( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
        }
        /*
        else if( VER6 == wVer )
        {
            if( dwLength == sizeof( calibration_struct_v6_m::calibration_param_T ) )
            {
                Ver6To9( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
        }
        */
        else
        {
            return ERR_UNKNOWN_VER_IN_MODULE;
        }
    }
    else if( VER6 == wVerFile )
    {
        /*
        if( VER9 == wVer )
        {
            if( dwLength == sizeof( calibration_struct_v9::calibration_param_T ) )
            {
                Ver9To6( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
        }
        else*/
        if( VER7 == wVer )
        {
            if( dwLengthFile == sizeof( calibration_struct_v6::calibration_param_T ) )
            {
                Ver7To6( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else 
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
        }
        else if( VER6 == wVer )
        {
            if( dwLength != dwLengthFile )
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
            
            if( dwLength == sizeof( calibration_struct_v6::calibration_param_T ) )
            {
                Ver6To6( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else if( dwLength == sizeof( calibration_struct_v6_m::calibration_param_T ) )
            {
                Ver6To6M( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
        }
        else if( VER5 == wVer )
        {
            if( dwLengthFile == sizeof( calibration_struct_v6::calibration_param_T ) )
            {
                Ver5To6( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else if( dwLengthFile == sizeof( calibration_struct_v6_m::calibration_param_T ) )
            {
                Ver5To6M( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
        }
        else
        {
            return ERR_UNKNOWN_VER_IN_MODULE;
        }
    }
    else if( VER5 == wVerFile )
    {
        if( VER5 == wVer )
        {
            if( dwLength != dwLengthFile )
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }

            if( dwLength == sizeof( calibration_struct_v5::calibration_param_T ) )
            {
                Ver5To5( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else if( dwLength == sizeof( calibration_struct_v5_m::calibration_param_T ) )
            {
                Ver5To5M( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
        }
        else if( VER7 == wVer )
        {
            if( dwLength == sizeof( calibration_struct_v7::calibration_param_T ) )
            {
                Ver7To5( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
        }
        else if( VER6 == wVer )
        {
            if( dwLength == sizeof( calibration_struct_v6::calibration_param_T ) )
            {
                Ver6To5( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else if( dwLength == sizeof( calibration_struct_v6_m::calibration_param_T ) )
            {
                Ver6To5M( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
        }
        else if( VER4 == wVer )
        {
            Ver4To5( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );

            DWORD dwAdcOffset,dwAdcLength;
            if(!FindNVOffset( ADC_ITEM,lpReadBuffer,dwReadSize,dwAdcOffset,dwAdcLength))
            {
                return ERR_NOT_FIND_PARAM_IN_MODULE;
            }

            // Battery[0] = ( adc_table[14] << 16 ) + 4200
            // Battery[1] = ( adc_table[8] << 16 ) + 3600
            BYTE* pAdc = lpReadBuffer + dwAdcOffset;
            BYTE* pBattery = pSrc + dwLengthFile + dwOffsetFile - 40;
            unsigned long value = ( pAdc[38] << 24 ) + ( pAdc[39] << 16 ) + 4200;
            pBattery[0] = HIBYTE( HIWORD( value ) );
            pBattery[1] = LOBYTE( HIWORD( value ) );
            pBattery[2] = HIBYTE( LOWORD( value ) );
            pBattery[3] = LOBYTE( LOWORD( value ) );
            
            value = ( pAdc[26] << 24 ) + ( pAdc[27] << 16 ) + 3600;
            pBattery[4] = HIBYTE( HIWORD( value ) );
            pBattery[5] = LOBYTE( HIWORD( value ) );
            pBattery[6] = HIBYTE( LOWORD( value ) );
            pBattery[7] = LOBYTE( LOWORD( value ) );
        }
        else if( VER3 == wVer )
        {
            Ver3To5( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );

            DWORD dwAdcOffset,dwAdcLength;
            if(!FindNVOffset( ADC_ITEM,lpReadBuffer,dwReadSize,dwAdcOffset,dwAdcLength))
            {
                return ERR_NOT_FIND_PARAM_IN_MODULE;
            }
            
            // Battery[0] = ( adc_table[14] << 16 ) + 4200
            // Battery[1] = ( adc_table[8] << 16 ) + 3600
            BYTE* pAdc = lpReadBuffer + dwAdcOffset;
            BYTE* pBattery = pSrc + dwOffsetFile + dwLengthFile - 40;
            unsigned long value = ( pAdc[38] << 24 ) + ( pAdc[39] << 16 ) + 4200;
            pBattery[0] = HIBYTE( HIWORD( value ) );
            pBattery[1] = LOBYTE( HIWORD( value ) );
            pBattery[2] = HIBYTE( LOWORD( value ) );
            pBattery[3] = LOBYTE( LOWORD( value ) );
            
            value = ( pAdc[26] << 24 ) + ( pAdc[27] << 16 ) + 3600;
            pBattery[4] = HIBYTE( HIWORD( value ) );
            pBattery[5] = LOBYTE( HIWORD( value ) );
            pBattery[6] = HIBYTE( LOWORD( value ) );
            pBattery[7] = LOBYTE( LOWORD( value ) );
        }
        else
        {
            return ERR_UNKNOWN_VER_IN_MODULE;
        }
    }
    else if( VER4 == wVerFile )
    {
        if( VER5 == wVer )
        {
            if( bOldReplaceNew )
            {
                Ver5To4( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );

                // Preserve adc item for d chip
                PreserveNVItem( ADC_ITEM,(LPBYTE)lpCode,dwCodeSize,lpReadBuffer,dwReadSize );
                
                DWORD dwAdcOffset,dwAdcLength;
                if(!FindNVOffset( ADC_ITEM,pSrc,dwCodeSize,dwAdcOffset,dwAdcLength))
                {
                    return ERR_NOT_FIND_PARAM_IN_FILE;
                }

                // adc_table[i] = ( ( battery[0] & 0xFFFF0000 ) >> 16 ) + ( i - ( battery[0] & 0xFFFF ) - 2800 ) / 100 ) * 20
                // adc_table[15] = 0xFFFF;
                BYTE* pAdc = pSrc + dwAdcOffset + 10;
                BYTE* pBattery = lpReadBuffer + dwLength + dwOffset - 40;
                DWORD value1 = ( pBattery[0] << 8 ) + pBattery[1];
                DWORD value2 = ( ( pBattery[2] << 8 ) + pBattery[3] - 2800 ) / 100;

                for( int i=0;i<15;i++ )
                {
                    WORD value = (WORD)(value1 + ( i - value2 ) * 20);
                    pAdc[i*2] = HIBYTE( value );
                    pAdc[i*2+1] = LOBYTE( value );
                }
                pAdc[i*2] = 0xFF;
                pAdc[i*2+1] = 0xFF;                
            }
            else
            {
                return ERR_OLD_VERSION;
            }
        }
        else if( VER4 == wVer )
        {
            if( dwLength != dwLengthFile )
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }

            Ver4To4( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            // Preserve adc item for d chip
            PreserveNVItem( ADC_ITEM,(LPBYTE)lpCode,dwCodeSize,lpReadBuffer,dwReadSize );
        }
        else if( VER3 == wVer )
        {
            Ver3To4( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
        }
        else
        {
            return ERR_UNKNOWN_VER_IN_MODULE;
        }
    }
    else if( wVerFile == VER3 )
    {
        if( wVer == VER3 )
        {
            if( dwLength != dwLengthFile )
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
            
            Ver3To3( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
        }
        else if( VER4 == wVer )
        {
            if( bOldReplaceNew )
            {
                Ver4To3( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else
            {
                return ERR_OLD_VERSION;
            }
        }
        else if( VER5 == wVer )
        {
            if( bOldReplaceNew )
            {
                Ver5To3( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else
            {
                return ERR_OLD_VERSION;
            }
        }
        else if( wVer == VER2 )
        {
            Ver2To3( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
        }
        else if( wVer == VER1 )
        {
            Ver1To3( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
        }
        else
        {
            return ERR_UNKNOWN_VER_IN_MODULE;
        }
    }
    else if(wVerFile == VER2)
    {
        if(wVer == VER2)
        {
            if(dwLength != dwLengthFile)
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }

            Ver2To2( pSrc,dwOffsetFile,lpReadBuffer,dwOffset,dwLength );
        }
        else if(wVer == VER1)
        {
            Ver1To2( pSrc,dwOffsetFile,lpReadBuffer,dwOffset,dwLengthFile );
        }
        else
        {
            return ERR_UNKNOWN_VER_IN_MODULE;
        }
    }
    else if(wVerFile == VER1)
    {
        if(wVer == VER2)
        {
            if( bOldReplaceNew)
            {
                Ver2To1( pSrc,dwOffsetFile,lpReadBuffer,dwOffset,dwLength );
            }
            else
            {
                return ERR_OLD_VERSION;
            }
        }
        else if(wVer == VER1)
        {
            if(dwLength != dwLengthFile)
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }

            memcpy(pSrc + dwOffsetFile,lpReadBuffer + dwOffset,dwLength);
        }
        else if(wVer == VER0)
        {
            Ver0To1( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
        }
        else if( dwLength < DEFAULT_LENGTH)
        {
            // There is no version field in module
            int nOffset = dwOffset;
            // Skip version info
            int nOffsetFile = 2 + dwOffsetFile;
            
            // Preserve from start to end of RF_ramp_PA_power_on_duration_DCS
            memcpy(pSrc + nOffsetFile,lpReadBuffer+nOffset,0x1c0);
            nOffsetFile += 0x1c0;
            nOffset += 0x1c0;
            // skip items list below
            // RF_ramp_up_table_PCS_stage0[NUM_RAMP_POINTS];
            // RF_ramp_up_table_PCS_stage1[NUM_RAMP_POINTS];
            // RF_ramp_down_table_PCS_stage0[NUM_RAMP_POINTS];
            // RF_ramp_down_table_PCS_stage1[NUM_RAMP_POINTS];
            // RF_ramppwr_step_factor_PCS[NUM_TX_LEVEL];
            // RF_ramp_delta_timing_PCS[NUM_TX_LEVEL];
            // RF_ramp_PA_power_on_duration_PCS[NUM_TX_LEVEL];
            nOffsetFile += 0xe0;
            
            // Preserve from is_using_si4134 to afc_alg_bias_dcs
            memcpy(pSrc + nOffsetFile,lpReadBuffer+nOffset,0xc);
            nOffsetFile += 0xc;
            nOffset += 0xc;
            // Skip afc_alg_bias_pcs
            nOffsetFile += 0x2;
            
            // Preserve from  osci_temp_comp_in_dac to dcs_max_rf_gain_index
            memcpy(pSrc + nOffsetFile,lpReadBuffer+nOffset,0x17a);
            nOffsetFile += 0x17a;
            nOffset += 0x17a;
            // Skip agc_ctrl_word_PCS and pcs_max_rf_gain_index
            nOffsetFile += 0xb8;
            
            // Preserve ramp_switch_level_GSM and ramp_switch_level_DCS
            memcpy(pSrc + nOffsetFile,lpReadBuffer + nOffset,0x4);
            nOffsetFile += 0x4;
            nOffset += 0x4;
            // Skip ramp_switch_level_PCS
            nOffsetFile += 0x2;
            
            // Alignment 
            nOffsetFile += 2;
            nOffset += 2;
            
            // Preserve  rx_whole_band_comp_gsm and  rx_whole_band_comp_dcs
            memcpy(pSrc + nOffsetFile,lpReadBuffer + nOffset,0xe);
            nOffsetFile += 0xe;
            nOffset += 0xe;
            // Skip  rx_whole_band_comp_pcs
            nOffsetFile += 0x7;
            
            // Preserve from pa_GSM_temp_comp to pa_DCS_vcc_comp_step
            memcpy(pSrc + nOffsetFile,lpReadBuffer + nOffset,0x22);
            nOffsetFile += 0x22;
            nOffset += 0x22;
            // Skip pa_PCS_vcc_comp_threshold and pa_PCS_vcc_comp_step
            nOffsetFile += 0x2;
            
            // Alignment
            nOffsetFile += 0x3;
            
            // Preserve from Misc_cal_MCU_use_T to PM_VERSION
            memcpy(pSrc + nOffsetFile,lpReadBuffer + nOffset,0xe);
        }
        else
        {
            return ERR_UNKNOWN_VER_IN_MODULE;
        }
    }
    else if(wVerFile == VER0)
    {
        if(wVer == VER1)
        {
            if( bOldReplaceNew)
            {
                Ver1To0( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
            }
            else
            {
                return ERR_OLD_VERSION;
            }
        }
        else if( wVer == VER0)
        {
            if(dwLength == dwLengthFile)
            {
                memcpy(pSrc + dwOffsetFile,lpReadBuffer + dwOffset,dwLength);
            }
            else
            {
                return ERR_UNKNOWN_VER_IN_MODULE;
            }
        }
        else if( dwLength < DEFAULT_LENGTH )
        {
            memcpy(pSrc + dwOffsetFile + NV_PRESERVE_OFFSET,lpReadBuffer + dwOffset,dwLength);           
        }        
        else
        {
            return ERR_UNKNOWN_VER_IN_MODULE;
        }
    }
    else
    {
        if( wVerFile == wVer )
        {
            if( dwLengthFile == dwLength )
            {
                // Version and length are both equal,just do copying
                memcpy( pSrc + dwOffsetFile,lpReadBuffer + dwOffset,dwLength );
                return 0;
            }
            else
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
        }
        return ERR_UNKNOWN_VER_IN_FILE;
    }
                
    return 0;
}

BOOL PreserveIMEI(LPBYTE lpCode, DWORD dwCodeSize, 
                  LPBYTE lpReadBuffer, DWORD dwReadSize )
{
    DWORD dwOffsetFile,dwLengthFile;
    if(FindNVOffset(NV_IMEI,lpCode, dwCodeSize,dwOffsetFile,dwLengthFile))
    {
        // Find calibration
        DWORD dwOffset,dwLength;
        if(FindNVOffset(NV_IMEI,lpReadBuffer,dwReadSize,dwOffset,dwLength))
        {
            if(dwLength == dwLengthFile)
            {
                memcpy( lpCode + dwOffsetFile,
                       lpReadBuffer + dwOffset,
                       dwLength);

                return TRUE;
            }
        }
        else
        {
            return TRUE;
        }
    }

    return FALSE;    
}

//¹¤¾ßÔÚ¸üÐÂcodeÊ±»á¸ù¾ÝËùÏÂÔØµÄNVÎÄ¼þÖÐµÄ P ÖÐµÄÄÚÈÝÀ´ÒÀ´Î±£Áô¡£
//×¢Òâ£¬²»ÊÇÓÃÊÖ»úÖÐ P ÏîµÄÄÚÈÝ¡£×îºóÓÃÎÄ¼þÖÐµÄPÌæ»»ÊÖ»úÖÐµÄ¡£
//Ò²¾ÍÊÇËµP±¾Éí²»±£Áô¡£
#define  NV_MSD_DATA      401   

BOOL PreserveNV( LPBYTE lpCode, DWORD dwCodeSize, 
                LPBYTE lpReadBuffer, DWORD dwReadSize )
{
    DWORD dwOffsetFile,dwLengthFile;
    // Find P
    if(FindNVOffset( NV_MSD_DATA ,lpCode, dwCodeSize,dwOffsetFile,dwLengthFile))
    {
        WORD wID = 0;
        for( UINT i = 0; i < dwLengthFile * sizeof( BYTE ) / sizeof( WORD ); i += 2  )
        {
            wID = (WORD)((*(lpCode + dwOffsetFile + i )<< 8) + *(lpCode + dwOffsetFile + i + 1));
            if( !PreserveNVItem( wID, lpCode, dwCodeSize, lpReadBuffer, dwReadSize ) )
            {
                return FALSE;
            }
        }
        return TRUE;
    }
    
    return FALSE;  
}

BOOL PreserveNVItem( WORD wID, LPBYTE lpCode, DWORD dwCodeSize, 
                    LPBYTE lpReadBuffer, DWORD dwReadSize)
{
    //CalibrationÏî£¨IDÎª2£©ºÍIMEIÏî£¨IDÎª5£©½«ÈÔ°´Ä¿Ç°µÄ·½·¨´¦Àí£¬
    //¼´ÎÞÂÛËüÃÇµÄIDÔÚ²»ÔÚPÖÐ¶¼½«±»±£Áô£¬³ý·Ç¹¤¾ßÉèÖÃÎª²»±£Áô£¨ÄÚ²¿°æ£©¡£
    if( wID == NV_L1_CALIBRATION_PARAMETER || wID == NV_IMEI )
    {
        return TRUE;
    }
    
    DWORD dwOffsetFile,dwLengthFile;
    if(FindNVOffset( wID, lpCode, dwCodeSize,dwOffsetFile,dwLengthFile))
    {
        DWORD dwOffset,dwLength;
        if(FindNVOffset( wID, lpReadBuffer,dwReadSize,dwOffset,dwLength))
        {
            if(dwLength == dwLengthFile)
            {
                memcpy( lpCode + dwOffsetFile,
                    lpReadBuffer + dwOffset,
                    dwLength);
                
                return TRUE;
            }
            //else:Èç¹ûÔÚ±£Áô¹ý³ÌÖÐ·¢ÏÖÄ³Ò»ÏîÔÚÊÖ»úÖÐ
            //ºÍÎÄ¼þÖÐµÄ³¤¶È²»Ò»Ñù£¬Ôò²»Óè±£Áô£¬Ö±½ÓÓÃÎÄ¼þÖÐµÄÌæ»»¡£
        }
        else
        {
            return TRUE;
        }
    }
    
    return FALSE;    
}

//BOOL PreserveBT( WORD wID, LPBYTE lpCode, DWORD dwCodeSize, 
//                    LPBYTE lpReadBuffer, DWORD dwReadSize,BOOL bContinue /* =FALSE */)
//{
//    //CalibrationÏî£¨IDÎª2£©ºÍIMEIÏî£¨IDÎª5£©½«ÈÔ°´Ä¿Ç°µÄ·½·¨´¦Àí£¬
//    //¼´ÎÞÂÛËüÃÇµÄIDÔÚ²»ÔÚPÖÐ¶¼½«±»±£Áô£¬³ý·Ç¹¤¾ßÉèÖÃÎª²»±£Áô£¨ÄÚ²¿°æ£©¡£
// //   if( wID == NV_L1_CALIBRATION_PARAMETER || wID == NV_IMEI )
//    //    {
//    //        return TRUE;
//    //    }
//    
//    DWORD dwOffsetFile,dwLengthFile;
//    if(FindNVOffset( wID, lpCode, dwCodeSize,dwOffsetFile,dwLengthFile))
//    {
//        DWORD dwOffset,dwLength;
//        if(FindNVOffset( wID, lpReadBuffer,dwReadSize,dwOffset,dwLength))
//        {
//            if(dwLength == dwLengthFile)
//            {
//                memcpy( lpCode + dwOffsetFile,
//                    lpReadBuffer + dwOffset,
//                    dwLength);
//                
//                return TRUE;
//            }
//            //else:Èç¹ûÔÚ±£Áô¹ý³ÌÖÐ·¢ÏÖÄ³Ò»ÏîÔÚÊÖ»úÖÐ
//            //ºÍÎÄ¼þÖÐµÄ³¤¶È²»Ò»Ñù£¬Ôò²»Óè±£Áô£¬Ö±½ÓÓÃÎÄ¼þÖÐµÄÌæ»»¡£
//        }
//        else //ÎÄ¼þÖÐÓÐBT¶øÊÖ»úÖÐÃ»ÓÐBT
//        {
//            return bContinue;
//        }
//    }
//    
//    return FALSE;    
//}


void TD_Ver1To2( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{    
    td_calibration_struct_v1::td_calibration_T para;
    td_calibration_struct_v2::td_calibration_T para_file;

    memcpy( &para,lpReadBuffer+dwOffset,sizeof( para ) );
    memcpy( &para_file,pSrc+dwOffsetFile,sizeof( para_file ) );

	para_file.cali_param.afc = para.cali_param.afc;

	//copy 3 times to ver2 apc[270]
	memcpy(&(para_file.cali_param.apc[0]),&(para.cali_param.apc[0]),
		(BYTE*)&(para.cali_param.apc[89])-(BYTE*)&(para.cali_param.apc[0])+sizeof(uint16));

    memcpy(&(para_file.cali_param.apc[90]),&(para.cali_param.apc[0]),
		(BYTE*)&(para.cali_param.apc[89])-(BYTE*)&(para.cali_param.apc[0])+sizeof(uint16));

	memcpy(&(para_file.cali_param.apc[180]),&(para.cali_param.apc[0]),
		(BYTE*)&(para.cali_param.apc[89])-(BYTE*)&(para.cali_param.apc[0])+sizeof(uint16));

    memcpy(&(para_file.cali_param.agc[0]),&(para.cali_param.agc[0]),
		(BYTE*)&(para.cali_param.agc[141])-(BYTE*)&(para.cali_param.agc[0])+sizeof(uint16));

	memcpy(&(para_file.cali_param.agc_ctrl[0]),&(para.cali_param.agc_ctrl[0]),
		(BYTE*)&(para.cali_param.agc_ctrl[141])-(BYTE*)&(para.cali_param.agc_ctrl[0])+sizeof(uint16));
	
	memcpy(&(para_file.reserved[0]),&(para.reserved[0]),
		(BYTE*)&(para_file.reserved[1687])-(BYTE*)&(para_file.reserved[0])+sizeof(uint8));	

    
    memcpy( pSrc + dwOffsetFile,&para_file,sizeof( para_file ) );
}

void TD_Ver2To1( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    td_calibration_struct_v2::td_calibration_T para;
    td_calibration_struct_v1::td_calibration_T para_file;

    memcpy( &para,lpReadBuffer+dwOffset,sizeof( para ) );
    memcpy( &para_file,pSrc+dwOffsetFile,sizeof( para_file ) );

	para_file.cali_param.afc = para.cali_param.afc;

	//copy middle to ver2 apc[90]
    memcpy(&(para_file.cali_param.apc[0]),&(para.cali_param.apc[90]),
		(BYTE*)&(para.cali_param.apc[179])-(BYTE*)&(para.cali_param.apc[90])+sizeof(uint16));

    memcpy(&(para_file.cali_param.agc[0]),&(para.cali_param.agc[0]),
		(BYTE*)&(para.cali_param.agc[141])-(BYTE*)&(para.cali_param.agc[0])+sizeof(uint16));

	memcpy(&(para_file.cali_param.agc_ctrl[0]),&(para.cali_param.agc_ctrl[0]),
		(BYTE*)&(para.cali_param.agc_ctrl[141])-(BYTE*)&(para.cali_param.agc_ctrl[0])+sizeof(uint16));
	
	memcpy(&(para_file.reserved[0]),&(para.reserved[0]),
		(BYTE*)&(para.reserved[1687])-(BYTE*)&(para.reserved[0]) + sizeof(uint8));	
    
    memcpy( pSrc + dwOffsetFile,&para_file,sizeof( para_file ) );
}

void TD_Ver3To3( LPBYTE pSrc,DWORD dwOffsetFile,LPBYTE lpReadBuffer,DWORD dwOffset )
{
    td_calibration_struct_v3::td_calibration_T para;
    td_calibration_struct_v3::td_calibration_T para_file;

    memcpy( &para,lpReadBuffer+dwOffset,sizeof( para ) );
    memcpy( &para_file,pSrc+dwOffsetFile,sizeof( para_file ) );

	para_file.rf_afc_dac = para.rf_afc_dac;
	para_file.rf_afc_slope = para.rf_afc_slope;

    memcpy(&(para_file.agc_ctl_word[0]),&(para.agc_ctl_word[0]),
		(BYTE*)&(para.agc_ctl_word[td_calibration_struct_v3::AGC_CTL_LEN_QS3200 - 1])-(BYTE*)&(para.agc_ctl_word[0])+sizeof(uint16));

    memcpy(&(para_file.agc_gain_word[0]),&(para.agc_gain_word[0]),
		(BYTE*)&(para.agc_gain_word[td_calibration_struct_v3::AGC_GAIN_LEN_QS3200-1])-(BYTE*)&(para.agc_gain_word[0])+sizeof(uint16));

	memcpy(&(para_file.TDPA_APC_control_word_index[0]),&(para.TDPA_APC_control_word_index[0]),
		(BYTE*)&(para.TDPA_APC_control_word_index[td_calibration_struct_v3::APC_CTL_LEN_QS3200-1])-(BYTE*)&(para.TDPA_APC_control_word_index[0])+sizeof(uint16));

	memcpy( pSrc + dwOffsetFile,&para_file,sizeof( para_file ) );
}

BOOL PreserveTDCalibration( LPBYTE lpCode, DWORD dwCodeSize,  
						   LPBYTE lpReadBuffer, DWORD dwReadSize,
						   DWORD dwOffsize, DWORD dwNvAfcSize/* = 0*/)
{
	DWORD dwOffsetFile,dwLengthFile;
    if(!FindNVOffset( 0x516,lpCode, dwCodeSize,dwOffsetFile,dwLengthFile))
    {
		return FALSE;
	}
	
	/* Update the timestamp to force nv manager to reload it */
	(*(DWORD*)lpCode) = GetTickCount();
//	(*(DWORD*)lpCode)++;
//	ASSERT(0xFFFFFFFF != *(DWORD*)lpCode);

	if( (*(WORD*)(lpCode + dwOffsetFile)) == 0x2 )
	{
		dwOffsetFile += dwOffsize; 
		if( dwNvAfcSize == 2 )
		{
			memcpy( lpCode + dwOffsetFile, lpReadBuffer, 2 );
		}
		dwOffsetFile += dwNvAfcSize + 2;
		for( int i = 0; i < 4; i++ )
		{
			memcpy( lpCode + dwOffsetFile, lpReadBuffer + dwNvAfcSize, APC_SIZE  );
			dwOffsetFile += APC_SIZE; 
		}
		memcpy( lpCode +dwOffsetFile, lpReadBuffer + dwNvAfcSize + APC_SIZE ,  AGC_SIZE  );
		
	}
	else
	{
		dwOffsetFile += dwOffsize; 
		memcpy( lpCode + dwOffsetFile,lpReadBuffer, dwReadSize );		
	}
	
	return TRUE;
	
}

DWORD  PreserveTDCalibrationEx( LPBYTE lpCode, DWORD dwCodeSize, 
                         LPBYTE lpReadBuffer, DWORD dwReadSize,
                         BOOL bOldReplaceNew , BOOL bContinue )
{
    DWORD dwOffsetFile,dwLengthFile;
    BYTE* pSrc = lpCode;

    if(!FindNVOffset( 0x516, pSrc,dwCodeSize,dwOffsetFile,dwLengthFile))
    {
        return ERR_NOT_FIND_PARAM_IN_FILE;
    }

    int wVerFile = *(pSrc + dwOffsetFile);
    wVerFile = wVerFile << 8;
    wVerFile += *(pSrc + dwOffsetFile + 1);

    // Find calibration
    DWORD dwOffset,dwLength;
    if(!FindNVOffset(0x516, lpReadBuffer,dwReadSize,dwOffset,dwLength)  )
    {
        if( bContinue )
        {
            return 0;
        }
        else
        {
            return ERR_NOT_FIND_PARAM_IN_MODULE;
        }
    }

    int wVer = (*(lpReadBuffer + dwOffset)<< 8) + *(lpReadBuffer + dwOffset + 1);

#define TDVER1            0x0001
#define TDVER2            0x0002
#define TDVER3            0x0003
	
	/* Update the timestamp to force nv manager to reload it */
	(*(DWORD*)lpCode) = GetTickCount();

	if(TDVER3 == wVerFile)
	{
		if( dwLengthFile != sizeof( td_calibration_struct_v3::td_calibration_T ) )
        {
            return ERR_PARAM_LEN_NOT_MATCH;
        }

        if(TDVER3 == wVer)
		{
			if( dwLengthFile == dwLength )
			{
				// Version and length are both equal,just do copying
				//memcpy( pSrc + dwOffsetFile,lpReadBuffer + dwOffset,dwLength );
				TD_Ver3To3(pSrc,dwOffsetFile,lpReadBuffer,dwOffset);
				return 0;
			}
			else
			{
				return ERR_PARAM_LEN_NOT_MATCH;
			}
		}
		else
        {
            return ERR_UNKNOWN_VER_IN_MODULE;
        }		
	}
    else if( TDVER2 == wVerFile )
    {
        if( dwLengthFile != sizeof( td_calibration_struct_v2::td_calibration_T ) )
        {
            return ERR_PARAM_LEN_NOT_MATCH;
        }
        if( TDVER1 == wVer )
        {
            if( dwLength != sizeof( td_calibration_struct_v1::td_calibration_T ) )
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
            TD_Ver1To2( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
        }
		else if(TDVER2 == wVer)
		{
			if( dwLengthFile == dwLength )
			{
				// Version and length are both equal,just do copying
				memcpy( pSrc + dwOffsetFile,lpReadBuffer + dwOffset,dwLength );
				return 0;
			}
			else
			{
				return ERR_PARAM_LEN_NOT_MATCH;
			}
		}
		else
        {
            return ERR_UNKNOWN_VER_IN_MODULE;
        }
    }
	else if( TDVER1 == wVerFile )
	{
        if( dwLengthFile != sizeof( td_calibration_struct_v1::td_calibration_T ) )
        {
            return ERR_PARAM_LEN_NOT_MATCH;
        }
		if( TDVER2 == wVer )
        {
            if( dwLength != sizeof( td_calibration_struct_v2::td_calibration_T ) )
            {
                return ERR_PARAM_LEN_NOT_MATCH;
            }
			if(bOldReplaceNew)
			{
				TD_Ver2To1( pSrc,dwOffsetFile,lpReadBuffer,dwOffset );
			}
			else
			{
				return ERR_OLD_VERSION;
			}
        }
		else if(TDVER1 == wVer)
		{
			if( dwLengthFile == dwLength )
			{
				// Version and length are both equal,just do copying
				memcpy( pSrc + dwOffsetFile,lpReadBuffer + dwOffset,dwLength );
				return 0;
			}
			else
			{
				return ERR_PARAM_LEN_NOT_MATCH;
			}
		}
		else
        {
            return ERR_UNKNOWN_VER_IN_MODULE;
        }
	}
	else
	{
		return ERR_UNKNOWN_VER_IN_FILE;
	}
	
	return 0;
	
}

BOOL PreserveNVItemEx( WORD wID, LPBYTE lpCode, DWORD dwCodeSize, 
					  LPBYTE lpReadBuffer, DWORD dwReadSize,
					  BOOL bOldReplaceNew/*=FALSE*/, BOOL bContinue/*=FALSE*/ )
{
	UNUSED_ALWAYS(bOldReplaceNew);
    //CalibrationÏî£¨IDÎª2£©ºÍIMEIÏî£¨IDÎª5£©½«ÈÔ°´Ä¿Ç°µÄ·½·¨´¦Àí£¬
    //¼´ÎÞÂÛËüÃÇµÄIDÔÚ²»ÔÚPÖÐ¶¼½«±»±£Áô£¬³ý·Ç¹¤¾ßÉèÖÃÎª²»±£Áô£¨ÄÚ²¿°æ£©¡£
    if( wID == NV_L1_CALIBRATION_PARAMETER || wID == NV_IMEI )
	{
        return TRUE;    
	}
    
    
    DWORD dwOffsetFile,dwLengthFile;
    if(FindNVOffset( wID, lpCode, dwCodeSize,dwOffsetFile,dwLengthFile))
    {
        DWORD dwOffset,dwLength;
        if(FindNVOffset( wID, lpReadBuffer,dwReadSize,dwOffset,dwLength))
        {
            if(dwLength == dwLengthFile)
            {
                memcpy( lpCode + dwOffsetFile,
                    lpReadBuffer + dwOffset,
                    dwLength);
                
                return TRUE;
            }
            //else:Èç¹ûÔÚ±£Áô¹ý³ÌÖÐ·¢ÏÖÄ³Ò»ÏîÔÚÊÖ»úÖÐ
            //ºÍÎÄ¼þÖÐµÄ³¤¶È²»Ò»Ñù£¬Ôò²»Óè±£Áô£¬Ö±½ÓÓÃÎÄ¼þÖÐµÄÌæ»»¡£
        }
        else //ÎÄ¼þÖÐÓÐ´ËÏî¶øÊÖ»úÖÐÃ»ÓÐ´ËÏî
        {
            return bContinue;
        }
    }
    
    return FALSE;    
}
