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