FreeCalypso > hg > leo2moko-debug
comparison g23m/condat/ms/src/aci/phb_aci.c @ 0:509db1a7b7b8
initial import: leo2moko-r1
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Mon, 01 Jun 2015 03:24:05 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:509db1a7b7b8 |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | Project : MMI-Framework (8417) | |
4 | Modul : PHB | |
5 +----------------------------------------------------------------------------- | |
6 | Copyright 2002 Texas Instruments Berlin, AG | |
7 | All rights reserved. | |
8 | | |
9 | This file is confidential and a trade secret of Texas | |
10 | Instruments Berlin, AG | |
11 | The receipt of or possession of this file does not convey | |
12 | any rights to reproduce or disclose its contents or to | |
13 | manufacture, use, or sell anything it may describe, in | |
14 | whole, or in part, without the specific written consent of | |
15 | Texas Instruments Berlin, AG. | |
16 +----------------------------------------------------------------------------- | |
17 | Purpose : This modul contains the functions to establish the phone book. | |
18 +----------------------------------------------------------------------------- | |
19 */ | |
20 | |
21 #ifdef TI_PS_FFS_PHB | |
22 | |
23 #include "aci_all.h" | |
24 #include "aci_cmh.h" | |
25 #include "aci_mem.h" | |
26 | |
27 #include "phb_aci.h" | |
28 | |
29 #ifdef _SIMULATION_ | |
30 /* | |
31 * Unfortunately we have a double definition of some preprocessor definitions | |
32 * within windows.h and within the protocol stack, so we undefine here. | |
33 */ | |
34 #undef PARITY_NONE | |
35 #undef PARITY_ODD | |
36 #undef PARITY_EVEN | |
37 #undef DRV_OK | |
38 #include "ffs_pc_api.h" | |
39 #undef PARITY_NONE | |
40 #undef PARITY_ODD | |
41 #undef PARITY_EVEN | |
42 #undef DRV_OK | |
43 #else | |
44 #include "ffs/ffs.h" | |
45 #endif | |
46 | |
47 #ifdef SIM_TOOLKIT | |
48 #include "psa.h" | |
49 #include "psa_sim.h" | |
50 #include "psa_cc.h" | |
51 #include "psa_sat.h" | |
52 #endif /* #ifdef SIM_TOOLKIT */ | |
53 | |
54 #include "cmh.h" | |
55 #include "cmh_phb.h" | |
56 | |
57 #ifdef DTI | |
58 #include "dti_conn_mng.h" | |
59 #endif | |
60 #include "cmh_sim.h" | |
61 | |
62 | |
63 /* | |
64 * Constants and enumerations | |
65 */ | |
66 //#define NR_EF_ICI 20 /* LRN, LMN */ | |
67 //#define SIZE_EF_ICI (28+16) /* alpha id 16 bytes, 31.102 clause 4.2.33 */ | |
68 | |
69 #define NR_EF_OCI 10 /* Arbitrary, LDN */ | |
70 #define SIZE_EF_OCI (27+16) /* alpha id 16 bytes, 31.102 clause 4.2.34 */ | |
71 | |
72 #define NR_EF_EXT5 10 /* Arbitrary */ | |
73 #define SIZE_EF_EXT5 13 /* 31.102 clause 4.2.37 */ | |
74 | |
75 #define NR_EF_LRN 10 /* Arbitrary, LRN */ | |
76 #define SIZE_EF_LRN SIZE_EF_OCI | |
77 | |
78 #define NR_EF_LMN 10 /* Arbitrary, LMN */ | |
79 #define SIZE_EF_LMN SIZE_EF_OCI | |
80 | |
81 #define NR_EF_EXT_LRN 10 /* Arbitrary */ | |
82 #define SIZE_EF_EXT_LRN SIZE_EF_EXT5 | |
83 | |
84 #define NR_EF_EXT_LMN 10 /* Arbitrary */ | |
85 #define SIZE_EF_EXT_LMN SIZE_EF_EXT5 | |
86 | |
87 #define PHB_MAX_QUEUE 4 /* Queued LDN entries */ | |
88 #define SIM_MAX_RECORD_SIZE 256 /* Maximum size of a SIM record */ | |
89 | |
90 #define PHB_STATE_NULL 0 /* NULL state before reading phonebook */ | |
91 #define PHB_STATE_IDLE 1 /* IDLE state, phonebook has been read */ | |
92 #define PHB_STATE_VERIFY 2 /* Verify SIM (Initialization, SAT) */ | |
93 #define PHB_STATE_READ 3 /* Reading from SIM (Initialization, SAT) */ | |
94 #define PHB_STATE_WRITE 4 /* Write/Delete single record to SIM */ | |
95 #define PHB_STATE_DELETE_BOOK 5 /* Delete a whole SIM phonebook */ | |
96 | |
97 #define SET_PHB_STATE(n) pba_data.state = n; | |
98 #define GET_PHB_STATE() pba_data.state | |
99 | |
100 typedef enum | |
101 { | |
102 INVALID_EXT = -1, | |
103 EXT1, /* ADN, LDN phonebook Extention */ | |
104 EXT2, /* FDN phonebook Extention */ | |
105 EXT3, | |
106 EXT4, | |
107 EXT5, /* Release 1999+ for EF_ICI, EF_OCI */ | |
108 EXT_LRN, /* Extension for LRN */ | |
109 EXT_LMN, /* Extension for LMN */ | |
110 MAX_PHB_EXT | |
111 } T_EXT_TYPE; | |
112 | |
113 typedef struct | |
114 { | |
115 USHORT index; | |
116 T_PHB_RECORD entry; | |
117 } T_PHB_QUEUE; | |
118 | |
119 /* | |
120 * Type definitions | |
121 */ | |
122 typedef struct | |
123 { | |
124 /* Fixed Dialling Numbers mode */ | |
125 T_PHB_FDN_MODE fdn_mode; | |
126 | |
127 /* Fixed Dialling Number class type */ | |
128 T_ACI_CLASS fdn_classtype; | |
129 | |
130 /* T_PHB_STATE of the phonebook */ | |
131 T_PHB_STAT phb_stat; | |
132 | |
133 /* Current state of the phonebook PHB_STATE_XXX */ | |
134 UBYTE state; | |
135 | |
136 /* SIM data */ | |
137 UBYTE *data; | |
138 | |
139 /* SIM service table */ | |
140 UBYTE sim_service_table[MAX_SRV_TBL]; | |
141 | |
142 /* Database has to be recreated (IMSI changed or DB unclean) */ | |
143 BOOL db_recreate; | |
144 | |
145 /* Paused elementary file if reading extension record, otherwise 0 */ | |
146 USHORT paused_ef; | |
147 | |
148 /* Paused record number if reading extension record, otherwise 0 */ | |
149 UBYTE paused_no; | |
150 | |
151 /* Delete all: Book to delete, Read: Current book reading */ | |
152 T_PHB_TYPE current_book; | |
153 | |
154 /* Delete all: current record */ | |
155 UBYTE del_record; | |
156 | |
157 /* Book created */ | |
158 BOOL book_created[MAX_PHONEBOOK]; | |
159 | |
160 /* Extension created */ | |
161 BOOL ext_created[MAX_PHB_EXT]; | |
162 | |
163 /* We are reading the 1st ext record only to get the number of records */ | |
164 BOOL ext_dummy_read; | |
165 | |
166 /* Read flags for SIM phonebooks. Set to TRUE when reading has started */ | |
167 BOOL book_read[MAX_PHONEBOOK]; | |
168 | |
169 /* Maximum number of phonebook records */ | |
170 UBYTE phb_record_max[MAX_PHONEBOOK]; | |
171 /* Maximum number of extension records */ | |
172 UBYTE ext_record_max[MAX_PHB_EXT]; | |
173 | |
174 /* Record sizes of phonebook records */ | |
175 UBYTE phb_record_len[MAX_PHONEBOOK]; | |
176 /* Record sizes of extension records */ | |
177 UBYTE ext_record_len[MAX_PHB_EXT]; | |
178 | |
179 /* Queued LDN entries during startup */ | |
180 UBYTE c_queued; | |
181 T_PHB_QUEUE *queued[PHB_MAX_QUEUE]; | |
182 | |
183 /* Records to be synchronized to the SIM */ | |
184 T_DB_CHANGED records_changed; | |
185 } T_PHB_ACI_DATA; | |
186 | |
187 /* We pack all internal data into one data structure */ | |
188 LOCAL T_PHB_ACI_DATA pba_data; | |
189 | |
190 | |
191 /* | |
192 * Prototypes for local functions | |
193 */ | |
194 LOCAL UBYTE pb_get_max_num_len (T_PHB_TYPE type); | |
195 LOCAL BOOL pb_sim_service (UBYTE nr); | |
196 LOCAL BOOL pb_read_sim_record (USHORT data_id, | |
197 UBYTE rcd_num, | |
198 UBYTE len); | |
199 LOCAL BOOL pb_read_sim (USHORT data_id, UBYTE len, UBYTE max_length); | |
200 LOCAL void pb_read_next_sim_book (void); | |
201 LOCAL void pb_read_sim_record_cb (SHORT table_id); | |
202 LOCAL void pb_read_sim_cb (SHORT table_id); | |
203 LOCAL void pb_sat_update_reset (USHORT ef); | |
204 LOCAL T_PHB_RETURN pb_sync_next_sim_record (BOOL first); | |
205 LOCAL T_PHB_RETURN pb_write_sim_record (USHORT ef, | |
206 UBYTE phy_recno, | |
207 UBYTE entry_size, | |
208 const UBYTE *buffer); | |
209 LOCAL void pb_write_sim_record_cb (SHORT table_id); | |
210 T_PHB_TYPE pb_get_phb_type_from_ef (USHORT ef); | |
211 T_EXT_TYPE pb_get_ext_type_from_ef (USHORT ef); | |
212 LOCAL void pb_status_ind (T_PHB_STAT phb_stat, | |
213 SHORT cmeError); | |
214 LOCAL T_PHB_RETURN pb_write_queue (const T_PHB_RECORD *entry); | |
215 LOCAL void pb_clear_queue (void); | |
216 LOCAL T_PHB_RETURN pb_read_queue (void); | |
217 | |
218 /* | |
219 * Functions - Interface functions to external modules | |
220 */ | |
221 | |
222 | |
223 /* | |
224 +----------------------------------------------------------------------------+ | |
225 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
226 | STATE : code ROUTINE : pb_init | | |
227 +----------------------------------------------------------------------------+ | |
228 | |
229 PURPOSE : Power-on initialization of the phonebook module. This function | |
230 is called at a point in time by pei_init() when it cannot be | |
231 expected that the protocol stack has been booted up completely, | |
232 so it is undesirable to do anything here which might rely on | |
233 a module still not started up like the PCM or the FFS. | |
234 | |
235 */ | |
236 GLOBAL void pb_init (void) | |
237 { | |
238 TRACE_FUNCTION ("pb_init()"); | |
239 | |
240 memset (&pba_data, 0, sizeof (T_PHB_ACI_DATA)); | |
241 | |
242 pba_data.fdn_mode = NO_OPERATION; | |
243 pba_data.fdn_classtype = CLASS_VceDatFaxSms; | |
244 | |
245 pb_sim_init(); | |
246 | |
247 #ifdef SIM_TOOLKIT | |
248 simShrdPrm.fuRef= - 1; | |
249 psaSAT_FURegister (pb_update); | |
250 #endif /* #ifdef SIM_TOOLKIT */ | |
251 | |
252 SET_PHB_STATE (PHB_STATE_NULL); | |
253 } | |
254 | |
255 | |
256 /* | |
257 +----------------------------------------------------------------------------+ | |
258 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
259 | STATE : code ROUTINE : pb_exit_phb | | |
260 +----------------------------------------------------------------------------+ | |
261 | |
262 PURPOSE : This function synchronizes, if necessary, all unwritten data, | |
263 shuts down the SIM phonebook layer and deallocates all | |
264 resources. The SIM itself is not deactivated here. | |
265 | |
266 | |
267 */ | |
268 LOCAL void pb_exit_phb (void) | |
269 { | |
270 TRACE_FUNCTION ("pb_exit_phb()"); | |
271 | |
272 /* | |
273 * Flush everything which has not yet been written. | |
274 * Note: It's a good idea if everything is written immediately | |
275 * so that we don't need to flush anything here. Competitor phones | |
276 * do the job in this way, this has the advantage that even after | |
277 * a phone crash immediately after dialling a number or missing | |
278 * a call nothing is lost. | |
279 */ | |
280 (void)pb_sim_flush_data (); | |
281 | |
282 /* Shutdown the lower layers */ | |
283 pb_sim_exit (); | |
284 | |
285 /* | |
286 * Free all allocated resources | |
287 */ | |
288 if (pba_data.data NEQ NULL) | |
289 { | |
290 ACI_MFREE (pba_data.data); | |
291 pba_data.data = NULL; | |
292 } | |
293 | |
294 pb_clear_queue (); | |
295 | |
296 /* | |
297 * Set phonebook to no operation | |
298 */ | |
299 pba_data.fdn_mode = NO_OPERATION; | |
300 pba_data.phb_stat = PHB_UNKNOWN; | |
301 SET_PHB_STATE (PHB_STATE_NULL); | |
302 } | |
303 | |
304 | |
305 /* | |
306 +----------------------------------------------------------------------------+ | |
307 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
308 | STATE : code ROUTINE : pb_exit | | |
309 +----------------------------------------------------------------------------+ | |
310 | |
311 PURPOSE : Shutdown phonebook and the SIM itself also. | |
312 | |
313 */ | |
314 GLOBAL void pb_exit (void) | |
315 { | |
316 TRACE_FUNCTION ("pb_exit()"); | |
317 | |
318 /* Shutdown SIM phonebook */ | |
319 pb_exit_phb (); | |
320 | |
321 /* Shutdown the SIM itself */ | |
322 simShrdPrm.synCs = SYNC_DEACTIVATE; | |
323 psaSIM_SyncSIM(); | |
324 } | |
325 | |
326 | |
327 /* | |
328 +----------------------------------------------------------------------------+ | |
329 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
330 | STATE : code ROUTINE : pb_reset | | |
331 +----------------------------------------------------------------------------+ | |
332 | |
333 PURPOSE : Resets the phonebook, basically pb_exit() / pb_init(). | |
334 | |
335 */ | |
336 GLOBAL void pb_reset (void) | |
337 { | |
338 TRACE_FUNCTION ("pb_reset()"); | |
339 | |
340 if (GET_PHB_STATE() EQ PHB_STATE_NULL) | |
341 return; | |
342 | |
343 pb_exit_phb(); | |
344 pb_init(); | |
345 } | |
346 | |
347 /* | |
348 +----------------------------------------------------------------------------+ | |
349 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
350 | STATE : code ROUTINE : pb_set_sim_ecc | | |
351 +----------------------------------------------------------------------------+ | |
352 | |
353 PURPOSE : This function set's the emergency call numbers. | |
354 This can only happen at startup time when the SIM when | |
355 a SIM_ACTIVATE_CNF / SIM_ACTIVATE_IND is received. | |
356 At this point in time the entering of PIN may be outstanding, | |
357 the only information we may have gotten are the emergency call | |
358 numbers. | |
359 | |
360 */ | |
361 GLOBAL void pb_set_sim_ecc (USHORT cause, | |
362 UBYTE ecc_len, | |
363 const UBYTE *sim_ecc) | |
364 { | |
365 TRACE_FUNCTION ("pb_set_sim_ecc()"); | |
366 | |
367 if (pba_data.fdn_mode NEQ NO_OPERATION) | |
368 { | |
369 /* | |
370 * Setting of the emergency call numbers after having gotten the | |
371 * IMSI of the SIM is ignored. | |
372 */ | |
373 return; | |
374 } | |
375 | |
376 if ((cause EQ SIM_CAUSE_OTHER_ERROR) OR | |
377 (cause EQ SIM_CAUSE_CARD_REMOVED) OR | |
378 (cause >= SIM_CAUSE_PARAM_WRONG AND cause <= SIM_CAUSE_DRV_TEMPFAIL)) | |
379 { | |
380 /* | |
381 * Some error from the SIM. Indicate a fallback to the PCM/FFS. | |
382 */ | |
383 (void)pb_sim_set_ecc (0, NULL); | |
384 } | |
385 else | |
386 { | |
387 (void)pb_sim_set_ecc (ecc_len, sim_ecc); | |
388 } | |
389 | |
390 | |
391 | |
392 } | |
393 | |
394 | |
395 /* | |
396 +----------------------------------------------------------------------------+ | |
397 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
398 | STATE : code ROUTINE : pb_inserted_sim | | |
399 +----------------------------------------------------------------------------+ | |
400 | |
401 PURPOSE : This function is called when the PIN has been entered and we have | |
402 the IMSI and full access on the SIM phonebook. Reading/Verifying | |
403 of phonebook data is not started at this point except for the | |
404 ECC phonebook. | |
405 | |
406 */ | |
407 GLOBAL void pb_inserted_sim (UBYTE c_sim_serv, | |
408 UBYTE *sim_serv, | |
409 const T_imsi_field *imsi_field, | |
410 UBYTE adn_bdn_fdn_func, | |
411 UBYTE phase) // For further study | |
412 { | |
413 T_FFS_SIZE ffs_size; /* FFS result code */ | |
414 T_ACI_CLASS classFDN; /* FDN class */ | |
415 UBYTE ub_class = (UBYTE)CLASS_None; /* T_ACI_CLASS */ | |
416 | |
417 TRACE_FUNCTION ("pb_inserted_sim()"); | |
418 | |
419 /* Store SIM service table */ | |
420 if (c_sim_serv > MAX_SRV_TBL) | |
421 c_sim_serv = MAX_SRV_TBL; /* Garbage protection */ | |
422 memcpy (pba_data.sim_service_table, sim_serv, c_sim_serv); | |
423 | |
424 /* | |
425 * Open SIM phonebook. Remember whether the database has to be recreated | |
426 * for some reason (SIM changed, database unclean). | |
427 */ | |
428 if (pb_sim_open (imsi_field, &pba_data.db_recreate) NEQ PHB_OK) | |
429 { | |
430 /* We're here in really big trouble and can do nothing about it */ | |
431 TRACE_ERROR ("Fatal: pb_sim_open() NEQ PHB_OK"); | |
432 } | |
433 | |
434 /* | |
435 * Update ECC phonebook | |
436 */ | |
437 pba_data.book_read[ECC] = TRUE; | |
438 if (!pb_read_sim (SIM_ECC, NOT_PRESENT_8BIT, (UBYTE)SIM_MAX_RECORD_SIZE)) | |
439 { | |
440 /* Unexpected problem. Live with previously read values */ | |
441 TRACE_ERROR ("Unexpected: No free SIM slot"); | |
442 } | |
443 | |
444 switch (adn_bdn_fdn_func) | |
445 { | |
446 case SIM_ADN_ENABLED: | |
447 case SIM_ADN_BDN_ENABLED: | |
448 pba_data.fdn_mode = FDN_DISABLE; | |
449 break; | |
450 | |
451 case SIM_FDN_ENABLED: | |
452 case SIM_FDN_BDN_ENABLED: | |
453 pba_data.fdn_mode = FDN_ENABLE; | |
454 | |
455 /* read last fdn_classtype from FFS */ | |
456 ffs_size = ffs_file_read ("/mmi/fdnClassType", &ub_class, sizeof(ub_class)); | |
457 | |
458 if (ffs_size EQ sizeof(ub_class)) /* successful read */ | |
459 { | |
460 classFDN = (T_ACI_CLASS)ub_class; | |
461 | |
462 /* only these two classes are currently supported */ | |
463 if (classFDN EQ CLASS_VceDatFax OR | |
464 classFDN EQ CLASS_VceDatFaxSms) | |
465 { | |
466 pba_data.fdn_classtype = classFDN; | |
467 } | |
468 } | |
469 break; | |
470 | |
471 default: /* SIM_NO_OPERATION or trash */ | |
472 pba_data.fdn_mode = NO_OPERATION; | |
473 break; | |
474 } | |
475 } | |
476 | |
477 | |
478 /* | |
479 +----------------------------------------------------------------------------+ | |
480 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
481 | STATE : code ROUTINE : pb_start_build | | |
482 +----------------------------------------------------------------------------+ | |
483 | |
484 PURPOSE : This function is called when the flash phonebook has to be | |
485 read/verified from/against the phonebook stored on the SIM card. | |
486 This is triggered by the reception of the | |
487 MNSMS_REPORT_IND (SMS_STATE_READY) primitive. | |
488 | |
489 */ | |
490 GLOBAL void pb_start_build (BOOL unchanged) | |
491 { | |
492 TRACE_FUNCTION ("pb_start_build()"); | |
493 | |
494 if (pba_data.db_recreate) | |
495 { | |
496 /* | |
497 * Indicate a busy phonebook. We have to re-read all from scratch | |
498 */ | |
499 pb_status_ind (PHB_BUSY, CME_ERR_NotPresent); | |
500 SET_PHB_STATE (PHB_STATE_READ); | |
501 } | |
502 else | |
503 { | |
504 /* | |
505 * SIM (IMSI) not changed and database clean, | |
506 * allow reading from the SIM phonebook by the MMI. | |
507 */ | |
508 pb_status_ind (PHB_READY, CME_ERR_NotPresent); | |
509 SET_PHB_STATE (PHB_STATE_VERIFY); | |
510 } | |
511 | |
512 pba_data.ext_dummy_read = FALSE; | |
513 | |
514 #ifdef _SIMULATION_ | |
515 TRACE_EVENT_P1 ("SRV_ADN: %s", pb_sim_service (SRV_ADN) ? "YES" : "NO"); | |
516 TRACE_EVENT_P1 ("SRV_FDN: %s", pb_sim_service (SRV_FDN) ? "YES" : "NO"); | |
517 TRACE_EVENT_P1 ("SRV_CCP: %s", pb_sim_service (SRV_CCP) ? "YES" : "NO"); | |
518 TRACE_EVENT_P1 ("SRV_MSISDN: %s",pb_sim_service (SRV_MSISDN) ? "YES" : "NO"); | |
519 TRACE_EVENT_P1 ("SRV_EXT1: %s", pb_sim_service (SRV_EXT1) ? "YES" : "NO"); | |
520 TRACE_EVENT_P1 ("SRV_EXT2: %s", pb_sim_service (SRV_EXT2) ? "YES" : "NO"); | |
521 TRACE_EVENT_P1 ("SRV_LDN: %s", pb_sim_service (SRV_LDN) ? "YES" : "NO"); | |
522 TRACE_EVENT_P1 ("SRV_SDN: %s", pb_sim_service (SRV_SDN) ? "YES" : "NO"); | |
523 TRACE_EVENT_P1 ("SRV_EXT3: %s", pb_sim_service (SRV_EXT3) ? "YES" : "NO"); | |
524 TRACE_EVENT_P1 ("SRV_BDN: %s", pb_sim_service (SRV_BDN) ? "YES" : "NO"); | |
525 TRACE_EVENT_P1 ("SRV_EXT4: %s", pb_sim_service (SRV_EXT4) ? "YES" : "NO"); | |
526 #endif | |
527 | |
528 pb_read_next_sim_book(); | |
529 } | |
530 | |
531 | |
532 /* | |
533 +----------------------------------------------------------------------------+ | |
534 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
535 | STATE : code ROUTINE : pb_update | | |
536 +----------------------------------------------------------------------------+ | |
537 | |
538 PURPOSE : This function is called when the SIM wants to inform the | |
539 phonebook that some elementary files have been changed. | |
540 Returns TRUE if no files aere changed affecting the phonebook, | |
541 otherwise FALSE. | |
542 | |
543 */ | |
544 GLOBAL BOOL pb_update (int ref, | |
545 T_SIM_FILE_UPDATE_IND *fu) | |
546 { | |
547 unsigned i; /* Index variable */ | |
548 T_PHB_TYPE phb_type; /* Phonebook type */ | |
549 T_EXT_TYPE ext_type; /* Extension type */ | |
550 USHORT ef; /* Elementary file number */ | |
551 | |
552 TRACE_FUNCTION ("pb_update()"); | |
553 | |
554 simShrdPrm.fuRef = -1; /* Assume phonebook is not affected */ | |
555 | |
556 for (i = 0; i < fu->val_nr; i++) | |
557 { | |
558 ef = fu->file_id[i]; | |
559 | |
560 if (ef EQ SIM_SST) | |
561 { | |
562 /* | |
563 * When SIM service table is changed, then all SIM phonebooks | |
564 * will be updated. | |
565 */ | |
566 | |
567 /* Mark all phonebooks as unread */ | |
568 pb_sat_update_reset (SIM_ECC); | |
569 pb_sat_update_reset (SIM_ADN); | |
570 pb_sat_update_reset (SIM_FDN); | |
571 pb_sat_update_reset (SIM_BDN); | |
572 #ifdef SIM_LND_SUPPORT | |
573 pb_sat_update_reset (SIM_LND); | |
574 #endif | |
575 pb_sat_update_reset (SIM_MSISDN); | |
576 pb_sat_update_reset (SIM_SDN); | |
577 | |
578 /* Mark all extensions as unread */ | |
579 pb_sat_update_reset (EXT1); | |
580 pb_sat_update_reset (EXT2); | |
581 pb_sat_update_reset (EXT3); | |
582 pb_sat_update_reset (EXT4); | |
583 | |
584 if (!pb_read_sim (SIM_SST, NOT_PRESENT_8BIT, (UBYTE)SIM_MAX_RECORD_SIZE)) | |
585 { | |
586 /* | |
587 * We could not get an empty slot and are in trouble now as there is | |
588 * no good error handling possible here. On the other hand, it is | |
589 * not expected ever that an error occurs here. | |
590 */ | |
591 TRACE_ERROR ("Internal problem getting a SIM slot"); | |
592 return TRUE; /* No update in progress */ | |
593 } | |
594 | |
595 simShrdPrm.fuRef = ref; /* Something to do */ | |
596 | |
597 SET_PHB_STATE (PHB_STATE_READ); | |
598 return FALSE; /* Update in progress */ | |
599 } | |
600 } | |
601 | |
602 /* | |
603 * At least the SIM service table has not been changed, check now for | |
604 * single phonebooks and extension records. | |
605 */ | |
606 | |
607 for (i = 0; i < fu->val_nr; i++) | |
608 { | |
609 ef = fu->file_id[i]; | |
610 phb_type = pb_get_phb_type_from_ef (ef); | |
611 ext_type = pb_get_ext_type_from_ef (ef); | |
612 | |
613 if (phb_type NEQ INVALID_PHB) | |
614 { | |
615 /* Phonebook affected by change */ | |
616 simShrdPrm.fuRef = ref; | |
617 | |
618 /* Reset respective field */ | |
619 pb_sat_update_reset (ef); | |
620 | |
621 switch (phb_type) | |
622 { | |
623 case ADN: | |
624 pb_sat_update_reset (SIM_FDN); | |
625 break; | |
626 | |
627 case FDN: | |
628 pb_sat_update_reset (SIM_ADN); | |
629 break; | |
630 | |
631 default: | |
632 break; | |
633 } | |
634 } | |
635 else if (ext_type NEQ INVALID_EXT) | |
636 { | |
637 /* Phonebook affected by change */ | |
638 simShrdPrm.fuRef = ref; | |
639 | |
640 /* Reset respective field */ | |
641 pb_sat_update_reset (ef); | |
642 | |
643 /* Mark also the appropriate book itself as unread */ | |
644 switch (ext_type) | |
645 { | |
646 case EXT1: | |
647 pb_sat_update_reset (SIM_ADN); | |
648 pb_sat_update_reset (SIM_MSISDN); | |
649 #ifdef SIM_LND_SUPPORT | |
650 pb_sat_update_reset (SIM_LND); | |
651 #endif | |
652 break; | |
653 | |
654 case EXT2: | |
655 pb_sat_update_reset (SIM_FDN); | |
656 break; | |
657 | |
658 case EXT3: | |
659 pb_sat_update_reset (SIM_SDN); | |
660 break; | |
661 | |
662 case EXT4: | |
663 pb_sat_update_reset (SIM_EXT4); | |
664 break; | |
665 | |
666 default: | |
667 TRACE_ERROR ("Unexpected default"); /* Everything caught */ | |
668 break; | |
669 } | |
670 } | |
671 } | |
672 | |
673 if (simShrdPrm.fuRef NEQ -1) | |
674 { | |
675 pb_start_build (FALSE); | |
676 return FALSE; /* FALSE means update in progress */ | |
677 } | |
678 | |
679 return TRUE; /* TRUE means nothing to do */ | |
680 } | |
681 | |
682 | |
683 /* | |
684 +----------------------------------------------------------------------------+ | |
685 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
686 | STATE : code ROUTINE : pb_flush_data | | |
687 +----------------------------------------------------------------------------+ | |
688 | |
689 PURPOSE : This function is called when someone wants to flush some pending | |
690 data to persistent memory. Probably a bad concept, it's always | |
691 better to flush always internally if some operation is finished | |
692 and to synchronize also to the SIM immediately. This has the | |
693 advantage that even after a crash nothing is lost. | |
694 | |
695 */ | |
696 T_PHB_RETURN pb_flush_data (void) | |
697 { | |
698 TRACE_FUNCTION ("pb_flush_data()"); | |
699 | |
700 /* This function is empty, and this should remain this way if possible */ | |
701 return PHB_OK; | |
702 } | |
703 | |
704 | |
705 /* | |
706 +----------------------------------------------------------------------------+ | |
707 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
708 | STATE : code ROUTINE : pb_add_record | | |
709 +----------------------------------------------------------------------------+ | |
710 | |
711 PURPOSE : This function adds or replaces a phonebook entry. | |
712 | |
713 */ | |
714 GLOBAL T_PHB_RETURN pb_add_record (T_PHB_TYPE type, | |
715 USHORT phy_recno, | |
716 const T_PHB_RECORD *entry) | |
717 { | |
718 T_PHB_RETURN phb_result; | |
719 T_DB_CHANGED dummy_changed; | |
720 | |
721 TRACE_FUNCTION ("pb_add_record()"); | |
722 | |
723 #ifdef _SIMULATION_ | |
724 { | |
725 char name [PHB_MAX_TAG_LEN + 1]; | |
726 char number[MAX_PHB_NUM_LEN]; | |
727 | |
728 memset (name, 0, PHB_MAX_TAG_LEN + 1); | |
729 memcpy (name, entry->tag, entry->tag_len); | |
730 cmhPHB_getAdrStr (number, | |
731 MAX_PHB_NUM_LEN - 1, | |
732 entry->number, | |
733 entry->len); | |
734 if ((UBYTE)(name[0]) >= 0x80) | |
735 strcpy (name, "<Some UCS2 coding>"); | |
736 | |
737 TRACE_EVENT_P4 ("Adding number %s with name '%s' to book %d record %d", | |
738 number, name, type, phy_recno); | |
739 } | |
740 #endif | |
741 | |
742 /* Fix phy_recno parameter for circular books */ | |
743 if ((type EQ LDN) OR (type EQ LMN) OR (type EQ LRN)) | |
744 { | |
745 if (phy_recno EQ 0) | |
746 phy_recno = 1; | |
747 } | |
748 | |
749 switch (GET_PHB_STATE()) | |
750 { | |
751 case PHB_STATE_IDLE: | |
752 | |
753 /* Add the data in the database */ | |
754 phb_result = pb_sim_add_record (type, | |
755 phy_recno, | |
756 entry, | |
757 &pba_data.records_changed); | |
758 if (phb_result NEQ PHB_OK) | |
759 return phb_result; /* Record could not be added to the database */ | |
760 | |
761 if (pba_data.records_changed.entries NEQ 0) | |
762 { | |
763 SET_PHB_STATE (PHB_STATE_WRITE); | |
764 } | |
765 | |
766 /* Start synchronizing record(s) to the SIM */ | |
767 return pb_sync_next_sim_record (TRUE); | |
768 | |
769 case PHB_STATE_VERIFY: | |
770 case PHB_STATE_READ: | |
771 if ((type EQ LRN) OR (type EQ LMN)) | |
772 { | |
773 /* | |
774 * In Release 1998- there is no counterpart on the SIM here, | |
775 * we can write immediately as we don't have to synch to the SIM. | |
776 */ | |
777 return (pb_sim_add_record (type, | |
778 phy_recno, | |
779 entry, | |
780 &dummy_changed)); | |
781 } | |
782 else if (type EQ LDN) | |
783 { | |
784 /* We have to queue the LDN entry and will write later */ | |
785 return pb_write_queue (entry); | |
786 } | |
787 return PHB_FAIL; | |
788 | |
789 default: | |
790 return PHB_FAIL; | |
791 } | |
792 } | |
793 | |
794 | |
795 /* | |
796 +----------------------------------------------------------------------------+ | |
797 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
798 | STATE : code ROUTINE : pb_del_record | | |
799 +----------------------------------------------------------------------------+ | |
800 | |
801 PURPOSE : This function deletes a phonebook entry. | |
802 | |
803 */ | |
804 GLOBAL T_PHB_RETURN pb_del_record (T_PHB_TYPE type, | |
805 USHORT phy_recno) | |
806 { | |
807 T_PHB_RETURN phb_result; | |
808 | |
809 TRACE_FUNCTION ("pb_del_record()"); | |
810 | |
811 if (GET_PHB_STATE() NEQ PHB_STATE_IDLE) | |
812 return PHB_FAIL; | |
813 | |
814 /* Delete the data in the database */ | |
815 phb_result = pb_sim_del_record (type, | |
816 phy_recno, | |
817 &pba_data.records_changed); | |
818 if (phb_result NEQ PHB_OK) | |
819 return phb_result; /* Record could not be deleted from the database */ | |
820 | |
821 if (pba_data.records_changed.entries NEQ 0) | |
822 { | |
823 SET_PHB_STATE (PHB_STATE_WRITE); | |
824 } | |
825 | |
826 /* Start synchronizing record(s) to the SIM */ | |
827 return pb_sync_next_sim_record (TRUE); | |
828 } | |
829 | |
830 | |
831 /* | |
832 +----------------------------------------------------------------------------+ | |
833 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
834 | STATE : code ROUTINE : pb_check_fdn | | |
835 +----------------------------------------------------------------------------+ | |
836 | |
837 PURPOSE : This function checks whether a phone number is in FDN phonebook. | |
838 | |
839 */ | |
840 #define RETURN(x) { retVal = x; goto cleanup_exit; } | |
841 /*lint -e{801} Use of goto*/ | |
842 GLOBAL T_PHB_RETURN pb_check_fdn (UBYTE toa, | |
843 const UBYTE *number) | |
844 { | |
845 T_PHB_RETURN retVal; | |
846 T_PHB_RECORD *phb_record; | |
847 size_t cmp_len; | |
848 CHAR cur_number[MAX_PHB_NUM_LEN]; | |
849 USHORT phy_recno; | |
850 SHORT max_rcd; | |
851 SHORT dummy_used_rcd; | |
852 UBYTE dummy_tag_len; | |
853 | |
854 ACI_MALLOC (phb_record, sizeof (T_PHB_RECORD)); | |
855 | |
856 TRACE_FUNCTION ("pb_check_fdn()"); | |
857 | |
858 retVal = pb_sim_read_sizes (FDN, | |
859 &max_rcd, | |
860 &dummy_used_rcd, | |
861 &dummy_tag_len); | |
862 if (retVal NEQ PHB_OK) | |
863 { | |
864 TRACE_ERROR ("Unexpected return from pb_sim_read_sizes()"); | |
865 RETURN (retVal) | |
866 } | |
867 | |
868 /* | |
869 * Do a linear search through all the records applying the number comparision | |
870 * rules which make us pass 51.010 test case 27.18.1.1.4.2. | |
871 * Those rules are different from those which are to be applied if a matching | |
872 * record has to be found for an incoming call, therefore we cannot use | |
873 * pb_sim_search_number() here. | |
874 * As normally FDN phonebooks have not more than 10 entries (max_rcd) a | |
875 * simple linear search will fulfill here all timing requirements. | |
876 */ | |
877 | |
878 for (phy_recno = 1; phy_recno <= max_rcd; phy_recno++) | |
879 { | |
880 retVal = pb_sim_read_record (FDN, phy_recno, phb_record); | |
881 if (retVal EQ PHB_OK) | |
882 { | |
883 cmhPHB_getAdrStr (cur_number, | |
884 MAX_PHB_NUM_LEN - 1, | |
885 phb_record->number, | |
886 phb_record->len); | |
887 cmp_len = strlen (cur_number); | |
888 if (strncmp ((char *)number, cur_number, cmp_len) EQ 0) | |
889 { | |
890 /* Number matches. ACI-SPR-11927: check type of address */ | |
891 if ((toa EQ 0) OR | |
892 (toa EQ phb_record->ton_npi) OR | |
893 (phb_record->ton_npi EQ 0xFF)) | |
894 { | |
895 RETURN (PHB_OK) | |
896 } | |
897 } | |
898 } | |
899 } | |
900 RETURN (PHB_FAIL) /* Not found */ | |
901 | |
902 cleanup_exit: | |
903 ACI_MFREE (phb_record); | |
904 return retVal; | |
905 } | |
906 | |
907 | |
908 /* | |
909 +----------------------------------------------------------------------------+ | |
910 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
911 | STATE : code ROUTINE : pb_switch_adn_fdn | | |
912 +----------------------------------------------------------------------------+ | |
913 | |
914 PURPOSE : This function switches FDN and ADN phonebooks (sAT_PlusCLCK()). | |
915 | |
916 */ | |
917 GLOBAL T_PHB_RETURN pb_switch_adn_fdn (T_PHB_FDN_MODE mode, | |
918 T_ACI_CLASS classFDN) | |
919 { | |
920 TRACE_FUNCTION ("pb_switch_adn_fdn()"); | |
921 | |
922 if (GET_PHB_STATE() NEQ PHB_STATE_IDLE) | |
923 return PHB_FAIL; | |
924 | |
925 /* Check parameters */ | |
926 switch (mode) | |
927 { | |
928 case FDN_DISABLE: | |
929 case FDN_ENABLE: | |
930 break; | |
931 | |
932 default: | |
933 return PHB_FAIL; | |
934 } | |
935 | |
936 if (classFDN NEQ pba_data.fdn_classtype) | |
937 { | |
938 UBYTE ub_class; | |
939 | |
940 ub_class = (UBYTE)classFDN; | |
941 pba_data.fdn_classtype = classFDN; | |
942 | |
943 #ifndef _SIMULATION_ | |
944 if (ffs_fwrite("/mmi/fdnClassType", &classFDN, sizeof(ub_class)) < 1) | |
945 { | |
946 TRACE_ERROR ("sAT_PlusCLCK: failed to write /mmi/fdnClassType"); | |
947 } | |
948 #endif /* #ifndef _SIMULATION_ */ | |
949 } | |
950 | |
951 #if 1 | |
952 | |
953 pba_data.fdn_mode = mode; | |
954 | |
955 /* Remove ADN from database */ | |
956 (void)pb_sim_remove_ef (SIM_ADN); | |
957 pba_data.book_created[ADN] = FALSE; | |
958 pba_data.book_read[ADN] = FALSE; | |
959 | |
960 /* Remove FDN from database */ | |
961 (void)pb_sim_remove_ef (SIM_FDN); | |
962 pba_data.book_created[FDN] = FALSE; | |
963 pba_data.book_read[FDN] = FALSE; | |
964 | |
965 /* Remove EXT2 from database */ | |
966 (void)pb_sim_remove_ef (SIM_EXT2); | |
967 pba_data.ext_created[EXT2] = FALSE; | |
968 | |
969 /* Force cmhPHB_StatIndication (PHB_BUSY, CME_ERR_NotPresent) */ | |
970 pba_data.db_recreate = TRUE; | |
971 | |
972 SET_PHB_STATE (PHB_STATE_READ); | |
973 | |
974 /* Start reading changed books */ | |
975 pb_start_build (FALSE); | |
976 #else | |
977 // This optimization does not comply with current test cases, | |
978 // not understood perfectly whether the test cases can be | |
979 // changed, so kept old behaviour. | |
980 if (pba_data.fdn_mode NEQ mode) | |
981 { | |
982 pba_data.fdn_mode = mode; | |
983 | |
984 if (mode EQ FDN_ENABLE) | |
985 { | |
986 /* Remove ADN from database */ | |
987 (void)pb_sim_remove_ef (SIM_ADN); | |
988 pba_data.book_created[ADN] = FALSE; | |
989 pba_data.book_read[ADN] = FALSE; | |
990 } | |
991 else | |
992 { | |
993 /* Remove FDN from database */ | |
994 (void)pb_sim_remove_ef (SIM_FDN); | |
995 pba_data.book_created[FDN] = FALSE; | |
996 pba_data.book_read[FDN] = FALSE; | |
997 | |
998 /* Remove EXT2 from database */ | |
999 (void)pb_sim_remove_ef (SIM_EXT2); | |
1000 pba_data.ext_created[EXT2] = FALSE; | |
1001 } | |
1002 | |
1003 /* Force cmhPHB_StatIndication (PHB_BUSY, CME_ERR_NotPresent) */ | |
1004 pba_data.db_recreate = TRUE; | |
1005 | |
1006 SET_PHB_STATE (PHB_STATE_READ); | |
1007 | |
1008 /* Start reading changed books */ | |
1009 pb_start_build (FALSE); | |
1010 } | |
1011 #endif | |
1012 return PHB_OK; | |
1013 } | |
1014 | |
1015 | |
1016 /* | |
1017 +----------------------------------------------------------------------------+ | |
1018 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
1019 | STATE : code ROUTINE : pb_del_book | | |
1020 +----------------------------------------------------------------------------+ | |
1021 | |
1022 PURPOSE : This function deletes a whole SIM phonebook | |
1023 | |
1024 */ | |
1025 GLOBAL T_PHB_RETURN pb_del_book (T_PHB_TYPE book) | |
1026 { | |
1027 T_PHB_RETURN phb_result; | |
1028 UBYTE max_record; | |
1029 | |
1030 TRACE_FUNCTION ("pb_del_book()"); | |
1031 | |
1032 if (GET_PHB_STATE() NEQ PHB_STATE_IDLE) | |
1033 return PHB_FAIL; | |
1034 | |
1035 /* Remember book to delete, initialize record to delete */ | |
1036 pba_data.current_book = book; | |
1037 pba_data.del_record = 1; | |
1038 max_record = pba_data.phb_record_max[pba_data.current_book]; | |
1039 | |
1040 do | |
1041 { | |
1042 /* Delete the record in the database */ | |
1043 phb_result = pb_sim_del_record (pba_data.current_book, | |
1044 pba_data.del_record, | |
1045 &pba_data.records_changed); | |
1046 if (phb_result NEQ PHB_OK) | |
1047 return phb_result; | |
1048 pba_data.del_record++; | |
1049 } | |
1050 while ((pba_data.del_record <= max_record) AND | |
1051 (pba_data.records_changed.entries EQ 0)); | |
1052 | |
1053 if (pba_data.records_changed.entries NEQ 0) | |
1054 { | |
1055 /* Synchronize to SIM */ | |
1056 SET_PHB_STATE (PHB_STATE_DELETE_BOOK); | |
1057 | |
1058 /* Start synchronizing record(s) to the SIM */ | |
1059 return pb_sync_next_sim_record (TRUE); | |
1060 } | |
1061 | |
1062 return PHB_OK; | |
1063 } | |
1064 | |
1065 | |
1066 /* | |
1067 +----------------------------------------------------------------------------+ | |
1068 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
1069 | STATE : code ROUTINE : pb_get_fdn_classtype | | |
1070 +----------------------------------------------------------------------------+ | |
1071 | |
1072 PURPOSE : This function gets the FDN class type | |
1073 | |
1074 */ | |
1075 GLOBAL T_ACI_CLASS pb_get_fdn_classtype (void) | |
1076 { | |
1077 TRACE_FUNCTION ("pb_get_fdn_classtype()"); | |
1078 | |
1079 return pba_data.fdn_classtype; | |
1080 | |
1081 } | |
1082 | |
1083 | |
1084 /* | |
1085 +----------------------------------------------------------------------------+ | |
1086 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
1087 | STATE : code ROUTINE : pb_get_fdn_mode | | |
1088 +----------------------------------------------------------------------------+ | |
1089 | |
1090 PURPOSE : This function gets the FDN mode | |
1091 | |
1092 */ | |
1093 GLOBAL T_PHB_FDN_MODE pb_get_fdn_mode (void) | |
1094 { | |
1095 TRACE_FUNCTION ("pb_get_fdn_mode()"); | |
1096 | |
1097 return pba_data.fdn_mode; | |
1098 | |
1099 } | |
1100 | |
1101 | |
1102 /* | |
1103 * Wrapper functions. Wrapper functions don't define own functionality | |
1104 * except of routing to a different block which is the SIM part of | |
1105 * the phonebook here. For a description of these functions have | |
1106 * a look into the SIM part of the phonebook. | |
1107 */ | |
1108 | |
1109 GLOBAL T_PHB_RETURN pb_read_record (T_PHB_TYPE type, | |
1110 SHORT phy_recno, | |
1111 T_PHB_RECORD *entry) | |
1112 { | |
1113 T_PHB_RETURN phb_result; | |
1114 | |
1115 TRACE_FUNCTION ("pb_read_record()"); | |
1116 | |
1117 if (phy_recno EQ 0) | |
1118 return PHB_FAIL; | |
1119 | |
1120 switch (GET_PHB_STATE()) | |
1121 { | |
1122 case PHB_STATE_VERIFY: | |
1123 /* | |
1124 * For LDN records, first have a look into the queue | |
1125 */ | |
1126 if ((type EQ LDN) AND (phy_recno - 1 < pba_data.c_queued)) | |
1127 { | |
1128 /* Entry freshly dialled and still in the queue */ | |
1129 *entry = pba_data.queued[phy_recno - 1]->entry; | |
1130 return PHB_OK; | |
1131 } | |
1132 phb_result = pb_sim_read_record (type, | |
1133 (USHORT)(phy_recno - pba_data.c_queued), | |
1134 entry); | |
1135 TRACE_EVENT_P3 ("type = %d, phy_recno = %d, phb_result = %d", | |
1136 type, phy_recno, phb_result); | |
1137 return phb_result; | |
1138 | |
1139 case PHB_STATE_READ: | |
1140 /* | |
1141 * For LDN records, first have a look into the queue | |
1142 */ | |
1143 if ((type EQ LDN) AND (phy_recno - 1 < pba_data.c_queued)) | |
1144 { | |
1145 /* Entry freshly dialled and still in the queue */ | |
1146 *entry = pba_data.queued[phy_recno - 1]->entry; | |
1147 return PHB_OK; | |
1148 } | |
1149 return PHB_FAIL; /* We already know the SIM was changed */ | |
1150 | |
1151 case PHB_STATE_IDLE: | |
1152 phb_result = pb_sim_read_record (type, phy_recno, entry); | |
1153 TRACE_EVENT_P3 ("type = %d, phy_recno = %d, phb_result = %d", | |
1154 type, phy_recno, phb_result); | |
1155 return phb_result; | |
1156 | |
1157 default: | |
1158 return PHB_FAIL; | |
1159 } | |
1160 } | |
1161 | |
1162 | |
1163 GLOBAL T_PHB_RETURN pb_read_alpha_record (T_PHB_TYPE type, | |
1164 SHORT order_num, | |
1165 T_PHB_RECORD *entry) | |
1166 { | |
1167 TRACE_FUNCTION ("pb_read_alpha_record()"); | |
1168 | |
1169 switch (GET_PHB_STATE()) | |
1170 { | |
1171 case PHB_STATE_IDLE: | |
1172 case PHB_STATE_VERIFY: | |
1173 return pb_sim_read_alpha_record (type, order_num, entry); | |
1174 default: | |
1175 return PHB_FAIL; | |
1176 } | |
1177 } | |
1178 | |
1179 | |
1180 GLOBAL T_PHB_RETURN pb_read_number_record (T_PHB_TYPE type, | |
1181 SHORT order_num, | |
1182 T_PHB_RECORD *entry) | |
1183 { | |
1184 TRACE_FUNCTION ("pb_read_number_record()"); | |
1185 | |
1186 switch (GET_PHB_STATE()) | |
1187 { | |
1188 case PHB_STATE_IDLE: | |
1189 case PHB_STATE_VERIFY: | |
1190 return pb_sim_read_number_record (type, order_num, entry); | |
1191 default: | |
1192 return PHB_FAIL; | |
1193 } | |
1194 } | |
1195 | |
1196 | |
1197 GLOBAL T_PHB_RETURN pb_search_name (T_PHB_TYPE type, | |
1198 T_PHB_MATCH match, | |
1199 const T_ACI_PB_TEXT *search_tag, | |
1200 SHORT *order_num) | |
1201 { | |
1202 T_PHB_RETURN phb_result; | |
1203 | |
1204 TRACE_FUNCTION ("pb_search_name()"); | |
1205 | |
1206 switch (GET_PHB_STATE()) | |
1207 { | |
1208 case PHB_STATE_IDLE: | |
1209 case PHB_STATE_VERIFY: | |
1210 TRACE_EVENT_P1 ("order_num = %d", *order_num); | |
1211 phb_result = pb_sim_search_name (type, match, search_tag, order_num); | |
1212 if (phb_result EQ PHB_OK) // #HM# Remove before production | |
1213 { | |
1214 TRACE_EVENT ("Entry found"); | |
1215 } | |
1216 else | |
1217 { | |
1218 TRACE_EVENT ("Entry not found"); | |
1219 } | |
1220 return phb_result; | |
1221 | |
1222 default: | |
1223 return PHB_FAIL; | |
1224 } | |
1225 } | |
1226 | |
1227 | |
1228 GLOBAL T_PHB_RETURN pb_search_number (T_PHB_TYPE type, | |
1229 const UBYTE *number, | |
1230 SHORT *order_num) | |
1231 { | |
1232 TRACE_FUNCTION ("pb_search_number()"); | |
1233 | |
1234 switch (GET_PHB_STATE()) | |
1235 { | |
1236 case PHB_STATE_IDLE: | |
1237 case PHB_STATE_VERIFY: | |
1238 return pb_sim_search_number (type, number, order_num); | |
1239 default: | |
1240 return PHB_FAIL; | |
1241 } | |
1242 } | |
1243 | |
1244 | |
1245 /* | |
1246 +----------------------------------------------------------------------------+ | |
1247 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
1248 | STATE : code ROUTINE : pb_get_max_num_len | | |
1249 +----------------------------------------------------------------------------+ | |
1250 | |
1251 PURPOSE : This function gets the maximum length of a number within a | |
1252 given phonebook. The length depends on the given phonebook and | |
1253 the availability of extension records (SIM service table). | |
1254 | |
1255 Question: From an architectural point of view, belongs this into | |
1256 the ACI part of the phonebook or more into the SIM part of the | |
1257 phonebook? SIM part until now has no information about SIM service | |
1258 table. | |
1259 | |
1260 */ | |
1261 LOCAL UBYTE pb_get_max_num_len (T_PHB_TYPE type) | |
1262 { | |
1263 TRACE_FUNCTION ("pb_get_max_num_len()"); | |
1264 | |
1265 switch (type) | |
1266 { | |
1267 case ECC: | |
1268 return 3; | |
1269 | |
1270 case ADN: | |
1271 case UPN: | |
1272 case ADN_ME: | |
1273 if (pb_sim_service (SRV_EXT1)) | |
1274 return 2 * PHB_PACKED_NUM_LEN; | |
1275 break; | |
1276 | |
1277 case FDN: | |
1278 if (pb_sim_service (SRV_EXT2)) | |
1279 return 2 * PHB_PACKED_NUM_LEN; | |
1280 break; | |
1281 | |
1282 case SDN: | |
1283 if (pb_sim_service (SRV_EXT3)) | |
1284 return 2 * PHB_PACKED_NUM_LEN; | |
1285 break; | |
1286 | |
1287 case BDN: | |
1288 if (pb_sim_service (SRV_EXT4)) | |
1289 return 2 * PHB_PACKED_NUM_LEN; | |
1290 break; | |
1291 | |
1292 case LDN: | |
1293 case LRN: | |
1294 case LMN: | |
1295 case ME: | |
1296 return 2 * PHB_PACKED_NUM_LEN; | |
1297 | |
1298 default: | |
1299 TRACE_ERROR ("Invalid phonebook type"); | |
1300 return 0; | |
1301 } | |
1302 return 20; /* Default according to 11.11 if no EXT records and not ECC */ | |
1303 } | |
1304 | |
1305 | |
1306 GLOBAL T_PHB_RETURN pb_read_sizes (T_PHB_TYPE type, /* IN */ | |
1307 SHORT *max_rcd, /* OUT */ | |
1308 SHORT *used_rcd, /* OUT */ | |
1309 UBYTE *num_len, /* OUT */ | |
1310 UBYTE *tag_len) /* OUT */ | |
1311 { | |
1312 T_PHB_RETURN phb_result; | |
1313 | |
1314 TRACE_FUNCTION ("pb_read_sizes()"); | |
1315 | |
1316 switch (GET_PHB_STATE()) | |
1317 { | |
1318 case PHB_STATE_IDLE: | |
1319 case PHB_STATE_VERIFY: | |
1320 | |
1321 /* | |
1322 * For a valid phonebook type, set all parameters to zero instead of | |
1323 * reporting an error. | |
1324 */ | |
1325 switch (type) | |
1326 { | |
1327 case ECC: | |
1328 case ADN: | |
1329 case FDN: | |
1330 case BDN: | |
1331 case LDN: | |
1332 case LRN: | |
1333 case SDN: | |
1334 case LMN: | |
1335 case UPN: | |
1336 /*case ME: | |
1337 case ADN_ME:*/ | |
1338 *num_len = pb_get_max_num_len (type); | |
1339 phb_result = pb_sim_read_sizes (type, max_rcd, used_rcd, tag_len); | |
1340 if (phb_result NEQ PHB_OK) | |
1341 { | |
1342 *max_rcd = 0; | |
1343 *used_rcd = 0; | |
1344 *num_len = 0; | |
1345 *tag_len = 0; | |
1346 } | |
1347 return PHB_OK; | |
1348 | |
1349 default: | |
1350 break; | |
1351 } | |
1352 return PHB_FAIL; /* Invalid phonebook */ | |
1353 | |
1354 default: | |
1355 return PHB_FAIL; /* Invalid state */ | |
1356 } | |
1357 } | |
1358 | |
1359 | |
1360 GLOBAL int pb_get_entry_len (const UBYTE *pb_tag, | |
1361 UBYTE max_pb_len) | |
1362 { | |
1363 TRACE_FUNCTION ("pb_get_entry_len()"); | |
1364 | |
1365 return pb_sim_get_entry_len (pb_tag, max_pb_len); | |
1366 } | |
1367 | |
1368 | |
1369 GLOBAL int pb_find_free_record (T_PHB_TYPE type) | |
1370 { | |
1371 /* | |
1372 * This function finds the number of the first free record in | |
1373 * a given phonebook. This is new functionality as from S621. | |
1374 */ | |
1375 TRACE_FUNCTION ("pb_find_free_record()"); | |
1376 | |
1377 switch (GET_PHB_STATE()) | |
1378 { | |
1379 case PHB_STATE_IDLE: | |
1380 case PHB_STATE_VERIFY: | |
1381 return pb_sim_find_free_record (type); | |
1382 default: | |
1383 return PHB_FAIL; | |
1384 } | |
1385 } | |
1386 | |
1387 | |
1388 /* | |
1389 * Internal functions, not part of the interface | |
1390 */ | |
1391 | |
1392 | |
1393 | |
1394 /* | |
1395 +----------------------------------------------------------------------------+ | |
1396 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
1397 | STATE : code ROUTINE : pb_sim_service | | |
1398 +----------------------------------------------------------------------------+ | |
1399 | |
1400 PURPOSE : This function checks whether a given service is | |
1401 "allocated and activated" on the SIM, if so TRUE is returned, | |
1402 otherwise the function returns FALSE. | |
1403 | |
1404 No, using psaSIM_ChkSIMSrvSup() is not a good alternative here | |
1405 as we may have to handle the situation where the SIM service | |
1406 table itself has been changed, in this case we are not signalled | |
1407 by the ACI when we have again a valid SIM service table, therefore | |
1408 this function exist here within the phonebook. | |
1409 | |
1410 */ | |
1411 LOCAL BOOL pb_sim_service (UBYTE nr) | |
1412 { | |
1413 UBYTE byte_offset; | |
1414 UBYTE bit_offset; | |
1415 UBYTE service; | |
1416 | |
1417 TRACE_FUNCTION ("pb_sim_service()"); | |
1418 | |
1419 if (nr > MAX_SRV_TBL * 4) | |
1420 return FALSE; /* Table overflow */ | |
1421 | |
1422 byte_offset = (nr - 1) / 4; | |
1423 bit_offset = ((nr - 1) & 0x03) * 2; | |
1424 service = (pba_data.sim_service_table[byte_offset] >> bit_offset) & 0x03; | |
1425 return (service EQ ALLOCATED_AND_ACTIVATED); | |
1426 } | |
1427 | |
1428 | |
1429 /* | |
1430 +----------------------------------------------------------------------------+ | |
1431 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
1432 | STATE : code ROUTINE : pb_read_sim_record | | |
1433 +----------------------------------------------------------------------------+ | |
1434 | |
1435 PURPOSE : This function sends a SIM_READ_RECORD_REQ to the SIM card. | |
1436 On success this function returns TRUE, otherwise FALSE. | |
1437 | |
1438 */ | |
1439 LOCAL BOOL pb_read_sim_record (USHORT data_id, UBYTE rcd_num, UBYTE len) | |
1440 { | |
1441 SHORT table_id; | |
1442 | |
1443 TRACE_FUNCTION ("pb_read_sim_record()"); | |
1444 | |
1445 table_id = psaSIM_atbNewEntry(); | |
1446 | |
1447 if (table_id NEQ NO_ENTRY) | |
1448 { | |
1449 /* Allocate room for the SIM data */ | |
1450 if (pba_data.data EQ NULL) | |
1451 { | |
1452 ACI_MALLOC (pba_data.data, SIM_MAX_RECORD_SIZE); | |
1453 } | |
1454 simShrdPrm.atb[table_id].ntryUsdFlg = TRUE; | |
1455 simShrdPrm.atb[table_id].accType = ACT_RD_REC; | |
1456 simShrdPrm.atb[table_id].reqDataFld = data_id; | |
1457 simShrdPrm.atb[table_id].recNr = rcd_num; | |
1458 if (rcd_num EQ 1) | |
1459 simShrdPrm.atb[table_id].dataLen = NOT_PRESENT_8BIT; | |
1460 else | |
1461 simShrdPrm.atb[table_id].dataLen = len; | |
1462 simShrdPrm.atb[table_id].exchData = pba_data.data; | |
1463 simShrdPrm.atb[table_id].rplyCB = pb_read_sim_record_cb; | |
1464 | |
1465 simShrdPrm.aId = table_id; | |
1466 | |
1467 if (psaSIM_AccessSIMData() < 0) | |
1468 { | |
1469 TRACE_EVENT("FATAL ERROR"); | |
1470 return FALSE; | |
1471 } | |
1472 return TRUE; | |
1473 } | |
1474 | |
1475 return FALSE; | |
1476 } | |
1477 | |
1478 | |
1479 /* | |
1480 +----------------------------------------------------------------------------+ | |
1481 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
1482 | STATE : code ROUTINE : pb_read_sim | | |
1483 +----------------------------------------------------------------------------+ | |
1484 | |
1485 PURPOSE : This function sends a SIM_READ_REQ to the SIM card. | |
1486 On success this function returns TRUE, otherwise FALSE. | |
1487 | |
1488 */ | |
1489 LOCAL BOOL pb_read_sim (USHORT data_id, UBYTE len, UBYTE max_length) | |
1490 { | |
1491 SHORT table_id; | |
1492 | |
1493 TRACE_FUNCTION ("pb_read_sim()"); | |
1494 | |
1495 table_id = psaSIM_atbNewEntry(); | |
1496 | |
1497 if (table_id NEQ NO_ENTRY) | |
1498 { | |
1499 /* Allocate room for the SIM data */ | |
1500 if (pba_data.data EQ NULL) | |
1501 { | |
1502 ACI_MALLOC (pba_data.data, SIM_MAX_RECORD_SIZE); | |
1503 } | |
1504 | |
1505 simShrdPrm.atb[table_id].ntryUsdFlg = TRUE; | |
1506 simShrdPrm.atb[table_id].accType = ACT_RD_DAT; | |
1507 simShrdPrm.atb[table_id].reqDataFld = data_id; | |
1508 simShrdPrm.atb[table_id].dataOff = 0; | |
1509 simShrdPrm.atb[table_id].dataLen = len; | |
1510 simShrdPrm.atb[table_id].recMax = max_length; | |
1511 simShrdPrm.atb[table_id].exchData = NULL; | |
1512 simShrdPrm.atb[table_id].rplyCB = pb_read_sim_cb; | |
1513 | |
1514 simShrdPrm.aId = table_id; | |
1515 | |
1516 if (psaSIM_AccessSIMData() < 0) | |
1517 { | |
1518 TRACE_EVENT("FATAL ERROR"); | |
1519 return FALSE; | |
1520 } | |
1521 return TRUE; | |
1522 } | |
1523 return FALSE; | |
1524 } | |
1525 | |
1526 | |
1527 /* | |
1528 +----------------------------------------------------------------------------+ | |
1529 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
1530 | STATE : code ROUTINE : pb_read_next_sim_book | | |
1531 +----------------------------------------------------------------------------+ | |
1532 | |
1533 PURPOSE : This function starts reading the phonebooks based on the | |
1534 information whether the phonebook is activated and allocated | |
1535 and still has to be read at all. | |
1536 | |
1537 */ | |
1538 LOCAL void pb_read_next_sim_book (void) | |
1539 { | |
1540 TRACE_FUNCTION("pb_read_next_sim_book()"); | |
1541 | |
1542 /* | |
1543 * The next three phonebooks ADN, MSISDN and LND share EXT1 records | |
1544 */ | |
1545 if ((pba_data.fdn_mode NEQ FDN_ENABLE) AND | |
1546 pb_sim_service (SRV_ADN) AND !pba_data.book_read[ADN]) | |
1547 { | |
1548 /* Read ADN from SIM card */ | |
1549 pba_data.current_book = ADN; | |
1550 pba_data.book_read[ADN] = TRUE; | |
1551 pb_read_sim_record (SIM_ADN, 1, NOT_PRESENT_8BIT); | |
1552 return; | |
1553 } | |
1554 | |
1555 if (pb_sim_service (SRV_MSISDN) AND !pba_data.book_read[UPN]) | |
1556 { | |
1557 /* Read MSISDN from SIM card */ | |
1558 pba_data.current_book = UPN; | |
1559 pba_data.book_read[UPN] = TRUE; | |
1560 pb_read_sim_record (SIM_MSISDN, 1, NOT_PRESENT_8BIT); | |
1561 return; | |
1562 } | |
1563 | |
1564 #ifdef SIM_LND_SUPPORT | |
1565 if (pb_sim_service (SRV_LDN) AND !pba_data.book_read[LDN]) | |
1566 { | |
1567 /* Read LND from SIM card */ | |
1568 pba_data.current_book = LDN; | |
1569 pba_data.book_read[LDN] = TRUE; | |
1570 pb_read_sim_record (SIM_LND, 1, NOT_PRESENT_8BIT); | |
1571 return; | |
1572 } | |
1573 #endif | |
1574 | |
1575 #ifdef SIM_LND_SUPPORT | |
1576 if (!pb_sim_service (SRV_LDN) AND !pba_data.book_read[LDN]) | |
1577 #else | |
1578 if (!pba_data.book_read[LDN]) | |
1579 #endif | |
1580 { | |
1581 /* | |
1582 * SIM card without LDN service. Create SIM_ICI and SIM_OCI here. | |
1583 * Don't create obsolete SIM_LND | |
1584 */ | |
1585 pba_data.book_read[LDN] = TRUE; | |
1586 | |
1587 /* Create now also some helper elementary files as of R99+ */ | |
1588 //(void)pb_sim_create_ef (SIM_ICI, SIZE_EF_ICI, NR_EF_ICI); | |
1589 (void)pb_sim_create_ef (FFS_LRN, SIZE_EF_LRN, NR_EF_LRN); | |
1590 (void)pb_sim_create_ef (FFS_EXT_LRN, SIZE_EF_EXT_LRN, NR_EF_EXT_LRN); | |
1591 (void)pb_sim_create_ef (FFS_LMN, SIZE_EF_LMN, NR_EF_LMN); | |
1592 (void)pb_sim_create_ef (FFS_EXT_LMN, SIZE_EF_EXT_LMN, NR_EF_EXT_LMN); | |
1593 | |
1594 (void)pb_sim_create_ef (SIM_OCI, SIZE_EF_OCI, NR_EF_OCI); | |
1595 (void)pb_sim_create_ef (SIM_EXT5, SIZE_EF_EXT5, NR_EF_EXT5); | |
1596 | |
1597 pba_data.phb_record_max[LDN] = NR_EF_OCI; | |
1598 pba_data.phb_record_len[LDN] = SIZE_EF_OCI; | |
1599 pba_data.book_created[LDN] = TRUE; | |
1600 | |
1601 //pba_data.phb_record_max[LRN] = NR_EF_ICI; /* Shared! */ | |
1602 //pba_data.phb_record_len[LRN] = SIZE_EF_ICI; | |
1603 pba_data.phb_record_max[LRN] = NR_EF_LRN; | |
1604 pba_data.phb_record_len[LRN] = SIZE_EF_LRN; | |
1605 pba_data.book_created[LRN] = TRUE; | |
1606 | |
1607 //pba_data.phb_record_max[LMN] = NR_EF_ICI; /* Shared! */ | |
1608 //pba_data.phb_record_len[LMN] = SIZE_EF_ICI; | |
1609 pba_data.phb_record_max[LMN] = NR_EF_LMN; | |
1610 pba_data.phb_record_len[LMN] = SIZE_EF_LMN; | |
1611 pba_data.book_created[LMN] = TRUE; | |
1612 | |
1613 pba_data.ext_record_max[EXT5] = NR_EF_EXT5; | |
1614 pba_data.ext_record_max[EXT_LRN] = NR_EF_EXT_LRN; | |
1615 pba_data.ext_record_max[EXT_LMN] = NR_EF_EXT_LMN; | |
1616 | |
1617 pba_data.ext_record_max[EXT5] = SIZE_EF_EXT5; | |
1618 pba_data.ext_record_max[EXT_LRN] = SIZE_EF_EXT_LRN; | |
1619 pba_data.ext_record_max[EXT_LMN] = SIZE_EF_EXT_LMN; | |
1620 } | |
1621 | |
1622 #ifdef SIM_LND_SUPPORT | |
1623 if (pba_data.book_read[ADN] OR | |
1624 pba_data.book_read[UPN] OR | |
1625 pba_data.book_read[LDN]) | |
1626 #else | |
1627 if (pba_data.book_read[ADN] OR | |
1628 pba_data.book_read[UPN]) | |
1629 #endif | |
1630 { | |
1631 /* At least one of the books referencing EXT1 has been read */ | |
1632 if (!pba_data.ext_created[EXT1] AND | |
1633 pb_sim_service (SRV_EXT1)) | |
1634 { | |
1635 /* Reading to get the number of records only */ | |
1636 pba_data.ext_dummy_read = TRUE; | |
1637 pb_read_sim_record (SIM_EXT1, 1, NOT_PRESENT_8BIT); | |
1638 return; | |
1639 } | |
1640 } | |
1641 | |
1642 /* | |
1643 * FDN phonebook only to be read if ADN is blocked | |
1644 */ | |
1645 if ((pba_data.fdn_mode EQ FDN_ENABLE) AND | |
1646 pb_sim_service (SRV_FDN) AND !pba_data.book_read[FDN]) | |
1647 { | |
1648 /* Read FDN from SIM card */ | |
1649 pba_data.current_book = FDN; | |
1650 pba_data.book_read[FDN] = TRUE; | |
1651 pb_read_sim_record (SIM_FDN, 1, NOT_PRESENT_8BIT); | |
1652 return; | |
1653 } | |
1654 | |
1655 if (pba_data.book_read[FDN] AND | |
1656 !pba_data.ext_created[EXT2] AND | |
1657 pb_sim_service (SRV_EXT2)) | |
1658 { | |
1659 /* Reading to get the number of records only */ | |
1660 pba_data.ext_dummy_read = TRUE; | |
1661 pb_read_sim_record (SIM_EXT2, 1, NOT_PRESENT_8BIT); | |
1662 return; | |
1663 } | |
1664 | |
1665 if (pb_sim_service (SRV_BDN) AND !pba_data.book_read[BDN]) | |
1666 { | |
1667 /* Read BDN from SIM card */ | |
1668 pba_data.current_book = BDN; | |
1669 pba_data.book_read[BDN] = TRUE; | |
1670 pb_read_sim_record (SIM_BDN, 1, NOT_PRESENT_8BIT); | |
1671 return; | |
1672 } | |
1673 | |
1674 if (pba_data.book_read[BDN] AND | |
1675 !pba_data.ext_created[EXT4] AND | |
1676 pb_sim_service (SRV_EXT4)) | |
1677 { | |
1678 /* Reading to get the number of records only */ | |
1679 pba_data.ext_dummy_read = TRUE; | |
1680 pb_read_sim_record (SIM_EXT4, 1, NOT_PRESENT_8BIT); | |
1681 return; | |
1682 } | |
1683 | |
1684 if (pb_sim_service (SRV_SDN) AND !pba_data.book_read[SDN]) | |
1685 { | |
1686 /* Read SDN from SIM card */ | |
1687 pba_data.current_book = SDN; | |
1688 pba_data.book_read[SDN] = TRUE; | |
1689 pb_read_sim_record (SIM_SDN, 1, NOT_PRESENT_8BIT); | |
1690 return; | |
1691 } | |
1692 | |
1693 if (pba_data.book_read[SDN] AND | |
1694 !pba_data.ext_created[EXT3] AND | |
1695 pb_sim_service (SRV_EXT3)) | |
1696 { | |
1697 /* Reading to get the number of records only */ | |
1698 pba_data.ext_dummy_read = TRUE; | |
1699 pb_read_sim_record (SIM_EXT3, 1, NOT_PRESENT_8BIT); | |
1700 return; | |
1701 } | |
1702 | |
1703 /* | |
1704 * For the phonebook entries which reside on SIM but don't have | |
1705 * timestamps some checks could be done here. | |
1706 * For example, we could read based on EF_LDN, subsequently we | |
1707 * could read the informations solely stored in the flash and | |
1708 * then we could decide whether we through away the last dialled | |
1709 * numbers or don't. | |
1710 * Probably this is overkill, old Nokia 5110 and more recent Nokia 6330i | |
1711 * simply does not support EF_LND at all but stores the last dialled | |
1712 * numbers in the flash. | |
1713 */ | |
1714 | |
1715 #ifdef SIM_TOOLKIT | |
1716 if (simShrdPrm.fuRef >= 0) | |
1717 { | |
1718 psaSAT_FUConfirm (simShrdPrm.fuRef, SIM_FU_SUCC_ADD); | |
1719 } | |
1720 #endif | |
1721 | |
1722 /* Free SIM exchange data */ | |
1723 if (pba_data.data NEQ NULL) | |
1724 { | |
1725 ACI_MFREE (pba_data.data); | |
1726 pba_data.data = NULL; | |
1727 } | |
1728 | |
1729 SET_PHB_STATE (PHB_STATE_IDLE); | |
1730 | |
1731 if (pb_read_queue() EQ PHB_EXCT) | |
1732 return; /* Queued LDN entry is written */ | |
1733 | |
1734 /* Finished reading phonebooks. Flush data. */ | |
1735 (void)pb_sim_flush_data (); | |
1736 | |
1737 /* Inform ACI that we're ready */ | |
1738 pb_status_ind (PHB_READY, CME_ERR_NotPresent); | |
1739 } | |
1740 | |
1741 | |
1742 /* | |
1743 +----------------------------------------------------------------------------+ | |
1744 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
1745 | STATE : code ROUTINE : pb_read_sim_record_cb | | |
1746 +----------------------------------------------------------------------------+ | |
1747 | |
1748 PURPOSE : This function is the callback when a SIM record has been read | |
1749 (SIM_READ_RECORD_CNF). | |
1750 | |
1751 */ | |
1752 | |
1753 LOCAL void pb_read_sim_record_cb (SHORT table_id) | |
1754 { | |
1755 T_PHB_RETURN phb_result; /* Phonebook result code */ | |
1756 T_PHB_TYPE phb_type; /* Phonebook type */ | |
1757 T_EXT_TYPE ext_type; /* Extension record type */ | |
1758 T_PHB_TYPE next_phb_type; /* Phonebook type of record to read */ | |
1759 T_EXT_TYPE next_ext_type; /* Extension record type of record to read */ | |
1760 USHORT reqDataFld; /* requested datafield identifier */ | |
1761 UBYTE recNr; /* record number */ | |
1762 UBYTE dataLen; /* Length of data */ | |
1763 UBYTE recMax; /* Maximum number of records */ | |
1764 USHORT errCode; /* Error code from the SIM */ | |
1765 USHORT ext_record_ef; /* Extension record elementary file id */ | |
1766 UBYTE ext_record_no; /* Extension record number */ | |
1767 BOOL changed; /* Record changed by pb_sim_write_ef() */ | |
1768 BOOL write_record; /* Write the record */ | |
1769 | |
1770 TRACE_FUNCTION ("pb_read_sim_record_cb()"); | |
1771 | |
1772 /* | |
1773 * Currently we have a limitation of 254 records in the code. | |
1774 * This is because there is a note in 11.11 version 8.3.0 clause 6.4.2 | |
1775 * that there is a limit of 254 records for linear fixed. | |
1776 * Same for USIM looking into 31.102 Annex G. | |
1777 * However this constraint is not valid for cyclic, and also this | |
1778 * note has not been present in 11.11 version 7.4.0 clause 6.2.4, | |
1779 * there is a limit of 255 records mentioned. | |
1780 * Not supporting the 255th record is a minor issue for now. | |
1781 * To avoid crashing, we have to limit here for now to 254. | |
1782 * This is not a theoretical issue only as there exists SIMs | |
1783 * which have 255 ADN entries. | |
1784 */ | |
1785 if (simShrdPrm.atb[table_id].recMax EQ 255) | |
1786 simShrdPrm.atb[table_id].recMax = 254; | |
1787 | |
1788 /* Get the important information from the read record from T_SIM_ACC_PRM */ | |
1789 reqDataFld = simShrdPrm.atb[table_id].reqDataFld; | |
1790 recNr = simShrdPrm.atb[table_id].recNr; | |
1791 dataLen = simShrdPrm.atb[table_id].dataLen; | |
1792 recMax = simShrdPrm.atb[table_id].recMax; | |
1793 errCode = simShrdPrm.atb[table_id].errCode; | |
1794 | |
1795 phb_type = pb_get_phb_type_from_ef (reqDataFld); | |
1796 ext_type = pb_get_ext_type_from_ef (reqDataFld); | |
1797 | |
1798 if (phb_type EQ INVALID_PHB AND | |
1799 ext_type EQ INVALID_EXT) | |
1800 { | |
1801 TRACE_ERROR ("Invalid reqDataFld!"); | |
1802 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; | |
1803 return; | |
1804 } | |
1805 | |
1806 /* We assume we write the record until we have certain errors */ | |
1807 write_record = TRUE; | |
1808 | |
1809 if (errCode NEQ SIM_NO_ERROR) | |
1810 { | |
1811 TRACE_EVENT_P1 ("SIM indicated problem code %04x", errCode); | |
1812 /* | |
1813 * At least use cleanly deleted data instead of trash. | |
1814 */ | |
1815 memset (pba_data.data, 0xff, SIM_MAX_RECORD_SIZE); | |
1816 } | |
1817 | |
1818 if (ext_type NEQ INVALID_EXT) | |
1819 { | |
1820 /* | |
1821 * Got an extension record. | |
1822 */ | |
1823 if (!pba_data.ext_created[ext_type]) | |
1824 { | |
1825 if (errCode NEQ SIM_NO_ERROR) | |
1826 { | |
1827 /* We won't create a field on invalid data and won't write */ | |
1828 write_record = FALSE; | |
1829 pba_data.ext_dummy_read = FALSE; | |
1830 } | |
1831 else | |
1832 { | |
1833 pba_data.ext_record_max[ext_type] = recMax; | |
1834 pba_data.ext_record_len[ext_type] = dataLen; | |
1835 | |
1836 /* Shadow field for extension record not yet created */ | |
1837 (void)pb_sim_create_ef (reqDataFld, dataLen, recMax); | |
1838 pba_data.ext_created[ext_type] = TRUE; | |
1839 } | |
1840 | |
1841 if (pba_data.ext_dummy_read) | |
1842 { | |
1843 /* | |
1844 * We are reading the first extension record which is assumed | |
1845 * to be not used just to get the number of respective extension | |
1846 * records. | |
1847 */ | |
1848 write_record = FALSE; | |
1849 pba_data.ext_dummy_read = FALSE; | |
1850 } | |
1851 } | |
1852 } | |
1853 else | |
1854 { | |
1855 /* | |
1856 * Got a normal phonebook record | |
1857 */ | |
1858 if (!pba_data.book_created[phb_type]) | |
1859 { | |
1860 if (errCode NEQ SIM_NO_ERROR) | |
1861 { | |
1862 /* We won't create a field on invalid data */ | |
1863 write_record = FALSE; | |
1864 } | |
1865 else | |
1866 { | |
1867 pba_data.phb_record_max[phb_type] = recMax; | |
1868 pba_data.phb_record_len[phb_type] = dataLen; | |
1869 | |
1870 /* Shadow field for normal phonebook record not yet created */ | |
1871 (void)pb_sim_create_ef (reqDataFld, dataLen, recMax); | |
1872 pba_data.book_created[phb_type] = TRUE; | |
1873 | |
1874 #ifdef SIM_LND_SUPPORT | |
1875 if (phb_type EQ LDN) | |
1876 { | |
1877 /* Create now also some helper elementary files as of R99+ */ | |
1878 (void)pb_sim_create_ef (SIM_OCI, (USHORT)(dataLen + 14), recMax); | |
1879 pba_data.phb_record_max[LDN] = recMax; | |
1880 pba_data.phb_record_len[LDN] = dataLen; | |
1881 pba_data.book_created[LDN] = TRUE; | |
1882 | |
1883 (void)pb_sim_create_ef (SIM_ICI, (USHORT)(dataLen + 14), recMax); | |
1884 pba_data.phb_record_max[LRN] = recMax; | |
1885 pba_data.phb_record_len[LRN] = dataLen; | |
1886 pba_data.book_created[LRN] = TRUE; | |
1887 | |
1888 pba_data.phb_record_max[LMN] = recMax; | |
1889 pba_data.phb_record_len[LMN] = dataLen; | |
1890 pba_data.book_created[LMN] = TRUE; | |
1891 } | |
1892 #endif | |
1893 } | |
1894 } | |
1895 } | |
1896 | |
1897 /* | |
1898 * Write raw record. The SIM layer is aware about the data structures | |
1899 * and gives us the information whether we have to read an/another | |
1900 * extension record now or whether we can continue reading normal | |
1901 * phonebook entries. | |
1902 */ | |
1903 if (write_record) | |
1904 { | |
1905 phb_result = pb_sim_write_ef(reqDataFld, | |
1906 recNr, | |
1907 dataLen, | |
1908 pba_data.data, | |
1909 &changed, | |
1910 &ext_record_ef, | |
1911 &ext_record_no); | |
1912 } | |
1913 else | |
1914 { | |
1915 /* | |
1916 * New field, record was trash, don't write it, continue reading | |
1917 * phonebook entries. | |
1918 */ | |
1919 TRACE_EVENT ("Record not written (trash/dummy ext)"); | |
1920 | |
1921 phb_result = PHB_OK; | |
1922 changed = FALSE; | |
1923 ext_record_ef = 0; | |
1924 ext_record_no = 0; | |
1925 } | |
1926 | |
1927 /* Mark SIM table as free now */ | |
1928 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; | |
1929 | |
1930 if ((GET_PHB_STATE() EQ PHB_STATE_VERIFY) AND | |
1931 (phb_result EQ PHB_OK) AND changed) | |
1932 { | |
1933 /* We have a change detected. Prevent further reading until all read */ | |
1934 SET_PHB_STATE (PHB_STATE_READ); | |
1935 } | |
1936 | |
1937 /* | |
1938 * Here an optimization is possible. This is, if an extension record | |
1939 * and already has been read we could skip reading the extension record | |
1940 * here. The optimization is not worth the effort, so we simply don't do | |
1941 * it. | |
1942 */ | |
1943 | |
1944 /* | |
1945 * Do some protection against garbage | |
1946 */ | |
1947 if (ext_record_ef NEQ 0) | |
1948 { | |
1949 /* Current record references an extension record */ | |
1950 next_ext_type = pb_get_ext_type_from_ef (ext_record_ef); | |
1951 | |
1952 if ((next_ext_type EQ INVALID_EXT) OR | |
1953 (ext_record_no < 1) OR | |
1954 (ext_record_no > 245)) | |
1955 { | |
1956 TRACE_ERROR ("pb_sim_write_ef() for ext delivered garbage EXT record"); | |
1957 ext_record_ef = 0; /* Try to proceed without this garbage */ | |
1958 } | |
1959 } | |
1960 | |
1961 if (ext_record_ef NEQ 0) | |
1962 { | |
1963 /* Current record references an extension record */ | |
1964 next_ext_type = pb_get_ext_type_from_ef (ext_record_ef); | |
1965 | |
1966 /* | |
1967 * We have to read an extension record. | |
1968 */ | |
1969 if (ext_type NEQ INVALID_EXT) | |
1970 { | |
1971 /* | |
1972 * It's the first extension record. Remember the paused phonebook. | |
1973 */ | |
1974 TRACE_EVENT_P4 ("PHB EF %04x record %d references EXT EF %04x record %d", | |
1975 reqDataFld, | |
1976 recNr, | |
1977 ext_record_ef, | |
1978 ext_record_ef); | |
1979 pba_data.paused_ef = reqDataFld; | |
1980 pba_data.paused_no = recNr; | |
1981 } | |
1982 | |
1983 /* Read the extension record. */ | |
1984 if (pba_data.ext_created[next_ext_type]) | |
1985 { | |
1986 (void)pb_read_sim_record (ext_record_ef, | |
1987 ext_record_no, | |
1988 pba_data.ext_record_len[next_ext_type]); | |
1989 } | |
1990 else | |
1991 { | |
1992 (void)pb_read_sim_record (ext_record_ef, | |
1993 ext_record_no, | |
1994 NOT_PRESENT_8BIT); | |
1995 } | |
1996 } | |
1997 else if (ext_type NEQ INVALID_EXT) | |
1998 { | |
1999 /* | |
2000 * The record read was the last extension record in the chain. | |
2001 * Come back reading normal phonebook entries. | |
2002 */ | |
2003 | |
2004 next_phb_type = pb_get_phb_type_from_ef (pba_data.paused_ef); | |
2005 //////(void)pb_sim_build_index (next_phb_type); | |
2006 if (pba_data.paused_no < pba_data.phb_record_max[next_phb_type]) | |
2007 { | |
2008 /* Continue reading the current phonebook */ | |
2009 (void)pb_read_sim_record (pba_data.paused_ef, | |
2010 (UBYTE)(pba_data.paused_no + 1), | |
2011 pba_data.phb_record_len[next_phb_type]); | |
2012 } | |
2013 else | |
2014 { | |
2015 ////// Update index - for now here | |
2016 (void)pb_sim_build_index (phb_type); | |
2017 | |
2018 /* Next book */ | |
2019 pb_read_next_sim_book (); | |
2020 } | |
2021 pba_data.paused_ef = 0; | |
2022 pba_data.paused_no = 0; | |
2023 | |
2024 } | |
2025 else if (simShrdPrm.atb[table_id].recNr < simShrdPrm.atb[table_id].recMax) | |
2026 { | |
2027 /* | |
2028 * Normal phonebook record read, no extension referenced and not | |
2029 * finished. Continue reading the current phonebook | |
2030 */ | |
2031 //////(void)pb_sim_build_index (phb_type); | |
2032 | |
2033 (void)pb_read_sim_record (simShrdPrm.atb[table_id].reqDataFld, | |
2034 (UBYTE)(simShrdPrm.atb[table_id].recNr + 1), | |
2035 simShrdPrm.atb[table_id].dataLen); | |
2036 } | |
2037 else | |
2038 { | |
2039 /* | |
2040 * Normal phonebook record read, no extension referenced and finished | |
2041 * reading this book. Continue reading the next book. | |
2042 */ | |
2043 (void)pb_sim_build_index (phb_type); | |
2044 | |
2045 /* Next book */ | |
2046 pb_read_next_sim_book (); | |
2047 } | |
2048 } | |
2049 | |
2050 | |
2051 /* | |
2052 +----------------------------------------------------------------------------+ | |
2053 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
2054 | STATE : code ROUTINE : pb_sat_update_reset | | |
2055 +----------------------------------------------------------------------------+ | |
2056 | |
2057 PURPOSE : This function marks the given elementary file as unread. | |
2058 | |
2059 */ | |
2060 LOCAL void pb_sat_update_reset (USHORT ef) | |
2061 { | |
2062 T_PHB_TYPE phb_type; | |
2063 | |
2064 TRACE_FUNCTION ("pb_sat_update_reset()"); | |
2065 | |
2066 phb_type = pb_get_phb_type_from_ef (ef); | |
2067 | |
2068 if (phb_type NEQ INVALID_PHB) | |
2069 { | |
2070 /* Mark book as unread */ | |
2071 pba_data.book_read[phb_type] = FALSE; | |
2072 } | |
2073 } | |
2074 | |
2075 | |
2076 /* | |
2077 +----------------------------------------------------------------------------+ | |
2078 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
2079 | STATE : code ROUTINE : pb_read_sim_cb | | |
2080 +----------------------------------------------------------------------------+ | |
2081 | |
2082 PURPOSE : This function is the callback when a SIM elementary file has | |
2083 been read (SIM_READ_CNF). | |
2084 There are two fields which can have been read here, those are | |
2085 the emergency call numbers and the SIM service table. | |
2086 | |
2087 */ | |
2088 | |
2089 | |
2090 LOCAL void pb_read_sim_cb (SHORT table_id) | |
2091 { | |
2092 TRACE_FUNCTION ("pb_read_sim_cb()"); | |
2093 | |
2094 switch (simShrdPrm.atb[table_id].reqDataFld) | |
2095 { | |
2096 case SIM_ECC: | |
2097 if (simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR) | |
2098 { | |
2099 (void)pb_sim_set_ecc (simShrdPrm.atb[table_id].dataLen, | |
2100 simShrdPrm.atb[table_id].exchData); | |
2101 | |
2102 #ifdef SIM_TOOLKIT | |
2103 if (simShrdPrm.fuRef >= 0) | |
2104 { | |
2105 psaSAT_FUConfirm (simShrdPrm.fuRef, SIM_FU_SUCCESS); | |
2106 } | |
2107 #endif /* #ifdef SIM_TOOLKIT */ | |
2108 | |
2109 } | |
2110 else | |
2111 { | |
2112 /* | |
2113 * Some error from the SIM. Indicate a fallback to the PCM/FFS. | |
2114 */ | |
2115 (void)pb_sim_set_ecc (0, NULL); | |
2116 | |
2117 #ifdef SIM_TOOLKIT | |
2118 if (simShrdPrm.fuRef >= 0) | |
2119 { | |
2120 psaSAT_FUConfirm (simShrdPrm.fuRef, SIM_FU_ERROR); | |
2121 } | |
2122 #endif | |
2123 | |
2124 } | |
2125 | |
2126 if (pba_data.data NEQ NULL) | |
2127 { | |
2128 ACI_MFREE (pba_data.data); | |
2129 pba_data.data = NULL; | |
2130 } | |
2131 break; | |
2132 | |
2133 case SIM_SST: | |
2134 if (simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR) | |
2135 { | |
2136 /* copy SIM service table */ | |
2137 memset(pba_data.sim_service_table, 0, MAX_SRV_TBL); | |
2138 memcpy(pba_data.sim_service_table, | |
2139 simShrdPrm.atb[table_id].exchData, | |
2140 MINIMUM(MAX_SRV_TBL, simShrdPrm.atb[table_id].dataLen)); | |
2141 | |
2142 /* start reading SIM phonebook */ | |
2143 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; | |
2144 pb_start_build (FALSE); | |
2145 } | |
2146 else | |
2147 { | |
2148 TRACE_ERROR ("Cannot read SIM service table, using old table"); | |
2149 | |
2150 #ifdef SIM_TOOLKIT | |
2151 if (simShrdPrm.fuRef >= 0) | |
2152 { | |
2153 psaSAT_FUConfirm (simShrdPrm.fuRef, SIM_FU_ERROR); | |
2154 } | |
2155 #endif | |
2156 | |
2157 /* start reading SIM phonebook (fallback action, best effort) */ | |
2158 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; | |
2159 pb_start_build (FALSE); | |
2160 } | |
2161 break; | |
2162 | |
2163 default: | |
2164 TRACE_ERROR ("Unexpected SIM_READ_CNF"); | |
2165 break; | |
2166 } | |
2167 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; | |
2168 } | |
2169 | |
2170 | |
2171 /* | |
2172 +----------------------------------------------------------------------------+ | |
2173 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
2174 | STATE : code ROUTINE : pb_is_sim_field | | |
2175 +----------------------------------------------------------------------------+ | |
2176 | |
2177 PURPOSE : This function determines wheter an elementary file has to | |
2178 be synchronized to the SIM or only exists locally in the FFS. | |
2179 | |
2180 */ | |
2181 LOCAL BOOL pb_is_sim_field (USHORT ef) | |
2182 { | |
2183 TRACE_FUNCTION ("pb_is_sim_field()"); | |
2184 | |
2185 switch (ef) | |
2186 { | |
2187 //case SIM_ICI: | |
2188 case FFS_LRN: | |
2189 case FFS_LMN: | |
2190 case FFS_EXT_LRN: | |
2191 case FFS_EXT_LMN: | |
2192 case SIM_OCI: | |
2193 case SIM_EXT5: | |
2194 return FALSE; /* Only in FFS */ | |
2195 | |
2196 default: | |
2197 return TRUE; /* Counterpart in SIM exists */ | |
2198 } | |
2199 } | |
2200 | |
2201 | |
2202 /* | |
2203 +----------------------------------------------------------------------------+ | |
2204 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
2205 | STATE : code ROUTINE : pb_sync_next_sim_record | | |
2206 +----------------------------------------------------------------------------+ | |
2207 | |
2208 PURPOSE : This function synchronizes a changed record to the SIM. | |
2209 | |
2210 The first parameter is given to determine whether it's the first | |
2211 record to be synchronized, in this case ACI has to be informed. | |
2212 | |
2213 If there was no record to synchronize, PHB_OK is returned. | |
2214 If there is a record to synchronize, PHB_EXCT is returned. | |
2215 If there was an internal failure we get PHB_FAIL | |
2216 (which is unexpected). | |
2217 | |
2218 */ | |
2219 | |
2220 LOCAL T_PHB_RETURN pb_sync_next_sim_record (BOOL first) | |
2221 { | |
2222 T_PHB_RETURN phb_result; | |
2223 USHORT field_id; | |
2224 USHORT record; | |
2225 USHORT entry_size; | |
2226 | |
2227 TRACE_FUNCTION ("pb_sync_next_sim_record()"); | |
2228 | |
2229 do | |
2230 { | |
2231 if (pba_data.records_changed.entries EQ 0) | |
2232 { | |
2233 SET_PHB_STATE (PHB_STATE_IDLE); | |
2234 | |
2235 if (pb_read_queue() EQ PHB_EXCT) | |
2236 return PHB_EXCT; /* Queued LDN entry is written */ | |
2237 | |
2238 /* Inform SIM layer we're done synchronizing */ | |
2239 (void)pb_sim_flush_data (); | |
2240 | |
2241 /* Inform ACI that we're ready */ | |
2242 pb_status_ind (PHB_READY, CME_ERR_NotPresent); | |
2243 | |
2244 return PHB_OK; /* No record to synchronize to the SIM */ | |
2245 } | |
2246 | |
2247 /* Get the next record from the list */ | |
2248 pba_data.records_changed.entries--; | |
2249 field_id = pba_data.records_changed.field_id[0]; | |
2250 record = pba_data.records_changed.record[0]; | |
2251 | |
2252 /* Remove the record from the list */ | |
2253 memmove (&pba_data.records_changed.field_id[0], | |
2254 &pba_data.records_changed.field_id[1], | |
2255 sizeof (USHORT) * (DB_MAX_AFFECTED - 1)); | |
2256 memmove (&pba_data.records_changed.record[0], | |
2257 &pba_data.records_changed.record[1], | |
2258 sizeof (USHORT) * (DB_MAX_AFFECTED - 1)); | |
2259 } | |
2260 while (!pb_is_sim_field(field_id)); | |
2261 | |
2262 TRACE_EVENT_P3 ("Synch ef %04X record %d, still %d entries to do", | |
2263 field_id, record, pba_data.records_changed.entries); | |
2264 | |
2265 /* Allocate room for the SIM data */ // #HM# Check for free | |
2266 if (pba_data.data EQ NULL) | |
2267 { | |
2268 ACI_MALLOC (pba_data.data, SIM_MAX_RECORD_SIZE); | |
2269 } | |
2270 | |
2271 /* Fetch record in raw form from the database */ | |
2272 phb_result = pb_sim_read_ef (field_id, | |
2273 record, | |
2274 &entry_size, | |
2275 pba_data.data); | |
2276 | |
2277 if (phb_result EQ PHB_OK) | |
2278 { | |
2279 /* And write it to the SIM */ | |
2280 phb_result = pb_write_sim_record (field_id, | |
2281 (UBYTE)record, | |
2282 (UBYTE)entry_size, | |
2283 pba_data.data); | |
2284 | |
2285 if (phb_result NEQ PHB_EXCT) | |
2286 { | |
2287 /* Inform ACI that we've had a problem */ | |
2288 pb_status_ind ( PHB_WRITE_FAIL, CME_ERR_NotPresent ); | |
2289 return phb_result; /* Some unexpected internal failure */ | |
2290 } | |
2291 | |
2292 if (first) | |
2293 { | |
2294 /* Inform ACI that we're busy synchronizing SIM entries */ | |
2295 pb_status_ind ( PHB_BUSY, CME_ERR_NotPresent ); | |
2296 } | |
2297 | |
2298 return PHB_EXCT; | |
2299 } | |
2300 return phb_result; | |
2301 } | |
2302 | |
2303 | |
2304 /* | |
2305 +----------------------------------------------------------------------------+ | |
2306 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
2307 | STATE : code ROUTINE : pb_write_sim_record | | |
2308 +----------------------------------------------------------------------------+ | |
2309 | |
2310 PURPOSE : This function writes a SIM record to the SIM. | |
2311 | |
2312 */ | |
2313 | |
2314 LOCAL T_PHB_RETURN pb_write_sim_record (USHORT ef, | |
2315 UBYTE phy_recno, | |
2316 UBYTE entry_size, | |
2317 const UBYTE *buffer) | |
2318 { | |
2319 SHORT table_id; | |
2320 | |
2321 | |
2322 TRACE_FUNCTION("pb_write_sim_record()"); | |
2323 | |
2324 table_id = psaSIM_atbNewEntry(); | |
2325 if (table_id EQ NO_ENTRY) | |
2326 { | |
2327 TRACE_ERROR ("pb_write_sim_record(): no more table entries"); | |
2328 return (PHB_FAIL); | |
2329 } | |
2330 | |
2331 simShrdPrm.atb[table_id].ntryUsdFlg = TRUE; | |
2332 simShrdPrm.atb[table_id].accType = ACT_WR_REC; | |
2333 simShrdPrm.atb[table_id].reqDataFld = ef; | |
2334 simShrdPrm.atb[table_id].recNr = phy_recno; | |
2335 simShrdPrm.atb[table_id].dataLen = entry_size; | |
2336 simShrdPrm.atb[table_id].exchData = (UBYTE *)buffer; | |
2337 simShrdPrm.atb[table_id].rplyCB = pb_write_sim_record_cb; | |
2338 | |
2339 simShrdPrm.aId = table_id; | |
2340 | |
2341 if (psaSIM_AccessSIMData() < 0) | |
2342 { | |
2343 TRACE_EVENT("pb_write_sim_record(): psaSIM_AccessSIMData() failed"); | |
2344 return (PHB_FAIL); | |
2345 } | |
2346 | |
2347 return (PHB_EXCT); | |
2348 } | |
2349 | |
2350 | |
2351 /* | |
2352 +----------------------------------------------------------------------------+ | |
2353 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
2354 | STATE : code ROUTINE : pb_write_sim_record_cb | | |
2355 +----------------------------------------------------------------------------+ | |
2356 | |
2357 PURPOSE : This function is the callback when a SIM record has been | |
2358 written to the SIM. | |
2359 | |
2360 */ | |
2361 | |
2362 LOCAL void pb_write_sim_record_cb (SHORT table_id) | |
2363 { | |
2364 UBYTE max_record; | |
2365 | |
2366 TRACE_FUNCTION("pb_write_sim_record_cb()"); | |
2367 | |
2368 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE; | |
2369 | |
2370 if (simShrdPrm.atb[table_id].errCode NEQ SIM_NO_ERROR) | |
2371 { | |
2372 /* | |
2373 * Data in the database and on the SIM probably now differ, | |
2374 * we can do not much about this. | |
2375 */ | |
2376 TRACE_ERROR("pb_write_cb(): error for writing"); | |
2377 pb_status_ind (PHB_WRITE_FAIL, | |
2378 (SHORT)cmhSIM_GetCmeFromSim (simShrdPrm.atb[table_id].errCode)); | |
2379 return; | |
2380 } | |
2381 | |
2382 switch (GET_PHB_STATE()) | |
2383 { | |
2384 case PHB_STATE_WRITE: | |
2385 /* Synchronize next SIM record */ | |
2386 switch (pb_sync_next_sim_record (FALSE)) | |
2387 { | |
2388 case PHB_OK: /* All done */ | |
2389 /* Inform the ACI that we're done */ | |
2390 pb_status_ind (PHB_READY, CME_ERR_NotPresent); | |
2391 break; | |
2392 | |
2393 case PHB_EXCT: | |
2394 break; /* Next record => SIM */ | |
2395 | |
2396 case PHB_FAIL: | |
2397 default: | |
2398 TRACE_ERROR ("Unexpected phb_result"); | |
2399 break; | |
2400 } | |
2401 break; | |
2402 | |
2403 case PHB_STATE_DELETE_BOOK: | |
2404 /* Synchronize next SIM record */ | |
2405 switch (pb_sync_next_sim_record (FALSE)) | |
2406 { | |
2407 case PHB_OK: | |
2408 /* | |
2409 * Record synched. Delete next record of phonebook, if available | |
2410 */ | |
2411 max_record = pba_data.phb_record_max[pba_data.current_book]; | |
2412 while ((pba_data.del_record <= max_record) AND | |
2413 (pba_data.records_changed.entries EQ 0)) | |
2414 { | |
2415 /* Delete the record in the database */ | |
2416 if (pb_sim_del_record (pba_data.current_book, | |
2417 pba_data.del_record, | |
2418 &pba_data.records_changed) NEQ PHB_OK) | |
2419 { | |
2420 TRACE_ERROR ("Unexpected problem from pb_sim_del_record()"); | |
2421 | |
2422 /* Inform SIM layer we're done synchronizing. | |
2423 * Should we indicate also there was a problem? */ | |
2424 (void)pb_sim_flush_data (); | |
2425 | |
2426 pb_status_ind (PHB_WRITE_FAIL, CME_ERR_NotPresent); | |
2427 | |
2428 SET_PHB_STATE (PHB_STATE_IDLE); | |
2429 return; | |
2430 } | |
2431 pba_data.del_record++; | |
2432 } | |
2433 | |
2434 if (pba_data.records_changed.entries NEQ 0) | |
2435 { | |
2436 /* Synchronizing record(s) to the SIM */ | |
2437 if (pb_sync_next_sim_record (FALSE) NEQ PHB_EXCT) | |
2438 { | |
2439 TRACE_ERROR ("Unexpected problem from pb_sync_next_sim_record()"); | |
2440 | |
2441 /* Inform SIM layer we're done synchronizing. | |
2442 * Should we indicate also there was a problem? */ | |
2443 (void)pb_sim_flush_data (); | |
2444 | |
2445 pb_status_ind (PHB_WRITE_FAIL, CME_ERR_NotPresent); | |
2446 | |
2447 SET_PHB_STATE (PHB_STATE_IDLE); | |
2448 return; | |
2449 } | |
2450 } | |
2451 | |
2452 /* | |
2453 * We're through | |
2454 */ | |
2455 | |
2456 (void)pb_sim_flush_data (); | |
2457 | |
2458 /* Inform the ACI that we're done */ | |
2459 pb_status_ind (PHB_READY, CME_ERR_NotPresent); | |
2460 | |
2461 SET_PHB_STATE (PHB_STATE_IDLE); | |
2462 break; | |
2463 | |
2464 case PHB_EXCT: | |
2465 break; /* Next record => SIM */ | |
2466 | |
2467 case PHB_FAIL: | |
2468 default: | |
2469 TRACE_ERROR ("Unexpected problem synching SIM"); | |
2470 | |
2471 (void)pb_sim_flush_data (); | |
2472 | |
2473 pb_status_ind (PHB_WRITE_FAIL, CME_ERR_NotPresent); | |
2474 /* Inform SIM layer we're done synchronizing. | |
2475 * Should we indicate also there was a problem? */ | |
2476 | |
2477 SET_PHB_STATE (PHB_STATE_IDLE); | |
2478 break; | |
2479 } | |
2480 break; | |
2481 | |
2482 default: | |
2483 TRACE_ERROR ("Unexpected default"); | |
2484 break; | |
2485 } | |
2486 } | |
2487 | |
2488 | |
2489 /* | |
2490 +----------------------------------------------------------------------------+ | |
2491 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
2492 | STATE : code ROUTINE : pb_get_phb_type_from_ef | | |
2493 +----------------------------------------------------------------------------+ | |
2494 | |
2495 PURPOSE : This function converts a SIM elementary file number to the | |
2496 appropriate constant of type T_PHB_TYPE, if applicable. | |
2497 Non applicable => INVALID_PHB | |
2498 | |
2499 */ | |
2500 T_PHB_TYPE pb_get_phb_type_from_ef (USHORT ef) | |
2501 { | |
2502 TRACE_FUNCTION ("pb_get_phb_type_from_ef()"); | |
2503 | |
2504 switch (ef) | |
2505 { | |
2506 case SIM_ECC: | |
2507 return ECC; | |
2508 | |
2509 case SIM_ADN: | |
2510 return ADN; | |
2511 | |
2512 case SIM_FDN: | |
2513 return FDN; | |
2514 | |
2515 case SIM_BDN: | |
2516 return BDN; | |
2517 | |
2518 case SIM_LND: | |
2519 return LDN; | |
2520 | |
2521 case SIM_MSISDN: | |
2522 return UPN; | |
2523 | |
2524 case SIM_SDN: | |
2525 return SDN; | |
2526 | |
2527 default: | |
2528 return INVALID_PHB; | |
2529 } | |
2530 } | |
2531 | |
2532 | |
2533 /* | |
2534 +----------------------------------------------------------------------------+ | |
2535 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
2536 | STATE : code ROUTINE : pb_get_ext_type_from_ef | | |
2537 +----------------------------------------------------------------------------+ | |
2538 | |
2539 PURPOSE : This function converts a SIM elementary file number to the | |
2540 appropriate constant of T_PHB_EXT_TYPE, if applicable. | |
2541 Non applicable => INVALID_EXT | |
2542 | |
2543 */ | |
2544 T_EXT_TYPE pb_get_ext_type_from_ef (USHORT ef) | |
2545 { | |
2546 TRACE_FUNCTION ("pb_get_ext_type_from_ef()"); | |
2547 | |
2548 switch (ef) | |
2549 { | |
2550 case SIM_EXT1: | |
2551 return EXT1; | |
2552 | |
2553 case SIM_EXT2: | |
2554 return EXT2; | |
2555 | |
2556 case SIM_EXT3: | |
2557 return EXT3; | |
2558 | |
2559 case SIM_EXT4: | |
2560 return EXT4; | |
2561 | |
2562 case SIM_EXT5: | |
2563 return EXT5; | |
2564 | |
2565 default: | |
2566 return INVALID_EXT; | |
2567 } | |
2568 } | |
2569 | |
2570 | |
2571 /* ------------------------------------------------------------------------ */ | |
2572 | |
2573 /* | |
2574 +----------------------------------------------------------------------------+ | |
2575 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
2576 | STATE : code ROUTINE : pb_search_number_ex | | |
2577 +----------------------------------------------------------------------------+ | |
2578 | |
2579 PURPOSE : At some places a more sohisticated number searching function | |
2580 is desirable which can be based on existing phonebook | |
2581 functionality. | |
2582 | |
2583 */ | |
2584 GLOBAL T_PHB_RETURN pb_search_number_ex (T_PHB_TYPE type, | |
2585 const UBYTE *number, | |
2586 SHORT *order_num, | |
2587 SHORT *found, | |
2588 T_PHB_RECORD *entry) | |
2589 { | |
2590 T_PHB_RETURN phb_result; | |
2591 SHORT index; | |
2592 | |
2593 TRACE_FUNCTION ("pb_search_number_ex()"); | |
2594 | |
2595 /* Search for first entry */ | |
2596 phb_result = pb_search_number (type, | |
2597 number, | |
2598 order_num); | |
2599 if (phb_result NEQ PHB_OK) | |
2600 return phb_result; | |
2601 | |
2602 /* | |
2603 * Determine number of found entries. We are doing a linear algorithm, | |
2604 * a binary algorithm is possible here to speed up things. | |
2605 */ | |
2606 if (found NEQ NULL) | |
2607 { | |
2608 *found = 1; | |
2609 index = *order_num; | |
2610 | |
2611 while (pb_search_number (type, number, &index) EQ PHB_OK) | |
2612 { | |
2613 ++(*found); | |
2614 /* index should not be incremented as lower layer (DB) will take | |
2615 care of it */ | |
2616 } | |
2617 } | |
2618 | |
2619 /* Read the first found entry, if desired */ | |
2620 if (entry NEQ NULL) | |
2621 return (pb_read_number_record (type, *order_num, entry)); | |
2622 return PHB_OK; | |
2623 } | |
2624 | |
2625 | |
2626 /* | |
2627 +----------------------------------------------------------------------------+ | |
2628 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
2629 | STATE : code ROUTINE : pb_search_name_ex | | |
2630 +----------------------------------------------------------------------------+ | |
2631 | |
2632 PURPOSE : At some places a more sohisticated name searching function | |
2633 is desirable which can be based on existing phonebook | |
2634 functionality. | |
2635 | |
2636 */ | |
2637 GLOBAL T_PHB_RETURN pb_search_name_ex (T_PHB_TYPE type, | |
2638 T_PHB_MATCH match, | |
2639 const T_ACI_PB_TEXT *search_tag, | |
2640 SHORT *order_num, | |
2641 SHORT *found, | |
2642 T_PHB_RECORD *entry) | |
2643 { | |
2644 T_PHB_RETURN phb_result; | |
2645 SHORT index; | |
2646 | |
2647 TRACE_FUNCTION ("pb_search_name_ex()"); | |
2648 | |
2649 /* Search for first entry */ | |
2650 phb_result = pb_search_name (type, | |
2651 match, | |
2652 search_tag, | |
2653 order_num); | |
2654 if (phb_result NEQ PHB_OK) | |
2655 return phb_result; | |
2656 | |
2657 /* | |
2658 * Determine number of found entries. We are doing a linear algorithm, | |
2659 * a binary algorithm is possible here to speed up things. | |
2660 */ | |
2661 if (found NEQ NULL) | |
2662 { | |
2663 *found = 1; | |
2664 index = *order_num; | |
2665 | |
2666 while (pb_search_name (type, match, search_tag, &index) EQ PHB_OK) | |
2667 { | |
2668 ++(*found); | |
2669 /* index should not be incremented as lower layer (DB) will take | |
2670 care of it */ | |
2671 } | |
2672 | |
2673 } | |
2674 | |
2675 /* Read the first found entry, if desired */ | |
2676 if (entry NEQ NULL) | |
2677 return (pb_read_alpha_record (type, *order_num, entry)); | |
2678 return PHB_OK; | |
2679 } | |
2680 | |
2681 | |
2682 /* | |
2683 +----------------------------------------------------------------------------+ | |
2684 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
2685 | STATE : code ROUTINE : pb_status_ind | | |
2686 +----------------------------------------------------------------------------+ | |
2687 | |
2688 PURPOSE : This function indicates the new phonebook status to the ACI | |
2689 preventing we're indication twice PHB_READY or PHB_BUSY. | |
2690 | |
2691 */ | |
2692 LOCAL void pb_status_ind (T_PHB_STAT phb_stat, SHORT cmeError) | |
2693 { | |
2694 TRACE_FUNCTION ("pb_status_ind()"); | |
2695 | |
2696 /* Avoid to indicate twice busy or ready */ | |
2697 if ((pba_data.phb_stat NEQ phb_stat) OR | |
2698 ((phb_stat NEQ PHB_READY) AND | |
2699 (phb_stat NEQ PHB_BUSY))) | |
2700 { | |
2701 cmhPHB_StatIndication ((UBYTE)phb_stat, cmeError,TRUE); | |
2702 pba_data.phb_stat = phb_stat; | |
2703 } | |
2704 } | |
2705 | |
2706 | |
2707 /* | |
2708 +----------------------------------------------------------------------------+ | |
2709 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
2710 | STATE : code ROUTINE : pb_write_queue | | |
2711 +----------------------------------------------------------------------------+ | |
2712 | |
2713 PURPOSE : This function writes a LDN entry to the queue if the SIM is busy. | |
2714 | |
2715 */ | |
2716 LOCAL T_PHB_RETURN pb_write_queue (const T_PHB_RECORD *entry) | |
2717 { | |
2718 TRACE_FUNCTION ("pb_write_queue()"); | |
2719 | |
2720 if (pba_data.c_queued < PHB_MAX_QUEUE) | |
2721 { | |
2722 memmove (&pba_data.queued[1], | |
2723 &pba_data.queued[0], | |
2724 pba_data.c_queued * sizeof (T_PHB_QUEUE *)); | |
2725 ACI_MALLOC (pba_data.queued[pba_data.c_queued], | |
2726 sizeof (T_PHB_QUEUE)); | |
2727 pba_data.queued[0]->entry = *entry; | |
2728 pba_data.c_queued++; | |
2729 return PHB_EXCT; | |
2730 } | |
2731 | |
2732 return PHB_FAIL; /* Queue full */ | |
2733 } | |
2734 | |
2735 | |
2736 /* | |
2737 +----------------------------------------------------------------------------+ | |
2738 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
2739 | STATE : code ROUTINE : pb_clear_queue | | |
2740 +----------------------------------------------------------------------------+ | |
2741 | |
2742 PURPOSE : This function clears the LDN queue. | |
2743 | |
2744 */ | |
2745 LOCAL void pb_clear_queue (void) | |
2746 { | |
2747 TRACE_FUNCTION ("pb_clear_queue()"); | |
2748 | |
2749 while (pba_data.c_queued NEQ 0) | |
2750 { | |
2751 pba_data.c_queued--; | |
2752 ACI_MFREE (pba_data.queued[pba_data.c_queued]); | |
2753 pba_data.queued[pba_data.c_queued] = NULL; | |
2754 } | |
2755 } | |
2756 | |
2757 | |
2758 /* | |
2759 +----------------------------------------------------------------------------+ | |
2760 | PROJECT : GSM-PS (6147) MODULE : PHB | | |
2761 | STATE : code ROUTINE : pb_read_queue | | |
2762 +----------------------------------------------------------------------------+ | |
2763 | |
2764 PURPOSE : This function reads the queue and adds the queued phonebook | |
2765 entries. | |
2766 | |
2767 */ | |
2768 LOCAL T_PHB_RETURN pb_read_queue (void) | |
2769 { | |
2770 T_PHB_RETURN phb_result; | |
2771 | |
2772 TRACE_FUNCTION ("pb_write_queue()"); | |
2773 | |
2774 while (pba_data.c_queued NEQ 0) | |
2775 { | |
2776 /* | |
2777 * LDN entries have been queued. Write them now. | |
2778 */ | |
2779 pba_data.c_queued--; | |
2780 phb_result = pb_add_record (LDN, | |
2781 pba_data.queued[pba_data.c_queued]->index, | |
2782 &pba_data.queued[pba_data.c_queued]->entry); | |
2783 ACI_MFREE (pba_data.queued[pba_data.c_queued]); | |
2784 pba_data.queued[pba_data.c_queued] = NULL; | |
2785 switch (phb_result) | |
2786 { | |
2787 case PHB_EXCT: | |
2788 return phb_result; | |
2789 case PHB_OK: | |
2790 break; | |
2791 default: | |
2792 pb_clear_queue(); | |
2793 return phb_result; | |
2794 } | |
2795 } | |
2796 return PHB_OK; | |
2797 } | |
2798 | |
2799 #endif /* #ifdef TI_PS_FFS_PHB */ |