comparison src/g23m-aci/aci/cphs.c @ 1:d393cd9bb723

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