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 */