comparison src/aci2/aci/cphs.c @ 3:93999a60b835

src/aci2, src/condat2: import of g23m/condat source pieces from TCS211
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 26 Sep 2016 00:29:36 +0000
parents
children
comparison
equal deleted inserted replaced
2:c41a534f33c6 3:93999a60b835
1 /*
2 +--------------------------------------------------------------------+
3 | PROJECT: $Workfile:: cphs.c $|
4 | $Author:: $Revision:: $|
5 | CREATED: $Modtime:: $|
6 | STATE : code |
7 +--------------------------------------------------------------------+
8
9 MODULE : CPHS
10
11 PURPOSE : This module contains the CPHS functionalities.
12 */
13
14 #ifdef FF_CPHS
15
16 #ifndef CPHS_C
17 #define CPHS_C
18
19 /* needed for all files that are part of ACI */
20 #include "aci_all.h"
21 #include "aci_cmh.h"
22 #include "phb.h"
23 #include "cphs.h"
24
25 #include "psa.h"
26 #include "cmh.h"
27 #include "psa_sim.h"
28 #include "dti_conn_mng.h"
29 #include "cmh_sim.h"
30
31 /* Definition of records indices in association with cphs lines */
32 #define CPHS_LINE1_REC (1)
33 #define CPHS_LINE2_REC (2)
34 #define CPHS_LINE_DATA_REC (3)
35 #define CPHS_LINE_FAX_REC (4)
36
37 /* cphs initialising status */
38 typedef enum
39 {
40 CPHS_NOT_INITIALISED = 0,
41 CPHS_INITIALISING, /* currently initialising */
42 CPHS_INITIALISED, /* initialised, currently does nothing */
43 CPHS_REFRESHING, /* refreshing cached data */
44 CPHS_WRITING_CFU, /* writing new CFU status on SIM */
45 CPHS_WRITING_VWI, /* writing new VWI status on SIM: user initiated */
46 CPHS_WRITING_VWI_IND /* writing new VWI status on SIM: network initiated */
47 } T_CPHS_STATUS;
48
49 /* data send to SIM */
50 static UBYTE exchData[100];
51
52 /* CPHS status: provides information on what action is currently on progress */
53 static T_CPHS_STATUS cphs_status = CPHS_NOT_INITIALISED;
54
55 /* parameter describing at what step updating currently is */
56 static UBYTE sim_cache_update_state = CPHS_SIM_NOT_UPDATING;
57
58 #define CINF_SIZE (3)
59
60 /* VWI and CFU tables have to have the same size */
61 #define FLAG_TABLE_SIZE (2)
62 #define CFU_SIZE FLAG_TABLE_SIZE
63 #define VWI_SIZE FLAG_TABLE_SIZE
64
65 typedef struct
66 {
67 T_CPHS_USER_CB *user_cb; /* callback used by CPHS module to pass results to ACI */
68 UBYTE current_record; /* record currently read */
69 UBYTE *sim_read_record_buffer; /* buffer for record currently read */
70
71 UBYTE tmp_activate_state; /* TEMP setting being currently written on SIM (CFU or VWI) */
72 T_CPHS_LINES tmp_lines; /* TEMP lines being currently written on SIM (CFU or VWI) */
73
74 UBYTE tmp_flag_set[FLAG_TABLE_SIZE]; /* Flags Field (corresponding to tmp_lines) being currently
75 written on SIM (CFU or VWI) */
76 UBYTE tmp_info[CINF_SIZE]; /* voice mail waiting bitmask of CPHS lines */
77 } T_CPHS_INTERNAL_PARAMS;
78
79 LOCAL T_CPHS_INTERNAL_PARAMS *cphs_internal_params;
80
81 /***** Parameters concerning ALS info ********/
82 /* how many different lines are there ? line1, line2, fax, data */
83 /* defines order of presentation of the lines when testing command AT%CPALS=? */
84 #define LINE1_ID (0)
85 #define LINE2_ID (1)
86 #define LINEDATA_ID (2)
87 #define LINEFAX_ID (3)
88 #define MAX_LINE_ID (4)
89
90 #define DEFAULT_LINE1_NAME "Line 1"
91 #define DEFAULT_LINE2_NAME "Line 2"
92 #define DEFAULT_DATA_NAME "Data"
93 #define DEFAULT_FAX_NAME "Fax"
94 #define CPHS_MAX_SIZE_ALPHA (22)
95
96 typedef struct
97 {
98 T_CPHS_LINES line;
99 CHAR line_desc[CPHS_MAX_SIZE_ALPHA];
100
101 } T_CPHS_ALS_NAMES;
102
103
104 /* structure containing the cached parameters from SIM */
105 typedef struct
106 {
107 UBYTE cfu_flags[CFU_SIZE]; /* same format as on the SIM: field 6F13 */
108 UBYTE vwi_flags[VWI_SIZE]; /* same format as on the SIM: field 6F11 */
109 UBYTE opn_long[CPHS_MAX_OPER_LONG]; /* operator long name */
110 UBYTE opn_short[CPHS_MAX_OPER_SHORT]; /* operator shortname */
111 T_CPHS_INF_NUM *info_numbers; /* contains all info numbers entries */
112 UBYTE max_info_numbers; /* index of last entry in info number list */
113 T_CPHS_ALS_NAMES *als;
114 UBYTE max_als_names_entries;
115 T_CPHS_CINF info; /* cphs information */
116 UBYTE csp[CPHS_MAX_CSP]; /* same format as on the SIM: field 6F15 */
117 UBYTE csp_length; /* Value given by SIM after Read action */
118 UBYTE orange_csp2[CPHS_MAX_CSP2]; /* Orange specific - same format as on the SIM: field 0x6f98 */
119 UBYTE orange_csp2_length; /* Orange specific - Value given by SIM after Read action */
120 T_CPHS_MB *mb_numbers;
121 UBYTE max_mb_numbers;
122 UBYTE max_mb_entry_length; /* max length for mailbox entry */
123 } T_CPHS_CACHED_PARAMS;
124
125 LOCAL T_CPHS_CACHED_PARAMS *cphs_cached_params; /* memory allocated at initialisation */
126
127 LOCAL void cphs_cache_sim_data(UBYTE max_records, UBYTE latest_record_len);
128 LOCAL void cphs_set_next_update_state(void);
129 LOCAL T_CPHS_RET cphs_get_indicator_flag(UBYTE *flag_set, T_CPHS_LINES line, UBYTE indicator);
130 LOCAL void cphs_write_indicator_flag(UBYTE flag_set,
131 T_CPHS_LINES lines,
132 UBYTE indicator);
133 LOCAL void get_name_pointer_over_lineid(T_CPHS_LINES line, CHAR **line_desc, UBYTE max_lined);
134
135 /*
136 +--------------------------------------------------------------------+
137 | PROJECT : GSM-PS (6147) MODULE : CPHS |
138 | STATE : code ROUTINE : Internal functions |
139 +--------------------------------------------------------------------+
140
141 PURPOSE : Set of functions used internally.
142 */
143
144 /* Informs user of the result of an operation */
145 GLOBAL void cphs_inform_user(T_CPHS_CB callback_type,
146 T_CPHS_RET return_value,
147 UBYTE set_flag,
148 T_CPHS_LINES line)
149 {
150 T_CPHS_PARAMS user_cb_params;
151
152 TRACE_EVENT_P4("cphs_inform_user(): cb_type: %d, result: %d, flag: %d, line: %d",
153 callback_type, return_value, set_flag, line);
154
155 user_cb_params.cb_type = callback_type;
156 user_cb_params.operation_result = return_value;
157
158 user_cb_params.set_flag = set_flag;
159 user_cb_params.line = line;
160
161 cphs_internal_params->user_cb(&user_cb_params);
162 }
163
164 /* Checks whether CPHS module has been initialised or if it is currently
165 being used.
166
167 *** All user interface function should use this function ***
168 *** to check cphs_status before processing *** */
169 GLOBAL T_CPHS_RET cphs_check_status(void)
170 {
171 TRACE_FUNCTION("cphs_check_status()");
172
173 switch(cphs_status)
174 {
175 case(CPHS_NOT_INITIALISED):
176 TRACE_EVENT("CPHS has not been initialised");
177 return(CPHS_NOT_INIT);
178
179 case(CPHS_INITIALISED):
180 return(CPHS_OK);
181
182 default:
183 TRACE_EVENT("CPHS is BUSY: currently processing data");
184 return(CPHS_BUSY);
185 }
186 }
187
188
189 /* Aborts currently processed operation */
190 GLOBAL void cphs_abort_current_action(void)
191 {
192 TRACE_EVENT_P1("cphs_abort_current_action(): action id: %d", cphs_status);
193
194 switch(cphs_status)
195 {
196 case(CPHS_INITIALISING):
197 case(CPHS_REFRESHING):
198 /* CPHS module was currently updating cached data from the SIM */
199 sim_cache_update_state = CPHS_SIM_NOT_UPDATING;
200
201 cphs_inform_user(CPHS_INIT_RES, CPHS_FAIL, NOT_PRESENT_8BIT, CPHS_LINE_NULL);
202 cphs_status = CPHS_NOT_INITIALISED; /* initialising aborted */
203 return;
204
205 default:
206 cphs_status = CPHS_INITIALISED;
207 return;
208 }
209 }
210
211 #define RECORD_BUFF (0)
212 #define INFO_BUFF (1)
213 #define ALS_BUFF (2)
214 #define MB_BUFF (3)
215
216 LOCAL void free_buffer(UBYTE buffer_id)
217 {
218 switch(buffer_id)
219 {
220 case(RECORD_BUFF):
221 if(cphs_internal_params->sim_read_record_buffer NEQ NULL)
222 {
223 MFREE(cphs_internal_params->sim_read_record_buffer);
224 cphs_internal_params->sim_read_record_buffer = NULL;
225 }
226 break;
227
228 case(INFO_BUFF):
229 if(cphs_cached_params->info_numbers NEQ NULL)
230 {
231 //MFREE(cphs_cached_params->info_numbers);
232 cphs_cached_params->info_numbers = NULL;
233 }
234 break;
235
236 case(ALS_BUFF):
237 if(cphs_cached_params->als NEQ NULL)
238 {
239 MFREE(cphs_cached_params->als);
240 cphs_cached_params->als = NULL;
241 }
242 break;
243
244 case(MB_BUFF):
245 if(cphs_cached_params->mb_numbers NEQ NULL)
246 {
247 MFREE(cphs_cached_params->mb_numbers);
248 cphs_cached_params->mb_numbers = NULL;
249 }
250 break;
251 }
252 }
253
254 LOCAL void write_dummy_function(UBYTE info_number_index, UBYTE *sim_data, UBYTE record_len)
255 {
256 TRACE_FUNCTION("write_dummy_function()");
257 }
258
259 LOCAL void write_info_number(UBYTE info_number_index, UBYTE *sim_data, UBYTE record_len)
260 {
261 UBYTE alpha_length, bcd_length;
262 BOOL check_network_specific_bit,
263 check_premium_service_bit;
264 UBYTE *ptr;
265 T_CPHS_INF_NUM *current_info_number;
266
267 TRACE_FUNCTION("write_info_number()");
268
269 /* write data read from SIM for current_record */
270 ptr = sim_data;
271
272 /* get structure where data are to be written for this record */
273 current_info_number = &cphs_cached_params->info_numbers[info_number_index];
274
275 current_info_number->element_index = info_number_index;
276
277 /* first byte: alpha_length */
278 alpha_length = *ptr;
279 if(alpha_length EQ 0xFF)
280 {
281 /* it has to be a NULL entry: Shall be ignored (see CPHS recom.). Jump to next record */
282 return;
283 }
284
285 /* second byte */
286 ptr++;
287 check_network_specific_bit = *ptr & 0x20;
288 check_premium_service_bit = *ptr & 0x10;
289 current_info_number->index_level = *ptr & 0x0F;
290
291 if(check_network_specific_bit)
292 {
293 /* info number is network specific */
294 current_info_number->network_flag = TRUE;
295 }
296 else
297 current_info_number->network_flag = FALSE;
298
299 if(check_premium_service_bit)
300 {
301 /* info number is network specific */
302 current_info_number->premium_flag = TRUE;
303 }
304 else
305 current_info_number->premium_flag = FALSE;
306
307 /* third byte to alpha_len+2 */
308 /* Check 03.40 ?? */
309 ptr++;
310
311 if(alpha_length > sizeof(current_info_number->alpha_tag))
312 {
313 alpha_length = sizeof(current_info_number->alpha_tag);
314 }
315
316 /* initialize with 0s */
317 memset(current_info_number->alpha_tag,
318 0,
319 sizeof(current_info_number->alpha_tag));
320 memcpy(current_info_number->alpha_tag, ptr, alpha_length);
321
322 /* Length of BCD byte */ /*********** ignore ??? ***************/
323 ptr += alpha_length;
324 if(*ptr EQ 0xFF)
325 {
326 /* this is a folder: no number information */
327 bcd_length = 1; /* TON/NPI */
328 }
329 else
330 bcd_length = *ptr;
331
332 /* TON and NPI byte */
333 ptr++;
334 current_info_number->type_of_address = *ptr;
335 bcd_length--; /* TON and NPI are counted in bcd length */
336
337 /* Digits section */
338 ptr++;
339 /* initialize with 0s */
340 memset(current_info_number->number,
341 0,
342 sizeof(current_info_number->number));
343 if(2*bcd_length > sizeof(current_info_number->number))
344 {
345 bcd_length = sizeof(current_info_number->number);
346 }
347 cphs_bcd2number(current_info_number->number, ptr, bcd_length);
348
349
350 /*********** Trace info number read: ****************/
351 TRACE_EVENT_P7("Info Number: add: %d, index: %d, alpha: %s, number: %s, index_level: %d, premium: %d, network: %d",
352 current_info_number,
353 current_info_number->element_index,
354 current_info_number->alpha_tag,
355 current_info_number->number,
356 current_info_number->index_level,
357 current_info_number->premium_flag,
358 current_info_number->network_flag);
359 }
360
361 LOCAL T_CPHS_LINES translate_index2line(UBYTE index)
362 {
363 switch(index - 1)
364 {
365 case(LINE1_ID):
366 return(CPHS_LINE1);
367
368 case(LINE2_ID):
369 return(CPHS_LINE2);
370
371 case(LINEDATA_ID):
372 return(CPHS_LINE_DATA);
373
374 case(LINEFAX_ID):
375 return(CPHS_LINE_FAX);
376
377 default:
378 TRACE_EVENT_P1("wrong index: %d", index);
379 return(CPHS_LINE_NULL);
380 }
381 }
382
383 LOCAL void write_als_names(UBYTE number_index, UBYTE *sim_data, UBYTE record_len)
384 {
385 UBYTE max_entries, alpha_length;
386 UBYTE i;
387 CHAR *line_desc;
388 T_CPHS_LINES lineid;
389
390 TRACE_FUNCTION("write_als_names( )");
391
392 max_entries = cphs_cached_params->max_als_names_entries;
393
394 lineid = translate_index2line(number_index);
395 get_name_pointer_over_lineid(lineid, &line_desc, max_entries);
396
397 if(line_desc EQ NULL)
398 {
399 TRACE_ERROR("line_desc is NULL");
400 return;
401 }
402
403 alpha_length = 0;
404 for(i=0 ; i<(record_len - CPHS_MIN_MB_LEN); i++)
405 {
406 if(sim_data[i] EQ 0xFF)
407 {
408 TRACE_EVENT_P1("length: %d", i);
409 break;
410 }
411 alpha_length++;
412 }
413
414 if(alpha_length EQ 0)
415 {
416 TRACE_EVENT("No alpha tag on SIM");
417 return;
418 }
419 memcpy(line_desc, sim_data, MINIMUM(alpha_length,CPHS_MAX_SIZE_ALPHA));
420 line_desc[alpha_length] = '\0';
421
422 /*********** Trace ****************/
423 TRACE_EVENT_P3("index: %d, line: %d, alpha: %s",
424 number_index,
425 lineid,
426 line_desc);
427 }
428
429 LOCAL void write_mb_number(UBYTE number_index, UBYTE *sim_data, UBYTE record_len)
430 {
431 UBYTE i;
432 UBYTE pos;
433 UBYTE bcd_len;
434 T_CPHS_MB *current_number;
435
436 TRACE_FUNCTION("write_mb_number()");
437
438 TRACE_EVENT_P3("idx: %d, ln: %d, data: %s",
439 number_index, record_len, sim_data);
440
441 /* get structure where data are to be written for this record */
442 current_number = &cphs_cached_params->mb_numbers[number_index-1];
443 memset(current_number->alpha_id, 0, sizeof(current_number->alpha_id));
444 memset(current_number->number, 0, sizeof(current_number->number));
445
446 if (cphs_cached_params->max_mb_numbers < number_index)
447 {
448 cphs_cached_params->max_mb_numbers = number_index;
449 }
450
451 /* map record index to lines */
452 switch(number_index)
453 {
454 case CPHS_LINE1_REC:
455 current_number->line = CPHS_LINE1;
456 break;
457 case CPHS_LINE2_REC:
458 current_number->line = CPHS_LINE2;
459 break;
460 case CPHS_LINE_DATA_REC:
461 current_number->line = CPHS_LINE_DATA;
462 break;
463 case CPHS_LINE_FAX_REC:
464 current_number->line = CPHS_LINE_FAX;
465 break;
466 default:
467 TRACE_EVENT("unexpected record index of cphs mailbox number");
468 break;
469 }
470
471 /* get alpha identifier, if available */
472 pos = record_len - CPHS_MIN_MB_LEN;
473 if ( ( pos > 0 ) AND ( sim_data[0] NEQ 0xFF ) )
474 {
475 for (i=0; i<pos; i++)
476 {
477 if (sim_data[i] NEQ 0xFF)
478 current_number->alpha_id[i] = sim_data[i];
479 }
480 }
481 else
482 {
483 TRACE_EVENT("empty MB alpha");
484 }
485
486 /* get length of bcd */
487 bcd_len = sim_data[pos];
488
489 if ( bcd_len EQ 0xFF )
490 {
491 /* empty MB number */
492 TRACE_EVENT_P2("empty MB number, pos: %d, bcd_len:%d",
493 pos, bcd_len);
494
495 current_number->toa = NOT_PRESENT_8BIT;
496 return;
497 }
498
499 /* TON and NPI byte */
500 pos++;
501 current_number->toa = sim_data[pos];
502 bcd_len--; /* TON and NPI are counted in bcd length */
503
504 /* Digits section */
505 pos++;
506 if(2*bcd_len > sizeof(current_number->number))
507 {
508 bcd_len = sizeof(current_number->number);
509 }
510 cphs_bcd2number(current_number->number, &(sim_data[pos]), bcd_len);
511
512
513 /*********** Trace mailbox number read: ****************/
514 TRACE_EVENT_P5("index: %d, line: %d, alpha: %s, number: %s, toa: %d",
515 number_index,
516 current_number->line,
517 current_number->alpha_id,
518 current_number->number,
519 current_number->toa);
520 }
521
522 LOCAL void write_csp_ok(UBYTE *sim_data, UBYTE record_len)
523 {
524 TRACE_FUNCTION("write_csp_ok()");
525
526 if( sim_data NEQ NULL )
527 {
528 memcpy(cphs_cached_params->csp, sim_data, record_len );
529 }
530 }
531 /*
532 +--------------------------------------------------------------------+
533 | PROJECT : GSM-PS (6147) MODULE : CPHS |
534 | STATE : code ROUTINE : cphs_first_free |
535 +--------------------------------------------------------------------+
536
537 PURPOSE : Find first free location in mailbox list
538 */
539 GLOBAL T_CPHS_RET cphs_first_free(
540 UBYTE *first_free)
541 {
542 UBYTE rec_id;
543
544 if(cphs_cached_params EQ NULL)
545 {
546 TRACE_ERROR("cphs_cached_params==NULL");
547 ACI_ERR_DESC(ACI_ERR_CLASS_Cme,CME_ERR_OpNotAllow);
548 return(CPHS_FAIL);
549 }
550
551 if (cphs_cached_params->mb_numbers EQ NULL)
552 {
553 TRACE_ERROR("cphs_cached_params->mb_numbers==NULL");
554 ACI_ERR_DESC(ACI_ERR_CLASS_Cme,CME_ERR_OpNotAllow);
555 return(CPHS_FAIL);
556 }
557
558 for (rec_id=0;rec_id<cphs_cached_params->max_mb_numbers;rec_id++)
559 {
560 if (cphs_cached_params->mb_numbers[rec_id].number[0] EQ 0)
561 {
562 *first_free=(UBYTE)(rec_id+1);
563 return(CPHS_OK);
564 }
565 }
566
567 /*
568 * List is full, indicate this with 0.
569 */
570 *first_free=0;
571 return(CPHS_OK);
572 }
573
574 /* temp until we use lists */
575 /* Size has to be set to 600 considering the length alignment of the datastrct*/
576 UBYTE info_numbers_buffer[600];
577
578 LOCAL void cphs_init_records_info(UBYTE max_records)
579 {
580 TRACE_FUNCTION("cphs_init_records_info( )");
581
582 if(cphs_cached_params->info_numbers EQ NULL) // should only be checked for first entry
583 {
584 /* This should happen only once: on the SIM are more records than thought at first.
585 structure size has to be increased (and this has to be done before 1st entry is copied !!) */
586 TRACE_EVENT_P1("cphs_cached_params->info_numbers list size: %d records on SIM", max_records);
587
588 /******* use lists !!!!!!!!!!!!! *****/
589 //MALLOC(cphs_cached_params->info_numbers, (ULONG)(max_records*sizeof(T_CPHS_INF_NUM)));
590 cphs_cached_params->info_numbers = (T_CPHS_INF_NUM*)&info_numbers_buffer;
591 cphs_cached_params->max_info_numbers = max_records;
592 }
593
594 /* First entry should be "ROOT" with index 0 */
595 cphs_cached_params->info_numbers[0].element_index = 0;
596 cphs_cached_params->info_numbers[0].index_level = 0;
597 sprintf(cphs_cached_params->info_numbers[0].alpha_tag, "ROOT");
598 memset(cphs_cached_params->info_numbers[0].number,
599 0,
600 sizeof(cphs_cached_params->info_numbers[0].number));
601 }
602
603 LOCAL void cphs_init_records_mailbox(UBYTE max_records)
604 {
605 TRACE_FUNCTION("cphs_init_records_mailbox( )");
606
607 if(cphs_cached_params->mb_numbers EQ NULL) // should only be checked for first entry
608 {
609
610 /* This should happen only once: on the SIM are more records than thought at first.
611 structure size has to be increased (and this has to be done before 1st entry is copied !!) */
612 TRACE_EVENT_P1("cphs_cached_params->mb_numbers list size: %d records on SIM", max_records);
613
614 MALLOC(cphs_cached_params->mb_numbers, (USHORT)(max_records*sizeof(T_CPHS_MB)));
615
616 cphs_cached_params->max_mb_numbers = max_records;
617 }
618
619 cphs_cached_params->mb_numbers[0].line = CPHS_LINE_NULL;
620 cphs_cached_params->mb_numbers[0].toa = NOT_PRESENT_8BIT;
621 memset(cphs_cached_params->mb_numbers[0].number, 0,
622 sizeof(cphs_cached_params->info_numbers[0].number));
623 memset(cphs_cached_params->mb_numbers[0].alpha_id, 0,
624 sizeof(cphs_cached_params->mb_numbers[0].alpha_id));
625 }
626
627 LOCAL void initialize_als_info(UBYTE als_max_records)
628 {
629 CHAR *line_desc;
630
631 TRACE_FUNCTION("initialize_als_info( )");
632
633 MALLOC(cphs_cached_params->als, (USHORT)(als_max_records* sizeof(T_CPHS_ALS_NAMES)));
634 cphs_cached_params->max_als_names_entries = als_max_records;
635
636 /* for SIMs with als_max_records > MAX_LINE_ID */
637 if (als_max_records > MAX_LINE_ID)
638 als_max_records = MAX_LINE_ID;
639
640 switch (als_max_records)
641 {
642 case (LINEFAX_ID+1):
643 cphs_cached_params->als[LINEFAX_ID].line = CPHS_LINE_FAX;
644 get_name_pointer_over_lineid(CPHS_LINE_FAX, &line_desc, als_max_records);
645 sprintf(line_desc, DEFAULT_FAX_NAME);
646 //lint -fallthrough
647 case (LINEDATA_ID+1):
648 cphs_cached_params->als[LINEDATA_ID].line = CPHS_LINE_DATA;
649 get_name_pointer_over_lineid(CPHS_LINE_DATA, &line_desc, als_max_records);
650 sprintf(line_desc, DEFAULT_DATA_NAME);
651 //lint -fallthrough
652 case (LINE2_ID+1):
653 cphs_cached_params->als[LINE2_ID].line = CPHS_LINE2;
654 get_name_pointer_over_lineid(CPHS_LINE2, &line_desc, als_max_records);
655 sprintf(line_desc, DEFAULT_LINE2_NAME);
656 //lint -fallthrough
657 case (LINE1_ID+1):
658 cphs_cached_params->als[LINE1_ID].line = CPHS_LINE1;
659 get_name_pointer_over_lineid(CPHS_LINE1, &line_desc, als_max_records);
660 sprintf(line_desc, DEFAULT_LINE1_NAME);
661 }
662 }
663
664 LOCAL void cphs_init_records_alsnames(UBYTE max_records)
665 {
666 TRACE_FUNCTION("cphs_init_records_alsnames( )");
667
668 TRACE_EVENT_P1("cphs_cached_params->als list size: %d records on SIM", max_records);
669
670 if(cphs_cached_params->als EQ NULL)
671 {
672 /* This should happen only once: on the SIM are more records than thought at first.
673 structure size has to be increased (and this has to be done before 1st entry is copied !!) */
674
675 /* init als name structure */
676 initialize_als_info(max_records);
677 }
678 }
679
680 LOCAL void cphs_init_records(UBYTE max_records, UBYTE sim_update_type)
681 {
682 TRACE_FUNCTION("cphs_init_records( )");
683
684 switch (sim_update_type)
685 {
686 case(CPHS_SIM_INFO_NUMS):
687 case(CPHS_SIM_INFO_NUMS_EA01):
688 cphs_init_records_info(max_records);
689 break;
690
691 case(CPHS_SIM_MB):
692 cphs_init_records_mailbox(max_records);
693 break;
694
695 case(CPHS_SIM_ALSNAMES):
696 cphs_init_records_alsnames(max_records);
697 break;
698
699 default:
700 TRACE_EVENT_P1("Wrong sim_update_state: %d", sim_update_type);
701 break;
702 }
703
704 }
705
706
707 #define DEFAULT_MAXSIZE_OF_RECORD (100)
708 typedef void T_CPHS_WRITE_NUMBER_FCT (UBYTE number_index, UBYTE *sim_data, UBYTE record_len);
709
710 LOCAL T_CPHS_WRITE_NUMBER_FCT *get_the_specific_data_update_type_dependant(UBYTE sim_update_type,
711 UBYTE *max_number)
712 {
713 switch(sim_update_type)
714 {
715 case(CPHS_SIM_INFO_NUMS):
716 case(CPHS_SIM_INFO_NUMS_EA01):
717 TRACE_EVENT("Information Numbers");
718 *max_number = cphs_cached_params->max_info_numbers;
719 return(write_info_number);
720
721 case(CPHS_SIM_MB):
722 TRACE_EVENT("Mailbox Numbers");
723 *max_number = cphs_cached_params->max_mb_numbers;
724 return(write_mb_number);
725
726 case(CPHS_SIM_ALSNAMES):
727 TRACE_EVENT("MSISDN Names");
728 *max_number = cphs_cached_params->max_als_names_entries;
729 return(write_als_names);
730
731 default:
732 TRACE_ERROR("wrong sim_update_type value");
733 break;
734 }
735 return(write_dummy_function);
736 }
737
738 /* returns TRUE if all records have been read... */
739 LOCAL BOOL cphs_read_sim_records(UBYTE max_records,
740 UBYTE sim_update_type,
741 UBYTE latest_record_len)
742 {
743 UBYTE *current_record = &cphs_internal_params->current_record;
744 UBYTE *number_exdata = cphs_internal_params->sim_read_record_buffer; /* buffer for the SIM to write data: temporary buffer */
745 T_CPHS_WRITE_NUMBER_FCT *write_number;
746 UBYTE max_numbers;
747
748 TRACE_FUNCTION("cphs_read_sim_records()");
749
750 write_number = get_the_specific_data_update_type_dependant(sim_update_type, &max_numbers);
751
752 switch(*current_record)
753 {
754 case(0):
755 TRACE_EVENT("CPHS read records: START !!!");
756
757 /* Begin of reading of the Information Numbers */
758 if(cphs_internal_params->sim_read_record_buffer EQ NULL)
759 {
760 MALLOC(cphs_internal_params->sim_read_record_buffer, DEFAULT_MAXSIZE_OF_RECORD); // buffer for the SIM to write data: temporary buffer
761 }
762 else
763 {
764 TRACE_EVENT("sim_read_record_buffer should be NULL: weird indeed...");
765 }
766 break;
767
768 case(1):
769 cphs_init_records(max_records, sim_update_type);
770 //lint -fallthrough
771
772 default:
773 TRACE_EVENT_P1("number retrieved from SIM: record %d read", *current_record);
774 if (write_number NEQ NULL)
775 {
776 write_number(*current_record, cphs_internal_params->sim_read_record_buffer, latest_record_len);
777 }
778 break;
779 }
780
781 /* last record read ?? */
782 if(*current_record EQ max_records)
783 {
784 *current_record = 0;
785 free_buffer(RECORD_BUFF);
786 return(TRUE);
787 }
788
789
790 /* Read next record */
791 (*current_record)++;
792
793 cphs_sim_access_data( CPHS_SIM_READ_RECORD,
794 sim_update_type,
795 *current_record,
796 cphs_internal_params->sim_read_record_buffer,
797 DEFAULT_MAXSIZE_OF_RECORD );
798
799 return(FALSE);
800 }
801
802 LOCAL void get_name_pointer_over_lineid(T_CPHS_LINES line, CHAR **line_desc, UBYTE max_lined)
803 {
804 UBYTE i;
805 T_CPHS_ALS_NAMES *current_als;
806
807 TRACE_FUNCTION("get_name_pointer_over_lineid()");
808
809 for(i=0; i<max_lined; i++)
810 {
811 current_als = &(cphs_cached_params->als[i]);
812 if(current_als->line EQ line)
813 {
814 *line_desc = current_als->line_desc;
815 return;
816 }
817 }
818
819 TRACE_ERROR("Ugly error: wrong line type");
820 *line_desc = NULL;
821 }
822
823 /* Read data to be cached from SIM */
824 /* param_max_records: when reading first record, SIM return the number of records to be found
825 on the SIM: thus CPHS module can check whether allocated memory is enough */
826 LOCAL void cphs_cache_sim_data(UBYTE max_records, UBYTE latest_record_len)
827 {
828 BOOL end_of_read;
829
830 TRACE_FUNCTION("cphs_cache_sim_data()");
831
832 /* operation to be performed */
833 switch(sim_cache_update_state)
834 {
835 case(CPHS_SIM_NOT_UPDATING):
836 /* START UPDATING !!! */
837 cphs_set_next_update_state();
838 cphs_cache_sim_data(NOT_PRESENT_8BIT, NOT_PRESENT_8BIT);
839 return;
840
841 case(CPHS_SIM_CFU):
842 /* Read Call Forwarding Flag */
843 cphs_sim_access_data( CPHS_SIM_READ_TRANSP_EF,
844 CPHS_SIM_CFU,
845 0,
846 cphs_cached_params->cfu_flags,
847 CFU_SIZE );
848 return;
849
850 case(CPHS_SIM_VWI):
851 /* read waiting flags on SIM */
852 cphs_sim_access_data( CPHS_SIM_READ_TRANSP_EF,
853 CPHS_SIM_VWI,
854 0,
855 cphs_cached_params->vwi_flags,
856 VWI_SIZE);
857 return;
858
859 case(CPHS_SIM_CINF):
860 /* read cphs info on SIM */
861 cphs_sim_access_data( CPHS_SIM_READ_TRANSP_EF,
862 CPHS_SIM_CINF,
863 0,
864 cphs_internal_params->tmp_info,
865 CINF_SIZE);
866 return;
867
868 case(CPHS_SIM_CSP):
869 /* read customer service profile on SIM */
870 cphs_sim_access_data( CPHS_SIM_READ_TRANSP_EF,
871 CPHS_SIM_CSP,
872 0,
873 cphs_cached_params->csp,
874 CPHS_MAX_CSP);
875 return;
876
877 /* Add support for Orange SIM's */
878 case(CPHS_SIM_ORANGE_CSP):
879 /* read customer service profile on SIM */
880 cphs_sim_access_data( CPHS_SIM_READ_TRANSP_EF,
881 CPHS_SIM_ORANGE_CSP,
882 0,
883 cphs_cached_params->orange_csp2,
884 CPHS_MAX_CSP2);
885 return;
886
887 case(CPHS_SIM_OPNLONG):
888 /* read operator name string on SIM */
889 cphs_sim_access_data( CPHS_SIM_READ_TRANSP_EF,
890 CPHS_SIM_OPNLONG,
891 0,
892 cphs_cached_params->opn_long,
893 CPHS_MAX_OPER_LONG);
894 return;
895
896 case(CPHS_SIM_OPNSHORT):
897 /* read operator name short string on SIM */
898 cphs_sim_access_data( CPHS_SIM_READ_TRANSP_EF,
899 CPHS_SIM_OPNSHORT,
900 0,
901 cphs_cached_params->opn_short,
902 CPHS_MAX_OPER_SHORT);
903 return;
904
905 case(CPHS_SIM_ALSNAMES):
906 case(CPHS_SIM_MB):
907 case(CPHS_SIM_INFO_NUMS):
908 case(CPHS_SIM_INFO_NUMS_EA01):
909 /* Read mailbox/information numbers */
910
911 end_of_read = cphs_read_sim_records(max_records, sim_cache_update_state, latest_record_len);
912
913 if(end_of_read)
914 {
915 /* END of mailbox/information numbers initialising */
916 TRACE_EVENT("End of Reading Numbers");
917 cphs_set_next_update_state();
918 cphs_cache_sim_data(NOT_PRESENT_8BIT, NOT_PRESENT_8BIT);
919 }
920 return;
921
922 case(CPHS_SIM_STOP_INIT):
923 default:
924 break;
925 }
926
927 /* End of update */
928 if(sim_cache_update_state NEQ CPHS_SIM_NOT_UPDATING)
929 {
930 TRACE_ERROR("wrong sim_cache_update_state state");
931 }
932 else
933 {
934 TRACE_EVENT("End of initialisation: Success");
935 sim_cache_update_state = CPHS_SIM_NOT_UPDATING;
936 }
937
938 /* reset states */
939 cphs_set_next_update_state();
940 cphs_status = CPHS_INITIALISED;
941
942 cphs_inform_user(CPHS_INIT_RES, CPHS_OK, NOT_PRESENT_8BIT, CPHS_LINE_NULL);
943 }
944
945 LOCAL void cphs_set_next_update_state(void)
946 {
947 switch(sim_cache_update_state)
948 {
949 /****** Mandatory Fields *******/
950 case(CPHS_SIM_NOT_UPDATING): /* START ! */
951 sim_cache_update_state = CPHS_SIM_CFU;
952 return;
953
954 case(CPHS_SIM_CFU):
955 sim_cache_update_state = CPHS_SIM_VWI;
956 return;
957
958 case(CPHS_SIM_VWI):
959 sim_cache_update_state = CPHS_SIM_OPNLONG;
960 return;
961
962 case(CPHS_SIM_OPNLONG):
963 sim_cache_update_state = CPHS_SIM_CINF;
964 return;
965
966 /****** Optional Fields *******/
967 case(CPHS_SIM_CINF):
968 sim_cache_update_state = CPHS_SIM_CSP;
969 return;
970
971 case(CPHS_SIM_CSP):
972 sim_cache_update_state = CPHS_SIM_ORANGE_CSP;
973 return;
974
975 /* Add support for Orange SIM's */
976 case(CPHS_SIM_ORANGE_CSP):
977 sim_cache_update_state = CPHS_SIM_OPNSHORT;
978 return;
979
980 case(CPHS_SIM_OPNSHORT):
981 sim_cache_update_state = CPHS_SIM_MB;
982 return;
983
984 case(CPHS_SIM_MB):
985 sim_cache_update_state = CPHS_SIM_INFO_NUMS;
986 return;
987
988 case(CPHS_SIM_INFO_NUMS):
989 case(CPHS_SIM_INFO_NUMS_EA01):
990 sim_cache_update_state = CPHS_SIM_ALSNAMES;
991 break;
992
993 case(CPHS_SIM_ALSNAMES):
994 sim_cache_update_state = CPHS_SIM_STOP_INIT;
995 break;
996
997 case(CPHS_SIM_STOP_INIT):
998 default:
999 sim_cache_update_state = CPHS_SIM_NOT_UPDATING;
1000 break;
1001 }
1002 }
1003
1004 /* Should action (e.g cache updating) be aborted if field
1005 is not present ? */
1006 LOCAL BOOL is_cphs_field_mandatory(UBYTE field_type)
1007 {
1008 TRACE_FUNCTION("is_cphs_field_mandatory()");
1009
1010 switch(field_type)
1011 {
1012 /****** Mandatory Fields *******/
1013 case(CPHS_SIM_CFU):
1014 case(CPHS_SIM_VWI):
1015 case(CPHS_SIM_CINF):
1016 case(CPHS_SIM_OPNLONG):
1017 return(TRUE);
1018
1019 /****** Optional fields ********/
1020 case(CPHS_SIM_OPNSHORT):
1021 case(CPHS_SIM_MB):
1022 case(CPHS_SIM_INFO_NUMS):
1023 case(CPHS_SIM_INFO_NUMS_EA01):
1024 case(CPHS_SIM_ALSNAMES):
1025 case(CPHS_SIM_CSP):
1026 /* Add support for Orange SIM's */
1027 case(CPHS_SIM_ORANGE_CSP):
1028 return(FALSE);
1029
1030 default:
1031 TRACE_EVENT_P1("Unexpected field type: %d", field_type);
1032 return(TRUE);
1033 }
1034 }
1035
1036 /* Positive Result of data SIM data access while updating cached data */
1037 LOCAL void cphs_init_sim_ok(UBYTE max_records, UBYTE sim_data_len)
1038 {
1039 UBYTE i;
1040 BOOL set_next_state = TRUE;
1041 USHORT temp_sst_ushort2;
1042
1043 TRACE_FUNCTION("cphs_init_sim_ok()");
1044
1045 TRACE_EVENT_P1("cphs_init_sim_ok(): data_len: %d", sim_data_len);
1046
1047 /* set next operation if needed */
1048 switch(sim_cache_update_state)
1049 {
1050 case(CPHS_SIM_CFU):
1051 TRACE_EVENT_P2("cfu_flags: %02X, %02X", cphs_cached_params->cfu_flags[0], cphs_cached_params->cfu_flags[1]);
1052 if(sim_data_len < CFU_SIZE)
1053 {
1054 /* Typically there are 2 bytes in CFU Ef_File: Yet only the first one is
1055 mandatory. Set non-present optional bytes to 0x00 */
1056 for(i=sim_data_len; i<CFU_SIZE; i++)
1057 {
1058 cphs_cached_params->cfu_flags[i] = 0x00;
1059 }
1060 }
1061 break;
1062
1063 case(CPHS_SIM_VWI):
1064 TRACE_EVENT_P2("vwi_flags: %02X, %02X", cphs_cached_params->vwi_flags[0], cphs_cached_params->vwi_flags[1]);
1065 if(sim_data_len < VWI_SIZE)
1066 {
1067 /* Typically there are 2 bytes in VWI Ef_File: Yet only the first one is
1068 mandatory. Set non-present optional bytes to 0x00 */
1069 for(i=sim_data_len; i<VWI_SIZE; i++)
1070 {
1071 cphs_cached_params->vwi_flags[i] = 0x00;
1072 }
1073 }
1074 break;
1075
1076 case(CPHS_SIM_MB):
1077 TRACE_EVENT_P1("store max_mb_entry_length: %d",sim_data_len);
1078 cphs_cached_params->max_mb_entry_length = sim_data_len;
1079 set_next_state = FALSE;
1080 break;
1081 case(CPHS_SIM_ALSNAMES):
1082 case(CPHS_SIM_INFO_NUMS):
1083 case(CPHS_SIM_INFO_NUMS_EA01):
1084 /* decision is made within cphs_cache_sim_data( )
1085 whether next action should be started */
1086 set_next_state = FALSE;
1087 break;
1088
1089 case(CPHS_SIM_CSP):
1090 if(sim_data_len > CPHS_MAX_CSP)
1091 {
1092 TRACE_EVENT_P1("Risk of loss of CSP data: sim_data_len: %d", sim_data_len);
1093 cphs_cached_params->csp_length = CPHS_MAX_CSP;
1094 }
1095 else
1096 {
1097 cphs_cached_params->csp_length = sim_data_len;
1098 TRACE_EVENT_P1("cphs_cached_params->csp_length: %d",
1099 cphs_cached_params->csp_length);
1100 }
1101 break;
1102
1103 /* Add support for Orange SIM's */
1104 case(CPHS_SIM_ORANGE_CSP):
1105 if(sim_data_len > CPHS_MAX_CSP2)
1106 {
1107 TRACE_EVENT_P1("Risk of loss of Orange CSP2 data: sim_data_len: %d", sim_data_len);
1108 cphs_cached_params->orange_csp2_length = CPHS_MAX_CSP2;
1109 }
1110 else
1111 {
1112 cphs_cached_params->orange_csp2_length = sim_data_len;
1113 TRACE_EVENT_P1("cphs_cached_params->orange_csp2_length: %d",
1114 cphs_cached_params->orange_csp2_length);
1115 }
1116 break;
1117
1118 case(CPHS_SIM_CINF):
1119 TRACE_EVENT_P3("CPHS info phase: %d sst: %02X, %02X",
1120 cphs_internal_params->tmp_info[0],
1121 cphs_internal_params->tmp_info[1],
1122 cphs_internal_params->tmp_info[2]);
1123
1124 cphs_cached_params->info.phase = cphs_internal_params->tmp_info[0];
1125
1126 cphs_cached_params->info.sst = 0x0000;
1127
1128 if(sim_data_len > 1)
1129 {
1130 cphs_cached_params->info.sst = (cphs_internal_params->tmp_info[1] << 8);
1131 }
1132
1133 if(sim_data_len < CINF_SIZE)
1134 {
1135 /* Typically there should be at least 3 bytes in CPHS information Ef_File:
1136 however, there are some SIMs with only 2 bytes... :-( Maybe with Phase 3 ?? */
1137 }
1138 else
1139 {
1140 temp_sst_ushort2 = 0x00FF & (USHORT)(cphs_internal_params->tmp_info[2]);
1141 cphs_cached_params->info.sst |= temp_sst_ushort2;
1142 }
1143
1144 TRACE_EVENT_P1("cphs_cached_params->info.sst: %04X",
1145 cphs_cached_params->info.sst);
1146 break;
1147 }
1148
1149 if(set_next_state)
1150 {
1151 cphs_set_next_update_state();
1152 }
1153
1154 /* Continue cache from SIM */
1155 cphs_cache_sim_data(max_records, sim_data_len);
1156 }
1157
1158 LOCAL void writing_vwi_ok(void)
1159 {
1160 TRACE_FUNCTION("writing_vwi_ok()");
1161
1162 memcpy(cphs_cached_params->vwi_flags, cphs_internal_params->tmp_flag_set, VWI_SIZE);
1163
1164 TRACE_EVENT_P2("vwi_flags: %02X %02X", cphs_cached_params->vwi_flags[0],
1165 cphs_cached_params->vwi_flags[1]);
1166
1167 if(cphs_status EQ CPHS_WRITING_VWI)
1168 {
1169 /* if this was initiated by user, then send final result */
1170 cphs_inform_user(CPHS_VOICE_MAIL_RES, CPHS_OK, NOT_PRESENT_8BIT, CPHS_LINE_NULL);
1171 }
1172 else
1173 {
1174 /* if this was initiated by network (upon receiving of an SMS, then send indication
1175 to the user */
1176 cphs_inform_user( CPHS_VOICE_MAIL_IND, CPHS_OK, cphs_internal_params->tmp_activate_state,
1177 cphs_internal_params->tmp_lines );
1178 }
1179 }
1180
1181 LOCAL void writing_cfu_ok(void)
1182 {
1183 TRACE_FUNCTION("writing_cfu_ok()");
1184
1185 memcpy(cphs_cached_params->cfu_flags, cphs_internal_params->tmp_flag_set, CFU_SIZE);
1186
1187 TRACE_EVENT_P2("cfu_flags: %02X %02X", cphs_cached_params->cfu_flags[0],
1188 cphs_cached_params->cfu_flags[1]);
1189
1190 cphs_inform_user(CPHS_CFU_RES, CPHS_OK, NOT_PRESENT_8BIT, CPHS_LINE_NULL);
1191 }
1192
1193 /* Positive Result of data SIM data access */
1194 GLOBAL void cphs_sim_data_accessed(UBYTE max_records, UBYTE data_len)
1195 {
1196 TRACE_FUNCTION("cphs_sim_data_accessed()");
1197
1198 switch(cphs_status)
1199 {
1200 case(CPHS_INITIALISING):
1201 case(CPHS_REFRESHING):
1202 cphs_init_sim_ok(max_records, data_len);
1203 return;
1204
1205 case(CPHS_WRITING_VWI_IND):
1206 case(CPHS_WRITING_VWI):
1207 TRACE_EVENT_P1("vwi_flags length: %d bytes", data_len);
1208 writing_vwi_ok();
1209 cphs_status = CPHS_INITIALISED;
1210 return;
1211
1212 case(CPHS_WRITING_CFU):
1213 /* cfu_flags is only updated if writing on SIM has been successful */
1214 TRACE_EVENT_P1("cfu_flags: %d bytes length", data_len);
1215 writing_cfu_ok();
1216 cphs_status = CPHS_INITIALISED;
1217 return;
1218
1219 default:
1220 TRACE_EVENT("cphs_sim_data_accessed(): unexpected status");
1221 cphs_status = CPHS_INITIALISED;
1222 return;
1223 }
1224 }
1225
1226 LOCAL void cphs_init_sim_failure(void)
1227 {
1228 TRACE_FUNCTION("cphs_init_sim_failure()");
1229
1230 /* set next operation if needed */
1231 switch(sim_cache_update_state)
1232 {
1233 case(CPHS_SIM_INFO_NUMS):
1234 /* Special case: when reading information number, if file 6F19
1235 is not present, another try should be done with EA01 for old SIMs */
1236 cphs_internal_params->current_record = 0;
1237 free_buffer(RECORD_BUFF);
1238 free_buffer(INFO_BUFF);
1239 sim_cache_update_state = CPHS_SIM_INFO_NUMS_EA01;
1240 cphs_cache_sim_data(NOT_PRESENT_8BIT, NOT_PRESENT_8BIT);
1241 return;
1242
1243 case(CPHS_SIM_INFO_NUMS_EA01):
1244 cphs_internal_params->current_record = 0;
1245 free_buffer(RECORD_BUFF);
1246 free_buffer(INFO_BUFF);
1247 /* No information numbers found... */
1248 cphs_cached_params->max_info_numbers = NOT_PRESENT_8BIT;
1249 break;
1250
1251 case(CPHS_SIM_ALSNAMES):
1252 cphs_internal_params->current_record = 0;
1253 free_buffer(ALS_BUFF);
1254 initialize_als_info(MAX_LINE_ID);
1255 break;
1256
1257 case(CPHS_SIM_MB):
1258 cphs_internal_params->current_record = 0;
1259 free_buffer(RECORD_BUFF);
1260 free_buffer(MB_BUFF);
1261 /* No mailbox numbers found... */
1262 cphs_cached_params->max_mb_numbers = NOT_PRESENT_8BIT;
1263 break;
1264 }
1265
1266 if(is_cphs_field_mandatory(sim_cache_update_state))
1267 {
1268 cphs_abort_current_action( );
1269 return;
1270 }
1271
1272 cphs_set_next_update_state();
1273 cphs_cache_sim_data(NOT_PRESENT_8BIT, NOT_PRESENT_8BIT);
1274 }
1275
1276 /* Failure Result of data SIM data access */
1277 GLOBAL void cphs_sim_data_failure(void)
1278 {
1279 TRACE_FUNCTION("cphs_sim_data_failure()");
1280
1281 switch(cphs_status)
1282 {
1283 case(CPHS_INITIALISING):
1284 case(CPHS_REFRESHING):
1285 cphs_init_sim_failure();
1286 break;
1287
1288 case(CPHS_WRITING_VWI):
1289 TRACE_ERROR("Voice Mail Indicator setting: SIM FAILURE !!!!");
1290 cphs_status = CPHS_INITIALISED;
1291 cphs_inform_user(CPHS_VOICE_MAIL_RES, CPHS_FAIL,
1292 NOT_PRESENT_8BIT, CPHS_LINE_NULL);
1293 return;
1294
1295 case(CPHS_WRITING_VWI_IND):
1296 TRACE_ERROR("Voice Mail Indication: SIM FAILURE !!!!");
1297 cphs_status = CPHS_INITIALISED;
1298 return;
1299
1300 case(CPHS_WRITING_CFU):
1301 TRACE_ERROR("Call Fwd Flags: SIM FAILURE !!!!");
1302 cphs_inform_user(CPHS_CFU_RES, CPHS_FAIL,
1303 NOT_PRESENT_8BIT, CPHS_LINE_NULL);
1304 cphs_status = CPHS_INITIALISED;
1305 return;
1306
1307 default:
1308 TRACE_EVENT("cphs_sim_data_failure(): unexpected status");
1309 return;
1310 }
1311 }
1312
1313 /*
1314 +--------------------------------------------------------------------+
1315 | PROJECT : GSM-PS (6147) MODULE : CPHS |
1316 | STATE : code ROUTINE : starts/ends/refreshes |
1317 +--------------------------------------------------------------------+
1318
1319 PURPOSE : Set of functions enabling initialising, ending or refreshing
1320 the CPHS module.
1321 */
1322
1323 GLOBAL T_CPHS_RET cphs_start (T_CPHS_USER_CB *cphs_user_cb)
1324 {
1325 TRACE_FUNCTION("cphs_start()");
1326
1327 /* Check CPHS status */
1328 switch(cphs_status)
1329 {
1330 case(CPHS_NOT_INITIALISED):
1331 TRACE_EVENT("CPHS starting !!!");
1332 break;
1333
1334 case(CPHS_INITIALISED):
1335 TRACE_EVENT("cphs_start: CPHS module already initialised");
1336 return(CPHS_OK);
1337
1338 default:
1339 TRACE_EVENT("cphs_start: CPHS has already been initialised: BUSY !!!");
1340 return(CPHS_BUSY);
1341 }
1342
1343 if(cphs_user_cb EQ NULL)
1344 {
1345 TRACE_ERROR("cphs_start: cphs_user_cb is NULL. CPHS module cannot be initialised");
1346 return(CPHS_FAIL);
1347 }
1348
1349 /* allocate memory for parameters to be cached from the SIM */
1350 MALLOC(cphs_cached_params, sizeof(T_CPHS_CACHED_PARAMS));
1351
1352 cphs_cached_params->max_mb_numbers = NOT_PRESENT_8BIT; //MAX_LINE_ID;
1353 cphs_cached_params->mb_numbers = NULL;
1354 cphs_cached_params->max_info_numbers = NOT_PRESENT_8BIT;
1355 cphs_cached_params->info_numbers = NULL;
1356 cphs_cached_params->als = NULL;
1357 cphs_cached_params->max_als_names_entries = NOT_PRESENT_8BIT;
1358
1359 memset(cphs_cached_params->opn_long, 0, sizeof(cphs_cached_params->opn_long));
1360 memset(cphs_cached_params->opn_short, 0, sizeof(cphs_cached_params->opn_short));
1361 memset(cphs_cached_params->csp, 0, sizeof(cphs_cached_params->csp));
1362 /* Add support for Orange SIM's */
1363 memset(cphs_cached_params->orange_csp2, 0, sizeof(cphs_cached_params->orange_csp2));
1364 cphs_cached_params->orange_csp2_length = 0; /* Set this to 0, will indicate if vaild */
1365
1366 MALLOC(cphs_internal_params, sizeof(T_CPHS_INTERNAL_PARAMS));
1367 /* Set user callback */
1368 cphs_internal_params->user_cb = cphs_user_cb;
1369
1370 cphs_internal_params->current_record = 0;
1371 cphs_internal_params->sim_read_record_buffer = NULL;
1372
1373
1374 /****** Get params from SIM *******/
1375 cphs_status = CPHS_INITIALISING;
1376
1377 cphs_cache_sim_data(NOT_PRESENT_8BIT, NOT_PRESENT_8BIT);
1378
1379 return(CPHS_EXEC);
1380 }
1381
1382
1383 GLOBAL T_CPHS_RET cphs_refresh_data (void)
1384 {
1385 T_CPHS_RET ret_status;
1386
1387 TRACE_FUNCTION("cphs_refresh_data()");
1388
1389 /* Check CPHS status */
1390 if((ret_status = cphs_check_status( )) NEQ CPHS_OK)
1391 {
1392 return(ret_status);
1393 }
1394
1395 cphs_status = CPHS_REFRESHING;
1396
1397 /****** Get params from SIM *******/
1398 cphs_cache_sim_data(NOT_PRESENT_8BIT, NOT_PRESENT_8BIT);
1399
1400 return(CPHS_EXEC);
1401 }
1402
1403 GLOBAL T_CPHS_RET cphs_stop (void)
1404 {
1405 T_CPHS_RET ret_status;
1406
1407 TRACE_FUNCTION("cphs_stop()");
1408
1409 /* Check CPHS status */
1410 if((ret_status = cphs_check_status( )) NEQ CPHS_OK)
1411 {
1412 return(ret_status);
1413 }
1414
1415 /* abort current action */
1416 cphs_abort_current_action( );
1417
1418 /* reinitialise CPHS status */
1419 cphs_status = CPHS_NOT_INITIALISED;
1420
1421 /* free memory allocated for CPHS */
1422 free_buffer(INFO_BUFF);
1423 free_buffer(ALS_BUFF);
1424 free_buffer(MB_BUFF);
1425
1426 MFREE(cphs_cached_params);
1427 MFREE(cphs_internal_params);
1428
1429 return(CPHS_OK);
1430 }
1431
1432 /*
1433 +--------------------------------------------------------------------+
1434 | PROJECT : GSM-PS (6147) MODULE : CPHS |
1435 | STATE : code ROUTINE : |
1436 +--------------------------------------------------------------------+
1437
1438 PURPOSE : Functions related to CPHS information numbers.
1439 */
1440
1441 /*
1442 Returns elements contained in a folder.
1443
1444 element_idx Index of folder element to be explored
1445 inf_num_list returns list of indexes of elements contained in folder
1446 max_elmts limits amount of bytes to be written in inf_num_indexes.
1447 If numbers of elements to be written is bigger, then function returns
1448 with CPHS_EXEC and amount of elements will be written in max_elmts
1449 (so that function caller knows how many memory it has to allocate
1450 to retrieve the whole list). */
1451
1452 GLOBAL T_CPHS_RET cphs_explore_info_nbs(UBYTE element_idx, UBYTE *inf_num_indexes, UBYTE *max_elmts)
1453 {
1454 T_CPHS_RET ret_status;
1455 T_CPHS_INF_NUM *explored_folder,
1456 *try_element;
1457 UBYTE i = 0, index;
1458
1459 TRACE_FUNCTION("cphs_explore_info_nbs()");
1460
1461 /* Check CPHS status */
1462 if((ret_status = cphs_check_status( )) NEQ CPHS_OK)
1463 {
1464 /* CPHS status not initialized, set error as CME_ERR_OpNotAllow */
1465 ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow );
1466 return(ret_status);
1467 }
1468 else
1469 ret_status = CPHS_OK; // unless we then find out buffer was too small...
1470
1471 if(cphs_cached_params EQ NULL OR
1472 inf_num_indexes EQ NULL OR
1473 max_elmts EQ NULL)
1474 {
1475 TRACE_ERROR("cphs_explore_info_nbs: some needed pointers have value NULL");
1476 return(CPHS_FAIL);
1477 }
1478
1479 /* init */
1480 *inf_num_indexes = 0;
1481
1482 if(element_idx > cphs_cached_params->max_info_numbers)
1483 {
1484 TRACE_ERROR("wrong element_idx");
1485 return(CPHS_FAIL);
1486 }
1487
1488 /* Check for info_numbers, set CME_ERR_NotFound return CPHS_FAIL */
1489 if (cphs_cached_params->info_numbers EQ NULL)
1490 {
1491 /* information numbers have not been read from SIM */
1492 *max_elmts = 0;
1493 ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_NotFound );
1494 return (CPHS_FAIL);
1495 }
1496
1497 explored_folder = &cphs_cached_params->info_numbers[element_idx];
1498
1499 if(explored_folder->number[0] NEQ 0)
1500 {
1501 TRACE_EVENT_P1("Cannot explore: element %d is not a folder", element_idx);
1502 return(CPHS_FAIL);
1503 }
1504
1505 index = element_idx + 1;
1506 try_element = &cphs_cached_params->info_numbers[index];
1507
1508 while(try_element->index_level NEQ explored_folder->index_level) // search for next element of same index_level
1509 {
1510 if( try_element->index_level EQ (explored_folder->index_level+1) ) // element is direct under folder
1511 {
1512 if(i < *max_elmts)
1513 {
1514 inf_num_indexes[i] = index;
1515 }
1516 else
1517 ret_status = CPHS_EXEC; // buffer is too small: but we need to count how many bytes are then needed
1518
1519 i++;
1520 }
1521 index++;
1522 try_element = &cphs_cached_params->info_numbers[index];
1523
1524 if(index > cphs_cached_params->max_info_numbers)
1525 {
1526 break; /* end of list: can happen, e.g when exploring the last folder of a given index_level */
1527 }
1528 }
1529
1530 *max_elmts = i;
1531 return(ret_status);
1532 }
1533
1534 /*
1535 Returns information related to element id
1536
1537 element_idx Index of element chosen
1538 inf_num structure containing information related to an element */
1539
1540 GLOBAL T_CPHS_RET cphs_read_info_nb (UBYTE element_idx, T_CPHS_INF_NUM *inf_num)
1541 {
1542 T_CPHS_RET ret_status;
1543
1544 TRACE_FUNCTION("cphs_read_info_nb()");
1545
1546 /* Check CPHS status */
1547 if((ret_status = cphs_check_status( )) NEQ CPHS_OK)
1548 {
1549 /* CPHS status not initialized, set error as CME_ERR_OpNotAllow */
1550 ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow );
1551 return(ret_status);
1552 }
1553
1554 if(cphs_cached_params EQ NULL)
1555 {
1556 TRACE_ERROR("cphs_cached_params EQ NULL");
1557 return(CPHS_FAIL);
1558 }
1559
1560 /* Check Information numbers are cached or not */
1561 if(cphs_cached_params->info_numbers EQ NULL)
1562 {
1563 ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_NotFound );
1564 return(CPHS_FAIL);
1565 }
1566
1567 if(element_idx < 1 OR
1568 element_idx > cphs_cached_params->max_info_numbers)
1569 {
1570 TRACE_ERROR("wrong element_idx");
1571 /* Element index not in the range, set CME_ERR_InvIdx */
1572 ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_InvIdx );
1573 return(CPHS_FAIL);
1574 }
1575
1576 memcpy(inf_num, &cphs_cached_params->info_numbers[element_idx], sizeof(T_CPHS_INF_NUM));
1577
1578 return(CPHS_OK);
1579 }
1580
1581 GLOBAL T_CPHS_RET cphs_info_num_get_max(UBYTE *max_index)
1582 {
1583 T_CPHS_RET ret_status;
1584
1585 TRACE_FUNCTION("cphs_info_num_get_max()");
1586
1587 /* Check CPHS status */
1588 if((ret_status = cphs_check_status( )) NEQ CPHS_OK)
1589 {
1590 /* CPHS status not initialized, set error as CME_ERR_OpNotAllow */
1591 ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow );
1592 return(ret_status);
1593 }
1594
1595 if(cphs_cached_params NEQ NULL AND
1596 cphs_cached_params->max_info_numbers NEQ NOT_PRESENT_8BIT)
1597 {
1598 *max_index = cphs_cached_params->max_info_numbers;
1599 return(CPHS_OK);
1600 }
1601
1602 ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_NotFound );
1603 return(CPHS_FAIL);
1604 }
1605
1606 /*
1607 +--------------------------------------------------------------------+
1608 | PROJECT : GSM-PS (6147) MODULE : CPHS |
1609 | STATE : code ROUTINE : |
1610 +--------------------------------------------------------------------+
1611
1612 PURPOSE : Functions related to CPHS alternate line service.
1613 */
1614
1615 /*
1616 Returns elements contained in a folder.
1617
1618 call_id call id of line being queried. This value is the same as the call id
1619 described in GSM 02.30 subclause 4.5.5.1 (also see AT+CLCC). If not present
1620 (value 255), then current active line is to be returned.
1621 line contains line of queried call, or current active line.
1622 line_desc line identification in SIM
1623 max_line_desc maximal length of line_desc:
1624 IN: should contain the size of memory allocated for line_desc.
1625 OUT: If memory is not enough, then function returns with CPHS_FAIL
1626 and max_line_desc will contain the amount of memory needed.
1627 Otherwise contains amount of written characters. */
1628
1629
1630 GLOBAL T_CPHS_RET cphs_get_line(UBYTE srcId, UBYTE call_id, T_CPHS_LINES *line,
1631 CHAR *line_desc, UBYTE *max_line_desc)
1632 {
1633 T_CPHS_RET ret_status;
1634 T_CPHS_LINES call_line;
1635 CHAR *cached_line_name;
1636
1637 TRACE_FUNCTION("cphs_get_line()");
1638
1639 /* Check CPHS status */
1640 if((ret_status = cphs_check_status( )) NEQ CPHS_OK)
1641 {
1642 return(ret_status);
1643 }
1644
1645 if(line EQ NULL)
1646 {
1647 TRACE_ERROR("wrong parameter: line is NULL");
1648 return(CPHS_FAIL);
1649 }
1650
1651 if(call_id EQ NOT_PRESENT_8BIT)
1652 {
1653 /* Get current active line */
1654 cphs_get_als_active_line(srcId, &call_line);
1655 }
1656 else
1657 {
1658 /* get line associated to call_id */
1659 call_line = als_get_call_info(call_id);
1660 }
1661
1662 if( call_line EQ CPHS_LINE_NULL )
1663 {
1664 TRACE_ERROR("als_get_call_info: not a valid call");
1665 return(CPHS_FAIL);
1666 }
1667 *line = call_line;
1668
1669 if(max_line_desc EQ NULL)
1670 {
1671 TRACE_ERROR("max_line_desc EQ NULL");
1672 return(CPHS_FAIL);
1673 }
1674
1675 if(*max_line_desc < CPHS_MAX_SIZE_ALPHA)
1676 {
1677 // buffer too small
1678 *max_line_desc = CPHS_MAX_SIZE_ALPHA;
1679 return(CPHS_EXEC);
1680 }
1681
1682 get_name_pointer_over_lineid(call_line, &cached_line_name,
1683 cphs_cached_params->max_als_names_entries);
1684 if(cached_line_name NEQ NULL)
1685 {
1686 memcpy(line_desc, cached_line_name, *max_line_desc);
1687 return(CPHS_OK);
1688 }
1689 else
1690 {
1691 memset(line_desc, 0, *max_line_desc);
1692 return(CPHS_FAIL);
1693 }
1694 }
1695
1696
1697 /*
1698 +--------------------------------------------------------------------+
1699 | PROJECT : GSM-PS (6147) MODULE : CPHS |
1700 | STATE : code ROUTINE : cphs_roaming_ind |
1701 +--------------------------------------------------------------------+
1702
1703 PURPOSE :
1704 */
1705
1706 GLOBAL void cphs_roaming_ind(UBYTE roaming_status)
1707 {
1708 T_CPHS_RET ret_status;
1709
1710 /* Check CPHS status */
1711 if((ret_status = cphs_check_status( )) NEQ CPHS_OK)
1712 {
1713 return;
1714 }
1715
1716 TRACE_FUNCTION("cphs_roaming_ind()");
1717
1718 /* inform user */
1719 cphs_inform_user(CPHS_ROAM_IND, CPHS_OK, roaming_status, CPHS_LINE_NULL);
1720 }
1721
1722 /*
1723 +--------------------------------------------------------------------+
1724 | PROJECT : GSM-PS (6147) MODULE : CPHS |
1725 | STATE : code ROUTINE : cphs_voice_mail_ind |
1726 +--------------------------------------------------------------------+
1727
1728 PURPOSE :
1729 */
1730
1731 GLOBAL void cphs_voice_mail_ind (UBYTE flag_set, USHORT line)
1732 {
1733 T_CPHS_RET ret_status;
1734
1735 /* Check CPHS status */
1736 if((ret_status = cphs_check_status( )) NEQ CPHS_OK)
1737 {
1738 TRACE_ERROR("cannot proceed Voice Mail Indication: CPHS module is busy");
1739 return;
1740 }
1741
1742 TRACE_FUNCTION("cphs_voice_mail_ind()");
1743
1744 /* write to SIM and in cached data */
1745 cphs_status = CPHS_WRITING_VWI_IND;
1746
1747 cphs_write_indicator_flag(flag_set, line, CPHS_SIM_VWI);
1748
1749 return;
1750 }
1751
1752 /*
1753 +--------------------------------------------------------------------+
1754 | PROJECT : GSM-PS (6147) MODULE : CPHS |
1755 | STATE : code ROUTINE : cphs_set_waiting_flag |
1756 +--------------------------------------------------------------------+
1757
1758 PURPOSE : set/clear waiting flag for given lines
1759 */
1760
1761 GLOBAL T_CPHS_RET cphs_set_waiting_flag(UBYTE flag_set, T_CPHS_LINES lines)
1762 {
1763 T_CPHS_RET ret_status;
1764
1765 TRACE_FUNCTION("cphs_set_waiting_flag()");
1766
1767 /* Check CPHS status */
1768 if((ret_status = cphs_check_status( )) NEQ CPHS_OK)
1769 {
1770 TRACE_ERROR("cannot proceed SET of Voice Mail Indicator: CPHS module is busy");
1771 ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow );
1772 return(ret_status);
1773 }
1774
1775 cphs_status = CPHS_WRITING_VWI;
1776
1777 cphs_write_indicator_flag(flag_set, lines, CPHS_SIM_VWI);
1778
1779 return(CPHS_EXEC);
1780 }
1781
1782
1783 /*
1784 +--------------------------------------------------------------------+
1785 | PROJECT : GSM-PS (6147) MODULE : CPHS |
1786 | STATE : code ROUTINE : cphs_get_waiting_flag |
1787 +--------------------------------------------------------------------+
1788
1789 PURPOSE : look up if waiting flag for queried line is set
1790 */
1791
1792 GLOBAL T_CPHS_RET cphs_get_waiting_flag(UBYTE *flag_set, T_CPHS_LINES line)
1793 {
1794 UBYTE setting = 0;
1795 T_CPHS_RET ret_status;
1796
1797 TRACE_FUNCTION("cphs_get_waiting_flag()");
1798
1799 /* Check CPHS status */
1800 if((ret_status = cphs_check_status( )) NEQ CPHS_OK)
1801 {
1802 return(ret_status);
1803 }
1804
1805 ret_status = cphs_get_indicator_flag(flag_set, line, CPHS_SIM_VWI);
1806
1807 return(ret_status);
1808 }
1809
1810 /*
1811 +--------------------------------------------------------------------+
1812 | PROJECT : GSM-PS (6147) MODULE : CPHS |
1813 | STATE : code ROUTINE : cphs_get_opn |
1814 +--------------------------------------------------------------------+
1815
1816 PURPOSE : look up operator name string and if available operator
1817 name short string
1818 */
1819
1820 GLOBAL T_CPHS_RET cphs_get_opn( CHAR *longname,
1821 UBYTE *max_longname,
1822 CHAR *shortname,
1823 UBYTE *max_shortname)
1824
1825 {
1826 UBYTE len, i;
1827 T_CPHS_RET ret_status;
1828 BOOL buffer_too_small = FALSE;
1829
1830 TRACE_FUNCTION("cphs_get_opn()");
1831
1832 /* Check CPHS status */
1833 if((ret_status = cphs_check_status( )) NEQ CPHS_OK)
1834 {
1835 ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow );
1836 return(ret_status);
1837 }
1838
1839 /* Length of Long Operator Name */
1840 len = strlen((CHAR *)cphs_cached_params->opn_long);
1841 for(i=0; i<len; i++)
1842 {
1843 if(cphs_cached_params->opn_long[i] EQ 0xFF)
1844 {
1845 len = i;
1846 break;
1847 }
1848 }
1849
1850 TRACE_EVENT_P1("opn_long length %d", len);
1851
1852 if( len > *max_longname )
1853 {
1854 TRACE_EVENT_P1("buffer for long name is not big enough: needed: %d", len);
1855 *max_longname = len;
1856 buffer_too_small = TRUE;
1857 }
1858 else
1859 {
1860 *max_longname = len;
1861 memcpy(longname, cphs_cached_params->opn_long, (int) len);
1862 longname[len] = '\0';
1863 }
1864
1865 /* Length of SHORT Operator Name */
1866 len = strlen((CHAR *)cphs_cached_params->opn_short);
1867 for(i=0; i<len; i++)
1868 {
1869 if(cphs_cached_params->opn_short[i] EQ 0xFF)
1870 {
1871 len = i;
1872 break;
1873 }
1874 }
1875
1876 TRACE_EVENT_P1("opn_short length %d", len);
1877
1878 if( len > *max_shortname )
1879 {
1880 TRACE_EVENT_P1("buffer for short name is not big enough: needed: %d", len);
1881 *max_shortname = len;
1882 buffer_too_small = TRUE;
1883 }
1884 else
1885 {
1886 *max_shortname = len;
1887 memcpy(shortname, cphs_cached_params->opn_short, (int) len);
1888 shortname[len] = '\0';
1889 }
1890
1891 if(buffer_too_small)
1892 {
1893 return(CPHS_FAIL);
1894 }
1895 else
1896 return(CPHS_OK);
1897 }
1898
1899
1900 /*
1901 +--------------------------------------------------------------------+
1902 | PROJECT : GSM-PS (6147) MODULE : CPHS |
1903 | STATE : code ROUTINE : cphs_get_cphs_info |
1904 +--------------------------------------------------------------------+
1905
1906 PURPOSE : look up cphs info
1907 */
1908
1909 GLOBAL T_CPHS_RET cphs_get_cphs_info( UBYTE *phase,
1910 USHORT *sst)
1911 {
1912 T_CPHS_RET ret_status;
1913
1914 TRACE_FUNCTION("cphs_get_cphs_info()");
1915
1916 /* Check CPHS status */
1917 if((ret_status = cphs_check_status( )) NEQ CPHS_OK)
1918 {
1919 return(ret_status);
1920 }
1921
1922 *phase = cphs_cached_params->info.phase;
1923 *sst = cphs_cached_params->info.sst;
1924
1925 return CPHS_OK;
1926 }
1927
1928 /*
1929 +--------------------------------------------------------------------+
1930 | PROJECT : GSM-PS (6147) MODULE : CPHS |
1931 | STATE : code ROUTINE : cphs_parse_csp |
1932 +--------------------------------------------------------------------+
1933
1934 PURPOSE : Look up CSP information
1935 */
1936 LOCAL T_CPHS_RET cphs_parse_csp ( UBYTE *cached_csp,
1937 CHAR *parsed_csp,
1938 UBYTE cached_csp_length,
1939 UBYTE *parsed_csp_length)
1940 {
1941 UBYTE pos;
1942 T_CPHS_RET ret_val = CPHS_OK;
1943
1944 TRACE_FUNCTION("cphs_parse_csp()");
1945
1946 /* Cached CSP not present return CPHS_FAIL */
1947 if (cached_csp EQ NULL)
1948 {
1949 return(CPHS_FAIL);
1950 }
1951
1952 /* analyze max size of csp hex string */
1953 if(*parsed_csp_length < (2*cached_csp_length + 1))
1954 {
1955 TRACE_EVENT_P1("buffer for CSP is too small: needed : %d",
1956 cached_csp_length);
1957 *parsed_csp_length = (2*cached_csp_length + 1);
1958 return(CPHS_FAIL);
1959 }
1960
1961 /* convert to hex string */
1962 for(pos=0,*parsed_csp_length = 0; pos < cached_csp_length; pos++,*parsed_csp_length = pos*2)
1963 {
1964 sprintf(parsed_csp + (*parsed_csp_length), "%02X", cached_csp[pos]);
1965 }
1966
1967 /* terminate string */
1968 parsed_csp[*parsed_csp_length] = 0;
1969
1970 /* set actual size of csp hex string */
1971 *parsed_csp_length++;
1972
1973 return CPHS_OK;
1974 }
1975
1976 /*
1977 +--------------------------------------------------------------------+
1978 | PROJECT : GSM-PS (6147) MODULE : CPHS |
1979 | STATE : code ROUTINE : cphs_get_csprof |
1980 +--------------------------------------------------------------------+
1981
1982 PURPOSE : look up cphs info
1983 */
1984
1985 GLOBAL T_CPHS_RET cphs_get_csprof( CHAR *csp,
1986 CHAR *csp2,
1987 UBYTE *max_csp_length,
1988 UBYTE *max_csp2_length)
1989 {
1990 T_CPHS_RET ret_val = CPHS_OK;
1991
1992 TRACE_FUNCTION("cphs_get_csprof()");
1993
1994 ret_val = cphs_parse_csp( cphs_cached_params->csp,
1995 csp,
1996 cphs_cached_params->csp_length,
1997 max_csp_length);
1998
1999 if (ret_val EQ CPHS_OK)
2000 {
2001 ret_val = cphs_parse_csp( cphs_cached_params->orange_csp2,
2002 csp2,
2003 cphs_cached_params->orange_csp2_length,
2004 max_csp2_length);
2005 }
2006 return ret_val;
2007 }
2008
2009
2010 /*
2011 +--------------------------------------------------------------------+
2012 | PROJECT : GSM-PS (6147) MODULE : CPHS |
2013 | STATE : code ROUTINE : cphs_read_mb_number |
2014 +--------------------------------------------------------------------+
2015
2016 PURPOSE : read mailbox number for given record id
2017 */
2018
2019 GLOBAL T_CPHS_RET cphs_read_mb_number( UBYTE rec_id,
2020 T_CPHS_MB *mailbox_entry)
2021 {
2022 T_CPHS_RET ret_status;
2023
2024 TRACE_FUNCTION("cphs_read_mb_number()");
2025
2026 /* Check CPHS status */
2027 if((ret_status = cphs_check_status( )) NEQ CPHS_OK)
2028 {
2029 ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow);
2030 return(ret_status);
2031 }
2032
2033 if(cphs_cached_params EQ NULL)
2034 {
2035 TRACE_ERROR("cphs_cached_params EQ NULL");
2036 ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_Unknown);
2037 return CPHS_FAIL;
2038 }
2039
2040 if ( (rec_id < 1) OR (rec_id > cphs_cached_params->max_mb_numbers) )
2041 {
2042 TRACE_ERROR("invalid record id, return CPHS_FAIL");
2043 ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_InvIdx);
2044 return CPHS_FAIL;
2045 }
2046
2047 if (cphs_cached_params->mb_numbers NEQ NULL)
2048 {
2049 memcpy(mailbox_entry,
2050 &cphs_cached_params->mb_numbers[rec_id-1],
2051 sizeof(T_CPHS_MB));
2052 }
2053 else
2054 { /* requested mb number has not been read from SIM,
2055 return empty mb number */
2056 memset(mailbox_entry, 0, sizeof(T_CPHS_MB));
2057 }
2058
2059 return CPHS_OK;
2060 }
2061
2062 /*
2063 +----------------------------------------------------------------------+
2064 | PROJECT : GSM-F&D (8411) MODULE : CPHS |
2065 | STATE : code ROUTINE : cphs_state_indication|
2066 +----------------------------------------------------------------------+
2067
2068 PURPOSE : state the result to the user
2069 */
2070
2071 GLOBAL SHORT cphs_state_indication ( UBYTE psaStatus, SHORT cmeError )
2072 {
2073 UBYTE cmdBuf;
2074 UBYTE ownBuf;
2075 T_PHB_CMD_PRM * pPHBCmdPrm;
2076
2077 TRACE_FUNCTION ("cphs_state_indication()");
2078
2079 cmdBuf = simEntStat.curCmd;
2080 ownBuf = simEntStat.entOwn;
2081
2082 switch ( psaStatus )
2083 {
2084 case ( CPHS_SIM_WRITE_OK ):
2085 {
2086 R_AT (RAT_OK, ownBuf) (cmdBuf);
2087 break;
2088 }
2089 case ( CPHS_SIM_WRITE_FAIL ):
2090 {
2091 TRACE_EVENT("cphs_state_indication: SIM write failed");
2092 R_AT( RAT_CME, ownBuf)( cmdBuf, cmeError );
2093 break;
2094 }
2095 default:
2096 {
2097 TRACE_EVENT("FATAL ERROR in cmhCHPS_StatIndication");
2098 return -1;
2099 }
2100 }
2101
2102 /* trigger RAT indications to the user */
2103 /*
2104 for( idx = 0; idx < CMD_SRC_MAX; idx++ )
2105 {
2106 R_AT( RAT_PHB_STATUS, idx )( cmhStatus );
2107 }
2108 */
2109 simEntStat.curCmd = AT_CMD_NONE;
2110 simEntStat.entOwn = simShrdPrm.owner = CMD_SRC_NONE;
2111
2112 return 0;
2113 }
2114
2115 /*
2116 +--------------------------------------------------------------------+
2117 | PROJECT : GSM-PS (6147) MODULE : CPHS |
2118 | STATE : code ROUTINE : cphs_write_mb_number_cb |
2119 +--------------------------------------------------------------------+
2120
2121 PURPOSE : write mailbox entry callback
2122
2123 */
2124
2125 GLOBAL void cphs_write_mb_number_cb( SHORT table_id )
2126 {
2127
2128 TRACE_FUNCTION("cphs_write_mb_number_cb()");
2129
2130 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
2131
2132 if (simShrdPrm.atb[table_id].errCode NEQ SIM_NO_ERROR)
2133 {
2134 TRACE_ERROR("cphs_write_mb_number_cb(): error for writing");
2135 cphs_state_indication( CPHS_SIM_WRITE_FAIL,
2136 (SHORT)cmhSIM_GetCmeFromSim( simShrdPrm.atb[table_id].errCode ));
2137 return;
2138 }
2139 else
2140 {
2141 /* write to ME cache */
2142 write_mb_number(simShrdPrm.atb[table_id].recNr,
2143 exchData,
2144 cphs_cached_params->max_mb_entry_length);
2145 /* reset exchange data */
2146 memset(exchData, 0xFF, 100);
2147 cphs_state_indication ( CPHS_SIM_WRITE_OK, CME_ERR_NotPresent );
2148 }
2149 return;
2150 }
2151
2152 /*
2153 +--------------------------------------------------------------------+
2154 | PROJECT : GSM-PS (6147) MODULE : CPHS |
2155 | STATE : code ROUTINE : cphs_write_mb_number |
2156 +--------------------------------------------------------------------+
2157
2158 PURPOSE : write mailbox number for given record id
2159 */
2160
2161 GLOBAL T_CPHS_RET cphs_write_mb_number( UBYTE srcId,
2162 UBYTE rec_id,
2163 UBYTE *tag,
2164 UBYTE tag_len,
2165 UBYTE bcd_len,
2166 UBYTE *number,
2167 UBYTE ton_npi)
2168 {
2169 UBYTE tmp_tag_len = 0;
2170 UBYTE max_aplha_len = 0;
2171 UBYTE max_entry_len = 0;
2172
2173 T_ACI_RETURN result;
2174
2175 TRACE_FUNCTION("cphs_write_mb_number()");
2176
2177 /* test state of CPHS */
2178 if(cphs_cached_params EQ NULL)
2179 {
2180 TRACE_ERROR("cphs_cached_params EQ NULL");
2181 return CPHS_NOT_INIT;
2182 }
2183
2184 max_aplha_len = cphs_cached_params->max_mb_entry_length - CPHS_MIN_MB_LEN;
2185 max_entry_len = cphs_cached_params->max_mb_entry_length;
2186
2187 /* test whether alpha tag is too long */
2188 if ( tag_len > max_aplha_len )
2189 {
2190 return CPHS_FAIL;
2191 }
2192
2193 /* test if mb numbers are supported/initialized */
2194 if ((cphs_cached_params->mb_numbers NEQ NULL) &&
2195 ( rec_id <= cphs_cached_params->max_mb_numbers ))
2196 {
2197
2198 /* write mb number to SIM - prepare data */
2199 /* get length of alpha tag */
2200 tmp_tag_len = pb_get_entry_len( tag, max_aplha_len );
2201
2202 /* reset exchData */
2203 memset(exchData, 0xFF, DEFAULT_MAXSIZE_OF_RECORD);
2204 if ((number NEQ NULL)||(tag NEQ NULL)) /* NULL causes delete of record */
2205 {
2206 /* alpha tag */
2207 memcpy(exchData, tag, tmp_tag_len);
2208 /* length of bcd number content */
2209 exchData[max_aplha_len] = bcd_len+1;
2210 /* ton_npi */
2211 exchData[max_aplha_len+1] = ton_npi;
2212 /* BCD number */
2213 if (number NEQ NULL)
2214 {
2215 memcpy((char *)&exchData[max_aplha_len+2],
2216 (char *)number, CPHS_MAX_MB_NUMBER_BYTES);
2217 }
2218 /* Capability field (empty) */
2219 exchData[max_aplha_len+12] = NOT_PRESENT_8BIT;
2220 }
2221 /* write to SIM */
2222 result= cmhSIM_WriteRecordEF( srcId,
2223 AT_CMD_CPMBW,
2224 SIM_CPHS_MBXN,
2225 rec_id,
2226 max_entry_len,
2227 exchData,
2228 cphs_write_mb_number_cb );
2229
2230 /* write to ME cache */
2231 if (result EQ AT_EXCT)
2232 {
2233 write_mb_number(rec_id, exchData, max_entry_len);
2234 }
2235 }
2236 else /* no mb supported */
2237 {
2238 return CPHS_NOT_INIT;
2239 }
2240 return CPHS_EXEC;
2241 }
2242
2243
2244 /*
2245 +----------------------------------------------------------------------+
2246 | PROJECT : GSM-F&D (8411) MODULE : CPHS |
2247 | STATE : code ROUTINE : cphs_get_mb_parameter|
2248 +----------------------------------------------------------------------+
2249
2250 PURPOSE : replies the CPHS mailbox parameters for test command
2251 */
2252
2253 GLOBAL T_CPHS_RET cphs_get_mb_parameter (SHORT* firstIdx,
2254 SHORT* lastIdx,
2255 UBYTE* nlength,
2256 UBYTE* tlength )
2257 {
2258
2259 UBYTE max_entry_len = 0;
2260 UBYTE max_entries = 0;
2261
2262 TRACE_FUNCTION ("cphs_get_mb_parameter()");
2263
2264 if(cphs_cached_params EQ NULL)
2265 {
2266 TRACE_ERROR("cphs_cached_params EQ NULL");
2267 return CPHS_NOT_INIT;
2268 }
2269
2270 max_entries = cphs_cached_params->max_mb_numbers;
2271 max_entry_len = cphs_cached_params->max_mb_entry_length;
2272
2273 /* handle index */
2274 if ( max_entries > 0 )
2275 {
2276 *firstIdx = (SHORT) CPHS_MIN_MB_ENTRIES;
2277 *lastIdx = (SHORT) max_entries;
2278 }
2279 else
2280 {
2281 *lastIdx = *firstIdx = 0;
2282 }
2283 /* handle entry length */
2284 if ( max_entry_len >= CPHS_MIN_MB_LEN )
2285 {
2286 *tlength = max_entry_len - CPHS_MIN_MB_LEN;
2287 }
2288 else
2289 {
2290 *tlength = 0;
2291 }
2292
2293 /* handle number length */
2294
2295 *nlength = CPHS_MAX_MB_NUMBER_BYTES;
2296
2297 return CPHS_OK;
2298 }
2299
2300
2301 /*
2302 +--------------------------------------------------------------------+
2303 | PROJECT : GSM-PS (6147) MODULE : CPHS |
2304 | STATE : code ROUTINE : cphs_get_fwd_flag |
2305 +--------------------------------------------------------------------+
2306
2307 PURPOSE : returns setting of CFU flag for given line
2308 */
2309
2310 #define SIM_FLAG_ON (0x0A)
2311 #define SIM_FLAG_OFF (0x05)
2312 #define SIM_FLAG_NONE (0x00)
2313
2314 /* if nibble = 0 (1st nibble)
2315 #define GET_FLAG_VALUE(flag, nibble) ( (flag & (0xF0)) >> 4 )
2316 if nibble=1 (2nd nibble)
2317 #define GET_FLAG_VALUE(flag, nibble) (flag & 0x0F)
2318 */
2319 #define GET_FLAG_VALUE(flag, nibble) ( (flag & (0x0F << (4 * (nibble ? 0 : 1)))) \
2320 >> (4 * (nibble ? 0 : 1)) )
2321
2322 LOCAL void get_relevant_flag_struct(UBYTE indicator, UBYTE **flag_table /*, UBYTE **temp_flag_table*/)
2323 {
2324 UBYTE *intern_flag_table;
2325
2326 switch(indicator)
2327 {
2328 case(CPHS_SIM_CFU):
2329 intern_flag_table = cphs_cached_params->cfu_flags;
2330 break;
2331
2332 case(CPHS_SIM_VWI):
2333 intern_flag_table = cphs_cached_params->vwi_flags;
2334 break;
2335
2336 default: /* shall be eventually removed ! */
2337 TRACE_ERROR("tttt: Wrong indicator value !!!");
2338 return;
2339 }
2340
2341 if(flag_table NEQ NULL)
2342 {
2343 *flag_table = intern_flag_table;
2344 }
2345 }
2346
2347 LOCAL void get_byte_index_and_nibble(T_CPHS_LINES line, UBYTE *byte_index, UBYTE *nibble)
2348 {
2349 /* byte: nibble1/nibble2 (nibble1 has value 0,
2350 nibble2 has value 1) */
2351 /* first byte: line1/line2 (first byte has value byte_index 0)*/
2352 /* second byte: fax/data (second byte has value byte_index 1)*/
2353 switch(line)
2354 {
2355 case(CPHS_LINE1):
2356 *byte_index = 0;
2357 *nibble = 0;
2358 break;
2359
2360 case(CPHS_LINE2):
2361 *byte_index = 0;
2362 *nibble = 1;
2363 break;
2364
2365 case(CPHS_LINE_FAX):
2366 *byte_index = 1;
2367 *nibble = 0;
2368 break;
2369
2370 case(CPHS_LINE_DATA):
2371 *byte_index = 1;
2372 *nibble = 1;
2373 break;
2374 }
2375 }
2376
2377 LOCAL T_CPHS_RET cphs_get_indicator_flag(UBYTE *flag_set, T_CPHS_LINES line, UBYTE indicator)
2378 {
2379 UBYTE setting;
2380 UBYTE byte_index, nibble;
2381 UBYTE *flag_table;
2382
2383 TRACE_FUNCTION("cphs_get_indicator_flag()");
2384
2385 if(!cphs_line_makes_sense(line))
2386 {
2387 TRACE_EVENT_P1("Queried line %d does not exist", line);
2388 return(CPHS_FAIL);
2389 }
2390
2391 get_byte_index_and_nibble(line, &byte_index, &nibble);
2392
2393 get_relevant_flag_struct(indicator, &flag_table /*, NULL*/ );
2394
2395 setting = GET_FLAG_VALUE(flag_table[byte_index], nibble);
2396
2397 switch(setting)
2398 {
2399 case(SIM_FLAG_ON):
2400 *flag_set = CPHS_FLAG_ACTIVATED;
2401 break;
2402
2403 case(SIM_FLAG_OFF):
2404 *flag_set = CPHS_FLAG_DEACTIVATED;
2405 break;
2406
2407 case(SIM_FLAG_NONE):
2408 *flag_set = CPHS_FLAG_NOT_PRESENT;
2409 break;
2410
2411 default:
2412 TRACE_EVENT_P1("cphs: get flag value unexpected: %02X", setting);
2413 *flag_set = CPHS_FLAG_ERROR;
2414 return(CPHS_FAIL);
2415 }
2416
2417 TRACE_EVENT_P3("Get Indicator Flag: line: %d, setting: %X, flag_set: %d", line, setting, *flag_set);
2418
2419 return(CPHS_OK);
2420 }
2421
2422 GLOBAL T_CPHS_RET cphs_get_fwd_flag(UBYTE *cfu_set, T_CPHS_LINES line)
2423 {
2424 UBYTE setting = 0;
2425 T_CPHS_RET ret_status;
2426
2427 TRACE_FUNCTION("cphs_get_fwd_flag()");
2428
2429 /* Check CPHS status */
2430 if((ret_status = cphs_check_status( )) NEQ CPHS_OK)
2431 {
2432 return(ret_status);
2433 }
2434
2435 return(cphs_get_indicator_flag(cfu_set, line, CPHS_SIM_CFU));
2436 }
2437
2438
2439 #define WRITE_FLAG_VALUE(flag, nibble, sim_state) \
2440 (flag = (flag & (0x0F << (4 * nibble))) | \
2441 (sim_state << (4 * (nibble ? 0 : 1))))
2442 /*
2443 #define WRITE_FLAG_VALUE(cfu, 0, state) (cfu = (cfu & 0x0F) | (state << 4))
2444 #define WRITE_FLAG_VALUE(cfu, 1, state) (cfu = (cfu & 0xF0) | state)
2445 */
2446
2447 LOCAL void cphs_write_indicator_flag(UBYTE flag_set,
2448 T_CPHS_LINES lines,
2449 UBYTE indicator)
2450 {
2451 UBYTE setting;
2452 UBYTE byte_index, nibble, table_length, i, sim_flag_status;
2453 UBYTE *flag_table;
2454 T_CPHS_LINES tested_line;
2455 T_CPHS_LINES really_written_lines;
2456
2457 TRACE_FUNCTION("cphs_write_indicator_flag()");
2458
2459 really_written_lines = CPHS_LINE_NULL; /* init */
2460
2461 if(flag_set EQ CPHS_FLAG_ACTIVATED)
2462 {
2463 sim_flag_status = SIM_FLAG_ON;
2464 }
2465 else
2466 sim_flag_status = SIM_FLAG_OFF;
2467
2468 get_relevant_flag_struct(indicator, &flag_table);
2469
2470 /* init temp flags */
2471 memcpy(cphs_internal_params->tmp_flag_set, flag_table, FLAG_TABLE_SIZE);
2472
2473 if(flag_table[1] EQ 0x00)
2474 {
2475 /* this means the optional FAX and DATA part is not present: write only 1st byte ! */
2476 table_length = 1;
2477 }
2478 else
2479 {
2480 table_length = FLAG_TABLE_SIZE;
2481 }
2482
2483 for(i=0;i<8*sizeof(T_CPHS_LINES);i++)
2484 {
2485 tested_line = CPHS_LINE1 << i;
2486
2487 if(tested_line & lines AND
2488 cphs_line_makes_sense(tested_line) )
2489 {
2490 get_byte_index_and_nibble(tested_line, &byte_index, &nibble);
2491
2492 setting = GET_FLAG_VALUE(flag_table[byte_index], nibble);
2493
2494 /* Only fields with an expected value (A or 5) can be written... It is assumed
2495 here that other values mean the corresponding Indicator class is not relevant.
2496 Therefore it will be ignored */
2497 if(setting EQ SIM_FLAG_ON OR
2498 setting EQ SIM_FLAG_OFF)
2499 {
2500 WRITE_FLAG_VALUE(cphs_internal_params->tmp_flag_set[byte_index],
2501 nibble, sim_flag_status);
2502 really_written_lines |= tested_line;
2503 }
2504 else
2505 {
2506 TRACE_EVENT_P2("Unexpected value for this indicator: Writing ignored: line: %d, setting: %X",
2507 tested_line, setting);
2508 }
2509 }
2510 }
2511
2512 /* This is what will be shown to the user when writing on SIM has been successful */
2513 cphs_internal_params->tmp_activate_state = flag_set;
2514 cphs_internal_params->tmp_lines = really_written_lines;
2515
2516 cphs_sim_access_data( CPHS_SIM_WRITE_TRANSP_EF,
2517 indicator,
2518 0,
2519 cphs_internal_params->tmp_flag_set,
2520 table_length );
2521 }
2522
2523 /*
2524 +--------------------------------------------------------------------+
2525 | PROJECT : GSM-PS (6147) MODULE : CPHS |
2526 | STATE : code ROUTINE : cphs_set_cfu_flag |
2527 +--------------------------------------------------------------------+
2528
2529 PURPOSE : set/clear cfu flag for given lines
2530 */
2531
2532 GLOBAL T_CPHS_RET cphs_set_cfu_flag(UBYTE cfu_set, T_CPHS_LINES lines)
2533 {
2534 T_CPHS_RET ret_status;
2535
2536 /* Check CPHS status */
2537 if((ret_status = cphs_check_status( )) NEQ CPHS_OK)
2538 {
2539 TRACE_ERROR("cannot proceed SET of Diverted Call Flag: CPHS module is busy");
2540 return(ret_status);
2541 }
2542
2543 TRACE_FUNCTION("cphs_set_cfu_flag()");
2544
2545 /* write to SIM and in cached data */
2546 cphs_status = CPHS_WRITING_CFU;
2547
2548 cphs_write_indicator_flag(cfu_set, lines, CPHS_SIM_CFU);
2549
2550 return(CPHS_EXEC);
2551 }
2552
2553 GLOBAL BOOL cphs_line_makes_sense(T_CPHS_LINES line)
2554 {
2555 switch(line)
2556 {
2557 case(CPHS_LINE1):
2558 case(CPHS_LINE2):
2559 case(CPHS_LINE_DATA):
2560 case(CPHS_LINE_FAX):
2561 return(TRUE);
2562
2563 }
2564
2565 return(FALSE);
2566 }
2567
2568 /*
2569 +--------------------------------------------------------------------+
2570 | PROJECT : GSM-PS (6147) MODULE : CPHS |
2571 | STATE : code ROUTINE : cphs_write_csp_cb |
2572 +--------------------------------------------------------------------+
2573
2574 PURPOSE : write CSP entry callback
2575
2576 */
2577 GLOBAL void cphs_write_csp_cb(SHORT table_id)
2578 {
2579 TRACE_FUNCTION("cphs_write_csp_cb()");
2580
2581 simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
2582
2583 if (simShrdPrm.atb[table_id].errCode NEQ SIM_NO_ERROR)
2584 {
2585 TRACE_ERROR("cphs_write_csp_cb(): error for writing");
2586 cphs_state_indication( CPHS_SIM_WRITE_FAIL,
2587 (SHORT)cmhSIM_GetCmeFromSim( simShrdPrm.atb[table_id].errCode ));
2588 }
2589 else
2590 {
2591 /* write to ME cache */
2592 write_csp_ok(exchData,
2593 cphs_cached_params->csp_length);
2594 /* reset exchange data */
2595 memset(exchData, 0xFF, sizeof(exchData));
2596 cphs_state_indication ( CPHS_SIM_WRITE_OK, CME_ERR_NotPresent );
2597 }
2598 }
2599 /*
2600 +--------------------------------------------------------------------+
2601 | PROJECT : GSM-PS (6147) MODULE : CPHS |
2602 | STATE : code ROUTINE : cphs_set_csp_value |
2603 +--------------------------------------------------------------------+
2604
2605 PURPOSE : write customer service profile
2606 */
2607 GLOBAL T_CPHS_RET cphs_set_csp_value(UBYTE srcId,
2608 UBYTE *csp,
2609 UBYTE csp_len)
2610 {
2611 T_ACI_RETURN result;
2612 USHORT i,j;
2613 UBYTE max_csp_len = 0;
2614 TRACE_FUNCTION("cphs_set_csp_value()");
2615
2616 /* test state of CPHS */
2617 if(cphs_cached_params EQ NULL)
2618 {
2619 TRACE_ERROR("cphs_cached_params EQ NULL");
2620 return CPHS_NOT_INIT;
2621 }
2622
2623 /* set exchData and max csp length*/
2624 max_csp_len = cphs_cached_params->csp_length;
2625 memset(exchData, 0xFF, DEFAULT_MAXSIZE_OF_RECORD);
2626 memcpy(exchData, cphs_cached_params->csp, max_csp_len );
2627
2628 /*
2629 only for valid service groups, associated services are written to SIM
2630 */
2631 if( csp NEQ NULL )
2632 {
2633 for( i=0; i < csp_len; i+=2 )
2634 {
2635 for( j=0; j < max_csp_len; j+=2 )
2636 {
2637 if ( csp[i] EQ exchData[j] )
2638 {
2639 exchData[j+1] = csp[i+1];
2640 }
2641 }
2642 }
2643 }
2644
2645 /* write to SIM */
2646 result = cmhSIM_WriteTranspEF(srcId,
2647 AT_CMD_CPINF,
2648 SIM_CPHS_CSP,
2649 0,
2650 max_csp_len,
2651 exchData,
2652 cphs_write_csp_cb );
2653
2654 /* If error occured while writing to SIM */
2655 if (result EQ AT_FAIL)
2656 {
2657 return(CPHS_FAIL);
2658 }
2659 return(CPHS_EXEC);
2660 }
2661
2662 #endif /* CPHS_C */
2663 #endif /* FF_CPHS */
2664
2665