thor: fix invalid larger device descriptor than requested
[profile/mobile/platform/kernel/u-boot-tm1.git] / property / backupnvitem.c
1 #include <common.h>
2 #include <malloc.h>
3
4 #define NV_MULTI_LANG_ID   (405)
5 #define GSM_CALI_ITEM_ID   (0x2)
6 #define GSM_IMEI_ITEM_ID   (0x5)
7 #define XTD_CALI_ITEM_ID   (0x516)
8 #define LTE_CALI_ITEM_ID   (0x9C4)
9 #define BT_ITEM_ID         (0x191)
10
11 #define BT_ADDR_LEN  6
12
13 #define IMEI_LEN                        (8)
14 #define GSM_CALI_VER_A      0xFF0A
15 #define GSM_CALI_VER_MIN    GSM_CALI_VER_A
16 #define GSM_CALI_VER_MAX    GSM_CALI_VER_A
17
18 #define NUM_TEMP_BANDS          (5)
19 #define NUM_RAMP_RANGES         (16)            /* constant parameter numbers, 16 level */
20 #define NUM_TX_LEVEL            (16)            /* 2db per step */
21 #define NUM_RAMP_POINTS         (20)
22 #define NUM_GSM_ARFCN_BANDS     (6)
23 #define NUM_DCS_ARFCN_BANDS     (8)
24 #define NUM_PCS_ARFCN_BANDS     (7)
25 #define NUM_GSM850_ARFCN_BANDS  (6)
26 #define MAX_COMPENSATE_POINT    (75)
27
28 enum
29 {
30         ERR_NONE,
31         ERR_NOT_FIND_PARAM_IN_FILE,
32         ERR_NOT_FIND_PARAM_IN_MODULE,
33         ERR_PARAM_LEN_NOT_MATCH,
34         ERR_UNKNOWN_VER_IN_MODULE,
35         ERR_OLD_VERSION,
36         ERR_UNKNOWN_VER_IN_FILE,  
37         ERR_PARAM_LEN_NOT_MATCH_DEF
38 };
39
40
41 typedef struct BT_CONFIG_T
42 {
43         unsigned char  bt_addr[BT_ADDR_LEN];
44         unsigned short xtal_dac;
45 }BT_CONFIG;
46
47 /* GSM Calibration */
48 typedef struct 
49 {
50         short stage0[NUM_RAMP_POINTS];
51         short stage1[NUM_RAMP_POINTS];
52         short stage2[NUM_RAMP_POINTS];
53         short stage3[NUM_RAMP_POINTS];
54         short stage4[NUM_RAMP_POINTS];
55         short stage5[NUM_RAMP_POINTS];
56         short stage6[NUM_RAMP_POINTS];
57         short stage7[NUM_RAMP_POINTS];
58         short stage8[NUM_RAMP_POINTS];
59         short stage9[NUM_RAMP_POINTS];
60         short stage10[NUM_RAMP_POINTS];
61         short stage11[NUM_RAMP_POINTS];
62         short stage12[NUM_RAMP_POINTS];
63         short stage13[NUM_RAMP_POINTS];
64         short stage14[NUM_RAMP_POINTS];
65         short stage15[NUM_RAMP_POINTS];
66
67 } RF_ramp_table_T;
68
69 typedef struct
70 {
71     /* unsigned short RF_ID;
72     unsigned short RF_Project_ID; */    
73     unsigned short slope_length ;
74     unsigned short cdac ;
75     unsigned short cafc ;
76     unsigned short slope_struct[3][17] ;
77     
78 }RF_aero2_AFC_T ;
79
80 typedef struct
81 {
82     /************* AFC  ********************/
83     unsigned short is_using_si4134;        /* TRUE, the si4134 from Silicon lab is used. Then the way to calibrate
84     // the 13Mhz is different. For si4134, Total 64 steps( 1.0 ppm per step)
85     // can be set to set coarse 13Mhz. */
86     unsigned short si4134_coarse_13m;      /* For si4134, it is 6bits, and for setting the CDAC register of si4134 */
87     
88     unsigned short afc_center;
89     unsigned short afc_slope_per_6bits;
90     
91 }RF_aero1_AFC_T ; 
92 typedef struct
93 {
94     /************* AFC  ********************/
95     RF_aero1_AFC_T rf_aero1_afc_struct;
96     /* Oscillator temperature calibration table. */
97     short  osci_temp_comp_in_dac[ NUM_TEMP_BANDS ];     /* In Hz */
98     /* Temp -30 ~ -11 
99        Temp -10 ~ 9 
100        Temp  10 ~ 29 
101        Temp  30 ~ 49 
102        Temp  50 ~ 69 */
103     RF_aero2_AFC_T rf_aero2_afc_struct;                                                        
104 } RF_param_common_DSP_use_T;
105
106 typedef struct
107 {
108     /* short RF_ramp_up_table_stage0[NUM_RAMP_POINTS]; //64 words totally
109     short RF_ramp_up_table_stage1[NUM_RAMP_POINTS];
110     short RF_ramp_down_table_stage0[NUM_RAMP_POINTS];
111     short RF_ramp_down_table_stage1[NUM_RAMP_POINTS]; */
112     short rf_ramp_param_constant_up[NUM_RAMP_RANGES]; /* const part of the ramp tale */
113     short rf_ramp_param_constant_down[NUM_RAMP_RANGES]; /* const part of the ramp tale */
114     short rf_ramp_up_param_num; /* the number of ramp up parameters in the ramp parameters table for one level */
115     short rf_ramp_down_param_num; /* the number of ramp down */
116
117     /* short temperature_and_voltage_compensate_structrue[30]*/
118     short reserved[64 - 2*NUM_RAMP_RANGES - 1 - 1]; /* keep 64words totally to keep consistency with dsp code */
119
120     short TX_compensate_boundary_arfcn_index[4];
121     short RF_ramppwr_step_factor[5][NUM_TX_LEVEL];
122     short RF_ramp_delta_timing[NUM_TX_LEVEL];
123     short RF_ramp_PA_power_on_duration[NUM_TX_LEVEL];
124     /* short RX_compensate_boundary_arfcn_index[4];
125     short RX_compensate_value[5]; */
126     short reserved1[9];
127     short temperature_RX_compensate_boundary_ADC[4];
128     short temperature_RX_compensate_value[5];
129     short temperature_TX_compensate_boundary_ADC[4];
130     short temperature_TX_rampwr_step_factor[5];
131     short  ramp_switch_level;
132     unsigned short afc_alg_bias;
133     unsigned short agc_ctrl_word[91];   /* The index is the expected received signal strangth in db in 2 db steps,
134                                            the content is the control word set the RF receiver chain agc. */
135     short  max_rf_gain_index;
136     short  reserve_for_future[20];
137     
138     short  RX_compensate_value[MAX_COMPENSATE_POINT];
139     RF_ramp_table_T RF_ramp_table;
140     
141 } RF_param_band_DSP_use_T;
142
143 typedef struct
144 {
145     RF_param_common_DSP_use_T   rf_common_param_dsp_use;
146     RF_param_band_DSP_use_T     rf_gsm_param_dsp_use;
147     RF_param_band_DSP_use_T     rf_dcs_param_dsp_use;
148     RF_param_band_DSP_use_T     rf_pcs_param_dsp_use;
149     RF_param_band_DSP_use_T     rf_gsm850_param_dsp_use;        
150 }RF_param_DSP_use_T;
151
152 typedef struct
153 {
154     char    rx_whole_band_comp_gsm[NUM_GSM_ARFCN_BANDS];
155     char    rx_whole_band_comp_dcs[NUM_DCS_ARFCN_BANDS];
156     char    rx_whole_band_comp_pcs[NUM_PCS_ARFCN_BANDS];
157     char    rx_whole_band_comp_gsm850[NUM_GSM850_ARFCN_BANDS];        
158     char    pa_GSM_temp_comp[ NUM_TEMP_BANDS];
159     
160     char    pa_DCS_temp_comp[ NUM_TEMP_BANDS];
161     
162     char    pa_PCS_temp_comp[ NUM_TEMP_BANDS];
163     char    pa_GSM850_temp_comp[ NUM_TEMP_BANDS];
164     
165     /******************** RX level calculation *********************/
166     /* The received signal level(RSSI) value reported to the network may need to be adjusted based on the received signal
167     level. */
168     char    rxlev_GSM_temp_comp[ NUM_TEMP_BANDS];
169     
170     char    rxlev_DCS_temp_comp[ NUM_TEMP_BANDS];
171     
172     char    rxlev_PCS_temp_comp[ NUM_TEMP_BANDS];
173     char    rxlev_GSM850_temp_comp[ NUM_TEMP_BANDS];
174     
175     /****** PA ramp compensation for battery voltage variation. *******/
176     char    pa_GSM_vcc_comp_threshold;      /* If the voltage is below the threshold, pa compensation is needed. Battery measure ADC value. */
177     char    pa_GSM_vcc_comp_step;           /* The PA ramp level need to be changed per threshold. */
178     char    pa_DCS_vcc_comp_threshold;      /* If the voltage is below the threshold, pa compensation is needed. */
179     char    pa_DCS_vcc_comp_step;           /* The PA ramp level need to be changed per threshold. */
180     char    pa_PCS_vcc_comp_threshold;      /* If the voltage is below the threshold, pa compensation is needed. */
181     char    pa_PCS_vcc_comp_step;           /* The PA ramp level need to be changed per threshold. */
182     char    pa_GSM850_vcc_comp_threshold;   /* If the voltage is below the threshold, pa compensation is needed. Battery measure ADC value. */
183     char    pa_GSM850_vcc_comp_step;           /* The PA ramp level need to be changed per threshold. */
184     
185 } RF_param_MCU_use_T;
186
187 typedef struct
188 {
189     /**************** Battery monitor *********************/
190     /* Battery measurement calibration.
191        Due to the unprecise of the divider resistor value for measure the battery voltage, the voltage
192        value measured may be not accurate enough for battery charging. */
193     unsigned long batt_mV_per_4bits;   /* The actual voltage for 4bits ADC output. */
194     
195     /******************* 32K/13M calibration. ***************/
196     /*the ratio of 32k and 13Mhz needs to be calibrated running
197     for deep sleep mode */
198     
199     unsigned short  clock_32k_cal_interval; /* How often the calibration shall be invoked. */
200     unsigned short  clock_32k_cal_duration; /* How long the calibration shall be done. */
201 }Misc_cal_MCU_use_T;
202
203 typedef struct
204 {
205     unsigned long    adc[2];           /* calibration of ADC, two test point */
206     unsigned long    battery[2];       /* calibraton of battery(include resistance), two test point */
207     unsigned long    reserved[8];      /* reserved for feature use. */
208 }ADC_T;
209
210 typedef struct
211 {
212     unsigned short              calibration_param_version;
213     RF_param_DSP_use_T  rf_param_dsp_use;
214     RF_param_MCU_use_T  rf_param_mcu_use;
215     Misc_cal_MCU_use_T  misc_cal_mcu_use;
216     short                   mic_gain;        /* In DB */
217     short                   auxi_mic_gain;   /* In DB */
218     unsigned short                  PM_version;      /* the version of phone module */
219     
220     /* Following Added by Lin.liu. (2003-08-29), CR: MS4474 */
221     unsigned short                  software_version;   /* Software version of Tools */
222     unsigned short                  station_num;
223     unsigned char                   operate_code[ 16 ];
224     unsigned long                  date;
225     
226     ADC_T                   adc;             /* Added By Lin.liu, for ADC calibration End Lin.liu Added. */ 
227     
228 } calibration_param_T;
229
230 #define XTD_CALI_VER_3            0x0003
231 #define XTD_CALI_VER_4            0x0004
232
233 /* TD Calibration */
234 /* td_calibration_struct_v3 */
235 #define AGC_GAIN_LEN_QS3200_V3  1495
236 #define AGC_CTL_LEN_QS3200      115
237 #define APC_CTL_LEN_QS3200_V3   1300
238 #define AGC_COMP_LEN_QS3200     61
239 #define APC_COMP_LEN_QS3200     613
240
241 typedef struct  
242 {   
243        unsigned short   cali_version;
244        unsigned short   antenna_switch_pin_control;
245        unsigned short   Antenna_switch_truth_table[8];
246        unsigned short   rf_afc_dac;
247        unsigned short   rf_afc_slope;
248        unsigned short   agc_ctl_word[AGC_CTL_LEN_QS3200];
249        unsigned short   agc_gain_word[AGC_GAIN_LEN_QS3200_V3];  /* 115*3+115+115*8+115 */
250        unsigned short   AGC_compensation[AGC_COMP_LEN_QS3200];  /* 1+30*2 */
251        unsigned short   tdpa_pin_control;
252        unsigned short   TDPA_APC_control_word_index[APC_CTL_LEN_QS3200_V3]; /* 100*4+100*9 */
253        unsigned short   APC_compensation[APC_COMP_LEN_QS3200];  /* 30+30+60+60+30+1+(4*13+20)*2+1+1+256 */
254        unsigned short   rf_register_num;
255        unsigned long    rf_Register_Initial[50];
256        unsigned long    rf_action_tbl[281];
257        unsigned char    reserved[500];
258
259 }td_calibration_v3_T;
260
261 /* td_calibration_struct_v4 */
262 #define AGC_GAIN_LEN_QS3200_V4  2875
263 #define APC_CTL_LEN_QS3200_V4   2500
264 typedef struct  
265 {
266         unsigned short   cali_version;
267         unsigned short   rf_afc_dac;
268         unsigned short   rf_afc_slope;
269         unsigned short   slope_length;
270         unsigned short   CDAC;
271         unsigned short   CAFC;
272         unsigned short   agc_gain_word[AGC_GAIN_LEN_QS3200_V4];                 /* 115*12 + 115*4 + 115*9 */
273         unsigned short   TDPA_APC_control_word_index[APC_CTL_LEN_QS3200_V4];    /* 100*12 + 100*4 + 100*9 */
274 }td_calibration_v4_T;
275
276 /* LTE Calibration */
277 #define LTE_CALI_VER_1            0x0001
278
279 /* LTE_NV_TYPE_FAST_PLLLOCK */
280 typedef struct _LTE_NV_CALI_FAST_PLLLOCK
281 {
282         unsigned short plllock_array[64];
283 }LTE_NV_CALI_FAST_PLLLOCK;
284         
285 /* LTE_NV_TYPE_AGC_GAIN_MAIN */
286 typedef struct _LTE_NV_CALI_AGC_GAIN_MAIN
287 {
288         unsigned short agc_gain_main_24G_center_array[124];
289         unsigned short agc_gain_main_24G_channel_array[21 + 20];
290         unsigned short agc_gain_main_26G_center_array[124];
291         unsigned short agc_gain_main_26G_channel_array[11+20];
292 }LTE_NV_CALI_AGC_GAIN_MAIN;
293         
294 /* LTE_NV_TYPE_AGC_DIV_MAIN */
295 typedef struct _LTE_NV_CALI_AGC_GAIN_DIV
296 {
297         unsigned short agc_gain_div_24G_center_array[124];
298         unsigned short agc_gain_div_24G_channel_array[21 + 20];
299         unsigned short agc_gain_div_26G_center_array[124];
300         unsigned short agc_gain_div_26G_channel_array[11 + 20];
301 }LTE_NV_CALI_AGC_GAIN_DIV;
302         
303 /* LTE_NV_TYPE_AFC_CONTROL */
304 typedef struct _LTE_NV_CALI_AFC_CONTROL
305 {
306         unsigned short AFC0;
307         unsigned short AFC_K;
308 }LTE_NV_CALI_AFC_CONTROL;
309         
310 /* LTE_NV_TYPE_APC_CONTROL_WORD_MAIN */
311 typedef struct _LTE_NV_CALI_APC_CONTROL_WORD_MAIN
312 {
313         unsigned short apc_control_main_24G_array[22][80];
314         unsigned short apc_control_main_26G_array[12][80];
315 }LTE_NV_CALI_APC_CONTROL_WORD_MAIN;
316         
317 /* LTE_NV_TYPE_APC_CONTROL_WORD_DIV */
318 typedef struct _LTE_NV_CALI_APC_CONTROL_WORD_DIV
319 {
320         unsigned short apc_control_div_24G_array[22][80];
321         unsigned short apc_control_div_26G_array[12][80];
322 }LTE_NV_CALI_APC_CONTROL_WORD_DIV;
323         
324 typedef struct _LTE_NV_CALI_PARAM_T
325 {
326         unsigned short                     CALI_PARAM_VERSION;
327         unsigned short                     CALI_PARAM_FLAG;
328         
329         LTE_NV_CALI_FAST_PLLLOCK            FAST_PLLLOCK;
330         LTE_NV_CALI_AGC_GAIN_MAIN           AGC_GAIN_MAIN;
331         LTE_NV_CALI_AGC_GAIN_DIV            AGC_GAIN_DIV;
332         LTE_NV_CALI_AFC_CONTROL             AFC_CONTROL;
333         LTE_NV_CALI_APC_CONTROL_WORD_MAIN   APC_CONTROL_WORD_MAIN;
334         LTE_NV_CALI_APC_CONTROL_WORD_DIV    APC_CONTROL_WORD_DIV;    
335 }LTE_NV_CALI_PARAM_T;
336
337
338 static unsigned long XCheckNVStruct(unsigned char *lpPhoBuf, unsigned long dwPhoSize, 
339         unsigned long bBigEndian, unsigned long bModule)
340 {
341         unsigned long dwOffset = 0, dwLength = 0, bRet;
342         unsigned char *lpCode = lpPhoBuf;
343         unsigned long dwCodeSize = dwPhoSize;
344         unsigned short wCurID;
345
346         dwOffset = 4;     /* Skip first four bytes,that is time stamp */
347         dwLength = 0;
348         unsigned char *pTemp = lpCode + dwOffset;
349
350         unsigned long bIMEI = 0;
351         unsigned long bGSMCali = 0;
352         unsigned short wGSMCaliVer = 0;
353     
354         while (dwOffset < dwCodeSize) {
355                 wCurID = *(unsigned short *)pTemp;
356                 pTemp += 2;
357
358                 dwLength = *(unsigned short *)pTemp;
359                 /* printf("wCurID = 0x%08x  dwLength = 0x%08x\n", wCurID, dwLength); */
360                 if (wCurID == GSM_IMEI_ITEM_ID) {
361                         if (dwLength != IMEI_LEN) {
362                                 return 0;
363                         } else {
364                                 bIMEI = 1;
365                         }
366                 } else if (wCurID == GSM_CALI_ITEM_ID) {
367                         wGSMCaliVer =  *(unsigned short *)(pTemp + 2); /* pTemp + 2: skip length */
368         
369                         /* printf("wGSMCaliVer = 0x%08x\n", wGSMCaliVer); */
370                         if ((wGSMCaliVer > GSM_CALI_VER_MAX) || (wGSMCaliVer < GSM_CALI_VER_MIN)) {
371                                 return 0;
372                         } else {
373                                 bGSMCali = 1;
374                         }
375                 }
376
377                 /* 0xFFFF is end-flag in module (NV in phone device) */
378                 if (wCurID == 0xFFFF) {
379                         if (!bIMEI || !bGSMCali) {
380                                 return 0;
381                         }
382                         return 1;
383                 }
384
385                 if (wCurID == 0 || dwLength == 0) {
386                         break;
387                 }
388
389                 pTemp += 2;
390                 dwOffset += 4;
391                 /* Must be four byte aligned */
392                 bRet = dwLength % 4;
393                 if (bRet != 0) {
394                         dwLength += 4 - bRet;
395                 }
396         
397                 dwOffset += dwLength;
398                 pTemp += dwLength;
399                 
400                 /* (dwOffset == dwCodeSize) is end condition in File */
401                 if (dwOffset == dwCodeSize) {
402                         if(!bIMEI || !bGSMCali) {
403                                 return 0;
404                         }
405                         return 1;
406                 }
407         }
408
409         return 0;
410 }
411
412 unsigned long XCheckNVStructEx(unsigned char *lpPhoBuf, unsigned long dwPhoSize, unsigned long bBigEndian, 
413         unsigned long bModule)
414 {
415         if (!XCheckNVStruct(lpPhoBuf, dwPhoSize, bBigEndian, bModule)) {
416                 printf("%s %d\n", __FUNCTION__, __LINE__);
417                 return 0;
418         }
419
420         return 1;
421 }
422
423 unsigned long XFindNVOffset(unsigned short wId, unsigned char *lpCode, unsigned long dwCodeSize, 
424         unsigned long *dwOffset, unsigned long *dwLength, unsigned long bBigEndian)
425 {
426     unsigned short wCurID;
427     unsigned char *pTemp;
428     unsigned long bRet;
429
430     *dwOffset = 4;     /* Skip first four bytes,that is time stamp */
431     *dwLength = 0;
432     pTemp = lpCode + *dwOffset;
433     
434     while (*dwOffset < dwCodeSize) {
435         wCurID = *(unsigned short *)pTemp;
436
437         pTemp += 2;
438
439         *dwLength = *(unsigned short *)pTemp;
440
441         pTemp += 2;
442         *dwOffset += 4;
443         /* Must be four byte aligned */
444         bRet = (*dwLength) % 4;
445         if (bRet != 0) {
446             *dwLength += 4 - bRet;
447         }
448         /* printf("wCurID = 0x%08x  dwLength = 0x%08x  bRet = %d\n", wCurID, *dwLength, bRet); */
449         /* 0xFFFF is end-flag */
450         if (wCurID == 0xFFFF) {
451                 return 0;
452         }
453         
454         if (wCurID == wId) {
455                 /* check length */
456                 printf("dwOffset = 0x%08lx  dwLength = 0x%08lx  bRet = %lu\n", *dwOffset, *dwLength, bRet);
457                 if ((*dwOffset + *dwLength - bRet) <= dwCodeSize)
458                         return 1;
459                 else
460                         return 0;
461         } else {
462                 *dwOffset += *dwLength;
463                 pTemp += *dwLength;
464         }
465     }
466     
467     return 0;
468 }
469
470 unsigned long XFindNVOffsetEx(unsigned short wId, unsigned char *lpCode, unsigned long dwCodeSize, 
471         unsigned long *dwOffset, unsigned long *dwLength, unsigned long bBigEndian, unsigned long bModule)
472 {
473         unsigned long bOK = 0;
474
475         if (XCheckNVStructEx(lpCode, dwCodeSize, 0, bModule)) {
476                 if (XFindNVOffset(wId, lpCode, dwCodeSize, dwOffset, dwLength, bBigEndian))
477                         bOK = 1;
478         }
479
480         return bOK;
481 }
482
483 unsigned long XCheckCalibration(unsigned char *lpPhoBuf, unsigned long dwPhoSize, unsigned long bModule)
484 {
485         unsigned long dwPhoCaliFlag = 0;
486         unsigned long dwOffsetPho = 0;
487         unsigned long dwLengthPho = 0;
488         unsigned char *pSrcPho = lpPhoBuf;
489
490         /*calibration_struct_va::*/calibration_param_T paraPho; 
491
492         if (!XFindNVOffsetEx(GSM_CALI_ITEM_ID, pSrcPho, dwPhoSize, &dwOffsetPho, &dwLengthPho, 0, bModule)) {
493                 printf("Not found cali in phone");
494                 return 0;
495
496         }
497
498         printf("dwOffsetPho = 0x%08lx  dwLengthPho = 0x%08lx\n", dwOffsetPho, dwLengthPho);
499
500         unsigned char *pCaliBuf = pSrcPho + dwOffsetPho;
501         unsigned short wVerPho = *(unsigned short *)pCaliBuf;
502         printf("wVerPho = 0x%08x  size = 0x%08x\n", wVerPho, sizeof(paraPho));
503         if (wVerPho != GSM_CALI_VER_A) {
504                 printf("Cali version in phone is wrong\n");
505                 return 0;
506         }
507
508         if (dwLengthPho != sizeof(paraPho)) {
509                 printf("Cali length in phone is wrong\n");
510                 return 0;
511         }
512         
513         memcpy(&paraPho, pSrcPho + dwOffsetPho, sizeof(paraPho));
514         dwPhoCaliFlag = paraPho.adc.reserved[7];
515
516         if (paraPho.adc.reserved[7] == 0) {     
517                 printf("GSM Calibration in phone is not calibrated, Reserved[7] : 0x%08lX\n", dwPhoCaliFlag);   
518                 return 0;
519         }
520
521         return 1;
522 }
523
524
525 static void GSM_VerAToA(unsigned char *pFileBuf, unsigned long dwOffsetFile, unsigned long bFileBigEndian, 
526                         unsigned char *pModuBuf, unsigned long dwOffsetModu, unsigned long bModuBigEndian,
527                         unsigned long CaliPolicy)
528 {
529         int i = 0;
530         /*calibration_struct_va::*/calibration_param_T para_modu, para_file;
531         
532         memcpy(&para_modu, pModuBuf + dwOffsetModu, sizeof(para_modu));
533         memcpy(&para_file, pFileBuf + dwOffsetFile, sizeof(para_file));
534     
535         if (CaliPolicy == 0 || CaliPolicy == 1 ) {
536                 /* not backup RF_ramp_delta_timing */
537                 for (i = 0; i < /*calibration_struct_va::*/NUM_TX_LEVEL; i++) {
538                         para_modu.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];
539                         para_modu.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];
540                         para_modu.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];
541                         para_modu.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];
542                 }
543
544                 if (CaliPolicy == 1) {
545                          /* For HTC */
546                         /* not backup RF_ramp_PA_power_on_duration */
547                         for (i = 0; i < /*calibration_struct_va::*/NUM_TX_LEVEL; i++) {
548                                 para_modu.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_PA_power_on_duration[i] = para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_PA_power_on_duration[i];
549                                 para_modu.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_PA_power_on_duration[i] = para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_PA_power_on_duration[i];
550                                 para_modu.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_PA_power_on_duration[i] = para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_PA_power_on_duration[i];
551                                 para_modu.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_PA_power_on_duration[i] = para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_PA_power_on_duration[i];
552                         }
553                         /* not backup RF_ramp_table */
554                         memcpy(&para_modu.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_table,
555                                    &para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_table,
556                                    sizeof(para_modu.rf_param_dsp_use.rf_gsm_param_dsp_use.RF_ramp_table));
557                         
558                         memcpy(&para_modu.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_table,
559                                    &para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_table,
560                                    sizeof(para_modu.rf_param_dsp_use.rf_dcs_param_dsp_use.RF_ramp_table));
561
562                         memcpy(&para_modu.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_table,
563                                    &para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_table,
564                                    sizeof(para_modu.rf_param_dsp_use.rf_pcs_param_dsp_use.RF_ramp_table));
565
566                         memcpy(&para_modu.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_table,
567                                    &para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_table,
568                                    sizeof(para_modu.rf_param_dsp_use.rf_gsm850_param_dsp_use.RF_ramp_table));
569
570                         /* not backup reserved "temperature_and_voltage_composate_structure" */
571                         memcpy(&(para_modu.rf_param_dsp_use.rf_gsm_param_dsp_use.reserved[0]),
572                                    &(para_file.rf_param_dsp_use.rf_gsm_param_dsp_use.reserved[0]),
573                                    sizeof(para_modu.rf_param_dsp_use.rf_gsm_param_dsp_use.reserved));
574                         
575                         memcpy(&(para_modu.rf_param_dsp_use.rf_dcs_param_dsp_use.reserved[0]),
576                                    &(para_file.rf_param_dsp_use.rf_dcs_param_dsp_use.reserved[0]),
577                                    sizeof(para_modu.rf_param_dsp_use.rf_dcs_param_dsp_use.reserved));
578                         
579                         memcpy(&(para_modu.rf_param_dsp_use.rf_pcs_param_dsp_use.reserved[0]),
580                                    &(para_file.rf_param_dsp_use.rf_pcs_param_dsp_use.reserved[0]),
581                                    sizeof(para_modu.rf_param_dsp_use.rf_pcs_param_dsp_use.reserved));
582                         
583                         memcpy(&(para_modu.rf_param_dsp_use.rf_gsm850_param_dsp_use.reserved[0]),
584                                    &(para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use.reserved[0]),
585                                    sizeof(para_modu.rf_param_dsp_use.rf_gsm850_param_dsp_use.reserved));
586                 }
587
588                 memcpy(pFileBuf + dwOffsetFile, &para_modu, sizeof(para_modu));
589         } else {
590                 /* adc */
591                 memcpy(&para_file.adc, &para_modu.adc, sizeof(para_file.adc));
592                 /* afc */
593                 memcpy(&para_file.rf_param_dsp_use.rf_common_param_dsp_use,
594                            &para_modu.rf_param_dsp_use.rf_common_param_dsp_use,
595                                 sizeof(para_file.rf_param_dsp_use.rf_common_param_dsp_use));
596
597                 /*calibration_struct_va::*/RF_param_band_DSP_use_T *pFile = NULL;
598                 /*calibration_struct_va::*/RF_param_band_DSP_use_T *pModu = NULL;
599
600                 for (i = 0; i < 4; i++) {       
601                         switch (i) {
602                         case 0:
603                                 pFile = &para_file.rf_param_dsp_use.rf_gsm_param_dsp_use;
604                                 pModu = &para_modu.rf_param_dsp_use.rf_gsm_param_dsp_use;
605                         break;
606                         case 1:
607                                 pFile = &para_file.rf_param_dsp_use.rf_dcs_param_dsp_use;
608                                 pModu = &para_modu.rf_param_dsp_use.rf_dcs_param_dsp_use;
609                         break;
610                         case 2:
611                                 pFile = &para_file.rf_param_dsp_use.rf_pcs_param_dsp_use;
612                                 pModu = &para_modu.rf_param_dsp_use.rf_pcs_param_dsp_use;
613                         break;
614                         case 3:
615                                 pFile = &para_file.rf_param_dsp_use.rf_gsm850_param_dsp_use;
616                                 pModu = &para_modu.rf_param_dsp_use.rf_gsm850_param_dsp_use;
617                         break;
618                         }
619                         
620                         /* agc */
621                         /* agc_ctrl_word */
622                         memcpy(pFile->agc_ctrl_word, pModu->agc_ctrl_word, sizeof(pFile->agc_ctrl_word));
623                         /* RX_compensate_value */
624                         memcpy(pFile->RX_compensate_value, pModu->RX_compensate_value, sizeof(pFile->RX_compensate_value));
625                         /* max_rf_gain_index */
626                         memcpy(&pFile->max_rf_gain_index, &pModu->max_rf_gain_index, sizeof(pFile->max_rf_gain_index)); 
627                         /* apc */
628                         /* rf_ramp_param_constant_value */
629                         memcpy( pFile->rf_ramp_param_constant_up, pModu->rf_ramp_param_constant_up, 
630                                 sizeof(pFile->rf_ramp_param_constant_up));
631                         /* rf_edge_tx_gain_table */
632                         memcpy(pFile->rf_ramp_param_constant_down, pModu->rf_ramp_param_constant_down,
633                          sizeof(pFile->rf_ramp_param_constant_down));
634                         /* RF_ramppwr_step_factor */
635                         memcpy(pFile->RF_ramppwr_step_factor, pModu->RF_ramppwr_step_factor, 
636                                 sizeof(pFile->RF_ramppwr_step_factor));
637                         /* rf_8psk_tx_compensation */
638                         memcpy(pFile->reserved1, pModu->reserved1, sizeof(pFile->reserved1));
639                 }
640
641                 memcpy(pFileBuf + dwOffsetFile, &para_file, sizeof(para_file));
642         }    
643 }
644
645 unsigned long GSMCaliPreserve(unsigned char *lpCode, unsigned long dwCodeSize, unsigned char *lpReadBuffer, 
646                         unsigned long dwReadSize, unsigned long bOldReplaceNew, unsigned long bContinue, 
647                         unsigned long CaliPolicy)
648 {
649         unsigned long dwOffsetFile = 0, dwLengthFile = 0;
650         unsigned long dwOffsetModu = 0, dwLengthModu = 0;
651         unsigned char *pFileBuf = lpCode;
652         unsigned char *pModuBuf = lpReadBuffer;
653
654         /* Find calibration in file */
655         if (!XFindNVOffsetEx(GSM_CALI_ITEM_ID, pFileBuf, dwCodeSize, &dwOffsetFile, &dwLengthFile, 0, 1)) {
656                 printf("%s %d\n", __FUNCTION__, __LINE__);              
657                 return ERR_NOT_FIND_PARAM_IN_FILE;
658         }
659
660         /*printf("dwOffsetFile = 0x%08x  dwLengthFile = 0x%08x\n", dwOffsetFile, dwLengthFile);*/
661         unsigned short wVerFile = *(unsigned short *)(pFileBuf + dwOffsetFile);
662
663         /* Find calibration in phone */
664         if (!XFindNVOffsetEx(GSM_CALI_ITEM_ID, pModuBuf, dwReadSize, &dwOffsetModu, &dwLengthModu, 0, 1)) {
665                 if (bContinue)
666                         return ERR_NONE;
667                 else
668                         return ERR_NOT_FIND_PARAM_IN_MODULE;
669         }
670
671         /*printf("dwOffsetModu = 0x%08x  dwLengthModu = 0x%08x\n", dwOffsetModu, dwLengthModu);*/
672         unsigned short wVerModu = *(unsigned short *)(pModuBuf + dwOffsetModu);
673         
674         /* Update the timestamp to force nv manager to reload it */
675         /* (*(unsigned long*)lpCode) = GetTickCount(); xin hongliang masked */
676
677         unsigned long dwSizeAligned = 0;
678
679         if (GSM_CALI_VER_A == wVerFile) { 
680                 dwSizeAligned = sizeof(/*calibration_struct_va::*/calibration_param_T); 
681                 dwSizeAligned = ((unsigned long)((dwSizeAligned + 3) / 4)) * 4;
682
683                 if (dwLengthFile != dwSizeAligned) {
684                         return ERR_PARAM_LEN_NOT_MATCH_DEF;
685                 }
686                 
687                 if (GSM_CALI_VER_A == wVerModu) {
688                         if (dwLengthFile == dwLengthModu) {
689                                 /* Version and length are both equal,just do copying */
690                                 /* memcpy( pSrc + dwOffsetFile,lpReadBuffer + dwOffset,dwLength ); */
691                                 GSM_VerAToA(pFileBuf, dwOffsetFile, 0, pModuBuf, dwOffsetModu, 0, CaliPolicy);
692                                 return ERR_NONE;
693                         } else
694                                 return ERR_PARAM_LEN_NOT_MATCH;
695                 } else
696                         return ERR_UNKNOWN_VER_IN_MODULE;
697         } else
698                 return ERR_UNKNOWN_VER_IN_FILE;
699 }
700
701 static void XTD_Ver3To3(unsigned char *pFileBuf, unsigned long dwOffsetFile, unsigned long bFileBigEndian, 
702         unsigned char *pModuBuf, unsigned long dwOffsetModu, unsigned long bModuBigEndian)
703 {
704         /*td_calibration_struct_v3::*/td_calibration_v3_T para_modu;
705         /*td_calibration_struct_v3::*/td_calibration_v3_T para_file;
706
707         memcpy(&para_modu, pModuBuf + dwOffsetModu, sizeof(para_modu));
708         memcpy(&para_file, pFileBuf + dwOffsetFile, sizeof(para_file));
709
710         para_file.rf_afc_dac = para_modu.rf_afc_dac;
711         para_file.rf_afc_slope = para_modu.rf_afc_slope;
712
713         memcpy(&(para_file.agc_ctl_word[0]), &(para_modu.agc_ctl_word[0]),
714                 (unsigned char *)&(para_modu.agc_ctl_word[/*td_calibration_struct_v3::*/AGC_CTL_LEN_QS3200 - 1]) - 
715                 (unsigned char *)&(para_modu.agc_ctl_word[0]) + sizeof(unsigned short));
716
717         memcpy(&(para_file.agc_gain_word[0]), &(para_modu.agc_gain_word[0]),
718                 (unsigned char *)&(para_modu.agc_gain_word[/*td_calibration_struct_v3::*/AGC_GAIN_LEN_QS3200_V3 - 1]) -
719                 (unsigned char *)&(para_modu.agc_gain_word[0]) + sizeof(unsigned short));
720
721         memcpy(&(para_file.TDPA_APC_control_word_index[0]), &(para_modu.TDPA_APC_control_word_index[0]),
722                 (unsigned char *)&(para_modu.TDPA_APC_control_word_index[/*td_calibration_struct_v3::*/APC_CTL_LEN_QS3200_V3 - 1]) - (unsigned char *)&(para_modu.TDPA_APC_control_word_index[0]) + sizeof(unsigned short));
723
724         memcpy(pFileBuf + dwOffsetFile, &para_file, sizeof(para_file));
725 }
726
727 static void XTD_Ver4To4(unsigned char *pFileBuf, unsigned long dwOffsetFile, unsigned long bFileBigEndian, 
728         unsigned char *pModuBuf, unsigned long dwOffsetModu, unsigned long bModuBigEndian )
729 {
730         /*td_calibration_struct_v4::*/td_calibration_v4_T para_modu;
731         /*td_calibration_struct_v4::*/td_calibration_v4_T para_file;
732
733         memcpy(&para_modu, pModuBuf + dwOffsetModu, sizeof(para_modu));
734         memcpy(&para_file, pFileBuf + dwOffsetFile, sizeof(para_file));
735
736         memcpy(pFileBuf + dwOffsetFile, &para_modu, sizeof(para_modu));
737 }
738
739 unsigned long XTDCaliPreserve(unsigned char *lpCode, unsigned long dwCodeSize, 
740         unsigned char *lpReadBuffer, unsigned long dwReadSize, 
741         unsigned long bOldReplaceNew, unsigned long bContinue)
742 {
743         unsigned long dwOffsetFile = 0, dwLengthFile = 0;
744         unsigned long dwOffsetModu = 0, dwLengthModu = 0;
745         unsigned char *pFileBuf = lpCode;
746         unsigned char *pModuBuf = lpReadBuffer;
747
748         /* Find calibration in file */
749         if (!XFindNVOffsetEx(XTD_CALI_ITEM_ID, pFileBuf, dwCodeSize, &dwOffsetFile, &dwLengthFile, 0, 1))
750                 return ERR_NOT_FIND_PARAM_IN_FILE;
751         printf("dwOffsetFile = 0x%08lx  dwLengthFile = 0x%08lx\n", dwOffsetFile, dwLengthFile);
752         unsigned short wVerFile = *(unsigned short *)(pFileBuf + dwOffsetFile);
753         printf("wVerFile = 0x%08x\n", wVerFile);
754
755         /* Find calibration in phone */
756         if (!XFindNVOffsetEx(XTD_CALI_ITEM_ID, pModuBuf, dwReadSize, &dwOffsetModu, &dwLengthModu, 0, 1)) {
757                 if (bContinue)
758                         return ERR_NONE;
759                 else
760                         return ERR_NOT_FIND_PARAM_IN_MODULE;
761         }
762         printf("dwOffsetModu = 0x%08lx  dwLengthModu = 0x%08lx\n", dwOffsetModu, dwLengthModu);
763         unsigned short wVerModu = *(unsigned short*)(pModuBuf + dwOffsetModu);
764         printf("wVerModu = 0x%08x\n", wVerModu);
765
766         /* Update the timestamp to force nv manager to reload it */
767         /* (*(unsigned long *)lpCode) = GetTickCount(); richard.feng masked */
768
769         unsigned long dwSizeAligned = 0;
770
771         if (XTD_CALI_VER_4 == wVerFile) { 
772                 dwSizeAligned = sizeof(/*td_calibration_struct_v4::*/td_calibration_v4_T);
773                 dwSizeAligned = ((unsigned long)((dwSizeAligned + 3) / 4)) * 4;
774                 printf("dwSizeAligned = 0x%08lx  dwLengthFile = 0x%08lx\n", dwSizeAligned, dwLengthFile);
775                 if (dwLengthFile != dwSizeAligned)
776                         return ERR_PARAM_LEN_NOT_MATCH_DEF;
777                 
778                 if (XTD_CALI_VER_4 == wVerModu) {
779                         if (dwLengthFile == dwLengthModu) {
780                                 /* Version and length are both equal,just do copying */
781                                 /* memcpy( pSrc + dwOffsetFile,lpReadBuffer + dwOffset,dwLength ); */
782                                 printf("%s %d\n", __FUNCTION__, __LINE__);
783                                 XTD_Ver4To4(pFileBuf, dwOffsetFile, 0, pModuBuf, dwOffsetModu, 0);
784                                 return ERR_NONE;
785                         } else
786                                 return ERR_PARAM_LEN_NOT_MATCH;
787                 } else
788                         return ERR_UNKNOWN_VER_IN_MODULE;
789         } else if (XTD_CALI_VER_3 == wVerFile) {
790                 dwSizeAligned = sizeof(/*td_calibration_struct_v3::*/td_calibration_v3_T);
791                 dwSizeAligned = ((unsigned long)((dwSizeAligned + 3) / 4)) * 4;
792                 printf("dwSizeAligned = 0x%08lx  dwLengthFile = 0x%08lx\n", dwSizeAligned, dwLengthFile);
793                 if (dwLengthFile != dwSizeAligned)
794                         return ERR_PARAM_LEN_NOT_MATCH_DEF;
795                 
796                 if (XTD_CALI_VER_3 == wVerModu) {
797                         if (dwLengthFile == dwLengthModu) {
798                                 /* Version and length are both equal,just do copying */
799                                 /* memcpy( pSrc + dwOffsetFile,lpReadBuffer + dwOffset,dwLength ); */
800                                 printf("%s %d\n", __FUNCTION__, __LINE__);
801                                 XTD_Ver3To3(pFileBuf, dwOffsetFile, 0, pModuBuf, dwOffsetModu, 0);
802                                 return ERR_NONE;
803                         } else
804                                 return ERR_PARAM_LEN_NOT_MATCH;
805                 } else
806                         return ERR_UNKNOWN_VER_IN_MODULE;
807         } else
808                 return ERR_UNKNOWN_VER_IN_FILE;
809 }
810
811 static void LTE_Ver1To1(unsigned char *pFileBuf, unsigned long dwOffsetFile, unsigned long bFileBigEndian, 
812                         unsigned char *pModuBuf, unsigned long dwOffsetModu,unsigned long bModuBigEndian)
813 {
814         /*lte_calibration_struct_v1::*/LTE_NV_CALI_PARAM_T para_modu;
815         /*lte_calibration_struct_v1::*/LTE_NV_CALI_PARAM_T para_file;
816         
817         memcpy(&para_modu, pModuBuf + dwOffsetModu, sizeof(para_modu));
818         memcpy(&para_file, pFileBuf + dwOffsetFile, sizeof(para_file));
819         
820         memcpy(pFileBuf + dwOffsetFile, &para_modu, sizeof(para_modu));
821 }
822
823 unsigned long LTECaliPreserve(unsigned char *lpCode, unsigned long dwCodeSize, 
824                          unsigned char *lpReadBuffer, unsigned long dwReadSize,
825                          unsigned long bOldReplaceNew , unsigned long bContinue )
826 {
827         unsigned long dwOffsetFile = 0, dwLengthFile = 0;
828         unsigned long dwOffsetModu = 0, dwLengthModu = 0;
829         unsigned char *pFileBuf = lpCode;
830         unsigned char *pModuBuf = lpReadBuffer;
831
832         /* Find calibration in file */
833         if (!XFindNVOffsetEx(LTE_CALI_ITEM_ID, pFileBuf, dwCodeSize, &dwOffsetFile, &dwLengthFile, 0, 1))
834                 return ERR_NOT_FIND_PARAM_IN_FILE;
835         unsigned short wVerFile = *(unsigned short *)(pFileBuf + dwOffsetFile);
836
837         /* Find calibration in phone */
838         if (!XFindNVOffsetEx(LTE_CALI_ITEM_ID, pModuBuf, dwReadSize, &dwOffsetModu, &dwLengthModu, 0, 1)) {
839                 if (bContinue)
840                         return ERR_NONE;
841                 else
842                         return ERR_NOT_FIND_PARAM_IN_MODULE;
843         }
844         unsigned short wVerModu = *(unsigned short *)(pModuBuf + dwOffsetModu);
845
846         /* Update the timestamp to force nv manager to reload it */
847         /* (*(unsigned long*)lpCode) = GetTickCount(); richard.feng masked */
848
849         unsigned long dwSizeAligned = 0;
850
851         if (LTE_CALI_VER_1 == wVerFile) { 
852                 dwSizeAligned = sizeof(/*lte_calibration_struct_v1::*/LTE_NV_CALI_PARAM_T);
853                 dwSizeAligned = ((unsigned long)((dwSizeAligned + 3) / 4)) * 4;
854                 
855                 if (dwLengthFile != dwSizeAligned)
856                         return ERR_PARAM_LEN_NOT_MATCH_DEF;
857
858                 if (LTE_CALI_VER_1 == wVerModu) {
859                         if (dwLengthFile == dwLengthModu) {
860                                 /* Version and length are both equal,just do copying */
861                                 /* memcpy( pSrc + dwOffsetFile,lpReadBuffer + dwOffset,dwLength ); */
862                                 LTE_Ver1To1(pFileBuf, dwOffsetFile, 0, pModuBuf, dwOffsetModu, 0);
863                                 return ERR_NONE;
864                         } else
865                                 return ERR_PARAM_LEN_NOT_MATCH;
866                 } else
867                         return ERR_UNKNOWN_VER_IN_MODULE;
868         } else
869                 return ERR_UNKNOWN_VER_IN_FILE;
870 }
871
872 unsigned long XPreserveNVItem(unsigned short wID, unsigned char *lpCode, unsigned long dwCodeSize, 
873                                 unsigned char *lpReadBuffer, unsigned long dwReadSize, 
874                                 unsigned long bOldReplaceNew, unsigned long bContinue)
875 {
876         unsigned long dwOffsetFile, dwLengthFile;
877         unsigned long dwOffsetModu, dwLengthModu;
878
879         if (wID == GSM_CALI_ITEM_ID || wID == XTD_CALI_ITEM_ID)
880                 return ERR_NONE;
881         printf("wID = 0x%08x\n", wID);
882         if (!XFindNVOffsetEx(wID, lpReadBuffer, dwReadSize, &dwOffsetModu, &dwLengthModu, 0, 1)) {
883                 if (bContinue)
884                         return ERR_NONE;
885                 else
886                         return ERR_NOT_FIND_PARAM_IN_MODULE;    
887         }
888         
889         printf("wID = 0x%08x  dwOffsetModu = 0x%08lx  dwLengthModu = 0x%08lx\n", wID, dwOffsetModu, dwLengthModu);
890
891         if (!XFindNVOffsetEx(wID, lpCode, dwCodeSize, &dwOffsetFile, &dwLengthFile, 0, 1))              
892                 return ERR_NOT_FIND_PARAM_IN_FILE;
893
894         printf("wID = 0x%08x  dwOffsetFile = 0x%08lx  dwLengthFile = 0x%08lx\n", wID, dwOffsetFile, dwLengthFile);
895
896         if (dwLengthModu != dwLengthFile)   
897                 return ERR_PARAM_LEN_NOT_MATCH;
898
899         /* BT */
900         if (wID == BT_ITEM_ID) {
901                 unsigned long dwSizeAligned = sizeof(BT_CONFIG);
902                 dwSizeAligned = ((unsigned long)((dwSizeAligned + 3) / 4)) * 4;         
903                 if(dwLengthFile != dwSizeAligned)
904                         return ERR_PARAM_LEN_NOT_MATCH_DEF;
905
906                 BT_CONFIG para = {0};
907                 memcpy(&para, lpReadBuffer + dwOffsetModu, dwLengthModu);
908                 memcpy(lpCode + dwOffsetFile, &para, dwLengthModu);
909         } else 
910                 memcpy(lpCode + dwOffsetFile, lpReadBuffer + dwOffsetModu, dwLengthModu);
911     
912         return ERR_NONE;    
913 }
914
915 unsigned long XPreserveIMEIs(unsigned short wID, unsigned char *lpCode, unsigned long dwCodeSize, 
916                                 unsigned char *lpReadBuffer, unsigned long dwReadSize, 
917                                 unsigned long bOldReplaceNew, unsigned long bContinue)
918 {
919         unsigned long dwRet = ERR_NONE;
920
921         if (wID == 0xFFFF) /* IMEI */
922                 wID = GSM_IMEI_ITEM_ID;
923
924         if (wID == GSM_IMEI_ITEM_ID)
925                 dwRet = XPreserveNVItem(wID, lpCode, dwCodeSize, lpReadBuffer, dwReadSize, 
926                                         bOldReplaceNew, bContinue);                     
927         else
928                 dwRet = XPreserveNVItem(wID, lpCode, dwCodeSize, lpReadBuffer, dwReadSize, bOldReplaceNew, 1);
929         
930         return dwRet;
931 }
932