comparison g23m-aci/aci/cphs.c @ 0:75a11d740a02

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