comparison src/g23m-gprs/grr/grr_psif.c @ 1:d393cd9bb723

src/g23m-*: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:40:46 +0000
parents
children
comparison
equal deleted inserted replaced
0:b6a5e36de839 1:d393cd9bb723
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : GPRS (8441)
4 | Modul : GRR
5 +-----------------------------------------------------------------------------
6 | Copyright 2002 Texas Instruments Berlin, AG
7 | All rights reserved.
8 |
9 | This file is confidential and a trade secret of Texas
10 | Instruments Berlin, AG
11 | The receipt of or possession of this file does not convey
12 | any rights to reproduce or disclose its contents or to
13 | manufacture, use, or sell anything it may describe, in
14 | whole, or in part, without the specific written consent of
15 | Texas Instruments Berlin, AG.
16 +-----------------------------------------------------------------------------
17 | Purpose : This module implements local functions for service PSI of
18 | entity GRR.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef GRR_PSIF_C
23 #define GRR_PSIF_C
24 #endif
25
26 #define ENTITY_GRR
27
28 #ifdef _SIMULATION_
29
30 /*
31 * Report warning 4005 as an error.
32 *
33 * There are identical macro definitons in the GRR message and the RRGRR SAP
34 * document which should be aligned at all the time
35 * (e.g. GPRS_RXLEV_ACCESS_MIN_INVALID, GPRS_MS_TXPWR_MAX_CCH, etc.)
36 */
37 #pragma warning( error : 4005 )
38
39 #endif /* #ifdef _SIMULATION_ */
40
41 /*==== INCLUDES =============================================================*/
42
43 #include "typedefs.h" /* to get Condat data types */
44
45 #include "vsi.h" /* to get a lot of macros */
46 #include "macdef.h"
47 #include "gprs.h"
48 #include "gsm.h" /* to get a lot of macros */
49 #include "ccdapi.h" /* to get CCD API */
50 #include "cnf_grr.h" /* to get cnf-definitions */
51 #include "mon_grr.h" /* to get mon-definitions */
52 #include "prim.h" /* to get the definitions of used SAP and directions */
53 #include "message.h"
54 #include "grr.h" /* to get the global entity definitions */
55 #include "grr_f.h"
56 #include "grr_psif.h" /* */
57 #include "grr_ctrls.h" /* */
58 #include "grr_css.h" /* signals exchanged between PSI and CS*/
59 #include "grr_meass.h" /* signals exchanged between PSI and MEAS*/
60
61 #include <string.h> /* for memcpy */
62 #include <stdio.h> /* for memcpy */
63 #include "grr_em.h" /*for Engineering mode*/
64
65 /*==== DIAGNOSTICS ==========================================================*/
66
67 /*==== CONST ================================================================*/
68 #define PBCCH_NOT_PRESENT 0x0 /* PBCCH not present in the cell */
69 #define PBCCH_PRESENT 0x1 /* PBCCH present in the cell */
70 /*==== LOCAL VARS ===========================================================*/
71 LOCAL void psi_reset_psi_pos ( void );
72 #ifndef _TARGET_
73 LOCAL void psi_fill_rel_pos(UBYTE *src, UBYTE max_src, UBYTE *psi_nr, UBYTE *pos_array);
74 #endif /*_TARGET_*/
75 /*==== PRIVATE FUNCTIONS ====================================================*/
76
77 LOCAL void psi_reset_complete_acq ( void );
78 LOCAL void psi_reset_psi1 (void );
79 LOCAL void psi_reset_psi2 (void );
80 LOCAL void psi_reset_psi3 (void );
81 LOCAL void psi_reset_psi3bis (void );
82 #if defined (REL99) AND defined (TI_PS_FF_EMR)
83 LOCAL void psi_reset_psi3ter (void );
84 #endif
85 LOCAL void psi_reset_psi4 (void );
86 LOCAL void psi_reset_psi5 (void );
87 #ifdef REL99
88 LOCAL void psi_reset_psi8 (void);
89 #endif
90 LOCAL void psi_reset_psi13 (void );
91 LOCAL void psi_init_states_of_psi ( void );
92 LOCAL void psi_init_rfl_psi2(void);
93 LOCAL void psi_init_cell_alloc(void);
94 LOCAL void psi_init_gprs_ms_alloc(BOOL psi2_only);
95
96 LOCAL void psi_copy_si13_params(T_D_SYS_INFO_13* si13);
97 LOCAL void psi_copy_psi13_params(T_PSI_13* psi13);
98 LOCAL BOOL psi_check_change_field (UBYTE psi_change_field);
99 LOCAL UBYTE psi_compare_change_mark(UBYTE received_change_mark, UBYTE stored_change_mark);
100
101 LOCAL BOOL psi_is_pbcch_des_different(T_PSI_13* psi13);
102
103 /*
104 * Private functions for handling of PSI3 and PSI3BIS messages.
105 * Reading of those messages in not ordered sequence.
106 */
107 /*
108 * Storing
109 */
110 LOCAL UBYTE psi_store_ncell_param ( T_ncell_par *p_ncell_par,
111 UBYTE c_ncell_par,
112 UBYTE v_ncell_par,
113 T_INFO_TYPE type,
114 UBYTE instance );
115
116 LOCAL void psi_store_ncell_param2 ( T_PSI_3_BIS *psi3bis,
117 UBYTE number );
118 LOCAL BOOL psi_store_cs_param2 ( T_NC_LIST *nc_list,
119 T_ncell_par2_set *cs_par2,
120 UBYTE instance,
121 UBYTE *number,
122 USHORT *freq,
123 USHORT freq_diff,
124 UBYTE same_ra_scell,
125 UBYTE cell_ba,
126 UBYTE bcc );
127
128 /*
129 * Restoring
130 */
131 LOCAL void psi_restore_ncell_param ( void );
132
133 #ifdef REL99
134 LOCAL void psi_update_bss_sgsn_rel ( T_D_SYS_INFO_13 *si13,
135 BOOL pbcch_status );
136 #endif
137
138 /*==== PUBLIC FUNCTIONS =====================================================*/
139
140 /*
141 +------------------------------------------------------------------------------
142 | Function : psi_compare_change_mark()
143 +------------------------------------------------------------------------------
144 | Description : The function psi_compare_change_mark() .... compares the change_mark values
145 | and indicates the incrementatiton value
146 |
147 | Parameters : UBYTE received_change_mark, UBYTE stored_change_mark
148 |
149 +------------------------------------------------------------------------------
150 */
151 LOCAL UBYTE psi_compare_change_mark(UBYTE received_change_mark, UBYTE stored_change_mark)
152 {
153 UBYTE incremented_value = 0;
154
155 if(received_change_mark NEQ stored_change_mark)
156 {
157 UBYTE dummy = (stored_change_mark + 1)%8;
158 if(dummy EQ received_change_mark)
159 incremented_value = 1;
160 else
161 incremented_value = 2;
162 }
163 return incremented_value;
164 }/* psi_compare_change_mark*/
165 /*
166 +------------------------------------------------------------------------------
167 | Function : psi_stop_psi_reading()
168 +------------------------------------------------------------------------------
169 | Description : The function psi_stop_psi_reading() .... stops to read PSI messages
170 |
171 | Parameters : void
172 |
173 +------------------------------------------------------------------------------
174 */
175 GLOBAL void psi_stop_psi_reading( ACQ_TYPE acq_type_in_idle)
176 {
177 TRACE_FUNCTION( "psi_stop_psi_reading" );
178 psc_db->acq_type = acq_type_in_idle;
179 if(grr_is_pbcch_present())
180 {
181 PALLOC(mphp_scell_pbcch_req, MPHP_SCELL_PBCCH_STOP_REQ);
182 PSEND(hCommL1,mphp_scell_pbcch_req);
183 }
184 }/* psi_stop_psi_reading*/
185
186 /*
187 +------------------------------------------------------------------------------
188 | Function : psi_check_acq_state
189 +------------------------------------------------------------------------------
190 | Description : The function psi_check_acq_state() .... checks the state of the acquisition
191 |
192 | Parameters : void
193 |
194 +------------------------------------------------------------------------------
195 */
196 GLOBAL T_ACQ_STATE_RET psi_check_acq_state ( void )
197 {
198 UBYTE n;
199 T_ACQ_STATE_RET return_val = ACQ_RUNNING;
200
201 TRACE_FUNCTION( "psi_check_acq_state" );
202
203 switch(psc_db->acq_type)
204 {
205 case PARTIAL:
206 return_val = ACQ_PART_OK;
207 for(n = 0; n <MAX_PSI; n++)
208 {
209 if(psc_db->state_of_PSI[n].state EQ NEEDED)
210 {
211 /*
212 * partial acquisition not completed
213 */
214 return_val = ACQ_RUNNING;
215 }
216 }
217 if(return_val EQ ACQ_PART_OK)
218 {
219 psi_stop_10sec(); /* partial acquisition completed */
220 psc_db->acq_type = NONE; /* e.g. wait 30 sec for reread PSI1*/
221 psc_db->psi1_params.first_psi1 = FALSE;
222 #ifdef REL99
223 /* Partial acquisition is complete. Send CBCH info
224 * to RR if needed.
225 */
226 if(psc_db->send_cbch_info_ind)
227 {
228 sig_psi_ctrl_cbch_info_ind();
229 psc_db->send_cbch_info_ind = FALSE;
230 }
231 #endif
232 }
233 break;
234 case COMPLETE:
235 return_val = ACQ_COMP_OK;
236 /*
237 * Check whether reading process completed or not
238 */
239 for(n = 0; n <MAX_PSI; n++)
240 {
241 if(psc_db->state_of_PSI[n].state EQ NEEDED)
242 {
243 /*
244 * acquisition of some PSI not completed
245 */
246 {
247 if(n EQ 3)
248 {
249 TRACE_EVENT("acq. incomplete PSI3bis missing!");
250 }
251 #if defined (REL99) AND defined (TI_PS_FF_EMR)
252 else if(n EQ 4)
253 {
254 TRACE_EVENT("acq. incomplete PSI3ter missing!");
255 }
256 else if(n EQ 7)
257 {
258 TRACE_EVENT("acq. incomplete PSI8 missing!");
259 }
260 else
261 {
262 TRACE_EVENT_P1("acq. incomplete PSI%d missing!", ((n>3)?n-1:n+1));
263 }
264 #else
265 else
266 {
267 TRACE_EVENT_P1("acq. incomplete PSI%d missing!", ((n>3)?n:n+1));
268 }
269 #endif
270 }
271 return_val = ACQ_RUNNING;
272 break; /* break for loop*/
273 }
274 }
275 if(return_val EQ ACQ_COMP_OK)
276 {
277 /*
278 * Start timer for 10 sec. if running
279 */
280 TRACE_EVENT("Acq. complete");
281 vsi_t_stop(GRR_handle, T_COMP_PSI);
282 psi_stop_10sec(); /* acquisition of all PSI completed */
283 psc_db->acq_type = NONE; /* e.g. wait 30 sec for reread PSI1*/
284 psc_db->psi1_params.first_psi1 = FALSE;
285 }
286 break;
287 case PERIODICAL_PSI1_READING:
288 psc_db->acq_type = NONE; /* e.g. wait 30 sec for reread PSI1*/
289 return_val = ACQ_PERIOD_OK;
290 break;
291 case FULL_PSI_IN_NEW_CELL:
292 return_val = ACQ_NPSI_OK;
293 psc_db->acq_type = NONE; /* e.g. wait 30 sec for reread PSI1*/
294 /*
295 * E.g. read all PSI in the reselected cell
296 * Check whether reading process completed or not
297 */
298 for(n = 0; n <MAX_PSI; n++)
299 {
300 if(psc_db->state_of_PSI[n].state EQ NEEDED)
301 {
302 /*
303 * acquisition of some PSI not completed
304 */
305 return_val = ACQ_RUNNING;
306 psc_db->acq_type = FULL_PSI_IN_NEW_CELL;
307 break; /* break for loop*/
308 }
309 }
310 if(n>MAX_PSI)
311 psc_db->psi1_params.first_psi1 = FALSE;
312 break;
313 case NONE:
314 /* nothing to do: we may received a PSI message without sending a request
315 * e.g. on PCCCH (PPCH: paging channel or paging group)
316 */
317 break;
318 default:
319 break;
320 }
321 return return_val;
322 } /* psi_check_acq_state() */
323
324
325 /*
326 +------------------------------------------------------------------------------
327 | Function : psi_reset_complete_acq
328 +------------------------------------------------------------------------------
329 | Description : The function psi_reset_complete_acq() ....
330 |
331 | Parameters : void
332 |
333 +------------------------------------------------------------------------------
334 */
335 LOCAL void psi_reset_complete_acq ( void )
336 {
337 TRACE_FUNCTION( "psi_reset_complete_acq" );
338 psc_db->acq_type = COMPLETE;
339
340 psc_db->complete_acq.needed = TRUE;
341 psc_db->complete_acq.psi1_ok = FALSE;
342 psc_db->complete_acq.psi2_ok = FALSE;
343 psc_db->complete_acq.made_at_least_one_attempt = FALSE;
344 }/* psi_reset_complete_acq*/
345
346 /*
347 +------------------------------------------------------------------------------
348 | Function : psi_reset_psi1
349 +------------------------------------------------------------------------------
350 | Description : The function psi_reset_psi1() ....
351 |
352 | Parameters : void
353 |
354 +------------------------------------------------------------------------------
355 */
356 LOCAL void psi_reset_psi1 ( void )
357 {
358 TRACE_FUNCTION( "psi_reset_psi1" );
359
360 psc_db->psi1_params.pbcch_change_mark = NOT_SET;
361 psc_db->psi1_params.psi_change_field = NOT_SET;
362 psc_db->psi1_params.psi_cnt_lr = 0;
363 psc_db->psi1_params.psi_cnt_hr = 0;
364 psc_db->psi1_params.psi1_repeat_period = NOT_SET;
365 psc_db->psi1_params.first_psi1 = TRUE;
366 }/* psi_reset_psi1*/
367
368 /*
369 +------------------------------------------------------------------------------
370 | Function : psi_reset_psi2
371 +------------------------------------------------------------------------------
372 | Description : The function psi_reset_psi2() ....
373 |
374 | Parameters : void
375 |
376 +------------------------------------------------------------------------------
377 */
378 LOCAL void psi_reset_psi2 ( void )
379 {
380 UBYTE n;
381 TRACE_FUNCTION( "psi_reset_psi2" );
382 /* reset psi2 parameters*/
383 psc_db->psi2_params.psi2_change_mark = NOT_SET; /*not set*/
384 psc_db->psi2_params.psi2_count = NOT_SET; /*not set*/
385
386 for(n = 0; n <MAX_NR_OF_INSTANCES_OF_PSI2 + 1; n++)
387 psc_db->psi2_params.instances[n] = FALSE;
388
389 #ifdef REL99
390 psc_db->v_add_psi = FALSE;
391 #endif
392 psi_init_rfl_psi2();
393 psi_init_cell_alloc();
394 psi_init_gprs_ms_alloc(TRUE);
395
396 } /* psi_reset_psi2 */
397
398 /*
399 +------------------------------------------------------------------------------
400 | Function : psi_reset_psi3
401 +------------------------------------------------------------------------------
402 | Description : The function psi_reset_psi3() ....
403 |
404 | Parameters : void
405 |
406 +------------------------------------------------------------------------------
407 */
408 LOCAL void psi_reset_psi3 ( void )
409 {
410 TRACE_FUNCTION( "psi_reset_psi3" );
411 /* reset psi3 parameters*/
412 psc_db->psi3_params.psi3_change_mark = NOT_SET;
413 psc_db->psi3_params.psi3_bis_count = NOT_SET;
414 #if defined (REL99) AND defined (TI_PS_FF_EMR)
415 grr_init_nc_list( &psc_db->nc_cw.list );
416 #endif
417 } /* psi_reset_psi3 */
418
419 /*
420 +------------------------------------------------------------------------------
421 | Function : psi_reset_psi3bis
422 +------------------------------------------------------------------------------
423 | Description : The function psi_reset_psi3bis() ....
424 |
425 | Parameters : void
426 |
427 +------------------------------------------------------------------------------
428 */
429 LOCAL void psi_reset_psi3bis ( void )
430 {
431 UBYTE n;
432 TRACE_FUNCTION( "psi_reset_psi3bis" );
433
434 psc_db->psi3bis_params.psi3bis_change_mark = NOT_SET;
435 psc_db->psi3bis_params.psi3bis_index = 0;
436
437 for(n = 0; n <MAX_NR_OF_INSTANCES_OF_PSI3BIS + 1; n++)
438 psc_db->psi3bis_params.instances[n] = FALSE;
439
440 grr_init_nc_list( &psc_db->nc_cw.list );
441 } /* psi_reset_psi3bis */
442
443 #if defined (REL99) AND defined (TI_PS_FF_EMR)
444 /*
445 +------------------------------------------------------------------------------
446 | Function : psi_reset_psi3ter
447 +------------------------------------------------------------------------------
448 | Description : The function psi_reset_psi3ter() ....
449 |
450 | Parameters : void
451 |
452 +------------------------------------------------------------------------------
453 */
454 LOCAL void psi_reset_psi3ter ( void )
455 {
456 UBYTE n;
457 TRACE_FUNCTION( "psi_reset_psi3ter" );
458
459 psc_db->psi3ter_params.psi3ter_change_mark = NOT_SET;
460 psc_db->psi3ter_params.prev_psi3ter_index = 0;
461 psc_db->psi3ter_params.psi3ter_index = 0;
462
463 for(n = 0; n <MAX_NR_OF_INSTANCES_OF_PSI3TER + 1; n++)
464 psc_db->psi3ter_params.instances[n] = FALSE;
465
466 psc_db->enh_cw.gprs_rept_prio_desc.num_cells = 0;
467 #ifdef TI_PS_FF_RTD
468 /* Rtd values has to be reset to not available */
469 for( n = 0; n < MAX_NR_OF_NCELL; n++ )
470 psc_db->rtd[n] = RTD_NOT_AVAILABLE;
471 #endif /* #ifdef TI_PS_FF_RTD */
472
473
474 } /* psi_reset_psi3ter */
475 #endif
476
477
478 /*
479 +------------------------------------------------------------------------------
480 | Function : psi_reset_psi4
481 +------------------------------------------------------------------------------
482 | Description : The function psi_reset_psi4() ....
483 |
484 | Parameters : void
485 |
486 +------------------------------------------------------------------------------
487 */
488 LOCAL void psi_reset_psi4 ( void )
489 {
490 UBYTE n;
491 TRACE_FUNCTION( "psi_reset_psi4" );
492 /* reset psi_reset_psi4 parameters*/
493 psc_db->psi4_params.psi4_index = 0;
494 psc_db->psi4_params.psi4_change_mark = NOT_SET;
495
496 for(n = 0; n <MAX_NR_OF_INSTANCES_OF_PSI4 + 1; n++)
497 psc_db->psi4_params.instances[n] = FALSE;
498
499
500 } /* psi_reset_psi4 */
501
502
503 /*
504 +------------------------------------------------------------------------------
505 | Function : psi_reset_psi5
506 +------------------------------------------------------------------------------
507 | Description : The function psi_reset_psi5() ....
508 |
509 | Parameters : void
510 |
511 +------------------------------------------------------------------------------
512 */
513 LOCAL void psi_reset_psi5 ( void )
514 {
515 UBYTE i;
516
517 TRACE_FUNCTION( "psi_reset_psi5" );
518 /* reset psi_reset_psi5 parameters*/
519 psc_db->psi5_params.psi5_index = 0;
520 psc_db->psi5_params.psi5_change_mark = NOT_SET;
521
522 for( i = 0; i < MAX_NR_OF_INSTANCES_OF_PSI5; i++ )
523 {
524 psc_db->psi5_params.idx[i].start = RRGRR_INVALID_IDX;
525 psc_db->psi5_params.idx[i].stop = RRGRR_INVALID_IDX;
526 psc_db->psi5_params.instances[i] = FALSE;
527 }
528 /*
529 * used for checking the consistency of PSI5. instances[0]: number of instances
530 */
531 psc_db->psi5_params.instances[MAX_NR_OF_INSTANCES_OF_PSI5] = FALSE;
532
533 grr_init_nc_param( &psc_db->nc_cw.param, TRUE );
534 grr_init_xmeas_struct( &psc_db->ext_psi5 );
535 #if defined (REL99) AND defined (TI_PS_FF_EMR)
536 grr_init_enh_param(&psc_db->enh_cw, FALSE);
537 grr_init_enh_param(&grr_data->psi.enh_param, FALSE);
538 #endif
539 } /* psi_reset_psi5 */
540
541 #ifdef REL99
542 /*
543 +------------------------------------------------------------------------------
544 | Function : psi_reset_psi8
545 +------------------------------------------------------------------------------
546 | Description : The function psi_reset_psi8() ....
547 |
548 | Parameters : void
549 |
550 +------------------------------------------------------------------------------
551 */
552 LOCAL void psi_reset_psi8 ( void )
553 {
554 UBYTE n;
555 TRACE_FUNCTION( "psi_reset_psi8" );
556 /* reset psi_reset_psi8 parameters*/
557 psc_db->psi8_params.psi8_index = 0;
558 psc_db->psi8_params.psi8_change_mark = NOT_SET;
559
560 for(n = 0; n <MAX_NR_OF_INSTANCES_OF_PSI8 + 1; n++)
561 psc_db->psi8_params.instances[n] = FALSE;
562
563 psc_db->send_cbch_info_ind = FALSE;
564 psc_db->v_cbch_chan_desc = FALSE;
565 } /* psi_reset_psi8 */
566 #endif
567
568 /*
569 +------------------------------------------------------------------------------
570 | Function : psi_reset_psi13
571 +------------------------------------------------------------------------------
572 | Description : The function psi_reset_psi13() ....
573 |
574 | Parameters : void
575 |
576 +------------------------------------------------------------------------------
577 */
578 LOCAL void psi_reset_psi13 ( void )
579 {
580 TRACE_FUNCTION( "psi_reset_psi13" );
581
582 grr_init_nc_param( &psc_db->nc_cw.param, TRUE );
583
584 } /* psi_reset_psi13 */
585
586 /*
587 +------------------------------------------------------------------------------
588 | Function : psi_reset_all
589 +------------------------------------------------------------------------------
590 | Description : The function psi_reset_all() ....
591 |
592 | Parameters : void
593 |
594 +------------------------------------------------------------------------------
595 */
596 GLOBAL void psi_reset_all ( void )
597 {
598 TRACE_FUNCTION( "psi_reset_all" );
599
600
601 /* reset complete acq.*/
602 psi_reset_complete_acq();
603
604 /* reset PSI1 parameters */
605 psi_reset_psi1();
606
607 /* reset psi2 parameters*/
608 psi_reset_psi2();
609
610 /* reset psi3 parameters*/
611 psi_reset_psi3();
612
613 /* reset psi3bis parameters*/
614 psi_reset_psi3bis();
615
616 #if defined (REL99) AND defined (TI_PS_FF_EMR)
617 /* reset psi3ter parameters*/
618 psi_reset_psi3ter();
619 #endif
620
621 /* reset psi4 parameters*/
622 psi_reset_psi4();
623
624 /* reset psi5 parameters*/
625 psi_reset_psi5();
626
627 #ifdef REL99
628 /* reset psi8 parameters*/
629 psi_reset_psi8();
630 #endif
631
632 /* reset psi13 parameters*/
633 psi_reset_psi13();
634
635 /* */
636 psc_db->send_psi_status = FALSE;
637
638
639 /* init the states of the PSI parameters*/
640 psi_init_states_of_psi();
641
642 psi_reset_si_entries();
643
644 } /* psi_reset_all() */
645
646
647
648 /*
649 +------------------------------------------------------------------------------
650 | Function : psi_stop_10sec
651 +------------------------------------------------------------------------------
652 | Description : The function psi_stop_10sec() ....
653 |
654 | Parameters : void
655 |
656 +------------------------------------------------------------------------------
657 */
658 GLOBAL void psi_stop_10sec ( void )
659 {
660 TRACE_FUNCTION( "psi_stop_10sec" );
661
662 vsi_t_stop(GRR_handle,T_10_SEC);
663 } /* psi_stop_10sec() */
664
665
666
667 /*
668 +------------------------------------------------------------------------------
669 | Function : psi_start_10sec
670 +------------------------------------------------------------------------------
671 | Description : The function psi_start_10sec() ....
672 |
673 | Parameters : void
674 |
675 +------------------------------------------------------------------------------
676 */
677 GLOBAL void psi_start_10sec ( void )
678 {
679 TRACE_FUNCTION( "psi_start_10sec" );
680
681 if(grr_data->psi.is_start_of_10_sec_allowed)
682 vsi_t_start(GRR_handle,T_10_SEC, T_10_SEC_VALUE);
683 } /* psi_start_10sec() */
684
685
686
687 /*
688 +------------------------------------------------------------------------------
689 | Function : psi_partial_acq
690 +------------------------------------------------------------------------------
691 | Description : The function psi_partial_acq() performs partial acquisition
692 |
693 | Parameters : void
694 |
695 +------------------------------------------------------------------------------
696 */
697 GLOBAL void psi_partial_acq ( void )
698 {
699 UBYTE psi_reading_type;
700 UBYTE dummy=0;
701
702 TRACE_FUNCTION( "psi_partial_acq" );
703
704 psi_reading_type = PSI_IN_HR_AND_LR;
705
706 psc_db->acq_type = PARTIAL;
707
708 if( psc_db->state_of_PSI[PSI2].state EQ NEEDED)
709 {
710 psi_reading_type = READ_PSI2;
711 psi_reset_psi2();
712 dummy++;
713 TRACE_EVENT("PSI 2 needed");
714 }
715
716 if( psc_db->state_of_PSI[PSI3].state EQ NEEDED)
717 {
718 psi_reading_type = READ_PSI3_3BIS;
719 psi_reset_psi3();
720 psi_reset_psi3bis();
721
722 #if defined (REL99) AND defined (TI_PS_FF_EMR)
723 psi_reset_psi3ter();
724 #endif
725
726 dummy++;
727 #if defined (REL99) AND defined (TI_PS_FF_EMR)
728 TRACE_EVENT("PSI3/3bis/3ter needed");
729 #else
730 TRACE_EVENT("PSI3/3bis needed");
731 #endif
732 }
733
734 if( psc_db->state_of_PSI[PSI4].state EQ NEEDED)
735 {
736 psi_reading_type = READ_PSI4;
737 psi_reset_psi4();
738 dummy++;
739 TRACE_EVENT("PSI 4 needed");
740 }
741
742 if( psc_db->state_of_PSI[PSI5].state EQ NEEDED)
743 {
744 psi_reading_type = READ_PSI5;
745 psi_reset_psi5();
746 dummy++;
747 TRACE_EVENT("PSI 5 needed");
748 }
749
750 #ifdef REL99
751 if( psc_db->state_of_PSI[PSI8].state EQ NEEDED)
752 {
753 psi_reading_type = READ_PSI8;
754 psi_reset_psi8();
755 dummy++;
756 TRACE_EVENT("PSI 8 needed");
757 }
758 #endif
759
760 if(dummy > 1)
761 psi_reading_type = PSI_IN_HR_AND_LR;
762
763 psi_receive_psi(psi_reading_type);
764 } /* psi_partial_acq() */
765
766
767 /*
768 +------------------------------------------------------------------------------
769 | Function : psi_init_states_of_psi
770 +------------------------------------------------------------------------------
771 | Description : The function psi_init_states_of_psi() ....
772 |
773 | Parameters : void
774 |
775 +------------------------------------------------------------------------------
776 */
777 LOCAL void psi_init_states_of_psi ( void )
778 {
779 psc_db->state_of_PSI[PSI1].state = NEEDED;
780 psc_db->state_of_PSI[PSI2].state = NEEDED;
781 psc_db->state_of_PSI[PSI3].state = NEEDED;
782 psc_db->state_of_PSI[PSI3bis].state = NEEDED;
783 #if defined (REL99) AND defined (TI_PS_FF_EMR)
784 psc_db->state_of_PSI[PSI3ter].state = NEEDED;
785 #endif
786 psc_db->state_of_PSI[PSI4].state = NEEDED;
787 psc_db->state_of_PSI[PSI5].state = NEEDED;
788 #ifdef REL99
789 psc_db->state_of_PSI[PSI8].state = NEEDED;
790 #endif
791 psc_db->state_of_PSI[PSI13].state = NEEDED;
792
793 }/* psi_init_states_of_psi() */
794
795 /*
796 +------------------------------------------------------------------------------
797 | Function : psi_init_rfl_psi2
798 +------------------------------------------------------------------------------
799 | Description : The function psi_init_rfl_psi2() ....
800 |
801 | Parameters : void
802 |
803 +------------------------------------------------------------------------------
804 */
805 LOCAL void psi_init_rfl_psi2(void)
806 {
807 UBYTE n;
808
809 /*
810 * please note that only the RFL_NUMBERs defined
811 * in the PSI2 will be marked as invalid
812 */
813 for (n = 0; n < MAX_RFL; n++)
814 {
815 psc_db->rfl[n].num = NOT_SET;
816 }
817 }/* psi_init_rfl_psi2() */
818 /*
819 +------------------------------------------------------------------------------
820 | Function : psi_init_cell_alloc
821 +------------------------------------------------------------------------------
822 | Description : The function psi_init_cell_alloc() ....
823 |
824 | Parameters : void
825 |
826 +------------------------------------------------------------------------------
827 */
828 LOCAL void psi_init_cell_alloc(void)
829 {
830 UBYTE n;
831 /*TRACE_EVENT("psi_init_cell_alloc");*/
832 psc_db->v_cell_alloc = FALSE;
833 for (n = 0; n < MAX_CELL_ALLOC; n++)
834 psc_db->cell_alloc[n].rfl_num = NOT_SET;
835 }/* psi_init_cell_alloc() */
836
837 /*
838 +------------------------------------------------------------------------------
839 | Function : psi_init_gprs_ms_alloc
840 +------------------------------------------------------------------------------
841 | Description : The function psi_init_gprs_ms_alloc() ....
842 |
843 | Parameters : BOOL psi2_only
844 |
845 +------------------------------------------------------------------------------
846 */
847 LOCAL void psi_init_gprs_ms_alloc(BOOL psi2_only)
848 {
849 UBYTE n;
850 if(psi2_only)
851 {
852 TRACE_EVENT("remove only PSI2 entries in GPRS_MA");
853 }
854 else
855 {
856 TRACE_EVENT("remove all entries in GPRS_MA");
857 }
858
859 for (n = 0; n < MAX_GPRS_MS_ALLOC; n++)
860 {
861 if(psi2_only)
862 {
863 if(
864 (psc_db->gprs_ms_alloc_in_psi2_psi13[n].ma_num NEQ MA_NUMBER_4_PSI13_OR_CELL_ALLOC )
865 AND /* ignore MA_NUMBER with 14 or 15: 0..13 in PSI2*/
866 (psc_db->gprs_ms_alloc_in_psi2_psi13[n].ma_num NEQ MA_NUMBER_4_ASSIGNMENT )
867 )
868 {
869 psc_db->gprs_ms_alloc_in_psi2_psi13[n].ma_num = NOT_SET;
870 }
871 }
872 else
873 {
874 psc_db->gprs_ms_alloc_in_psi2_psi13[n].ma_num = NOT_SET;
875 }
876 }
877
878 /*
879 * When deleting the MA defined in the assignment message,
880 * the corresponding RFL list should be deleted, too.
881 */
882 psc_db->gprs_ms_alloc_in_assignment.ma_num = NOT_SET;
883 psc_db->rfl[MAX_RFL].num = NOT_SET;
884 }/* psi_init_gprs_ms_alloc() */
885
886 /*
887 +------------------------------------------------------------------------------
888 | Function : psi_init
889 +------------------------------------------------------------------------------
890 | Description : The function psi_init() ....
891 |
892 | Parameters : void
893 |
894 +------------------------------------------------------------------------------
895 */
896 GLOBAL void psi_init ( void )
897 {
898 TRACE_FUNCTION( "psi_init" );
899
900 psi_init_params();
901 psi_reset_psi_pos( );
902
903 INIT_STATE(PSI, PSI_NULL);
904
905 } /* psi_init() */
906
907
908
909 /*
910 +------------------------------------------------------------------------------
911 | Function : psi_complete_acq
912 +------------------------------------------------------------------------------
913 | Description : The function psi_complete_acq() ....
914 |
915 | Parameters : UBYTE acq_type: COMPLETE (in serving cell) or FULL_PSI_IN_NEW_CELL
916 |
917 +------------------------------------------------------------------------------
918 */
919 GLOBAL void psi_complete_acq ( ACQ_TYPE acq_type )
920 {
921 TRACE_FUNCTION( "psi_complete_acq" );
922 /*
923 * Start timer for 10 sec.
924 */
925 vsi_t_start(GRR_handle,T_COMP_PSI, T_10_SEC_VALUE);
926
927 psi_receive_psi(READ_COMPLETE);
928
929 psi_reset_all();
930
931 psc_db->acq_type = acq_type;
932
933 psc_db->state_of_PSI[PSI13].state = RECEIPT_OK; /* we do not need to read PSI13 again*/
934
935 } /* psi_complete_acq() */
936
937
938
939 /*
940 +------------------------------------------------------------------------------
941 | Function : psi_send_psi_status
942 +------------------------------------------------------------------------------
943 | Description : The function psi_send_psi_status() ....
944 |
945 | Parameters : void
946 |
947 +------------------------------------------------------------------------------
948 */
949 GLOBAL void psi_send_psi_status (void )
950 {
951 TRACE_FUNCTION( "psi_send_psi_status" );
952
953 /* SZML-PSI/003 */
954
955 } /* psi_send_psi_status() */
956
957
958
959 /*
960 +------------------------------------------------------------------------------
961 | Function : psi_stop_30sec
962 +------------------------------------------------------------------------------
963 | Description : The function psi_stop_30sec() ....
964 |
965 | Parameters : BOOL start_again: whether the timer should be started again or not
966 |
967 +------------------------------------------------------------------------------
968 */
969 GLOBAL void psi_stop_30sec (BOOL start_again )
970 {
971 TRACE_FUNCTION( "psi_stop_30sec" );
972
973 vsi_t_stop(GRR_handle,T_30_SEC);
974 if(start_again)
975 {
976 /*
977 TRACE_EVENT("30 sec. running");
978 */
979 vsi_t_start(GRR_handle,T_30_SEC, T_30_SEC_VALUE);
980 }
981 else
982 {
983 TRACE_EVENT("30 sec. stopped");
984 }
985 } /* psi_stop_30sec() */
986
987
988
989 /*
990 +------------------------------------------------------------------------------
991 | Function : psi_start_30sec
992 +------------------------------------------------------------------------------
993 | Description : The function psi_start_30sec() ....
994 |
995 | Parameters : void
996 |
997 +------------------------------------------------------------------------------
998 */
999 GLOBAL void psi_start_30sec (void )
1000 {
1001 TRACE_FUNCTION( "psi_start_30sec" );
1002 /*
1003 TRACE_EVENT("30 sec. running");
1004 */
1005 vsi_t_start(GRR_handle,T_30_SEC, T_30_SEC_VALUE);
1006 } /* psi_start_30sec() */
1007
1008
1009
1010 /*
1011 +------------------------------------------------------------------------------
1012 | Function : psi_start_60sec
1013 +------------------------------------------------------------------------------
1014 | Description : The function psi_start_60sec() ....
1015 |
1016 | Parameters : void
1017 |
1018 +------------------------------------------------------------------------------
1019 */
1020 GLOBAL void psi_start_60sec ( void )
1021 {
1022 TRACE_FUNCTION( "psi_start_60sec" );
1023 /*
1024 TRACE_EVENT("60 sec. running");
1025 */
1026 vsi_t_start(GRR_handle,T_60_SEC, T_60_SEC_VALUE);
1027 } /* psi_start_60sec() */
1028
1029
1030 /*
1031 +------------------------------------------------------------------------------
1032 | Function : psi_stop_60sec
1033 +------------------------------------------------------------------------------
1034 | Description : The function psi_stop_60sec () ....
1035 |
1036 | Parameters : BOOL start_again
1037 |
1038 +------------------------------------------------------------------------------
1039 */
1040 GLOBAL void psi_stop_60sec ( BOOL start_again )
1041 {
1042 TRACE_FUNCTION( "psi_stop_60sec " );
1043
1044 vsi_t_stop(GRR_handle,T_60_SEC);
1045 if(start_again)
1046 {
1047 /*
1048 TRACE_EVENT("60 sec. running");
1049 */
1050 vsi_t_start(GRR_handle,T_60_SEC, T_60_SEC_VALUE);
1051 }
1052 else
1053 {
1054 TRACE_EVENT("60 sec. stopped");
1055 }
1056
1057 } /* psi_stop_60sec () */
1058
1059 /*
1060 +------------------------------------------------------------------------------
1061 | Function : psi_copy_ma_from_psi13
1062 +------------------------------------------------------------------------------
1063 | Description : The function psi_copy_ma_from_psi13() ....
1064 |
1065 | Parameters : T_gprs_ms_alloc* ms_alloc: pointer to T_gprs_ms_alloc
1066 |
1067 +------------------------------------------------------------------------------
1068 */
1069 LOCAL void psi_copy_ma_from_psi13(T_gprs_ms_alloc_ie* ms_alloc)
1070 {
1071 UBYTE n;
1072 MCAST(si13,D_SYS_INFO_13); /* T_D_SYS_INFO_13 */
1073
1074 TRACE_FUNCTION( "psi_copy_ma_from_psi13 " );
1075
1076 if(D_SYS_INFO_13 NEQ si13->msg_type)
1077 { /* PSI13 was received */
1078 for(n = 0; n < MAX_GPRS_MS_ALLOC; n++)
1079 {
1080 if( (psc_db->gprs_ms_alloc_in_psi2_psi13[n].ma_num EQ MA_NUMBER_4_PSI13_OR_CELL_ALLOC) ||
1081 (psc_db->gprs_ms_alloc_in_psi2_psi13[n].ma_num EQ NOT_SET) )
1082 {
1083 psc_db->gprs_ms_alloc_in_psi2_psi13[n].ma_num = MA_NUMBER_4_PSI13_OR_CELL_ALLOC;
1084 memcpy(&(psc_db->gprs_ms_alloc_in_psi2_psi13[n].gprs_ms_alloc_ie),
1085 ms_alloc, sizeof(T_gprs_ms_alloc_ie));
1086 n = MAX_GPRS_MS_ALLOC; /* break for loop*/
1087 }
1088 }
1089 }
1090 else
1091 { /* SI13 was received */
1092 UBYTE i;
1093 T_gprs_ma *gprs_ma = (T_gprs_ma*)ms_alloc;
1094 for(n = 0; n < MAX_GPRS_MS_ALLOC; n++)
1095 {
1096 if( (psc_db->gprs_ms_alloc_in_psi2_psi13[n].ma_num EQ MA_NUMBER_4_PSI13_OR_CELL_ALLOC) ||
1097 (psc_db->gprs_ms_alloc_in_psi2_psi13[n].ma_num EQ NOT_SET) )
1098 {
1099 memset(&(psc_db->gprs_ms_alloc_in_psi2_psi13[n].gprs_ms_alloc_ie), 0,
1100 sizeof(T_gprs_ms_alloc_ie));
1101 psc_db->gprs_ms_alloc_in_psi2_psi13[n].ma_num =
1102 MA_NUMBER_4_PSI13_OR_CELL_ALLOC;
1103 psc_db->gprs_ms_alloc_in_psi2_psi13[n].gprs_ms_alloc_ie.hsn =
1104 gprs_ma->hsn;
1105 if(gprs_ma->v_rfln)
1106 {
1107 psc_db->gprs_ms_alloc_in_psi2_psi13[n].gprs_ms_alloc_ie.v_rfl_num_list
1108 = TRUE;
1109 psc_db->gprs_ms_alloc_in_psi2_psi13[n].gprs_ms_alloc_ie.c_rfl_num_list
1110 = gprs_ma->c_rfln;
1111 for(i = 0;i < gprs_ma->c_rfln;i++)
1112 {
1113 psc_db->gprs_ms_alloc_in_psi2_psi13[n].gprs_ms_alloc_ie.rfl_num_list[i].rfl_num
1114 = gprs_ma->rfln[i];
1115 }
1116 }
1117 psc_db->gprs_ms_alloc_in_psi2_psi13[n].gprs_ms_alloc_ie.flag =
1118 gprs_ma->hop;
1119 if(gprs_ma->hop)
1120 {
1121 if(gprs_ma->v_arfcn_idx)
1122 {
1123 psc_db->gprs_ms_alloc_in_psi2_psi13[n].gprs_ms_alloc_ie.v_arfcn_index_list
1124 = TRUE;
1125 psc_db->gprs_ms_alloc_in_psi2_psi13[n].gprs_ms_alloc_ie.c_arfcn_index_list
1126 = gprs_ma->c_arfcn_idx;
1127 for(i = 0;i < gprs_ma->c_arfcn_idx;i++)
1128 {
1129 psc_db->gprs_ms_alloc_in_psi2_psi13[n].gprs_ms_alloc_ie.arfcn_index_list[i].arfcn_index
1130 = gprs_ma->arfcn_idx[i];
1131 }
1132 }
1133 }
1134 else
1135 {
1136 psc_db->gprs_ms_alloc_in_psi2_psi13[n].gprs_ms_alloc_ie.v_ma_struct
1137 = TRUE;
1138 psc_db->gprs_ms_alloc_in_psi2_psi13[n].gprs_ms_alloc_ie.ma_struct.ma_len
1139 = gprs_ma->allo_len6;
1140 psc_db->gprs_ms_alloc_in_psi2_psi13[n].gprs_ms_alloc_ie.ma_struct.c_ma_map
1141 = gprs_ma->c_allo_bmp6;
1142 for(i = 0;i < gprs_ma->c_allo_bmp6;i++)
1143 {
1144 psc_db->gprs_ms_alloc_in_psi2_psi13[n].gprs_ms_alloc_ie.ma_struct.ma_map[i]
1145 = gprs_ma->allo_bmp6[i];
1146 }
1147 }
1148 break;
1149 }
1150 }
1151 }
1152 }/*psi_copy_ma_from_psi13*/
1153
1154 /*
1155 +------------------------------------------------------------------------------
1156 | Function : psi_process_si13()
1157 +------------------------------------------------------------------------------
1158 | Description : The function psi_process_si13()....
1159 |
1160 | Parameters : void
1161 |
1162 +------------------------------------------------------------------------------
1163 */
1164 GLOBAL T_SI13_RET psi_process_si13( T_D_SYS_INFO_13 *si13)
1165 {
1166 BOOL pbcch_was_present;
1167 T_SI13_RET ret_value = SI13_OK;
1168 #ifdef REL99
1169 UBYTE current_nw_rel = psc_db->network_rel;
1170 #endif
1171
1172 TRACE_FUNCTION( "psi_process_si13" );
1173
1174 if(!si13->si13_rest_oct.v_si13_info)
1175 {
1176 TRACE_ERROR( "No restoctects present in SI13: reread si13" );
1177 ret_value = SI13_REREAD;
1178 }
1179 else
1180 {
1181
1182 #ifdef REL99
1183 /* Update the BSS release when the 1st SI13 message is received in case of
1184 * PBCCH's PRESENCE.
1185 * The correct BSS release will be updated after receiving PSIs
1186 */
1187 if(si13->si13_rest_oct.si13_info.flag1)
1188 {
1189 /* PBCCH is present in the cell */
1190 /* This is the 1st SI13 message */
1191 if(psc_db->psi13_params.bcch_change_mark EQ NOT_SET)
1192 {
1193 /* Update the BSS and the SGSN releases */
1194 psi_update_bss_sgsn_rel(si13, PBCCH_PRESENT);
1195 }
1196 }
1197 else
1198 {
1199 /* Update the BSS and SGSN releases every time the SI13 message is received
1200 * in case of PBCCH's ABSENCE.
1201 */
1202 psi_update_bss_sgsn_rel(si13, PBCCH_NOT_PRESENT);
1203
1204 if(psc_db->network_rel NEQ current_nw_rel)
1205 {
1206 TRACE_EVENT_P2("((SI13)BSS Network release changed from %d to %d <0 - REL_97, 1 - REL_99, 2 - REL_04>",
1207 current_nw_rel, psc_db->network_rel);
1208 }
1209 }
1210 #endif
1211
1212 pbcch_was_present = grr_is_pbcch_present();
1213 /*
1214 * Copy PBCCH or non PBCCH desc. and change field
1215 */
1216 if( !pbcch_was_present AND si13->si13_rest_oct.si13_info.v_pbcch_des )
1217 {
1218 /* No PBCCH description was present in the GPRS_DATA_BASE or PBCCH was released:
1219 * SI13 message contains PBCCH description, so we have to start a complete acq of
1220 * PSI messages.
1221 */
1222 if(psc_db->psi13_params.bcch_change_mark EQ NOT_SET)
1223 {
1224 psi_copy_si13_params(si13);
1225 }
1226
1227 psc_db->psi13_params.bcch_change_mark = si13->si13_rest_oct.si13_info.bcch_cm;
1228 ret_value = SI13_COMPLETE_PSI;
1229 }
1230 else
1231 {
1232 psi_copy_si13_params(si13);
1233
1234 /*
1235 * There is no PBCCH description present in the SI13 message and there can be
1236 * no PBCCH description in the GPRS_DATA_BASE
1237 */
1238 if(psc_db->psi13_params.bcch_change_mark NEQ NOT_SET)
1239 {
1240 /*
1241 * This is not the first SI13 message.
1242 * Check BCCH_CHANGE_MARK
1243 */
1244 {
1245 UBYTE incremented_value =
1246
1247 psi_compare_change_mark
1248 (
1249 si13->si13_rest_oct.si13_info.bcch_cm,
1250 psc_db->psi13_params.bcch_change_mark
1251 );
1252
1253 if(incremented_value EQ 1) /*partial acq*/
1254 {
1255 if(psi_is_update_needed(si13->si13_rest_oct.si13_info.si_cf))
1256 {
1257 ret_value = SI13_PARTIAL_SI;
1258 }
1259 }
1260 else if(incremented_value > 1) /* incremented_value > 1: complete acq*/
1261 {
1262 ret_value = SI13_COMPLETE_SI;
1263 }
1264 }
1265 }
1266 psc_db->psi13_params.bcch_change_mark = si13->si13_rest_oct.si13_info.bcch_cm;
1267 }
1268 }
1269 psc_db->state_of_PSI[PSI13].state = RECEIPT_OK;
1270 grr_set_pg_nmo();
1271 TRACE_EVENT_P1("SI13 processed: %d", ret_value);
1272 return ret_value;
1273 } /* psi_process_si13() */
1274
1275 /*
1276 +------------------------------------------------------------------------------
1277 | Function : psi_process_psi13
1278 +------------------------------------------------------------------------------
1279 | Description : The function psi_process_psi13() ....
1280 |
1281 | Parameters : void
1282 |
1283 +------------------------------------------------------------------------------
1284 */
1285 GLOBAL T_PSI13_RET psi_process_psi13 ( T_PSI_13 * psi13 )
1286 {
1287 T_PSI13_RET ret_val = PSI13_OK;
1288
1289 TRACE_FUNCTION( "psi_process_psi13" );
1290
1291 if(grr_is_pbcch_present())
1292 {
1293 /*
1294 * PBCCH description already exists: we have to compare PBCCH parameters
1295 */
1296 if(psi_is_pbcch_des_different(psi13))
1297 {
1298 /*
1299 * PBCCH no longer available
1300 * or PBCCH description is differnt from the saved one in the MS
1301 */
1302 if(psi13->flag)
1303 {
1304 ret_val = PSI13_COMPLETE_PSI;
1305 }
1306 else
1307 {
1308 ret_val = PSI13_PBCCH_RELEASED;
1309 }
1310 }
1311 else
1312 {
1313 /*
1314 * PBCCH description is the same
1315 * Copy at least SI13_CHANGE_MARK and GPRS Mobile Allocation
1316 */
1317 psi_copy_psi13_params(psi13);
1318 #ifdef REL99
1319 /* PSI13 message has been received when PBCCH is present.
1320 * CBCH information may have to be updated if hopping is
1321 * allowed.
1322 */
1323 if(psc_db->v_cbch_chan_desc AND !psc_db->cbch_chan_desc.freq_par.v_arfcn)
1324 {
1325 sig_psi_ctrl_cbch_info_ind();
1326 }
1327 #endif
1328 /*
1329 * Check BCCH_CHANGE_MARK
1330 */
1331 {
1332 UBYTE incremented_value = psi_compare_change_mark(psi13->bcch_change_ma, psc_db->psi13_params.bcch_change_mark);
1333 psc_db->psi13_params.bcch_change_mark = psi13->bcch_change_ma;
1334
1335 if(incremented_value EQ 1) /*partial acq*/
1336 {
1337 if(psi_is_update_needed(psi13->si_change_ma))
1338 {
1339 ret_val = PSI13_PARTIAL_SI;
1340 }
1341 }
1342 else if(incremented_value > 1) /* incremented_value > 1: complete acq*/
1343 {
1344 ret_val = PSI13_COMPLETE_SI;
1345 }
1346 }
1347 }
1348 }
1349 else
1350 {
1351 /*
1352 * No PBCCH description present in the GPRS_DATA_BASE:
1353 * and we received a PSI13 in BCCH_TRANSFER state
1354 * So we have to check whether this message contains a
1355 * PBCCH description or not. If YES, complete acq. of PSI
1356 * messages should be started. If NO, BCCH_CHANGE_MARK should be compared
1357 */
1358 if(psi13->flag)
1359 {
1360 ret_val = PSI13_PBCCH_ESTABLISHED;
1361 }
1362 else
1363 {
1364 /*
1365 * Copy PBCCH or non PBCCH desc. and change field
1366 */
1367 psi_copy_psi13_params(psi13);
1368
1369 {
1370 UBYTE incremented_value = psi_compare_change_mark(psi13->bcch_change_ma, psc_db->psi13_params.bcch_change_mark);
1371 psc_db->psi13_params.bcch_change_mark = psi13->bcch_change_ma;
1372
1373 if(incremented_value EQ 1) /*partial acq*/
1374 {
1375 if(psi_is_update_needed(psi13->si_change_ma))
1376 {
1377 ret_val = PSI13_PARTIAL_SI;
1378 }
1379 }
1380 else if(incremented_value > 1) /* incremented_value > 1: complete acq*/
1381 {
1382 ret_val = PSI13_COMPLETE_SI;
1383 }
1384 }
1385 }
1386 }
1387
1388 #ifdef REL99
1389 /* Update the SGSN release */
1390 if (psi13->v_release_99_str_psi_13)
1391 {
1392 psc_db->sgsn_rel = psi13->release_99_str_psi_13.sgsnr ? PS_SGSN_99_ONWARDS : PS_SGSN_98_OLDER;
1393
1394 /* Update the SGSN release in the Common library context */
1395 cl_nwrl_set_sgsn_release(psc_db->sgsn_rel);
1396 }
1397 #endif
1398
1399 psc_db->state_of_PSI[PSI13].state = RECEIPT_OK;
1400
1401 grr_set_pg_nmo();
1402 return ret_val;
1403 } /* psi_process_psi13() */
1404
1405 /*
1406 +------------------------------------------------------------------------------
1407 | Function : psi_process_psi5
1408 +------------------------------------------------------------------------------
1409 | Description : The function psi_process_psi5() ....
1410 |
1411 | Parameters : T_PSI_5 *psi5
1412 |
1413 +------------------------------------------------------------------------------
1414 */
1415 GLOBAL T_PSI5_RET psi_process_psi5 (T_PSI_5 *psi5 )
1416 {
1417 BOOL is_psi5_ok;
1418 UBYTE n;
1419 BOOL cpy_prm_set;
1420
1421 TRACE_FUNCTION( "psi_process_psi5" );
1422
1423 /*
1424 * Check consistency
1425 */
1426 if(psc_db->psi5_params.psi5_change_mark EQ NOT_SET)
1427 {
1428 /*
1429 * Copy change mark etc.
1430 */
1431 psc_db->psi5_params.psi5_change_mark = psi5->psi5_cm;
1432 psc_db->psi5_params.psi5_count = psi5->psi5_cnt;
1433 psc_db->psi5_params.instances[0] = psi5->psi5_cnt;/* number of instances */
1434 }
1435 else
1436 {
1437 /*
1438 * There is a valid change mark present in the database
1439 * Check consistency of COUNT and INDEX
1440 */
1441 if(
1442 (psc_db->psi5_params.psi5_count NEQ psi5->psi5_cnt)
1443 OR
1444 (psc_db->psi5_params.psi5_count < psi5->psi5_ind)
1445 OR
1446 (psc_db->psi5_params.psi5_change_mark NEQ psi5->psi5_cm)
1447 )
1448 {
1449 /*
1450 * Error situation read a new PSI5
1451 * The PSI5 change mark field is changed each time information has been updated
1452 * A new value indicates that the mobile
1453 * station shall re-read the information from the PSI5
1454 */
1455
1456 TRACE_ERROR( "PSI5: inconsistent parameter" );
1457 psc_db->is_ext_psi5_valid = FALSE;
1458 return PSI5_REREAD;
1459 }
1460
1461 /* psi5_change_markhas not changed, i.e.
1462 * PSI5 message has not changed, we already have a consistent set, so we
1463 * do not have to read the PSI5 message
1464 */
1465 if((psc_db->psi5_params.psi5_change_mark EQ psi5->psi5_cm) &&
1466 (psc_db->state_of_PSI[PSI5].state EQ RECEIPT_OK))
1467 {
1468 /* Message has not changed, we already have a consistent set, so we
1469 * do not have to read it
1470 */
1471 TRACE_EVENT( "PSI5: message has not changed" );
1472 return PSI5_OK;
1473 }
1474 }
1475
1476 psc_db->psi5_params.psi5_index = psi5->psi5_ind;
1477
1478
1479 if( psc_db->psi5_params.instances[psi5->psi5_ind + 1] EQ FALSE )
1480 {
1481 if( grr_data->nc2_on )
1482 {
1483 if(
1484 psi5->v_nc_meas_par AND
1485 (
1486 psc_db->nc_cw.param.idx EQ NOT_SET OR
1487 psc_db->nc_cw.param.idx < psi5->psi5_ind
1488 )
1489 )
1490 {
1491 /*
1492 * This is the first time that we want to save network controlled
1493 * measurement parameters or the last index for NC parameters were
1494 * not bigger than the currently received one.
1495 *
1496 * Maybe more than one instance of PSI5, store data in temporary location.
1497 */
1498 grr_data->psi.v_nc_param = TRUE;
1499
1500 grr_prcs_nc_param_struct
1501 ( &grr_data->psi.nc_param, &psi5->nc_meas_par, psi5->psi5_ind );
1502 }
1503
1504 if( psi5->v_xmeas_par )
1505 {
1506 cpy_prm_set = ( psc_db->ext_psi5.idx EQ NOT_SET OR
1507 psc_db->ext_psi5.idx < psi5->psi5_ind );
1508
1509 grr_prcs_xmeas_struct ( &psc_db->ext_psi5,
1510 &psi5->xmeas_par,
1511 cpy_prm_set,
1512 psi5->psi5_ind,
1513 &psc_db->psi5_params.idx[psi5->psi5_ind].start,
1514 &psc_db->psi5_params.idx[psi5->psi5_ind].stop );
1515 }
1516
1517 #if defined (REL99) AND defined (TI_PS_FF_EMR)
1518 if(psi5->v_release_99_str_psi_5 AND psi5->release_99_str_psi_5.v_enh_rep_param_struct)
1519 {
1520 psc_db->psi5_params.v_enh_rep_param_struct = TRUE;
1521 grr_prcs_enh_param_cw_temp
1522 ( &grr_data->psi.enh_param, &psi5->release_99_str_psi_5.enh_rep_param_struct,
1523 psi5->psi5_ind );
1524 }
1525 #endif
1526 }
1527 /*
1528 * check whether PSI5 has been received completely or not
1529 */
1530 psc_db->psi5_params.instances[psi5->psi5_ind + 1] = TRUE;
1531 is_psi5_ok = TRUE;
1532 for(n = 0; n <= psc_db->psi5_params.instances[0]; n++ )
1533 {
1534 if(!(psc_db->psi5_params.instances[n + 1]))
1535 {
1536 is_psi5_ok = FALSE;/* consistent set of PSI5 not complete */
1537 break;
1538 }
1539 }
1540
1541 TRACE_EVENT_P2( "PSI5: received with count = %d, index = %d ",
1542 psi5->psi5_cnt, psi5->psi5_ind);
1543
1544 if(is_psi5_ok)
1545 {
1546 psc_db->state_of_PSI[PSI5].state = RECEIPT_OK;
1547
1548 /*
1549 * the NC parameter are stored temporarily and
1550 * now transferred to final location
1551 */
1552 if( grr_data->nc2_on )
1553 {
1554 grr_prcs_nc_param_final ( &psc_db->nc_cw.param,
1555 &grr_data->psi.v_nc_param,
1556 &grr_data->psi.nc_param );
1557
1558 grr_sort_ext_lst_freq ( &psc_db->ext_psi5.em1.list,
1559 MAX_NR_OF_INSTANCES_OF_PSI5,
1560 &psc_db->psi5_params.idx[0] );
1561
1562 #if defined (REL99) AND defined (TI_PS_FF_EMR)
1563 if(rr_get_support_for_emr() AND psc_db->psi5_params.v_enh_rep_param_struct)
1564 {
1565 /*
1566 * the ENH parameter are stored temporarily and
1567 * now transferred to final location
1568 */
1569 memcpy(&(psc_db->enh_cw), &(grr_data->psi.enh_param),
1570 sizeof(T_GRR_ENH_PARA));
1571 }
1572 else
1573 {
1574 memset(&(psc_db->enh_cw), 0, sizeof(T_GRR_ENH_PARA));
1575 psc_db->enh_cw.rept_type = REPORT_TYPE_REP;
1576 psc_db->psi5_params.v_enh_rep_param_struct = FALSE;
1577 }
1578 #endif
1579 /*
1580 * Inform MEAS that the Interference parameters are valid
1581 */
1582 psc_db->is_ext_psi5_valid = TRUE;
1583
1584 return PSI5_MEAS_PARAM_VALID;
1585 }
1586 }
1587 }
1588 else
1589 {
1590 TRACE_EVENT_P2( "PSI5: already received with count = %d, index = %d",
1591 psi5->psi5_cnt, psi5->psi5_ind );
1592 }
1593
1594 return PSI5_OK;
1595 } /* psi_process_psi5() */
1596
1597
1598
1599 /*
1600 +------------------------------------------------------------------------------
1601 | Function : psi_process_psi4
1602 +------------------------------------------------------------------------------
1603 | Description : The function psi_process_psi4() ....
1604 |
1605 | Parameters : T_PSI_4 *psi4
1606 |
1607 +------------------------------------------------------------------------------
1608 */
1609 GLOBAL T_PSI4_RET psi_process_psi4 (T_PSI_4 *psi4 )
1610 {
1611 UBYTE i,m,n;
1612 BOOL is_psi4_ok;
1613 TRACE_FUNCTION( "psi_process_psi4" );
1614
1615 /*
1616 * Check consistency
1617 */
1618 if(psc_db->psi4_params.psi4_change_mark EQ NOT_SET)
1619 {
1620 /*
1621 * Copy change mark etc.
1622 */
1623 psc_db->psi4_params.psi4_change_mark = psi4->psi4_cm;
1624 psc_db->psi4_params.psi4_count = psi4->psi4_cnt;
1625 psc_db->psi4_params.instances[0] = psi4->psi4_cnt;/* number of instances */
1626 }
1627 else
1628 {
1629 /*
1630 * There is a valid change mark present in the database
1631 * Check consistency of COUNT and INDEX
1632 */
1633 if(
1634 (psc_db->psi4_params.psi4_count NEQ psi4->psi4_cnt)
1635 OR
1636 (psc_db->psi4_params.psi4_count < psi4->psi4_ind)
1637 OR
1638 (psc_db->psi4_params.psi4_change_mark NEQ psi4->psi4_cm)
1639 )
1640 {
1641 /*
1642 * Error situation read a new PSI4
1643 * The PSI4 change mark field is changed each time information has been updated
1644 * A new value indicates that the mobile
1645 * station shall re-read the information from the PSI4
1646 */
1647 TRACE_ERROR( "PSI4: inconsistent parameters" );
1648 psc_db->number_of_valid_int_meas_channels = 0;
1649 return PSI4_REREAD;
1650 }
1651
1652 /* psi4_change_markhas not changed, i.e.
1653 * PSI4 message has not changed, we already have a consistent set, so we
1654 * do not have to read the PSI4 message
1655 */
1656 if((psc_db->psi4_params.psi4_change_mark EQ psi4->psi4_cm) &&
1657 (psc_db->state_of_PSI[PSI4].state EQ RECEIPT_OK))
1658 {
1659 /* Message has not changed, we already have a consistent set, so we
1660 * do not have to read it
1661 */
1662 TRACE_EVENT( "PSI4: message has not changed" );
1663 return PSI4_OK;
1664 }
1665 }
1666
1667 psc_db->psi4_params.psi4_index = psi4->psi4_ind;
1668
1669 if( psc_db->psi4_params.instances[psi4->psi4_ind + 1] EQ FALSE )
1670 {
1671 /*
1672 * We assume that we receive PSI4 instances in the right order,
1673 * i.e. instance1, instance2, instance3, ..., instance8
1674 * This is ETSI-Requirement 05.02
1675 */
1676 m = psc_db->number_of_valid_int_meas_channels;
1677 if(m < MAX_CHAN_IMEAS)
1678 {
1679 /*
1680 * copy first channel list in the current instance
1681 */
1682 psc_db->int_meas_chan_list[m].v_arfcn = FALSE;
1683 psc_db->int_meas_chan_list[m].v_ma_num_maio = FALSE;
1684
1685 if(psi4->chan_list_imeas.chan_group.v_arfcn)
1686 {
1687 psc_db->int_meas_chan_list[m].v_arfcn = TRUE; /* valid-flag for arfcn*/
1688 psc_db->int_meas_chan_list[m].arfcn = psi4->chan_list_imeas.chan_group.arfcn; /* ARFCN*/
1689 }
1690 else
1691 {
1692 psc_db->int_meas_chan_list[m].v_ma_num_maio = TRUE;
1693 psc_db->int_meas_chan_list[m].ma_num = psi4->chan_list_imeas.chan_group.ma_num_maio.ma_num;
1694 psc_db->int_meas_chan_list[m].maio = psi4->chan_list_imeas.chan_group.ma_num_maio.maio;
1695 }
1696
1697 psc_db->int_meas_chan_list[m].ts_alloc = psi4->chan_list_imeas.chan_group.ts_alloc;
1698
1699 m++;
1700 if(psi4->chan_list_imeas.v_chan_list2)
1701 {
1702 for(i=0; i < (psi4->chan_list_imeas.c_chan_list2) AND (m < MAX_CHAN_IMEAS); i++ )
1703 {
1704 /*
1705 * copy remaining channel list in the current instance
1706 */
1707 psc_db->int_meas_chan_list[m].v_arfcn = FALSE;
1708 psc_db->int_meas_chan_list[m].v_ma_num_maio = FALSE;
1709
1710 if(psi4->chan_list_imeas.chan_list2[i].chan_group.v_arfcn)
1711 {
1712 psc_db->int_meas_chan_list[m].v_arfcn = TRUE; /* valid-flag for arfcn*/
1713 psc_db->int_meas_chan_list[m].arfcn = psi4->chan_list_imeas.chan_list2[i].chan_group.arfcn; /* ARFCN*/
1714 }
1715 else
1716 {
1717 psc_db->int_meas_chan_list[m].v_ma_num_maio = TRUE;
1718 psc_db->int_meas_chan_list[m].ma_num = psi4->chan_list_imeas.chan_list2[i].chan_group.ma_num_maio.ma_num;
1719 psc_db->int_meas_chan_list[m].maio = psi4->chan_list_imeas.chan_list2[i].chan_group.ma_num_maio.maio;
1720 }
1721 psc_db->int_meas_chan_list[m].ts_alloc = psi4->chan_list_imeas.chan_list2[i].chan_group.ts_alloc;
1722 m++;
1723 }
1724 }
1725 }
1726 else
1727 {
1728 TRACE_ERROR( "PSI4: list of INT meas. channels full" );
1729 }
1730 psc_db->number_of_valid_int_meas_channels = m;
1731
1732 /*
1733 * check whether PSI4 has been received completely or not
1734 */
1735 psc_db->psi4_params.instances[psi4->psi4_ind + 1] = TRUE;
1736 is_psi4_ok = TRUE;
1737 for(n = 0; n <= psc_db->psi4_params.instances[0]; n++ )
1738 {
1739 if(!(psc_db->psi4_params.instances[n + 1]))
1740 {
1741 is_psi4_ok = FALSE;/* consistent set of PSI4 not complete */
1742 break;
1743 }
1744 }
1745
1746 TRACE_EVENT_P2( "PSI4: received with count = %d, index = %d",
1747 psi4->psi4_cnt, psi4->psi4_ind );
1748
1749 if(is_psi4_ok)
1750 {
1751 psc_db->state_of_PSI[PSI4].state = RECEIPT_OK;
1752 return PSI4_INT_LIST_VALID;
1753 }
1754 }
1755 else
1756 {
1757 TRACE_EVENT_P2( "PSI4: already received with count = %d, index = %d",
1758 psi4->psi4_cnt, psi4->psi4_ind );
1759 }
1760
1761
1762
1763 return PSI4_OK;
1764
1765 } /* psi_process_psi4() */
1766
1767 #if defined (REL99) AND defined (TI_PS_FF_EMR)
1768 /*
1769 +------------------------------------------------------------------------------
1770 | Function : psi_process_psi3ter
1771 +------------------------------------------------------------------------------
1772 | Description : The function psi_process_psi3ter() processes the IEs received
1773 | in PSI3 ter message
1774 |
1775 | Parameters : T_PSI_3_TER *psi3ter
1776 |
1777 +------------------------------------------------------------------------------
1778 */
1779 GLOBAL T_PSI3TER_RET psi_process_psi3ter (T_PSI_3_TER *psi3ter)
1780 {
1781 BOOL is_psi3ter_ok;
1782 #ifdef TI_PS_FF_RTD
1783 UBYTE n,rtd_index;
1784 #else
1785 UBYTE n;
1786 #endif /* #ifdef TI_PS_FF_RTD */
1787
1788
1789 TRACE_FUNCTION( "psi_process_psi3ter" );
1790
1791 if(psc_db->psi3ter_params.psi3ter_change_mark EQ NOT_SET)
1792 {
1793 if( ( (psc_db->psi3_params.psi3_change_mark NEQ NOT_SET) AND
1794 (psi3ter->psi3_cm NEQ psc_db->psi3_params.psi3_change_mark) ) OR
1795 ( (psc_db->psi3bis_params.psi3bis_change_mark NEQ NOT_SET) AND
1796 (psi3ter->psi3_cm NEQ psc_db->psi3bis_params.psi3bis_change_mark) ) )
1797 {
1798 /*
1799 * Error situation read new PSI3ter
1800 * The PSI3 change mark field is changed each time information has been updated
1801 * in any of the PSI3 to PSI3 ter messages. A new value indicates that the mobile
1802 * station shall re-read the information from the PSI3 to PSI3 ter messages.
1803 */
1804 TRACE_ERROR( "PSI3ter: inconsistent change mark, read PSI3 to PSI3ter");
1805 return PSI3TER_REREAD_PSI3_3BIS_3TER;
1806 }
1807
1808 /*
1809 * Copy change mark etc.
1810 */
1811 psc_db->psi3ter_params.psi3ter_change_mark = psi3ter->psi3_cm;
1812 psc_db->psi3ter_params.psi3ter_count = psi3ter->psi3ter_cnt;
1813 psc_db->psi3ter_params.instances[0] = psi3ter->psi3ter_cnt; /* number of instances */
1814 }
1815 else
1816 /*
1817 * There is a valid change mark present in the database
1818 * Check consistency of COUNT and INDEX
1819 */
1820 {
1821 if( (psc_db->psi3ter_params.psi3ter_change_mark NEQ psi3ter->psi3_cm) OR
1822 ( (psc_db->psi3_params.psi3_change_mark NEQ NOT_SET) AND
1823 (psc_db->psi3ter_params.psi3ter_change_mark NEQ
1824 psc_db->psi3_params.psi3_change_mark) ) OR
1825 ( (psc_db->psi3bis_params.psi3bis_change_mark NEQ NOT_SET) AND
1826 (psc_db->psi3ter_params.psi3ter_change_mark NEQ
1827 psc_db->psi3bis_params.psi3bis_change_mark) ) )
1828 {
1829 /*
1830 * Error situation read new PSI3ter
1831 * The PSI3 change mark field is changed each time information has been updated
1832 * in any of the PSI3 to PSI3 ter messages. A new value indicates that the mobile
1833 * station shall re-read the information from the PSI3 to PSI3 ter messages.
1834 */
1835 TRACE_ERROR( "PSI3ter: inconsistent change mark, read PSI3 to PSI3ter");
1836 return PSI3TER_REREAD_PSI3_3BIS_3TER;
1837 }
1838 if( (psc_db->psi3ter_params.psi3ter_count NEQ psi3ter->psi3ter_cnt) OR
1839 (psc_db->psi3ter_params.psi3ter_count < psi3ter->psi3ter_ind) )
1840 {
1841 TRACE_ERROR( "PSI3ter: inconsistent parameters, read PSI3ter");
1842 return PSI3TER_REREAD_PSI3TER;
1843 }
1844
1845 if((psc_db->psi3ter_params.psi3ter_change_mark EQ psi3ter->psi3_cm) AND
1846 (psc_db->state_of_PSI[PSI3ter].state EQ RECEIPT_OK))
1847 {
1848 /* Message has not changed, we already have a consistent set, so we
1849 * do not have to read it
1850 */
1851 TRACE_EVENT("PSI3ter: message has not changed");
1852 return PSI3TER_OK;
1853 }
1854 } /* psi3ter_change_mark valid */
1855
1856 psc_db->psi3ter_params.psi3ter_index = psi3ter->psi3ter_ind;
1857
1858 if( psc_db->psi3ter_params.instances[psi3ter->psi3ter_ind + 1] EQ FALSE )
1859 {
1860 /*
1861 * Copy GPRS report priority parameters
1862 */
1863 /* GPRS Report priority can be received in only one instance since start
1864 index is not given for mapping to BA as in RTD and BSIC mapping in SI */
1865 if( (psi3ter->rtd_rep_prio_trnc_grp.v_gprs_rep_prio_cell_desc EQ TRUE) AND
1866 (psi3ter->rtd_rep_prio_trnc_grp.gprs_rep_prio_cell_desc.number_cells NEQ 0) )
1867 {
1868 if(psi3ter->rtd_rep_prio_trnc_grp.gprs_rep_prio_cell_desc.number_cells > MAX_NR_OF_GSM_NC)
1869 {
1870 grr_data->psi.enh_param.gprs_rept_prio_desc.num_cells =
1871 MAX_NR_OF_GSM_NC;
1872 }
1873 else
1874 {
1875 grr_data->psi.enh_param.gprs_rept_prio_desc.num_cells =
1876 psi3ter->rtd_rep_prio_trnc_grp.gprs_rep_prio_cell_desc.number_cells;
1877
1878 /* Set default report prio for the remaining cells upto max of 96 cells */
1879 for(n = psi3ter->rtd_rep_prio_trnc_grp.gprs_rep_prio_cell_desc.number_cells;
1880 n < MAX_NR_OF_GSM_NC; n++)
1881 {
1882 grr_data->psi.enh_param.gprs_rept_prio_desc.rept_prio[n] =
1883 NORMAL_PRIO;
1884 }
1885 }
1886
1887 for (n = 0; n < grr_data->psi.enh_param.gprs_rept_prio_desc.num_cells; n++)
1888 {
1889 grr_data->psi.enh_param.gprs_rept_prio_desc.rept_prio[n] =
1890 psi3ter->rtd_rep_prio_trnc_grp.gprs_rep_prio_cell_desc.rep_prio[n];
1891 }
1892 }
1893
1894 #ifdef TI_PS_FF_RTD
1895 /* Store the received RTD values into the temporary location */
1896 if(psi3ter->rtd_rep_prio_trnc_grp.v_real_time_diff EQ TRUE)
1897 {
1898 if(psi3ter->rtd_rep_prio_trnc_grp.real_time_diff.v_rtd_struct_6bit EQ TRUE)
1899 {
1900 if(psi3ter->rtd_rep_prio_trnc_grp.real_time_diff.rtd_struct_6bit.v_cell_index_start_rtd EQ TRUE)
1901 rtd_index = psi3ter->rtd_rep_prio_trnc_grp.real_time_diff.rtd_struct_6bit.cell_index_start_rtd;
1902 else
1903 rtd_index = RTD_DEFAULT_INDEX;
1904 if( rtd_index < MAX_NR_OF_NCELL )
1905 {
1906 grr_data->psi.rtd[rtd_index] = psi3ter->rtd_rep_prio_trnc_grp.real_time_diff.rtd_struct_6bit.rtd6_struct.rtd_6bit;
1907 for(n=0;n<psi3ter->rtd_rep_prio_trnc_grp.real_time_diff.rtd_struct_6bit.c_rtd6_struct_opt_array AND rtd_index < MAX_NR_OF_NCELL - 1;n++)
1908 {
1909 rtd_index++;
1910 grr_data->psi.rtd[rtd_index] = psi3ter->rtd_rep_prio_trnc_grp.real_time_diff.rtd_struct_6bit.rtd6_struct_opt_array[n].rtd_6bit;
1911 } /*for*/
1912 } /*if*/
1913 } /*if*/
1914 if(psi3ter->rtd_rep_prio_trnc_grp.real_time_diff.v_rtd_struct_12bit EQ TRUE)
1915 {
1916 if(psi3ter->rtd_rep_prio_trnc_grp.real_time_diff.rtd_struct_12bit.v_cell_index_start_rtd EQ TRUE)
1917 rtd_index = psi3ter->rtd_rep_prio_trnc_grp.real_time_diff.rtd_struct_12bit.cell_index_start_rtd;
1918 else
1919 rtd_index = RTD_DEFAULT_INDEX;
1920 if( rtd_index < MAX_NR_OF_NCELL )
1921 {
1922 grr_data->psi.rtd[rtd_index] = RTD_12BIT;
1923 grr_data->psi.rtd[rtd_index] |= psi3ter->rtd_rep_prio_trnc_grp.real_time_diff.rtd_struct_12bit.rtd12_struct.rtd_12bit;
1924 for(n=0;n<psi3ter->rtd_rep_prio_trnc_grp.real_time_diff.rtd_struct_12bit.c_rtd12_struct_opt_array AND rtd_index < MAX_NR_OF_NCELL - 1;n++)
1925 {
1926 rtd_index++;
1927 grr_data->psi.rtd[rtd_index] = RTD_12BIT;
1928 grr_data->psi.rtd[rtd_index] |= psi3ter->rtd_rep_prio_trnc_grp.real_time_diff.rtd_struct_12bit.rtd12_struct_opt_array[n].rtd_12bit;
1929 } /*for*/
1930 }/*if*/
1931 } /*if*/
1932 } /*if*/
1933 #endif /* #ifdef TI_PS_FF_RTD */
1934
1935 TRACE_EVENT_P2( "PSI3ter: received with count = %d, index = %d",
1936 psi3ter->psi3ter_cnt, psi3ter->psi3ter_ind );
1937
1938 /*
1939 * check whether PSI3TER has been received completely or not
1940 */
1941 psc_db->psi3ter_params.instances[psi3ter->psi3ter_ind + 1] = TRUE;
1942 psc_db->psi3ter_params.prev_psi3ter_index =
1943 psc_db->psi3ter_params.psi3ter_index;
1944
1945 is_psi3ter_ok = TRUE;
1946 for(n = 0; n <= psc_db->psi3ter_params.instances[0]; n++ )
1947 {
1948 if(!(psc_db->psi3ter_params.instances[n + 1]))
1949 {
1950 is_psi3ter_ok = FALSE;/* consistent set of PSI3TER not complete */
1951 break;
1952 }
1953 }
1954
1955 if(is_psi3ter_ok)
1956 {
1957 psc_db->state_of_PSI[PSI3ter].state = RECEIPT_OK;
1958
1959 /* Copy the GPRS priority information to permanent storage */
1960 if(grr_data->psi.enh_param.gprs_rept_prio_desc.num_cells NEQ 0)
1961 {
1962 for(n = 0; n <= grr_data->psi.enh_param.gprs_rept_prio_desc.num_cells; n++)
1963 {
1964 psc_db->enh_cw.gprs_rept_prio_desc.rept_prio[n] =
1965 grr_data->psi.enh_param.gprs_rept_prio_desc.rept_prio[n];
1966 }
1967 /* Initialize to 0 before receiving the next consistent set of PSI3 ter */
1968 grr_data->psi.enh_param.gprs_rept_prio_desc.num_cells = 0;
1969 }
1970 else
1971 {
1972 /* Set report priority to NORMAL if not received */
1973 for(n = 0; n < MAX_NR_OF_GSM_NC; n++)
1974 {
1975 psc_db->enh_cw.gprs_rept_prio_desc.rept_prio[n] = NORMAL_PRIO;
1976 }
1977 }
1978 #ifdef TI_PS_FF_RTD
1979 /* store the RTD values received in all instances of PSI3ter in permanent location */
1980 memcpy(&psc_db->rtd,&grr_data->psi.rtd,MAX_NR_OF_NCELL*sizeof(T_RTD_VALUE));
1981 /* reset the temporary storage to RTD value not available */
1982 for( n = 0; n < MAX_NR_OF_NCELL; n++ )
1983 grr_data->psi.rtd[n] = RTD_NOT_AVAILABLE;
1984 #endif /* #ifdef TI_PS_FF_RTD */
1985 return PSI3TER_OK;
1986
1987 }
1988 }
1989 else
1990 {
1991 TRACE_EVENT_P2( "PSI3ter: already received with count = %d, index = %d",
1992 psi3ter->psi3ter_cnt, psi3ter->psi3ter_ind );
1993 }
1994
1995 return PSI3TER_OK;
1996 } /* psi_process_psi3ter() */
1997 #endif
1998
1999
2000 /*
2001 +------------------------------------------------------------------------------
2002 | Function : psi_process_psi3bis
2003 +------------------------------------------------------------------------------
2004 | Description : The function psi_process_psi3bis() ....
2005 |
2006 | Parameters : T_PSI_3_BIS *psi3bis
2007 |
2008 +------------------------------------------------------------------------------
2009 */
2010 GLOBAL T_PSI3BIS_RET psi_process_psi3bis (T_PSI_3_BIS *psi3bis)
2011 {
2012 BOOL is_psi3bis_ok;
2013 UBYTE n;
2014
2015 TRACE_FUNCTION( "psi_process_psi3bis" );
2016
2017 /*
2018 * Each neighbour cell listed in PSI3 and in one or more instances
2019 * of PSI3bis is assigned an ascending index used for measurement reports.
2020 * The first neighbour cell in PSI3 has the lowest index (= 0),
2021 * and the last neighbour cell in the highest indexed PSI3bis message has
2022 * the highest index. The total number of neighbour cells in the BA-GPRS
2023 * shall not exceed 32.
2024 * If a mobile station receives more than 32 cells in the BA-GPRS,
2025 * only the 32 cells with the lowest indexes shall be considered.
2026 */
2027
2028 if(psc_db->psi3bis_params.psi3bis_change_mark EQ NOT_SET)
2029 {
2030 /*
2031 * Copy change mark etc.
2032 */
2033 psc_db->psi3bis_params.psi3bis_change_mark = psi3bis->psi3_cm;
2034 psc_db->psi3bis_params.psi3bis_count = psi3bis->psi3bis_cnt;
2035 psc_db->psi3bis_params.instances[0] = psi3bis->psi3bis_cnt; /* number of instances */
2036 }
2037 else
2038 {
2039 /*
2040 * There is a valid change mark present in the database
2041 * Check consistency of COUNT and INDEX
2042 */
2043 if(
2044 (psc_db->psi3bis_params.psi3bis_count NEQ psi3bis->psi3bis_cnt)
2045 OR
2046 (psc_db->psi3bis_params.psi3bis_count < psi3bis->psi3bis_ind)
2047 OR
2048 (psc_db->psi3bis_params.psi3bis_change_mark NEQ psi3bis->psi3_cm)
2049 )
2050 {
2051 /*
2052 * Error situation read a new PSI3bis
2053 * The PSI3 change mark field is changed each time information has been updated
2054 * in any of the PSI3 or PSI3 bis messages. A new value indicates that the mobile
2055 * station shall re-read the information from the PSI3 and all PSI3 bis messages.
2056 */
2057 #if defined (REL99) AND defined (TI_PS_FF_EMR)
2058 TRACE_ERROR( "PSI3bis: inconsistent parameters, read PSI3 PSI3bis and PSI3ter");
2059
2060 return PSI3BIS_REREAD_PSI3_3BIS_3TER;
2061 #else
2062 TRACE_ERROR( "PSI3bis: inconsistent parameters, read PSI3 and PSI3bis");
2063
2064 return PSI3BIS_REREAD_PSI3_3BIS;
2065 #endif
2066 }
2067
2068 if((psc_db->psi3bis_params.psi3bis_change_mark EQ psi3bis->psi3_cm) &&
2069 (psc_db->state_of_PSI[PSI3bis].state EQ RECEIPT_OK))
2070 {
2071 /* Message has not changed, we already have a consistent set, so we
2072 * do not have to read it
2073 */
2074 TRACE_EVENT("PSI3bis: message has not changed");
2075 return PSI3BIS_OK;
2076 }
2077 else if(psc_db->psi3bis_params.psi3bis_change_mark NEQ psi3bis->psi3_cm)
2078 {
2079 TRACE_ERROR("PSI3bis: message has changed");
2080 return PSI3BIS_REREAD_PSI3BIS;
2081 }
2082
2083 } /* psi3bis_change_mark valid */
2084
2085 psc_db->psi3bis_params.psi3bis_index = psi3bis->psi3bis_ind;
2086
2087 if( psc_db->psi3bis_params.instances[psi3bis->psi3bis_ind + 1] EQ FALSE )
2088 {
2089 UBYTE number;
2090
2091 /*
2092 * Copy NCELL parameters
2093 */
2094 number =
2095 psi_store_ncell_param( &psi3bis->ncell_par_trnc_grp.ncell_par[0],
2096 psi3bis->ncell_par_trnc_grp.c_ncell_par,
2097 psi3bis->ncell_par_trnc_grp.v_ncell_par,
2098 INFO_TYPE_PSI3BIS,
2099 psi3bis->psi3bis_ind );
2100
2101 /*
2102 * Copy NCELL parameters 2
2103 */
2104 psi_store_ncell_param2( psi3bis, number );
2105
2106 TRACE_EVENT_P2( "PSI3bis: received with count = %d, index = %d",
2107 psi3bis->psi3bis_cnt, psi3bis->psi3bis_ind );
2108
2109 /*
2110 * check whether PSI3BIS has been received completely or not
2111 */
2112 psc_db->psi3bis_params.instances[psi3bis->psi3bis_ind + 1] = TRUE;
2113 is_psi3bis_ok = TRUE;
2114 for(n = 0; n <= psc_db->psi3bis_params.instances[0]; n++ )
2115 {
2116 if(!(psc_db->psi3bis_params.instances[n + 1]))
2117 {
2118 is_psi3bis_ok = FALSE;/* consistent set of PSI3BIS not complete */
2119 break;
2120 }
2121 }
2122
2123 if(is_psi3bis_ok)
2124 {
2125 psc_db->state_of_PSI[PSI3bis].state = RECEIPT_OK;
2126
2127 if( psc_db->state_of_PSI[PSI3].state EQ RECEIPT_OK )
2128 {
2129 psi_restore_ncell_param( );
2130
2131 return PSI3BIS_NCELL_VALID;
2132 }
2133 else
2134 {
2135 return PSI3BIS_OK;
2136 }
2137 }
2138 }
2139 else
2140 {
2141 TRACE_EVENT_P2( "PSI3bis: already received with count = %d, index = %d",
2142 psi3bis->psi3bis_cnt, psi3bis->psi3bis_ind );
2143 }
2144
2145
2146 return PSI3BIS_OK;
2147 } /* psi_process_psi3bis() */
2148
2149 /*
2150 +------------------------------------------------------------------------------
2151 | Function : psi_process_psi3
2152 +------------------------------------------------------------------------------
2153 | Description : The function psi_process_psi3() ....
2154 |
2155 | Parameters : T_PSI_3 *psi3
2156 |
2157 +------------------------------------------------------------------------------
2158 */
2159 GLOBAL T_PSI3_RET psi_process_psi3 (T_PSI_3 *psi3 )
2160 {
2161 T_PSI3_RET return_val = PSI3_OK;
2162
2163 TRACE_FUNCTION( "psi_process_psi3" );
2164
2165 /*
2166 * Check whether the cell has been barred or not. If YES, inform CTRL
2167 */
2168 if(psi3->scell_par.cell_ba)
2169 {
2170 /*Barred*/
2171 TRACE_EVENT( "PSI3: cell barred" );
2172
2173 GRR_EM_SET_CELL_BARRED;
2174
2175 return PSI3_CELL_BARRED;
2176 }
2177
2178 psc_db->state_of_PSI[PSI3].state = RECEIPT_OK;
2179
2180 if(psc_db->psi3_params.psi3_change_mark NEQ NOT_SET)
2181 {
2182 /* compare change mark*/
2183 if(psc_db->psi3_params.psi3_change_mark EQ psi3->psi3_cm)
2184 {
2185 /*
2186 * Information of the PSI3 PSI3ter messages have NOT been updated: return!!
2187 */
2188 TRACE_EVENT( "PSI3: messages PSI3 and PSI3bis have not changed" );
2189 return PSI3_OK;
2190 }
2191 /*
2192 * Information of the PSI3 message has been updated, so we have to re-read the parameters
2193 *
2194 * A new value indicates that the mobile station shall re-read the information from
2195 * the PSI3 - PSI3ter messages.
2196 */
2197 /*
2198 * Set the change mark parameter of psi3bis to NOT_SET. This causes that the PSI3BIS and
2199 * PSI3 ter instances to be read again
2200 */
2201 psc_db->psi3bis_params.psi3bis_change_mark = NOT_SET;
2202 psc_db->state_of_PSI[PSI3bis].state = NEEDED;
2203 #if defined (REL99) AND defined (TI_PS_FF_EMR)
2204 psc_db->psi3ter_params.psi3ter_change_mark = NOT_SET;
2205
2206 if(psc_db->v_add_psi AND psc_db->add_psi.psi3ter_broadcast)
2207 {
2208 psc_db->state_of_PSI[PSI3ter].state = NEEDED;
2209 }
2210 else
2211 {
2212 psc_db->state_of_PSI[PSI3ter].state = NOT_SEND;
2213 }
2214 #endif
2215
2216 /*
2217 * Set the consistent set parameters to FALSE
2218 */
2219 psi_reset_psi3bis();
2220 #if defined (REL99) AND defined (TI_PS_FF_EMR)
2221 psi_reset_psi3ter();
2222 #endif
2223
2224 /* This field is coded as the binary representation of the PSI3 bis index
2225 * (in the PSI3 bis message) for the last (highest indexed) individual PSI3
2226 * bis message.Range: 0-15.
2227 */
2228 psc_db->psi3_params.psi3_bis_count = psi3->psi3bis_cnt;
2229 /*
2230 * Ncell parameter are invalid. We have to inform MEAS-Service
2231 */
2232 return_val = PSI3_NCELL_INVALID;
2233 }
2234 else
2235 {
2236 /* This is the first time that we have received a PSI3 message*/
2237 psc_db->psi3_params.psi3_change_mark = psi3->psi3_cm;
2238 psc_db->psi3_params.psi3_bis_count = psi3->psi3bis_cnt;
2239 }
2240
2241 /* copy Serving Cell parameters */
2242 psc_db->scell_par.cell_ba = psi3->scell_par.cell_ba;
2243 psc_db->scell_par.exc_acc = psi3->scell_par.exc_acc;
2244 psc_db->scell_par.cr_par_1.cr_pow_par.gprs_rxlev_access_min
2245 = psi3->scell_par.gprs_rxlev_access_min;
2246 psc_db->scell_par.cr_par_1.cr_pow_par.gprs_ms_txpwr_max_cch
2247 = psi3->scell_par.txpwr_max_cch;
2248 grr_data->meas.pwr_offset = 0;
2249
2250 psc_db->scell_par.cr_par_1.v_hcs_par = psi3->scell_par.v_hcs_par;
2251 psc_db->scell_par.cr_par_1.hcs_par = psi3->scell_par.hcs_par;
2252 psc_db->scell_par.multi_band_rep = psi3->scell_par.multi_band_rep;
2253
2254 /*copy General Cell Selection parameter */
2255 memcpy(&(psc_db->gen_cell_par), &(psi3->gen_cell_par),sizeof(T_gen_cell_par));
2256
2257 /* process default values for General Cell Selection parameter */
2258 if( psc_db->gen_cell_par.v_t_resel EQ FALSE )
2259 {
2260 psc_db->gen_cell_par.v_t_resel = TRUE;
2261 psc_db->gen_cell_par.t_resel = GRR_T_RESEL_DEFAULT;
2262 }
2263
2264 if( psc_db->gen_cell_par.v_ra_re_hyst EQ FALSE )
2265 {
2266 psc_db->gen_cell_par.v_ra_re_hyst = TRUE;
2267 psc_db->gen_cell_par.ra_re_hyst = psc_db->gen_cell_par.gprs_c_hyst;
2268 }
2269
2270 /* copy Neighbor cell parameters*/
2271 psi_store_ncell_param( &psi3->ncell_par[0], psi3->c_ncell_par,
2272 psi3->v_ncell_par, INFO_TYPE_PSI3, 0 );
2273
2274 if( psc_db->state_of_PSI[PSI3].state EQ RECEIPT_OK AND
2275 psc_db->state_of_PSI[PSI3bis].state EQ RECEIPT_OK )
2276 {
2277 psi_restore_ncell_param( );
2278
2279 return_val = PSI3_NCELL_VALID;
2280 }
2281
2282 TRACE_EVENT_P1( "PSI3: received with return value %d", return_val );
2283
2284 grr_data->pwr_ctrl_valid_flags.v_glbl_pwr_ctrl_param = TRUE;
2285
2286 return return_val;
2287 } /* psi_process_psi3() */
2288
2289 /*
2290 +------------------------------------------------------------------------------
2291 | Function : psi_copy_rfl
2292 +------------------------------------------------------------------------------
2293 | Description : The function psi_copy_rfl() .... copy Reference Frequency List (RFL)
2294 |
2295 | Parameters : T_PSI_2 *psi2: pointer to PSI2 message
2296 |
2297 +------------------------------------------------------------------------------
2298 */
2299
2300 LOCAL void psi_copy_rfl(T_PSI_2 *psi2)
2301 {
2302
2303 UBYTE m, n;
2304 TRACE_FUNCTION( "psi_copy_rfl" );
2305
2306 for(m = 0; m < psi2->psi_2_trnc_grp.c_rfl; m++)
2307 {
2308 for(n = 0; n < MAX_RFL; n++)
2309 {
2310 if( (psi2->psi_2_trnc_grp.rfl[m].rfl_num EQ psc_db->rfl[n].num) OR (psc_db->rfl[n].num EQ NOT_SET) )
2311 {
2312 psc_db->rfl[n].num = psi2->psi_2_trnc_grp.rfl[m].rfl_num;
2313 /*
2314 * This function copies the frequencies into list. This function takes the arranging
2315 * of ARFCN into account cf. 12.10a GPRS Mobile Allocation in 04.60
2316 */
2317 grr_create_channel_list (&psi2->psi_2_trnc_grp.rfl[m], psc_db->rfl[n].list);
2318 /*
2319 * Exit from the for loop
2320 */
2321 n = MAX_RFL;
2322 }
2323 }
2324 }
2325
2326 }/* psi_copy_rfl*/
2327
2328 /*
2329 +------------------------------------------------------------------------------
2330 | Function : psi_copy_ma_from_psi2
2331 +------------------------------------------------------------------------------
2332 | Description : The function psi_copy_ma_from_psi2() .... copy GPRS Mobile Allocation (MA)
2333 |
2334 | Parameters : T_PSI_2 *psi2: pointer to PSI2 message
2335 |
2336 +------------------------------------------------------------------------------
2337 */
2338 LOCAL void psi_copy_ma_from_psi2(T_PSI_2 *psi2)
2339 {
2340 UBYTE m, n, copiedElements = 0;
2341 TRACE_FUNCTION( "psi_copy_ma_from_psi2" );
2342
2343 for(m = 0; m < psi2->psi_2_trnc_grp.c_gprs_ms_alloc; m++)
2344 {
2345 if((psi2->psi_2_trnc_grp.gprs_ms_alloc[m].ma_num != MA_NUMBER_4_PSI13_OR_CELL_ALLOC ) && /* ignore MA_NUMBER with 14 or 15: 0..13 in PSI2*/
2346 (psi2->psi_2_trnc_grp.gprs_ms_alloc[m].ma_num != MA_NUMBER_4_ASSIGNMENT ))
2347 {
2348 for(n = 0; n < MAX_GPRS_MS_ALLOC; n++)
2349 {
2350 if( (psi2->psi_2_trnc_grp.gprs_ms_alloc[m].ma_num EQ psc_db->gprs_ms_alloc_in_psi2_psi13[n].ma_num) ||
2351 (psc_db->gprs_ms_alloc_in_psi2_psi13[n].ma_num EQ NOT_SET) )
2352 {
2353 psc_db->gprs_ms_alloc_in_psi2_psi13[n].ma_num = psi2->psi_2_trnc_grp.gprs_ms_alloc[m].ma_num;
2354 memcpy(&(psc_db->gprs_ms_alloc_in_psi2_psi13[n].gprs_ms_alloc_ie),
2355 &(psi2->psi_2_trnc_grp.gprs_ms_alloc[m].gprs_ms_alloc_ie),
2356 sizeof(T_gprs_ms_alloc_ie));
2357 n = MAX_GPRS_MS_ALLOC; /* to break the for loop*/
2358 copiedElements++; /* for debug*/
2359 }
2360 }
2361 }
2362 }
2363
2364 if(copiedElements < psi2->psi_2_trnc_grp.c_gprs_ms_alloc)
2365 {
2366 TRACE_ERROR("copiedElements < psi2->c_gprs_ms_alloc in" );
2367 }
2368 }/* psi_copy_ma_from_psi2*/
2369
2370 /*
2371 +------------------------------------------------------------------------------
2372 | Function : psi_copy_ca
2373 +------------------------------------------------------------------------------
2374 | Description : The function psi_copy_ca() .... copy Cell Allocation (CA)
2375 |
2376 | Parameters : T_PSI_2 *psi2: pointer to PSI2 message
2377 |
2378 +------------------------------------------------------------------------------
2379 */
2380 LOCAL void psi_copy_ca(T_PSI_2 *psi2)
2381 {
2382 UBYTE m,n;
2383 TRACE_FUNCTION( "psi_copy_ca" );
2384 /*TRACE_EVENT("psi_copy_ca");
2385 TRACE_EVENT_P1("c_ca: %d", psi2->c_cell_alloc);
2386 */
2387 for(m = 0; m < psi2->psi_2_trnc_grp.c_cell_alloc; m++)
2388 {
2389 for(n = 0; n < MAX_CELL_ALLOC; n++)
2390 {
2391 if( (psi2->psi_2_trnc_grp.cell_alloc[m].rfl_num EQ psc_db->cell_alloc[n].rfl_num)
2392 || (psc_db->cell_alloc[n].rfl_num EQ NOT_SET) )
2393 {
2394 psc_db->cell_alloc[n].rfl_num = psi2->psi_2_trnc_grp.cell_alloc[m].rfl_num;
2395 n = MAX_CELL_ALLOC;
2396 }
2397 }
2398 psc_db->v_cell_alloc = TRUE;
2399 }
2400 }/* psi_copy_ca*/
2401
2402 /*
2403 +------------------------------------------------------------------------------
2404 | Function : psi_copy_pccch
2405 +------------------------------------------------------------------------------
2406 | Description : The function psi_copy_pccch() .... copy PCCCH Description
2407 |
2408 | Parameters : T_PSI_2 *psi2: pointer to PSI2 message
2409 |
2410 +------------------------------------------------------------------------------
2411 */
2412 LOCAL void psi_copy_pccch(T_PSI_2 *psi2)
2413 {
2414 UBYTE m, n, i, ii, j;
2415
2416 TRACE_FUNCTION( "psi_copy_pccch" );
2417
2418 m = 0;
2419 for(n = 0; n < psi2->psi_2_trnc_grp.c_pccch_des; n++)
2420 {
2421 if(psi2->psi_2_trnc_grp.pccch_des[n].v_nh_pccch_c AND (m < MAX_PCCCH_DES))
2422 {
2423 /*
2424 * Non hopping parameters
2425 */
2426 for(j = 0; j < psi2->psi_2_trnc_grp.pccch_des[n].c_nh_pccch_c; j++)
2427 {
2428 ii = 128;
2429 for(i = 0; i < 8; i++)
2430 {
2431 if( ((psi2->psi_2_trnc_grp.pccch_des[n].nh_pccch_c[j].ts_alloc & ii ) EQ ii) ) /* to get the timeslot number */
2432 {
2433 psc_db->paging_group.pccch[m].is_static = TRUE;
2434 psc_db->paging_group.pccch[m].tsc = psi2->psi_2_trnc_grp.pccch_des[n].tsc;
2435 psc_db->paging_group.pccch[m].arfcn = psi2->psi_2_trnc_grp.pccch_des[n].nh_pccch_c[j].arfcn;
2436 psc_db->paging_group.pccch[m].tn = i;/* timeslot number*/
2437 m++;
2438 if( m >= MAX_PCCCH_DES )
2439 break;
2440 }
2441 ii = ii/2;
2442 }
2443 }
2444 }
2445
2446 if(psi2->psi_2_trnc_grp.pccch_des[n].v_ma_h_s1 AND (m < MAX_PCCCH_DES))
2447 {
2448 /*
2449 * Hopping parameters
2450 */
2451 for(j = 0; j < psi2->psi_2_trnc_grp.pccch_des[n].ma_h_s1.c_h_pccch_c; j++)
2452 {
2453
2454 ii = 128;
2455 for(i = 0; i < 8; i++)
2456 {
2457 if( ((psi2->psi_2_trnc_grp.pccch_des[n].ma_h_s1.h_pccch_c[j].ts_alloc & ii ) EQ ii) ) /* to get the timeslot number */
2458 {
2459 psc_db->paging_group.pccch[m].is_static = FALSE;
2460 psc_db->paging_group.pccch[m].ma_num = psi2->psi_2_trnc_grp.pccch_des[n].ma_h_s1.ma_num;
2461 psc_db->paging_group.pccch[m].tsc = psi2->psi_2_trnc_grp.pccch_des[n].tsc;
2462 psc_db->paging_group.pccch[m].maio = psi2->psi_2_trnc_grp.pccch_des[n].ma_h_s1.h_pccch_c[j].maio;
2463 psc_db->paging_group.pccch[m].tn = i;/* timeslot number*/
2464 m++;
2465 if( m >= MAX_PCCCH_DES )
2466 break;
2467 }
2468 ii = ii/2;
2469 }
2470 }
2471 }
2472 psc_db->paging_group.kc = m; /*number of timeslots carrying PCCCH*/
2473 }
2474 }/* psi_copy_pccch*/
2475
2476 /*
2477 +------------------------------------------------------------------------------
2478 | Function : psi_copy_cell_id
2479 +------------------------------------------------------------------------------
2480 | Description : The function psi_copy_cell_id() ....
2481 |
2482 | Parameters : T_PSI_2 *psi2: pointer to PSI2 message strcuture
2483 |
2484 +------------------------------------------------------------------------------
2485 */
2486 LOCAL void psi_copy_cell_id(T_PSI_2 *psi2)
2487 {
2488 TRACE_FUNCTION( "psi_copy_cell_id" );
2489
2490 psc_db->cell_info_for_gmm.cell_info.cell_env.rai.plmn.v_plmn = TRUE;
2491
2492 if( psi2->psi_2_trnc_grp.cell_id.loc_area_ident.c_mnc EQ 2 )
2493 {
2494 /* Internally G23 uses always 3-digit-MNC */
2495 psi2->psi_2_trnc_grp.cell_id.loc_area_ident.c_mnc = SIZE_MNC;
2496 psi2->psi_2_trnc_grp.cell_id.loc_area_ident.mnc[2] = 0xf;
2497 }
2498
2499 memcpy( psc_db->cell_info_for_gmm.cell_info.cell_env.rai.plmn.mcc,
2500 psi2->psi_2_trnc_grp.cell_id.loc_area_ident.mcc, SIZE_MCC );
2501
2502 memcpy( psc_db->cell_info_for_gmm.cell_info.cell_env.rai.plmn.mnc,
2503 psi2->psi_2_trnc_grp.cell_id.loc_area_ident.mnc, SIZE_MNC );
2504
2505 psc_db->cell_info_for_gmm.cell_info.cell_env.rai.lac = psi2->psi_2_trnc_grp.cell_id.loc_area_ident.lac;
2506 psc_db->cell_info_for_gmm.cell_info.cell_env.rai.rac = psi2->psi_2_trnc_grp.cell_id.rac;
2507 psc_db->cell_info_for_gmm.cell_info.cell_env.cid = psi2->psi_2_trnc_grp.cell_id.cell_id_ie;
2508
2509 }/* psi_copy_cell_id*/
2510
2511 /*
2512 +------------------------------------------------------------------------------
2513 | Function : psi_copy_non_gprs_opt
2514 +------------------------------------------------------------------------------
2515 | Description : The function psi_copy_non_gprs_opt() ....
2516 |
2517 | Parameters : T_PSI_2 *psi2: pointer to PSI2 message strcuture
2518 |
2519 +------------------------------------------------------------------------------
2520 */
2521 LOCAL void psi_copy_non_gprs_opt(T_PSI_2 *psi2)
2522 {
2523 TRACE_FUNCTION( "psi_copy_non_gprs_opt" );
2524
2525 psc_db->v_non_gprs_opt = TRUE;
2526 /* copy parameters*/
2527 memcpy(&(psc_db->non_gprs_opt), &(psi2->psi_2_trnc_grp.non_gprs_opt), sizeof(T_non_gprs_opt));
2528
2529
2530 }/* psi_copy_non_gprs_opt*/
2531 /*
2532 +------------------------------------------------------------------------------
2533 | Function : psi_process_psi2
2534 +------------------------------------------------------------------------------
2535 | Description : The function psi_process_psi2() ....
2536 |
2537 | Parameters : T_PSI_2 *psi2
2538 |
2539 +------------------------------------------------------------------------------
2540 */
2541 GLOBAL T_PSI2_RET psi_process_psi2 (T_PSI_2 *psi2 )
2542 {
2543 UBYTE n=0;
2544
2545 TRACE_FUNCTION( "psi_process_psi2" );
2546
2547 if(psc_db->psi2_params.psi2_change_mark EQ NOT_SET)
2548 {
2549 /* This is the first PSI2 message*/
2550 psc_db->psi2_params.psi2_change_mark = psi2->psi2_cm;
2551 psc_db->psi2_params.psi2_count = psi2->psi2_cnt;
2552 psc_db->psi2_params.instances[0] = psi2->psi2_cnt;/* number of instances */
2553 }
2554 else
2555 {
2556 /* Check consistency of COUNT and INDEX*/
2557 if(
2558 (psc_db->psi2_params.psi2_count NEQ psi2->psi2_cnt)
2559 OR
2560 (psc_db->psi2_params.psi2_count < psi2->psi2_ind)
2561 OR
2562 (psc_db->psi2_params.psi2_change_mark NEQ psi2->psi2_cm)
2563 )
2564 {
2565 /* Error situation read a new PSI2*/
2566 TRACE_EVENT( "PSI2: inconsistent parameters" );
2567 return PSI2_REREAD;
2568 }
2569
2570 /* There was a valid psi2_change_mark: compare change_mark values*/
2571 if((psc_db->psi2_params.psi2_change_mark EQ psi2->psi2_cm) AND
2572 (psc_db->state_of_PSI[PSI2].state EQ RECEIPT_OK))
2573 {
2574 /* PSI2 message has not changed, we already have a consistent set, so we
2575 * do not have to read the PSI2 message
2576 */
2577 TRACE_EVENT( "PSI2: message has not changed" );
2578 return PSI2_OK;
2579 }
2580 } /* psi2_change_mark set */
2581
2582
2583 if( psc_db->psi2_params.instances[psi2->psi2_ind + 1] EQ FALSE )
2584 {
2585 psc_db->psi2_params.instances[psi2->psi2_ind + 1] = TRUE;
2586
2587 /*check consistency */
2588 psc_db->complete_acq.psi2_ok = TRUE;
2589 for(n = 0; n <= psc_db->psi2_params.instances[0]; n++ )
2590 {
2591 if(!(psc_db->psi2_params.instances[n + 1]))
2592 {
2593 psc_db->complete_acq.psi2_ok = FALSE;/* consistent set of PSI2 not complete */
2594 break;
2595 }
2596 }
2597
2598 psc_db->state_of_PSI[PSI2].state = (psc_db->complete_acq.psi2_ok) ? RECEIPT_OK : NEEDED;
2599
2600 if(psi2->psi_2_trnc_grp.v_cell_id)
2601 {
2602 /* copy cell identification*/
2603 psi_copy_cell_id(psi2);
2604 }
2605
2606 if(psi2->psi_2_trnc_grp.v_non_gprs_opt)
2607 {
2608 /* copy non GPRS cell options*/
2609 psi_copy_non_gprs_opt(psi2);
2610 }
2611
2612 /*
2613 * copy Reference Frequency List (RFL)
2614 */
2615 psi_copy_rfl(psi2);
2616
2617 /*
2618 * copy Cell Allocation (CA)
2619 */
2620 psi_copy_ca(psi2);
2621
2622 /*
2623 * copy GPRS Mobile Allocation (MA)
2624 */
2625 psi_copy_ma_from_psi2(psi2);
2626
2627 /*
2628 * copy PCCCH Description
2629 */
2630 psi_copy_pccch(psi2);
2631 #ifdef REL99
2632 if(psi2->psi_2_trnc_grp.v_release_99_str_psi_2 AND psi2->psi_2_trnc_grp.release_99_str_psi_2.v_add_psi)
2633 {
2634 psc_db->add_psi = psi2->psi_2_trnc_grp.release_99_str_psi_2.add_psi;
2635 psc_db->v_add_psi = TRUE;
2636
2637 if(!psi2->psi_2_trnc_grp.release_99_str_psi_2.add_psi.Psi8_broadcast)
2638 {
2639 psc_db->state_of_PSI[PSI8].state = NOT_SEND;
2640 psc_db->v_cbch_chan_desc = FALSE;
2641
2642 /* as this is r-99 network, and PBCCH is present
2643 * CBCH info should be sent to RR. As psi8 is
2644 * not present, it will deactivated.
2645 */
2646 psc_db->send_cbch_info_ind = TRUE;
2647 }
2648
2649 /* Process psi3ter broadcast indicator */
2650 if(!psi2->psi_2_trnc_grp.release_99_str_psi_2.add_psi.psi3ter_broadcast)
2651 {
2652 psc_db->state_of_PSI[PSI3ter].state = NOT_SEND;
2653 }
2654 }
2655
2656 if(psc_db->state_of_PSI[PSI2].state EQ RECEIPT_OK)
2657 {
2658 /* A consistent set of PSI2 has been received. */
2659 /* Additional PSI Messages information element is within truncation
2660 notation. If it wasn't received at all, then we should assume 0,
2661 hence mark PSI3 ter and PSI 8 as "NOT_SEND" */
2662 if(!psc_db->v_add_psi)
2663 {
2664 psc_db->state_of_PSI[PSI8].state = NOT_SEND;
2665 psc_db->v_cbch_chan_desc = FALSE;
2666 if(psc_db->network_rel)
2667 {
2668
2669 /* as this is r-99 network, and PBCCH is present
2670 * CBCH info should be sent to RR. As psi8 is
2671 * not present, it will deactivated.
2672 */
2673 psc_db->send_cbch_info_ind = TRUE;
2674 }
2675
2676 psc_db->state_of_PSI[PSI3ter].state = NOT_SEND;
2677 }
2678 /* PSI2 has got updated. CBCH channel description
2679 * could depend of PSI2 in case hopping is allowed
2680 */
2681 if(psc_db->v_cbch_chan_desc AND !psc_db->cbch_chan_desc.freq_par.v_arfcn)
2682 {
2683 psc_db->send_cbch_info_ind = TRUE;
2684 }
2685 }
2686 #endif
2687 TRACE_EVENT_P2( "PSI2: received with count = %d, index = %d",
2688 psi2->psi2_cnt, psi2->psi2_ind );
2689 }
2690 else
2691 {
2692 TRACE_EVENT_P2( "PSI2: already received with count = %d, index = %d",
2693 psi2->psi2_cnt, psi2->psi2_ind );
2694 }
2695
2696
2697
2698 return PSI2_OK;
2699 } /* psi_process_psi2() */
2700
2701 #ifdef REL99
2702 /*
2703 +------------------------------------------------------------------------------
2704 | Function : psi_process_psi8
2705 +------------------------------------------------------------------------------
2706 | Description : This function stores the contents of PSI 8 for further
2707 | processing.
2708 | In R-99, PSI8 contains CBCH configuration. If PSI8 is not
2709 | broadcast or if none of the instances of PSI8 contain
2710 | CBCH information, then SMSCB is not active in the cell.
2711 |
2712 | CBCH is handled in ALR entity and is configured through RR entity.
2713 | This message contains CBCH channel description. If cbch
2714 | channel description indicates hopping, then to decode
2715 | frequency parameters to extract the frequencies for mobile allocation,
2716 | prior receipt of PSI 2(all instances) and
2717 | optionally SI13 messages is essential.
2718 | Hence PSI 8 frequency parameters is not decoded here. It is
2719 | stored in psc data blase and is decoded before giving
2720 | RRGRR_CBCH_INFO_IND to RR entity. RRGRR sap messages are
2721 | sent from service CTRL.
2722 | Parameters : T_PSI_4 *psi4
2723 |
2724 +------------------------------------------------------------------------------
2725 */
2726 GLOBAL T_PSI8_RET psi_process_psi8 (T_PSI_8 *psi8 )
2727 {
2728 UBYTE n;
2729 BOOL is_psi8_ok;
2730 TRACE_FUNCTION( "psi_process_psi8" );
2731
2732 /*
2733 * Check consistency
2734 */
2735 if(psc_db->psi8_params.psi8_change_mark EQ NOT_SET)
2736 {
2737 /*
2738 * Copy change mark etc.
2739 */
2740 psc_db->psi8_params.psi8_change_mark = psi8->psi8_cm;
2741 psc_db->psi8_params.psi8_count = psi8->psi8_cnt;
2742 psc_db->psi8_params.instances[0] = psi8->psi8_cnt;/* number of instances */
2743 psc_db->v_cbch_chan_desc = FALSE;
2744 }
2745 else
2746 {
2747 /*
2748 * There is a valid change mark present in the database
2749 * Check consistency of COUNT and INDEX
2750 */
2751 if(
2752 (psc_db->psi8_params.psi8_count NEQ psi8->psi8_cnt)
2753 OR
2754 (psc_db->psi8_params.psi8_count < psi8->psi8_ind)
2755 OR
2756 (psc_db->psi8_params.psi8_change_mark NEQ psi8->psi8_cm)
2757 )
2758 {
2759 /*
2760 * Error situation; read a new PSI4
2761 * The PSI4 change mark field is changed each time information has been updated
2762 * A new value indicates that the mobile
2763 * station shall re-read the information from the PSI4
2764 */
2765 TRACE_ERROR( "PSI8: inconsistent parameters" );
2766 psc_db->v_cbch_chan_desc = FALSE;
2767 return PSI8_REREAD;
2768 }
2769
2770 /* psi8_change_markh as not changed, i.e.
2771 * PSI8 message has not changed, we already have a consistent set, so we
2772 * do not have to read the PSI4 message
2773 */
2774 if((psc_db->psi8_params.psi8_change_mark EQ psi8->psi8_cm) &&
2775 (psc_db->state_of_PSI[PSI8].state EQ RECEIPT_OK))
2776 {
2777 /* Message has not changed, we already have a consistent set, so we
2778 * do not have to read it
2779 */
2780 TRACE_EVENT( "PSI8: message has not changed" );
2781 return PSI8_OK;
2782 }
2783 }
2784
2785 psc_db->psi8_params.psi8_index = psi8->psi8_ind;
2786
2787 if( psc_db->psi8_params.instances[psi8->psi8_ind + 1] EQ FALSE )
2788 {
2789 /* Store CBCH channel description. To decode Frequency Parameters,
2790 * it is necessary to receive all instances of PSI2 message.
2791 * Hence defer decoding of hopping frequency list till
2792 * end of acquisition.
2793 */
2794 if(psi8->v_cbch_chan_desc)
2795 {
2796 memcpy(&(psc_db->cbch_chan_desc),&(psi8->cbch_chan_desc),sizeof(T_cbch_chan_desc));
2797 psc_db->v_cbch_chan_desc = TRUE;
2798 }
2799 /*
2800 * check whether PSI8 has been received completely or not
2801 */
2802 psc_db->psi8_params.instances[psi8->psi8_ind + 1] = TRUE;
2803 is_psi8_ok = TRUE;
2804 for(n = 0; n <= psc_db->psi8_params.instances[0]; n++ )
2805 {
2806 if(!(psc_db->psi8_params.instances[n + 1]))
2807 {
2808 is_psi8_ok = FALSE;/* consistent set of PSI8 not complete */
2809 break;
2810 }
2811 }
2812
2813 TRACE_EVENT_P2( "PSI8: received with count = %d, index = %d",
2814 psi8->psi8_cnt, psi8->psi8_ind );
2815
2816 if(is_psi8_ok)
2817 {
2818 if(psc_db->state_of_PSI[PSI8].state NEQ RECEIPT_OK)
2819 {
2820 /* A new copy of PSI8 has been received.
2821 * RRGRR_CBCH_INFO_IND has to be sent after
2822 * all instances of PSI2 have been received when
2823 * acquisition is PARTIAL, and in case of COMPLETE
2824 * acquisition after access to the cell is enabled.
2825 */
2826 psc_db->state_of_PSI[PSI8].state = RECEIPT_OK;
2827 psc_db->send_cbch_info_ind = TRUE;
2828 return PSI8_OK;
2829 }
2830 }
2831 }
2832 else
2833 {
2834 TRACE_EVENT_P2( "PSI8: already received with count = %d, index = %d",
2835 psi8->psi8_cnt, psi8->psi8_ind );
2836 }
2837
2838 return PSI8_OK;
2839
2840 } /* psi_process_psi8() */
2841 #endif
2842
2843 /*
2844 +------------------------------------------------------------------------------
2845 | Function : psi_check_change_field
2846 +------------------------------------------------------------------------------
2847 | Description : The function psi_check_change_field() ....
2848 |
2849 | Parameters : UBYTE psi_change_field; return TRUE: acq needed, FALSE: not needed
2850 |
2851 +------------------------------------------------------------------------------
2852 */
2853 LOCAL BOOL psi_check_change_field (UBYTE psi_change_field)
2854 {
2855 BOOL return_value = FALSE;
2856 TRACE_FUNCTION( "psi_check_change_field" );
2857
2858 switch(psi_change_field)
2859 {
2860 case UPDATE_UNS_PSI: /*Update of unspecified PSI message(s);*/
2861 psc_db->state_of_PSI[PSI2].state = NEEDED;
2862 psc_db->state_of_PSI[PSI3].state = NEEDED;
2863 psc_db->state_of_PSI[PSI3bis].state = NEEDED;
2864 #if defined (REL99) AND defined (TI_PS_FF_EMR)
2865 psc_db->state_of_PSI[PSI3ter].state = NEEDED;
2866 #endif
2867 psc_db->state_of_PSI[PSI4].state = NEEDED;
2868 psc_db->state_of_PSI[PSI5].state = NEEDED; /*??*/
2869 #ifdef REL99
2870 /* It is necessary to set PSI 8 to needed here. In case
2871 * PSI 8 is not broadcast in the cell, this value \
2872 * would be sent to NOT_SEND when PSI 2 is received
2873 */
2874 psc_db->state_of_PSI[PSI8].state = NEEDED;
2875 #endif
2876 /*psc_db->state_of_PSI[13] = NEEDED;*/
2877 return_value = TRUE;
2878 break;
2879 case UPDATE_UNKNOWN: /* Unknown*/
2880 return_value = FALSE;
2881 break;
2882 case UPDATE_PSI2: /* PSI2 updated*/
2883 psc_db->state_of_PSI[PSI2].state = NEEDED;
2884 return_value = TRUE;
2885 break;
2886 case UPDATE_PSI3: /* PSI3/PSI3bis/PSI3ter updated*/
2887 psc_db->state_of_PSI[PSI3].state = NEEDED;
2888 psc_db->state_of_PSI[PSI3bis].state = NEEDED;
2889 #if defined (REL99) AND defined (TI_PS_FF_EMR)
2890 if(psc_db->v_add_psi AND psc_db->add_psi.psi3ter_broadcast)
2891 {
2892 psc_db->state_of_PSI[PSI3ter].state = NEEDED;
2893 }
2894 else
2895 {
2896 psc_db->state_of_PSI[PSI3ter].state = NOT_SEND;
2897 }
2898 #endif
2899 return_value = TRUE;
2900 break;
2901 case UPDATE_PSI4: /* PSI4 updated*/
2902 psc_db->state_of_PSI[PSI4].state = NEEDED;
2903 return_value = TRUE;
2904 break;
2905 case UPDATE_PSI5: /* PSI5 updated*/
2906 psc_db->state_of_PSI[PSI5].state = NEEDED;
2907 return_value = TRUE;
2908 break;
2909 #ifdef REL99
2910 case UPDATE_PSI8:
2911 psc_db->state_of_PSI[PSI8].state = NEEDED;
2912 return_value = TRUE;
2913 break;
2914 #endif
2915 default: /* All other values shall be interpreted as 'Update of unknown SI message type'.*/
2916 return_value = FALSE;
2917 break;
2918 }
2919 return return_value;
2920 } /* psi_check_change_field() */
2921
2922 /*
2923 +------------------------------------------------------------------------------
2924 | Function : psi_process_psi1
2925 +------------------------------------------------------------------------------
2926 | Description : The function psi_process_psi1() ....
2927 |
2928 | Parameters : T_PSI_1 *psi1
2929 |
2930 +------------------------------------------------------------------------------
2931 */
2932 GLOBAL T_PSI1_RET psi_process_psi1 (T_PSI_1 *psi1 )
2933 {
2934 T_PSI1_RET return_val = PSI1_OK;
2935 #ifdef REL99
2936 UBYTE current_nw_rel = psc_db->network_rel;
2937 #endif
2938
2939 TRACE_FUNCTION( "psi_process_psi1" );
2940
2941 if(psi1->pccch_org_par.bs_pcc_rel)
2942 {
2943 /*
2944 * last PDCH carrying PCCCH and PBCCH will be released shortly, receive si13
2945 */
2946 return_val = PSI1_PBCCH_RELEASED;
2947 }
2948 else if( grr_is_pbcch_present( ) EQ FALSE )
2949 {
2950 return_val = PSI1_PBCCH_ESTABLISHED;
2951 }
2952 else
2953 {
2954 psc_db->state_of_PSI[PSI1].state = RECEIPT_OK;
2955 psc_db->complete_acq.psi1_ok = TRUE; /*PSI1 has been received*/
2956
2957 /* copy repeat period*/
2958 psc_db->psi1_params.psi1_repeat_period = psi1->psi1_rep_per + 1;
2959
2960 /* copy repetition rates */
2961 psc_db->psi1_params.psi_cnt_lr = psi1->psi_cnt_lr;
2962 if(psi1->v_psi_cnt_hr)
2963 {
2964 psc_db->psi1_params.psi_cnt_hr = psi1->psi_cnt_hr + 1;
2965 }
2966 else
2967 {
2968 psc_db->psi1_params.psi_cnt_hr = 0;/*default*/
2969 }
2970
2971
2972 psc_db->psi1_params.psi_status_supported = (psi1->psi_status_ind EQ 1) ? TRUE : FALSE;
2973 psc_db->measurement_order = psi1->meas_order; /*PSI5 is present in the cell or not*/
2974
2975 if(!psc_db->measurement_order)
2976 psc_db->state_of_PSI[PSI5].state = RECEIPT_OK;
2977
2978 /* Process PRACH parameters*/
2979 psi_process_prach(&(psi1->prach_ctrl_par));
2980
2981 /*copy pccch org params*/
2982 psc_db->pccch.bs_pcc_rel = psi1->pccch_org_par.bs_pcc_rel;
2983 psc_db->pccch.bs_pbcch_blks = psi1->pccch_org_par.bs_pbcch_blks;
2984 psc_db->pccch.bs_pag_blks = CLIP_BS_PAG_BLKS_RES( psi1->pccch_org_par.bs_pag_blks );
2985 psc_db->pccch.bs_prach_blks = CLIP_BS_PRACH_BLKS( psi1->pccch_org_par.bs_prach_blks );
2986
2987 /*copy GPRS cell options*/
2988 psc_db->v_gprs_cell_opt = TRUE;
2989 psc_db->cell_info_for_gmm.cell_info.net_mode = psi1->gprs_cell_opt.nmo;
2990 psc_db->gprs_cell_opt.nmo = psi1->gprs_cell_opt.nmo;
2991 psc_db->gprs_cell_opt.t3168 = psi1->gprs_cell_opt.t3168;
2992 psc_db->gprs_cell_opt.t3192 = psi1->gprs_cell_opt.t3192;
2993 psc_db->gprs_cell_opt.drx_t_max = psi1->gprs_cell_opt.drx_t_max;
2994 psc_db->gprs_cell_opt.ab_type = psi1->gprs_cell_opt.ab_type;
2995 psc_db->gprs_cell_opt.ctrl_ack_type = psi1->gprs_cell_opt.ctrl_ack_type;
2996 psc_db->gprs_cell_opt.bs_cv_max = psi1->gprs_cell_opt.bs_cv_max;
2997
2998 memcpy(&(psc_db->gprs_cell_opt), &(psi1->gprs_cell_opt), sizeof(T_gprs_cell_opt));
2999
3000 /*if(psi1->gprs_cell_opt.v_pan_struct)
3001 {
3002 psc_db->gprs_cell_opt.pan_struct.inc = psi1->gprs_cell_opt.pan_struct.inc;
3003 psc_db->gprs_cell_opt.pan_struct.dec = psi1->gprs_cell_opt.pan_struct.dec;
3004 psc_db->gprs_cell_opt.pan_struct.pmax = ( psi1->gprs_cell_opt.pan_struct.pmax + 1 ) * 4;
3005 psc_db->gprs_cell_opt.v_pan_struct = 1;
3006 }*/
3007 if(psi1->gprs_cell_opt.v_gprs_ext_bits)
3008 {
3009 memcpy(&(psc_db->gprs_cell_opt.gprs_ext_bits), &(psi1->gprs_cell_opt.gprs_ext_bits), sizeof(T_gprs_ext_bits));
3010 psc_db->gprs_cell_opt.v_gprs_ext_bits = 1;
3011 }
3012
3013 /*Global power control parameters*/
3014 grr_store_g_pwr_par( &psi1->g_pwr_par );
3015
3016 /* check whether the PSI4 is broadcast or not*/
3017 if(!psc_db->g_pwr_par.imeas_chan_list)
3018 psc_db->state_of_PSI[PSI4].state = RECEIPT_OK;
3019
3020
3021 TRACE_EVENT_P2( "PSI1: database change mark: %d, message change mark: %d",
3022 psc_db->psi1_params.pbcch_change_mark,
3023 psi1->pbcch_change_ma );
3024
3025 if(psc_db->psi1_params.first_psi1)
3026 {
3027 psc_db->psi1_params.pbcch_change_mark = psi1->pbcch_change_ma; /* set the new change mark value*/
3028 }
3029 else
3030 {
3031 UBYTE incremented_value = psi_compare_change_mark(psi1->pbcch_change_ma, psc_db->psi1_params.pbcch_change_mark);
3032 psc_db->psi1_params.pbcch_change_mark = psi1->pbcch_change_ma; /* set the new change mark value*/
3033
3034 if(incremented_value EQ 1)/*partial acq*/
3035 {
3036 if(psi_check_change_field(psi1->psi_change_field))
3037 {
3038 return_val = PSI1_PARTIAL_ACQ;
3039 }
3040 }
3041 else if(incremented_value > 1) /* incremented_value more than 1: complete acq*/
3042 {
3043 return_val = PSI1_COMPLETE_ACQ;
3044 }
3045 }
3046
3047 #ifdef REL99
3048 /* Update the BSS release from PSI1 instead of SI13, when PBCCH is present */
3049 /* Update the SGSN release */
3050 if (psi1->v_release_99_str_psi_1)
3051 {
3052 psc_db->network_rel = BSS_NW_REL_99;
3053 psc_db->sgsn_rel = psi1->release_99_str_psi_1.sgsnr ? PS_SGSN_99_ONWARDS : PS_SGSN_98_OLDER;
3054 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
3055 psc_db->band_indicator = psi1->release_99_str_psi_1.band_indicator;
3056 #endif
3057 }
3058 else
3059 {
3060 psc_db->sgsn_rel = PS_SGSN_98_OLDER;
3061 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
3062 psc_db->band_indicator = NOT_PRESENT_8BIT;
3063 #endif
3064 }
3065
3066 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
3067 /*
3068 * Update std depending on the band indicator
3069 */
3070 att_update_std_band_indicator ( psc_db->band_indicator );
3071 #endif
3072
3073 /* Please note that there is no check for (psi1->release_99 EQ FALSE) and
3074 * then setting the psc_db->network_rel to BSS_NW_REL_97 as sometimes the
3075 * the R99 or R4 network may not broadcast the optional R99 IEs. At that
3076 * time, the network release is assigned wrongly if the above check exists.
3077 */
3078 if(psc_db->network_rel NEQ current_nw_rel)
3079 {
3080 TRACE_EVENT_P2("(PSI1)BSS Network release changed from %d to %d <0 - REL_97, 1 - REL_99, 2 - REL_04>",
3081 current_nw_rel, psc_db->network_rel);
3082 }
3083
3084 /* Update the SGSN release in the Common library context */
3085 cl_nwrl_set_sgsn_release(psc_db->sgsn_rel);
3086 #endif
3087
3088 }
3089 TRACE_EVENT_P1( "PSI1: received with return value %d", return_val );
3090 grr_set_pg_nmo();
3091 return return_val;
3092 } /* psi_process_psi1() */
3093
3094
3095 /*
3096 +------------------------------------------------------------------------------
3097 | Function : psi_receive_psi
3098 +------------------------------------------------------------------------------
3099 | Description : The function psi_receive_psi() ....
3100 |
3101 | Parameters : BOOL read_all
3102 |
3103 +------------------------------------------------------------------------------
3104 */
3105 GLOBAL void psi_receive_psi ( UBYTE psi_reading_type)
3106 {
3107 TRACE_FUNCTION( "psi_receive_psi" );
3108
3109 if(grr_data->psi.is_pbcch_req_allowed)
3110 {
3111 /*
3112 * Prepare MPHP_SCELL_PBCCH_REQ to receive psi
3113 */
3114 PALLOC(mphp_scell_pbcch_req, MPHP_SCELL_PBCCH_REQ);
3115 psi_prepare_scell_pbcch_req(mphp_scell_pbcch_req, psi_reading_type);
3116 PSEND(hCommL1,mphp_scell_pbcch_req);
3117 grr_data->psi.is_pbcch_req_needed =FALSE;
3118 }
3119 else
3120 {
3121 TRACE_EVENT("PBCCH request needed after release of TBF, stop of RR tasks, etc.");
3122 grr_data->psi.is_pbcch_req_needed =TRUE;
3123 /*
3124 * store the reading_type in case of needed in/after release procedure
3125 */
3126 grr_data->psi.reading_type=psi_reading_type;
3127 }
3128 } /* psi_receive_psi() */
3129
3130
3131 /*
3132 +------------------------------------------------------------------------------
3133 | Function : psi_process_prach
3134 +------------------------------------------------------------------------------
3135 | Description : The function psi_process_prach() ....
3136 |
3137 | Parameters : T_prach_ctrl_par *prach: pointer to PRACH control parameters
3138 |
3139 +------------------------------------------------------------------------------
3140 */
3141 GLOBAL void psi_process_prach ( T_prach_ctrl_par *prach )
3142 {
3143 TRACE_FUNCTION( "psi_process_prach" );
3144
3145 psc_db->v_prach = TRUE;
3146
3147 memcpy(&(psc_db->prach), prach, sizeof(T_prach_ctrl_par));
3148
3149 TRACE_EVENT_P5("ac_class: %d max_ret %d %d %d %d",
3150 prach->ac_class,
3151 prach->max_retrans[0],
3152 prach->max_retrans[1],
3153 prach->max_retrans[2],
3154 prach->max_retrans[3]);
3155 TRACE_EVENT_P2("s_prach: %d tx_int:%d", prach->s_prach, prach->tx_int);
3156 if(prach->v_pers_lev)
3157 {
3158 TRACE_EVENT_P4("pers: %d %d %d %d",
3159 prach->pers_lev.plev[0],
3160 prach->pers_lev.plev[1],
3161 prach->pers_lev.plev[2],
3162 prach->pers_lev.plev[3]);
3163 }
3164
3165
3166 } /* psi_process_prach() */
3167
3168
3169 /*
3170 +------------------------------------------------------------------------------
3171 | Function : psi_reset_si_entries
3172 +------------------------------------------------------------------------------
3173 | Description : The function psi_reset_si_entries() ....
3174 |
3175 | Parameters : void
3176 |
3177 +------------------------------------------------------------------------------
3178 */
3179 GLOBAL void psi_reset_si_entries ( void )
3180 {
3181 TRACE_FUNCTION( "psi_reset_si_entries" );
3182
3183 psc_db->psi13_params.bcch_change_mark = NOT_SET;
3184 psc_db->psi13_params.si13_change_mark = NOT_SET;
3185
3186 } /* psi_reset_si_entries() */
3187
3188 /*
3189 +------------------------------------------------------------------------------
3190 | Function : psi_acq_state_of_si
3191 +------------------------------------------------------------------------------
3192 | Description : The function psi_acq_state_of_si() ....
3193 | This function is ONLY called after processing SI13 message
3194 | Parameters : T_si_states si_states: contains the state of the SI messages
3195 | needed for checking for packet access allowance
3196 |
3197 +------------------------------------------------------------------------------
3198 */
3199 GLOBAL T_ACQ_STATE_RET psi_acq_state_of_si ( T_si_states si_states)
3200 {
3201 T_ACQ_STATE_RET ret_value = ACQ_RUNNING;
3202
3203 TRACE_FUNCTION( "psi_acq_state_of_si" );
3204
3205 switch(psc_db->acq_type)
3206 {
3207 case PARTIAL:
3208 ret_value = ACQ_PART_OK;
3209 break;
3210 case COMPLETE:
3211 if((si_states.si3_state EQ SI3_RECEIVED) AND (si_states.si13_state EQ SI13_RECEIVED))
3212 {
3213 if((si_states.si1_state EQ SI1_NOT_SEND) OR (si_states.si1_state EQ SI1_RECEIVED))
3214 {
3215 ret_value = ACQ_COMP_OK;
3216 }
3217 }
3218 break;
3219 case PERIODICAL_SI13_READING:
3220 ret_value = ACQ_PERIOD_OK;
3221 break;
3222 default:
3223 break;
3224 }
3225 return ret_value;
3226 } /* psi_acq_state_of_si() */
3227
3228
3229 /*
3230 +------------------------------------------------------------------------------
3231 | Function : psi_is_update_needed
3232 +------------------------------------------------------------------------------
3233 | Description : The function psi_is_update_needed() ....
3234 |
3235 | Parameters : void
3236 |
3237 +------------------------------------------------------------------------------
3238 */
3239 GLOBAL BOOL psi_is_update_needed ( UBYTE si_change_field )
3240 {
3241 TRACE_FUNCTION( "psi_is_update_needed" );
3242
3243 switch(si_change_field)
3244 {
3245 case UNSPECIFIED_SI:
3246 case UPDATE_SI1:
3247 case UPDATE_SI2_SI2BIS_OR_SI2TER:
3248 case UPDATE_SI3_SI4_SI7_OR_SI8:
3249 case UPDATE_SI9:
3250 return TRUE;
3251 default:
3252 return FALSE;
3253 }
3254 } /* psi_is_update_needed() */
3255
3256 /*
3257 +------------------------------------------------------------------------------
3258 | Function : psi_update_data_to_request
3259 +------------------------------------------------------------------------------
3260 | Description : The function psi_update_data_to_request updates the static
3261 | and hopping frequencies and other parameters to request PSI
3262 | data. This function is called after receiving SI13 or PSI13 or PSI1
3263 |
3264 | Parameters : UBYTE init_needed: checks whether initialization is needed or not
3265 |
3266 +------------------------------------------------------------------------------
3267 */
3268 GLOBAL void psi_update_data_to_request( UBYTE init_needed)
3269 {
3270 T_MPHP_SCELL_PBCCH_REQ *ptr_prim;
3271
3272 TRACE_FUNCTION( "psi_update_data_to_request" );
3273
3274 ptr_prim = &psc_db->scell_pbcch;
3275
3276 if(init_needed)
3277 {
3278 TRACE_EVENT("Init Needed");
3279 memset(&psc_db->pccch, 0, sizeof(T_pccch_org_par)); /*initial*/
3280 psc_db->psi1_params.psi_cnt_hr = 0; /* initial*/
3281 psc_db->psi1_params.psi_cnt_lr = 0; /* initial*/
3282 }
3283
3284 /*
3285 * set values for mphp_scell_pbcch_req
3286 */
3287 ptr_prim->pb = psc_db->pbcch.pbcch_des.pb; /*< Power reduction value */
3288 ptr_prim->bs_pbcch_blks = psc_db->pccch.bs_pbcch_blks; /*< Number of PBCCH per multiframe */
3289 ptr_prim->psi1_rep_period = psc_db->psi1_params.psi1_repeat_period; /*< PSI1 repeat period */
3290 ptr_prim->p_ch_des.tsc = psc_db->pbcch.pbcch_des.tsc; /*< Training sequence code */
3291 ptr_prim->p_ch_des.tn = psc_db->pbcch.pbcch_des.tn; /*< timeslot number */
3292
3293 if (psc_db->pbcch.pbcch_des.v_arfcn
3294 OR
3295 (
3296 (psc_db->pbcch.pbcch_des.flag EQ 0)
3297 AND /* use bcch.arfcn*/
3298 (psc_db->pbcch.pbcch_des.flag2 EQ 0)
3299 )
3300 )
3301 {
3302 ptr_prim->p_ch_des.p_chan_sel.hopping = 0;
3303 ptr_prim->p_ch_des.p_chan_sel.p_rf_ch.arfcn = (psc_db->pbcch.pbcch_des.v_arfcn )
3304 ?grr_g23_arfcn_to_l1(psc_db->pbcch.pbcch_des.arfcn)
3305 :grr_g23_arfcn_to_l1(psc_db->pbcch.bcch.arfcn);
3306
3307 TRACE_EVENT_P8("Up_s: pbcch:%d per:%d hr:%d lr:%d pb:%d tsc:%d tn:%d arfcn:%d",
3308 psc_db->pccch.bs_pbcch_blks,
3309 psc_db->psi1_params.psi1_repeat_period,
3310 psc_db->psi1_params.psi_cnt_hr,
3311 psc_db->psi1_params.psi_cnt_lr,
3312 psc_db->pbcch.pbcch_des.pb,
3313 psc_db->pbcch.pbcch_des.tsc,
3314 psc_db->pbcch.pbcch_des.tn,
3315 ptr_prim->p_ch_des.p_chan_sel.p_rf_ch.arfcn);
3316 }
3317 else
3318 {
3319 grr_create_freq_list( MA_NUMBER_4_PSI13_OR_CELL_ALLOC,
3320 psc_db->pbcch.pbcch_des.maio,
3321 &ptr_prim->p_ch_des.p_chan_sel,
3322 &ptr_prim->p_freq_list );
3323
3324 TRACE_EVENT_P8("Up_h1: pbcch:%d per:%d hr:%d lr:%d pb:%d tsc:%d tn:%d maio:%d",
3325 psc_db->pccch.bs_pbcch_blks,
3326 psc_db->psi1_params.psi1_repeat_period,
3327 psc_db->psi1_params.psi_cnt_hr,
3328 psc_db->psi1_params.psi_cnt_lr,
3329 psc_db->pbcch.pbcch_des.pb,
3330 psc_db->pbcch.pbcch_des.tsc,
3331 psc_db->pbcch.pbcch_des.tn,
3332 psc_db->pbcch.pbcch_des.maio);
3333
3334
3335
3336 }
3337 } /* psi_update_data_to_request() */
3338
3339 /*
3340 +------------------------------------------------------------------------------
3341 | Function : psi_is_access_class_changed
3342 +------------------------------------------------------------------------------
3343 | Description : This function checks the access class control parameter and
3344 | return TRUE/FALSE value
3345 |
3346 | Parameters : void; return BOOL: TRUE: access class changed; FALSE: nothing has changed
3347 |
3348 +------------------------------------------------------------------------------
3349 */
3350 GLOBAL BOOL psi_is_access_class_changed(void)
3351 {
3352 USHORT dummy1, dummy2, access_changed;
3353
3354 TRACE_FUNCTION("psi_is_access_class_changed");
3355
3356 access_changed = FALSE;
3357 /* check the access control class and inform the service: CTRL
3358 * check access class control for authorized classes 0 to 9 and
3359 * check access class control for authorized classes 11 to 15 and
3360 */
3361 dummy1 = grr_data->ms.access_ctrl_class & 0x3FF;
3362 dummy2 = grr_data->ms.access_ctrl_class & 0xF800;
3363
3364 if(
3365 ((dummy1 & ~psc_db->prach.ac_class) > 0) /* 0 to 9*/
3366 OR
3367 ((dummy2 & ~psc_db->prach.ac_class) > 0) /* 11 to 15*/
3368 )
3369 {
3370 /*
3371 * The MS belongs to one of the authorized access classes
3372 */
3373 if(psc_db->cell_info_for_gmm.access_status NEQ GPRS_ACCESS_ALLOWED)
3374 {
3375 /*
3376 * Access was NOT allowed, so we have to inform GMM
3377 */
3378 access_changed = TRUE;
3379 psc_db->cell_info_for_gmm.access_status = GPRS_ACCESS_ALLOWED;
3380 }
3381 }
3382 else
3383 {
3384 /*
3385 * Access barred
3386 */
3387 if(psc_db->cell_info_for_gmm.access_status NEQ GPRS_ACCESS_BARRED)
3388 {
3389 /*
3390 * Access was ALLOWED, so we have to inform GMM
3391 */
3392 access_changed = TRUE;
3393 psc_db->cell_info_for_gmm.access_status = GPRS_ACCESS_BARRED;
3394 }
3395 }
3396
3397 if( access_changed )
3398 {
3399 TRACE_EVENT( "Access class changed" );
3400
3401 grr_set_cell_info_service( );
3402 }
3403
3404 return( access_changed );
3405 }/* psi_is_access_class_changed*/
3406
3407 /*
3408 +------------------------------------------------------------------------------
3409 | Function : psi_init_params
3410 +------------------------------------------------------------------------------
3411 | Description : The function psi_init_params() ....
3412 |
3413 | Parameters : void
3414 |
3415 +------------------------------------------------------------------------------
3416 */
3417 GLOBAL void psi_init_params ( void )
3418 {
3419 #if defined (TI_PS_FF_RTD) AND defined (REL99)
3420 UBYTE n;
3421 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
3422
3423 TRACE_FUNCTION( "psi_init_params" );
3424
3425 grr_data->psi.is_pbcch_req_needed =FALSE; /*PBCCH req. waiting for perform*/
3426 grr_data->psi.is_pbcch_req_allowed =TRUE; /*PBCCH req. allowed due to transition rules or not*/
3427 #if defined (TI_PS_FF_RTD) AND defined (REL99)
3428 for( n = 0; n < MAX_NR_OF_NCELL; n++ )
3429 grr_data->psi.rtd[n] = RTD_NOT_AVAILABLE;
3430 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
3431
3432 psi_reset_all();
3433
3434 psi_init_rfl_psi2(); /* set the Reference Frequency List parameters to initial values */
3435 psi_init_cell_alloc(); /* init cell allocation structure */
3436 psi_init_gprs_ms_alloc(FALSE); /* init GPRS Mobile Allocations struct */
3437
3438 } /* psi_init_params() */
3439
3440
3441 /*
3442 +------------------------------------------------------------------------------
3443 | Function : psi_stop_timer
3444 +------------------------------------------------------------------------------
3445 | Description : The function stops psi timers if they are running
3446 |
3447 | Parameters : void
3448 |
3449 +------------------------------------------------------------------------------
3450 */
3451 GLOBAL void psi_stop_timer ( void )
3452 {
3453 TRACE_FUNCTION( "psi_stop_timer" );
3454
3455 vsi_t_stop(GRR_handle,T_10_SEC);
3456
3457 vsi_t_stop(GRR_handle,T_30_SEC);
3458
3459 vsi_t_stop(GRR_handle,T_60_SEC);
3460
3461 vsi_t_stop(GRR_handle,T_COMP_PSI);
3462
3463 } /* psi_stop_timer() */
3464
3465 /*
3466 +------------------------------------------------------------------------------
3467 | Function : psi_is_access_allowed
3468 +------------------------------------------------------------------------------
3469 | Description : The function checks whether the access to the network is allowed
3470 | or not
3471 |
3472 | Parameters : BOOL: TRUE if access allowed, otherwise FALSE
3473 |
3474 +------------------------------------------------------------------------------
3475 */
3476 GLOBAL BOOL psi_is_access_allowed(void)
3477 {
3478 TRACE_FUNCTION("psi_is_access_allowed");
3479 /*
3480 * Check whether access is enabled or not: Access is allowed
3481 * if PSI acquisition is completed or PSI1&PSI2 was read with
3482 * success AND psi status is suppoerted by the network
3483 */
3484 #ifdef _SIMULATION_
3485 if(
3486 psc_db->psi1_params.psi_status_supported
3487 AND
3488 psc_db->complete_acq.psi1_ok
3489 AND
3490 psc_db->complete_acq.psi2_ok
3491 )
3492 return TRUE;
3493 #endif /* #ifdef _SIMULATION_ */
3494
3495 return FALSE;
3496 }/*psi_is_access_allowed */
3497
3498 /*
3499 +------------------------------------------------------------------------------
3500 | Function : psi_reread_psi2
3501 +------------------------------------------------------------------------------
3502 | Description : The function starts the reading process of PSI2
3503 |
3504 | Parameters : void
3505 |
3506 +------------------------------------------------------------------------------
3507 */
3508 GLOBAL void psi_reread_psi2(void)
3509 {
3510 TRACE_FUNCTION("psi_reread_psi2");
3511
3512 psc_db->state_of_PSI[PSI2].state = NEEDED;
3513 psi_partial_acq();
3514 psi_reset_psi2();
3515 psi_start_10sec();
3516 }/* psi_reread_psi2*/
3517
3518
3519 /*
3520 +------------------------------------------------------------------------------
3521 | Function : psi_reread_psi3_and_3bis
3522 +------------------------------------------------------------------------------
3523 | Description : The function starts the reading process of PSI3 nad PSI3bis
3524 |
3525 | Parameters : void
3526 |
3527 +------------------------------------------------------------------------------
3528 */
3529 GLOBAL void psi_reread_psi3_and_3bis(void)
3530 {
3531 TRACE_FUNCTION("psi_reread_psi3_and_3bis");
3532
3533 psc_db->state_of_PSI[PSI3bis].state = NEEDED;
3534 psc_db->state_of_PSI[PSI3].state = NEEDED;
3535 psi_partial_acq();
3536
3537 /*
3538 * Reset PSI3 and PSI3BIS paramter
3539 */
3540 psi_reset_psi3bis();
3541 psi_reset_psi3();
3542 psi_start_10sec();
3543 }/* psi_reread_psi3_and_3bis*/
3544
3545
3546 /*
3547 +------------------------------------------------------------------------------
3548 | Function : psi_reread_psi3bis
3549 +------------------------------------------------------------------------------
3550 | Description : The function starts the reading process of PSI3bis
3551 |
3552 | Parameters : void
3553 |
3554 +------------------------------------------------------------------------------
3555 */
3556 GLOBAL void psi_reread_psi3bis(void)
3557 {
3558 TRACE_FUNCTION("psi_reread_psi3bis");
3559
3560 /*
3561 * Message has changed, reset all values and read new consistent message set
3562 */
3563 psc_db->state_of_PSI[PSI3bis].state = NEEDED;
3564 psi_partial_acq();
3565
3566 psi_reset_psi3bis();
3567 psi_start_10sec();
3568 }/* psi_reread_psi3bis*/
3569
3570 #if defined (REL99) AND defined (TI_PS_FF_EMR)
3571 /*
3572 +------------------------------------------------------------------------------
3573 | Function : psi_reread_psi3ter
3574 +------------------------------------------------------------------------------
3575 | Description : The function starts the reading process of PSI3ter
3576 |
3577 | Parameters : void
3578 |
3579 +------------------------------------------------------------------------------
3580 */
3581 GLOBAL void psi_reread_psi3ter(void)
3582 {
3583 TRACE_FUNCTION("psi_reread_psi3ter");
3584
3585 /*
3586 * Message has changed, reset all values and read new consistent message set
3587 */
3588 psc_db->state_of_PSI[PSI3ter].state = NEEDED;
3589 psi_partial_acq();
3590
3591 psi_reset_psi3ter();
3592 psi_start_10sec();
3593 }/* psi_reread_psi3ter*/
3594
3595 /*
3596 +------------------------------------------------------------------------------
3597 | Function : psi_reread_psi3_3bis_3ter
3598 +------------------------------------------------------------------------------
3599 | Description : The function starts the reading process of PSI3 to PSI3ter
3600 |
3601 | Parameters : void
3602 |
3603 +------------------------------------------------------------------------------
3604 */
3605 GLOBAL void psi_reread_psi3_3bis_3ter(void)
3606 {
3607 TRACE_FUNCTION("psi_reread_psi3_3bis_3ter");
3608
3609 if(psc_db->v_add_psi AND psc_db->add_psi.psi3ter_broadcast)
3610 {
3611 psc_db->state_of_PSI[PSI3ter].state = NEEDED;
3612 }
3613 else
3614 {
3615 psc_db->state_of_PSI[PSI3ter].state = NOT_SEND;
3616 }
3617
3618 psc_db->state_of_PSI[PSI3bis].state = NEEDED;
3619 psc_db->state_of_PSI[PSI3].state = NEEDED;
3620 psi_partial_acq();
3621
3622 /*
3623 * Reset PSI3 to PSI3ter parameters
3624 */
3625 /* psi_reset_psi3quater(); */
3626 psi_reset_psi3ter();
3627 psi_reset_psi3bis();
3628 psi_reset_psi3();
3629 psi_start_10sec();
3630 }/* psi_reread_psi3_3bis_3ter */
3631
3632 #endif
3633
3634
3635 /*
3636 +------------------------------------------------------------------------------
3637 | Function : psi_reread_psi4
3638 +------------------------------------------------------------------------------
3639 | Description : The function starts the reading process of PSI4
3640 |
3641 | Parameters : void
3642 |
3643 +------------------------------------------------------------------------------
3644 */
3645 GLOBAL void psi_reread_psi4(void)
3646 {
3647 TRACE_FUNCTION("psi_reread_psi4");
3648
3649 psc_db->state_of_PSI[PSI4].state = NEEDED;
3650 psi_partial_acq();
3651
3652 /*
3653 * Reset PSI4
3654 */
3655 psi_reset_psi4();
3656 psi_start_10sec();
3657 }/* psi_reread_psi4*/
3658
3659 /*
3660 +------------------------------------------------------------------------------
3661 | Function : psi_reread_psi5
3662 +------------------------------------------------------------------------------
3663 | Description : The function starts the reading process of PSI5
3664 |
3665 | Parameters : void
3666 |
3667 +------------------------------------------------------------------------------
3668 */
3669 GLOBAL void psi_reread_psi5(void)
3670 {
3671 TRACE_FUNCTION("psi_reread_psi5");
3672
3673 psc_db->state_of_PSI[PSI5].state = NEEDED;
3674 psi_partial_acq();
3675
3676 /*
3677 * Reset PSI5
3678 */
3679 psi_reset_psi5();
3680 psi_start_10sec();
3681 }/* psi_reread_psi5*/
3682
3683 #ifdef REL99
3684 /*
3685 +------------------------------------------------------------------------------
3686 | Function : psi_reread_psi8
3687 +------------------------------------------------------------------------------
3688 | Description : The function starts the reading process of PSI8
3689 |
3690 | Parameters : void
3691 |
3692 +------------------------------------------------------------------------------
3693 */
3694 GLOBAL void psi_reread_psi8(void)
3695 {
3696 TRACE_FUNCTION("psi_reread_psi8");
3697
3698 psc_db->state_of_PSI[PSI8].state = NEEDED;
3699 psi_partial_acq();
3700
3701 /*
3702 * Reset PSI8
3703 */
3704 psi_reset_psi8();
3705 psi_start_10sec();
3706 }/* psi_reread_psi8*/
3707 #endif
3708
3709 /*
3710 +------------------------------------------------------------------------------
3711 | Function : psi_handle_psi1
3712 +------------------------------------------------------------------------------
3713 | Description : The function handles PSI1 message on both PBCCH and PACCH channels
3714 |
3715 | Parameters : T_PSI_1*
3716 |
3717 +------------------------------------------------------------------------------
3718 */
3719 GLOBAL void psi_handle_psi1(T_PSI_1 * psi1)
3720 {
3721 TRACE_FUNCTION("psi_handle_psi1");
3722 switch(psi_process_psi1(psi1))
3723 {
3724 case PSI1_PBCCH_RELEASED:
3725 SET_STATE( PSI, PSI_NULL );
3726 psi_initiate_pbcch_switching( PSI_DC_PBCCH_RELEASED );
3727 return; /* sorry: dirty solution */
3728 case PSI1_PBCCH_ESTABLISHED:
3729 SET_STATE( PSI, PSI_NULL );
3730 psi_initiate_pbcch_switching( PSI_DC_PBCCH_ESTABLISHED );
3731 return; /* sorry: another dirty solution */
3732 case PSI1_OK:
3733 if( psc_db->measurement_order EQ FALSE )
3734 {
3735 sig_psi_ctrl_meas_param_invalid_psi5( );
3736 }
3737
3738 /* update readin parameters of psi */
3739 psi_update_data_to_request(INIT_NOT_NEEDED);
3740 /*
3741 * check the state of the acquisition
3742 */
3743 switch(psi_check_acq_state())
3744 {
3745 case ACQ_RUNNING:
3746 /*
3747 * Check whether access to the network is allowed or not,
3748 * in case of having complete acq
3749 */
3750 if(psi_is_access_allowed() AND (psc_db->acq_type EQ COMPLETE))
3751 {
3752 psc_db->psi1_params.first_psi1 = FALSE;
3753 psi_stop_psi_reading(NONE);
3754 psi_stop_10sec(); /* Stop this timer, if running */
3755 #ifdef _SIMULATION_
3756 vsi_t_stop(GRR_handle,T_COMP_PSI);
3757 #endif
3758 /*
3759 * restart 30 sec:e.g. wait 30 sec for reread PSI1
3760 */
3761 psi_stop_30sec(TRUE);
3762
3763 /*
3764 * Access to the network is allowed
3765 */
3766 psi_send_access_enable_if_needed();
3767 }
3768 else if(psi_is_access_allowed() AND (psc_db->acq_type EQ FULL_PSI_IN_NEW_CELL))
3769 {
3770 /*
3771 * Access to the new re-selected cell is allowed
3772 */
3773 psc_db->psi1_params.first_psi1 = FALSE;
3774 psi_stop_psi_reading(NONE);
3775 /*
3776 * restart 30 sec:e.g. wait 30 sec for reread PSI1
3777 */
3778 psi_stop_30sec(TRUE);
3779 sig_psi_ctrl_ncell_psi_read( TRUE);
3780 }
3781 else
3782 {
3783 /*
3784 * Acq. is running, check whether we received the PSI1 message
3785 * for the first time or not.
3786 * if the PSI1 message is received for the first time, restart to read PBCCH blocks,
3787 * because of reading new parameters in PSI1 message,e.g. PCCCH parameters
3788 */
3789 if(
3790 psc_db->psi1_params.first_psi1
3791 AND
3792 ((psc_db->acq_type EQ COMPLETE) OR (psc_db->acq_type EQ FULL_PSI_IN_NEW_CELL))
3793 )
3794 {
3795 psi_stop_30sec(TRUE);/*restart 30 sec*/
3796 psi_receive_psi(READ_COMPLETE);
3797 }
3798 }
3799 break;
3800 case ACQ_PART_OK:
3801 psi_stop_psi_reading(NONE);
3802 #ifdef _TARGET_
3803 TRACE_EVENT("PSI1->NEW_PCCCH");
3804 sig_psi_ctrl_new_pccch();
3805 #if defined (REL99) AND defined (TI_PS_FF_EMR)
3806 psc_db->network_pg_mode = psi1->page_mode;
3807 #endif
3808 #endif
3809 break;
3810 case ACQ_COMP_OK:
3811 psi_stop_60sec(TRUE);/*restart 60 sec*/
3812 psi_stop_30sec(TRUE);/*restart 30 sec*/
3813 psi_stop_psi_reading(NONE);
3814 /*
3815 * Access to the network is allowed
3816 */
3817 psi_send_access_enable_if_needed();
3818 break;
3819 case ACQ_PERIOD_OK:
3820 /*
3821 * Periodical pSI1 reading is O.K.
3822 */
3823 psi_stop_60sec(TRUE);/*restart 60 sec*/
3824 psi_stop_30sec(TRUE);/*restart 30 sec*/
3825 psi_stop_psi_reading(NONE);
3826 break;
3827 default:
3828 TRACE_ERROR("Unexpected acq_ret in PSI1");
3829 break;
3830 }/* switch acq_state*/
3831 break;
3832 case PSI1_COMPLETE_ACQ:
3833 psi_initiate_read_complete_psi( INIT_NOT_NEEDED );
3834 break;
3835 case PSI1_PARTIAL_ACQ:
3836 /* update psi data*/
3837 psi_stop_60sec(TRUE);/*restart 60 sec*/
3838 psi_stop_30sec(TRUE);/*restart 30 sec*/
3839 psi_update_data_to_request( INIT_NOT_NEEDED);
3840 psi_partial_acq();
3841 /*TRACE_EVENT("Complete instead partial");
3842 psi_receive_psi(READ_COMPLETE);*/
3843 psc_db->send_psi_status = TRUE; /* this parameters has meaning if the network supports PSI STATUS */
3844 psi_start_10sec();
3845 break;
3846 }/* switch process_psi1*/
3847 if(psi_is_access_class_changed() AND !psc_db->psi1_params.first_psi1)
3848 {
3849 /*
3850 * Implies the CTRL to send CELL_IND
3851 */
3852 sig_psi_ctrl_access_changed();
3853 }
3854 if(psc_db->acq_type NEQ COMPLETE)
3855 {
3856 psc_db->psi1_params.first_psi1 = FALSE;
3857 }
3858
3859 }/* psi_handle_psi1*/
3860
3861 /*
3862 +------------------------------------------------------------------------------
3863 | Function : psi_handle_psi2
3864 +------------------------------------------------------------------------------
3865 | Description : The function handles PSI2 message on both PBCCH and PACCH channels
3866 |
3867 | Parameters : T_PSI_2*
3868 |
3869 +------------------------------------------------------------------------------
3870 */
3871 GLOBAL void psi_handle_psi2(T_PSI_2 * psi2)
3872 {
3873 TRACE_FUNCTION("psi_handle_psi2");
3874 switch(psi_process_psi2(psi2))
3875 {
3876 case PSI2_OK:
3877 switch(psi_check_acq_state())
3878 {
3879 case ACQ_RUNNING:
3880 /*
3881 * Check whether access to the network is allowed or not,
3882 * in case of having complete acq
3883 */
3884 if(psi_is_access_allowed() AND (psc_db->acq_type EQ COMPLETE))
3885 {
3886 psi_stop_psi_reading(NONE);
3887 psi_stop_10sec(); /* Stop this timer, if running */
3888 #ifdef _SIMULATION_
3889 vsi_t_stop(GRR_handle,T_COMP_PSI);
3890 #endif
3891 /*
3892 * Access to the network is allowed
3893 */
3894 psi_send_access_enable_if_needed();
3895 }
3896 else if(psi_is_access_allowed() AND (psc_db->acq_type EQ FULL_PSI_IN_NEW_CELL))
3897 {
3898 /*
3899 * Access to the new re-selected cell is allowed
3900 */
3901 psi_stop_psi_reading(NONE);
3902 sig_psi_ctrl_ncell_psi_read( TRUE );
3903 }
3904 break;
3905 case ACQ_PART_OK:
3906 psi_stop_psi_reading(NONE);
3907 /*
3908 * TimeSlot number may have changed, so we have to restart PCCCH reading
3909 */
3910 TRACE_EVENT("PSI2->NEW_PCCCH");
3911 sig_psi_ctrl_new_pccch();
3912 #if defined (REL99) AND defined (TI_PS_FF_EMR)
3913 psc_db->network_pg_mode = psi2->page_mode;
3914 #endif
3915 break;
3916 case ACQ_COMP_OK:
3917 psi_stop_psi_reading(NONE);
3918 /*
3919 * Access to the network is allowed
3920 */
3921 psi_send_access_enable_if_needed();
3922 break;
3923 default:
3924 TRACE_ERROR("Unexpected acq_ret in PSI2");
3925 break;
3926 }/*switch check_acq*/
3927 break;
3928 case PSI2_REREAD:
3929 /*
3930 * Error situation read a new PSI2
3931 */
3932 psi_reread_psi2();
3933 break;
3934 }
3935 }/* psi_handle_psi2*/
3936 /*
3937 +------------------------------------------------------------------------------
3938 | Function : psi_handle_psi3
3939 +------------------------------------------------------------------------------
3940 | Description : The function handles PSI3 message on both PBCCH and PACCH channels
3941 |
3942 | Parameters : T_PSI_3*
3943 |
3944 +------------------------------------------------------------------------------
3945 */
3946 GLOBAL void psi_handle_psi3(T_PSI_3 * psi3)
3947 {
3948 TRACE_FUNCTION("psi_handle_psi3");
3949 switch(psi_process_psi3(psi3))
3950 {
3951 case PSI3_NCELL_VALID:
3952 /*
3953 * Inform MEAS that the NCELL parameters are valid
3954 */
3955 sig_psi_ctrl_ncell_param_valid();
3956
3957 /*lint -fallthrough*/
3958
3959 case PSI3_OK:
3960 /*
3961 * check the acquisition state: it is only for having a complete set of information
3962 */
3963 switch(psi_check_acq_state())
3964 {
3965 case ACQ_RUNNING:
3966 /*
3967 * Nothing to do
3968 */
3969 break;
3970 case ACQ_PART_OK:
3971 psi_stop_psi_reading(NONE);
3972 #ifdef _TARGET_
3973 TRACE_EVENT("PSI3->NEW_PCCCH");
3974 sig_psi_ctrl_new_pccch();
3975 #if defined (REL99) AND defined (TI_PS_FF_EMR)
3976 psc_db->network_pg_mode = psi3->page_mode;
3977 #endif
3978 #endif
3979 break;
3980 case ACQ_COMP_OK:
3981 psi_stop_psi_reading(NONE);
3982 /*
3983 * Access to the network is allowed
3984 */
3985 psi_send_access_enable_if_needed();
3986 break;
3987 default:
3988 TRACE_ERROR("Unexpected acq_ret in PSI3");
3989 break;
3990 }/*switch check_acq*/
3991 break;
3992 case PSI3_NCELL_INVALID:
3993 grr_init_nc_list( &psc_db->nc_cw.list );
3994 sig_psi_ctrl_ncell_param_invalid();
3995 break;
3996 case PSI3_CELL_BARRED:
3997 sig_psi_ctrl_access_barred();
3998 break;
3999 }/* switch psi_process_psi3*/
4000 }/*psi_handle_psi3*/
4001 /*
4002 +------------------------------------------------------------------------------
4003 | Function : psi_handle_psi3bis
4004 +------------------------------------------------------------------------------
4005 | Description : The function handles PSI3_BIS message on both PBCCH and PACCH channels
4006 |
4007 | Parameters : T_PSI_3_BIS*
4008 |
4009 +------------------------------------------------------------------------------
4010 */
4011 GLOBAL void psi_handle_psi3bis(T_PSI_3_BIS * psi3bis)
4012 {
4013 TRACE_FUNCTION("psi_handle_psi3bis");
4014 switch(psi_process_psi3bis(psi3bis))
4015 {
4016 case PSI3BIS_REREAD_PSI3BIS:
4017 psi_reread_psi3bis();
4018 /*
4019 * Ncell parameter are invalid. We have to inform MEAS-Service
4020 */
4021 grr_init_nc_list( &psc_db->nc_cw.list );
4022 sig_psi_ctrl_ncell_param_invalid();
4023 break;
4024 #if defined (REL99) AND defined (TI_PS_FF_EMR)
4025 case PSI3BIS_REREAD_PSI3_3BIS_3TER:
4026 psi_reread_psi3_3bis_3ter();
4027 #else
4028 case PSI3BIS_REREAD_PSI3_3BIS:
4029 psi_reread_psi3_and_3bis();
4030 #endif
4031 /*
4032 * Ncell parameter are invalid. We have to inform MEAS-Service
4033 */
4034 grr_init_nc_list( &psc_db->nc_cw.list );
4035 sig_psi_ctrl_ncell_param_invalid();
4036 break;
4037
4038 case PSI3BIS_NCELL_VALID:
4039 /*
4040 * Inform MEAS that the NCELL parameters are valid
4041 */
4042 sig_psi_ctrl_ncell_param_valid();
4043
4044 /*lint -fallthrough*/
4045
4046 case PSI3BIS_OK:
4047 /*
4048 * check the acquisition state: it is only for having a complete set of information
4049 */
4050 switch(psi_check_acq_state())
4051 {
4052 case ACQ_RUNNING:
4053 /*
4054 * Nothing to do
4055 */
4056 break;
4057 case ACQ_PART_OK:
4058 psi_stop_psi_reading(NONE);
4059 #ifdef _TARGET_
4060 TRACE_EVENT("PSI3bis->NEW_PCCCH");
4061 sig_psi_ctrl_new_pccch();
4062 #if defined (REL99) AND defined (TI_PS_FF_EMR)
4063 psc_db->network_pg_mode = psi3bis->page_mode;
4064 #endif
4065 #endif
4066 break;
4067 case ACQ_COMP_OK:
4068 psi_stop_psi_reading(NONE);
4069 /*
4070 * Access to the network is allowed
4071 */
4072 psi_send_access_enable_if_needed();
4073 break;
4074 default:
4075 TRACE_ERROR("Unexpected acq_ret in PSI3bis");
4076 break;
4077 }/*switch check_acq*/
4078 break;
4079 }/* switch process_psi3bis*/
4080
4081 }/*psi_handle_psi3bis*/
4082
4083 #if defined (REL99) AND defined (TI_PS_FF_EMR)
4084 /*
4085 +------------------------------------------------------------------------------
4086 | Function : psi_handle_psi3ter
4087 +------------------------------------------------------------------------------
4088 | Description : The function handles PSI3_TER message on both PBCCH and PACCH channels
4089 |
4090 | Parameters : T_PSI_3_TER*
4091 |
4092 +------------------------------------------------------------------------------
4093 */
4094 GLOBAL void psi_handle_psi3ter(T_PSI_3_TER * psi3ter)
4095 {
4096 TRACE_FUNCTION("psi_handle_psi3ter");
4097 switch(psi_process_psi3ter(psi3ter))
4098 {
4099 case PSI3TER_REREAD_PSI3TER:
4100 psi_reread_psi3ter();
4101 break;
4102 case PSI3TER_REREAD_PSI3_3BIS_3TER:
4103 psi_reread_psi3_3bis_3ter();
4104 break;
4105 case PSI3TER_OK:
4106 /*
4107 * check the acquisition state: it is only for having a complete set of information
4108 */
4109 switch(psi_check_acq_state())
4110 {
4111 case ACQ_RUNNING:
4112 /*
4113 * Nothing to do
4114 */
4115 break;
4116 case ACQ_PART_OK:
4117 psi_stop_psi_reading(NONE);
4118 #ifdef _TARGET_
4119 TRACE_EVENT("PSI3ter->NEW_PCCCH");
4120 sig_psi_ctrl_new_pccch();
4121 psc_db->network_pg_mode = psi3ter->page_mode;
4122 #endif
4123 break;
4124 case ACQ_COMP_OK:
4125 psi_stop_psi_reading(NONE);
4126 /*
4127 * Access to the network is allowed
4128 */
4129 psi_send_access_enable_if_needed();
4130 break;
4131 default:
4132 TRACE_ERROR("Unexpected acq_ret in PSI3bis");
4133 break;
4134 }/*switch check_acq*/
4135 break;
4136 }/* switch process_psi3ter*/
4137
4138 }/*psi_handle_psi3ter*/
4139
4140 #endif
4141
4142
4143
4144 /*
4145 +------------------------------------------------------------------------------
4146 | Function : psi_handle_psi4
4147 +------------------------------------------------------------------------------
4148 | Description : The function handles PSI4 message on both PBCCH and PACCH channels
4149 |
4150 | Parameters : T_PSI_4*
4151 |
4152 +------------------------------------------------------------------------------
4153 */
4154 GLOBAL void psi_handle_psi4(T_PSI_4 * psi4)
4155 {
4156 TRACE_FUNCTION("psi_handle_psi4");
4157 switch(psi_process_psi4(psi4))
4158 {
4159 case PSI4_REREAD:
4160 psi_reread_psi4();
4161 /*
4162 * Interference channel list is invalid. We have to inform MEAS-Service
4163 */
4164 sig_psi_ctrl_int_list_invalid();
4165 break;
4166 case PSI4_INT_LIST_VALID:
4167 /*
4168 * Inform MEAS that the Interference parameters are valid
4169 */
4170 sig_psi_ctrl_int_list_valid();
4171
4172 /*lint -fallthrough*/
4173
4174 case PSI4_OK:
4175 /*
4176 * check the acquisition state: it is only for having a complete set of information
4177 */
4178 switch(psi_check_acq_state())
4179 {
4180 case ACQ_RUNNING:
4181 /*
4182 * Nothing to do
4183 */
4184 break;
4185 case ACQ_PART_OK:
4186 psi_stop_psi_reading(NONE);
4187 #ifdef _TARGET_
4188 TRACE_EVENT("PSI4->NEW_PCCCH");
4189 sig_psi_ctrl_new_pccch();
4190 #if defined (REL99) AND defined (TI_PS_FF_EMR)
4191 psc_db->network_pg_mode = psi4->page_mode;
4192 #endif
4193 #endif
4194 break;
4195 case ACQ_COMP_OK:
4196 psi_stop_psi_reading(NONE);
4197 /*
4198 * Access to the network is allowed
4199 */
4200 psi_send_access_enable_if_needed();
4201 break;
4202 default:
4203 TRACE_ERROR("Unexpected acq_ret in PSI4");
4204 break;
4205 }/*switch check_acq*/
4206 break;
4207 }
4208 }/* psi_handle_psi4*/
4209
4210 #ifdef REL99
4211 /*
4212 +------------------------------------------------------------------------------
4213 | Function : psi_handle_psi8
4214 +------------------------------------------------------------------------------
4215 | Description : The function handles PSI8 message on both PBCCH and PACCH channels
4216 |
4217 | Parameters : T_PSI_8*
4218 |
4219 +------------------------------------------------------------------------------
4220 */
4221 GLOBAL void psi_handle_psi8(T_PSI_8 * psi8)
4222 {
4223 TRACE_FUNCTION("psi_handle_psi8");
4224 switch(psi_process_psi8(psi8))
4225 {
4226 case PSI8_REREAD:
4227 psi_reread_psi8();
4228 break;
4229 case PSI8_OK:
4230 /*
4231 * check the acquisition state: it is only for having a complete set of information
4232 */
4233 switch(psi_check_acq_state())
4234 {
4235 case ACQ_RUNNING:
4236 /*
4237 * Nothing to do
4238 */
4239 break;
4240 case ACQ_PART_OK:
4241 psi_stop_psi_reading(NONE);
4242 #ifdef _TARGET_
4243 TRACE_EVENT("PSI8->NEW_PCCCH");
4244 sig_psi_ctrl_new_pccch();
4245 psc_db->network_pg_mode = psi8->page_mode;
4246 #endif
4247 break;
4248 case ACQ_COMP_OK:
4249 psi_stop_psi_reading(NONE);
4250 /*
4251 * Access to the network is allowed
4252 */
4253 psi_send_access_enable_if_needed();
4254 break;
4255 default:
4256 TRACE_ERROR("Unexpected acq_ret in PSI8");
4257 break;
4258 }/*switch check_acq*/
4259 break;
4260 }
4261 }/* psi_handle_psi8*/
4262 #endif
4263
4264 /*
4265 +------------------------------------------------------------------------------
4266 | Function : psi_copy_si13_params
4267 +------------------------------------------------------------------------------
4268 | Description : The function copies si13 parameters into sc_db
4269 |
4270 | Parameters : T_D_SYS_INFO_13*
4271 |
4272 +------------------------------------------------------------------------------
4273 */
4274 LOCAL void psi_copy_si13_params(T_D_SYS_INFO_13* si13)
4275 {
4276 TRACE_FUNCTION("psi_copy_si13_params");
4277
4278 /*
4279 * Copy SI13_CHANGE_MARK and GPRS Mobile Allocation
4280 */
4281 if(si13->si13_rest_oct.si13_info.flag)
4282 {
4283 psc_db->psi13_params.si13_change_mark = si13->si13_rest_oct.si13_info.si13_cm;
4284 psi_copy_ma_from_psi13((T_gprs_ms_alloc_ie*)&(si13->si13_rest_oct.si13_info.gprs_ma));
4285 }
4286
4287 grr_set_pbcch( si13->si13_rest_oct.si13_info.v_pbcch_des );
4288
4289 if(si13->si13_rest_oct.si13_info.v_pbcch_des)
4290 {
4291 /*
4292 * PBCCH description present in the SI13 message
4293 */
4294
4295 psc_db->psi1_params.psi1_repeat_period = si13->si13_rest_oct.si13_info.psi1_period + 1;
4296 /* pbcch description in database and in SI13 is different!!!*/
4297 psc_db->pbcch.pbcch_des.pb = si13->si13_rest_oct.si13_info.pbcch_des.pb;
4298 psc_db->pbcch.pbcch_des.tsc = si13->si13_rest_oct.si13_info.pbcch_des.tsc;
4299 psc_db->pbcch.pbcch_des.tn = si13->si13_rest_oct.si13_info.pbcch_des.tn;
4300
4301 if((si13->si13_rest_oct.si13_info.pbcch_des.flag EQ FALSE) AND (si13->si13_rest_oct.si13_info.pbcch_des.flag2 EQ FALSE))
4302 {
4303 psc_db->pbcch.pbcch_des.flag = FALSE;
4304 }
4305 else
4306 {
4307 psc_db->pbcch.pbcch_des.flag = TRUE;
4308 }
4309
4310 psc_db->pbcch.pbcch_des.v_arfcn = si13->si13_rest_oct.si13_info.pbcch_des.v_arfcn;
4311 psc_db->pbcch.pbcch_des.arfcn = si13->si13_rest_oct.si13_info.pbcch_des.arfcn;
4312 psc_db->pbcch.pbcch_des.v_maio = si13->si13_rest_oct.si13_info.pbcch_des.v_maio;
4313 psc_db->pbcch.pbcch_des.maio = si13->si13_rest_oct.si13_info.pbcch_des.maio;
4314 }
4315 else
4316 {
4317 /*
4318 * No PBCCH description present in the SI13 message
4319 */
4320
4321 /*
4322 * Copy non PBCCH parameters: RAC, SPGC_CCCH_SUP, PRIORITY_ACCESS_THR,
4323 * NETWORK_CONTROL_ORDER
4324 */
4325 /* Set RAC value */
4326 psc_db->cell_info_for_gmm.cell_info.cell_env.rai.rac = si13->si13_rest_oct.si13_info.rac;
4327
4328 psc_db->net_ctrl.spgc_ccch_supp.nw_supp = si13->si13_rest_oct.si13_info.spgc;
4329 psc_db->net_ctrl.priority_access_thr = si13->si13_rest_oct.si13_info.prio_acc_thr;
4330
4331 /*
4332 * Copy NC measurement parameter
4333 */
4334 {
4335 T_nc_meas_par nc_meas_par;
4336
4337 nc_meas_par.ctrl_order = si13->si13_rest_oct.si13_info.nco;
4338 nc_meas_par.v_nc_meas_per = FALSE;
4339 /*
4340 * SI13 doesnt carry the nc meas parameters. So we should not reset/change the
4341 * parameters after receiving every SI13 periodic reading.
4342 */
4343 if( (nc_meas_par.ctrl_order EQ NCMEAS_NC2) OR (nc_meas_par.ctrl_order EQ NCMEAS_NC1) )
4344 {
4345 if ( (psc_db->nc_cw.param.rep_per_i NEQ NC_REP_PER_I_DEFAULT ) AND
4346 (psc_db->nc_cw.param.rep_per_t NEQ NC_REP_PER_T_DEFAULT) AND
4347 (psc_db->nc_cw.param.non_drx_per NEQ NC_NON_DRX_PER_DEFAULT) AND
4348 (psc_db->nc_cw.param.ctrl_order NEQ NC_NC0) AND
4349 (psc_db->nc_cw.param.idx NEQ NOT_SET) )
4350 {
4351 nc_meas_par.nc_meas_per.non_drx_per = psc_db->nc_cw.param.non_drx_per;
4352 nc_meas_par.nc_meas_per.rep_per_i = psc_db->nc_cw.param.rep_per_i ;
4353 nc_meas_par.nc_meas_per.rep_per_t = psc_db->nc_cw.param.rep_per_t;
4354 nc_meas_par.v_nc_meas_per = TRUE;
4355 }
4356 }
4357
4358 /*
4359 * Only one instance of SI13, store data in final location.
4360 */
4361 grr_prcs_nc_param_struct ( &psc_db->nc_cw.param, &nc_meas_par, 0 );
4362 }
4363
4364 /*
4365 * Copy GPRS cell options
4366 */
4367 psc_db->v_gprs_cell_opt = TRUE;
4368 /*
4369 * SZML-PSI/001
4370 */
4371 memcpy(&(psc_db->gprs_cell_opt), &(si13->si13_rest_oct.si13_info.gprs_cell_opt), sizeof(T_gprs_cell_opt));
4372
4373 if(si13->si13_rest_oct.si13_info.gprs_cell_opt.nmo EQ GMMRR_NET_MODE_III)
4374 {
4375 TRACE_EVENT("NMO III in network ----> GMMRR_NET_MODE_II");
4376 psc_db->cell_info_for_gmm.cell_info.net_mode = GMMRR_NET_MODE_II;
4377 }
4378 else
4379 {
4380 psc_db->cell_info_for_gmm.cell_info.net_mode = si13->si13_rest_oct.si13_info.gprs_cell_opt.nmo;
4381 }
4382
4383
4384 /*
4385 * Copy power control parameters
4386 */
4387 {
4388 T_si13_info *si13_info = &si13->si13_rest_oct.si13_info;
4389
4390 psc_db->v_g_pwr_par = TRUE;
4391
4392 psc_db->g_pwr_par.alpha = CLIP_ALPHA( si13_info->alpha );
4393 psc_db->g_pwr_par.t_avg_w = CLIP_T_AVG( si13_info->t_avg_w );
4394 psc_db->g_pwr_par.t_avg_t = CLIP_T_AVG( si13_info->t_avg_t );
4395 psc_db->g_pwr_par.pb = 0;
4396 psc_db->g_pwr_par.pc_meas_chan = si13_info->pc_meas_chan;
4397 psc_db->g_pwr_par.imeas_chan_list = FALSE;
4398 psc_db->g_pwr_par.n_avg_i = si13_info->n_avg_i;
4399
4400 grr_data->pwr_ctrl_valid_flags.v_glbl_pwr_ctrl_param = TRUE;
4401 }
4402 }
4403 }/* psi_copy_si13_params */
4404
4405
4406
4407 /*
4408 +------------------------------------------------------------------------------
4409 | Function : psi_is_pbcch_des_different
4410 +------------------------------------------------------------------------------
4411 | Description : The function checks whether PBCCH description of the received
4412 | PSI13 message is different from the stored one
4413 |
4414 | Parameters : T_PSI_13*; TRUE: If desc. are different FALSE: same
4415 |
4416 +------------------------------------------------------------------------------
4417 */
4418 LOCAL BOOL psi_is_pbcch_des_different(T_PSI_13* psi13)
4419 {
4420 TRACE_FUNCTION("psi_is_pbcch_des_different");
4421 if(!psi13->flag) /* No PBCCH description present: PBCCH no longer available*/
4422 return TRUE;
4423
4424 /* compare PBCCH descriptions*/
4425 if((psc_db->pbcch.pbcch_des.pb EQ psi13->psi1_pbcch_info.pbcch_des.pb) AND
4426 (psc_db->pbcch.pbcch_des.tsc EQ psi13->psi1_pbcch_info.pbcch_des.tsc) AND
4427 (psc_db->pbcch.pbcch_des.tn EQ psi13->psi1_pbcch_info.pbcch_des.tn))
4428 {
4429 /* compare BCCH carrier-flag, if exists*/
4430 if(psc_db->pbcch.pbcch_des.flag NEQ psi13->psi1_pbcch_info.pbcch_des.flag)
4431 return TRUE;
4432
4433 /* compare non-hopping carrier, if exists: ARFCN*/
4434 if(
4435 (psc_db->pbcch.pbcch_des.v_arfcn NEQ psi13->psi1_pbcch_info.pbcch_des.v_arfcn)
4436 OR
4437 (psc_db->pbcch.pbcch_des.arfcn NEQ psi13->psi1_pbcch_info.pbcch_des.arfcn)
4438 )
4439 return TRUE;
4440
4441 /* Compare hopping carrier, if exists: MAIO*/
4442 if(
4443 (psc_db->pbcch.pbcch_des.v_maio NEQ psi13->psi1_pbcch_info.pbcch_des.v_maio)
4444 OR
4445 (psc_db->pbcch.pbcch_des.maio NEQ psi13->psi1_pbcch_info.pbcch_des.maio)
4446 )
4447 return TRUE;
4448 }
4449 else
4450 {
4451 return TRUE;
4452 }
4453 return FALSE;
4454 }/* psi_is_pbcch_des_different*/
4455
4456 /*
4457 +------------------------------------------------------------------------------
4458 | Function : psi_copy_psi13_params
4459 +------------------------------------------------------------------------------
4460 | Description : The function copies psi13 parameters into sc_db
4461 |
4462 | Parameters : T_PSI_13*
4463 |
4464 +------------------------------------------------------------------------------
4465 */
4466 LOCAL void psi_copy_psi13_params(T_PSI_13* psi13)
4467 {
4468 TRACE_FUNCTION("psi_copy_psi13_params");
4469
4470 /*
4471 * Handle SI13_CHANGE_MARK and GPRS Mobile Allocation
4472 */
4473 if(psi13->v_si13_cm_gprs_alloc)
4474 {
4475 psc_db->psi13_params.si13_change_mark = psi13->si13_cm_gprs_alloc.si13_cm;
4476 psi_copy_ma_from_psi13(&(psi13->si13_cm_gprs_alloc.gprs_ms_alloc_ie));
4477 }
4478
4479 grr_set_pbcch( psi13->flag );
4480
4481 if(psi13->flag)
4482 {
4483 /*
4484 * PBCCH description present in the PSI13 message
4485 */
4486
4487 psc_db->psi1_params.psi1_repeat_period = psi13->psi1_pbcch_info.psi1_rep_per + 1;
4488 memcpy(&(psc_db->pbcch.pbcch_des), &(psi13->psi1_pbcch_info.pbcch_des), sizeof(T_pbcch_des));
4489 }
4490 else
4491 {
4492 /*
4493 * No PBCCH description present in the PSI13 message
4494 */
4495
4496 /*
4497 * Copy non PBCCH parameters: RAC, SPGC_CCCH_SUP, PRIORITY_ACCESS_THR
4498 */
4499 /* Set RAC value */
4500 psc_db->cell_info_for_gmm.cell_info.cell_env.rai.rac = psi13->pbcch_n_pres.rac;
4501
4502 psc_db->net_ctrl.spgc_ccch_supp.nw_supp = psi13->pbcch_n_pres.spgc_ccch_sup;
4503 psc_db->net_ctrl.priority_access_thr = psi13->pbcch_n_pres.prio_acc_thr;
4504
4505 /*
4506 * Copy NC measurement parameter
4507 */
4508 {
4509 T_nc_meas_par nc_meas_par;
4510
4511 nc_meas_par.ctrl_order = psi13->pbcch_n_pres.ctrl_order;
4512 nc_meas_par.v_nc_meas_per = FALSE;
4513
4514 /*
4515 * Only one instance of PSI13, store data in final location.
4516 */
4517 grr_prcs_nc_param_struct ( &psc_db->nc_cw.param, &nc_meas_par, 0 );
4518 }
4519
4520 /*
4521 * Copy GPRS cell options
4522 */
4523 psc_db->v_gprs_cell_opt = TRUE;
4524 /*
4525 * SZML-PSI/002
4526 */
4527 memcpy(&(psc_db->gprs_cell_opt), &(psi13->pbcch_n_pres.gprs_cell_opt), sizeof(T_gprs_cell_opt));
4528 psc_db->cell_info_for_gmm.cell_info.net_mode = psi13->pbcch_n_pres.gprs_cell_opt.nmo;
4529
4530 /*
4531 * Copy power control parameters
4532 */
4533 {
4534 T_psi13_pwr_par *pwr_par = &psi13->pbcch_n_pres.psi13_pwr_par;
4535
4536 psc_db->v_g_pwr_par = TRUE;
4537
4538 psc_db->g_pwr_par.alpha = CLIP_ALPHA( pwr_par->alpha);
4539 psc_db->g_pwr_par.t_avg_w = CLIP_T_AVG( pwr_par->t_avg_w );
4540 psc_db->g_pwr_par.t_avg_t = CLIP_T_AVG( pwr_par->t_avg_t );
4541 psc_db->g_pwr_par.pb = 0;
4542 psc_db->g_pwr_par.pc_meas_chan = pwr_par->pc_meas_chan;
4543 psc_db->g_pwr_par.imeas_chan_list = FALSE;
4544 psc_db->g_pwr_par.n_avg_i = pwr_par->n_avg_i;
4545
4546 grr_data->pwr_ctrl_valid_flags.v_glbl_pwr_ctrl_param = TRUE;
4547 }
4548 }
4549 } /* psi_copy_psi13_params */
4550
4551 /*
4552 +------------------------------------------------------------------------------
4553 | Function : psi_send_access_enable_if_needed
4554 +------------------------------------------------------------------------------
4555 | Description : The function sends signal to CTRL to indicate that the access
4556 | is enabled
4557 |
4558 | Parameters :
4559 |
4560 +------------------------------------------------------------------------------
4561 */
4562 GLOBAL void psi_send_access_enable_if_needed()
4563 {
4564 TRACE_FUNCTION("psi_send_access_enable_if_needed");
4565
4566 if(!psc_db->is_access_enabled)
4567 {
4568 psc_db->is_access_enabled = TRUE;
4569
4570 sig_psi_ctrl_access_enabled( );
4571 }
4572 #ifdef _TARGET_
4573 else if(grr_is_pbcch_present())
4574 {
4575 /*
4576 * Inform CTRL about new pccch, if there is a new one exists.
4577 * It may be the PBCCH and/or PCCCH description has been
4578 * changed, so that PCCCH reading should be started again.
4579 * If not this is not a big problem. This is done to avoid
4580 * saving PCCCH description in database to compare whether
4581 * it has been changed or not.
4582 */
4583 TRACE_EVENT("Access enabled, PCCCH may have changed");
4584 sig_psi_ctrl_new_pccch();
4585 }
4586 #endif /* _TARGET_ */
4587
4588 #ifdef REL99
4589 TRACE_EVENT_P2 ("pbbch %d, cbch_info %d", grr_is_pbcch_present(), psc_db->send_cbch_info_ind);
4590 if(grr_is_pbcch_present() AND psc_db->send_cbch_info_ind)
4591 {
4592 sig_psi_ctrl_cbch_info_ind();
4593 psc_db->send_cbch_info_ind = FALSE;
4594 }
4595 #endif
4596
4597 }/*psi_send_access_enable_if_needed */
4598
4599 /*
4600 +------------------------------------------------------------------------------
4601 | Function : psi_initiate_read_complete_si
4602 +------------------------------------------------------------------------------
4603 | Description :
4604 |
4605 | Parameters :
4606 |
4607 +------------------------------------------------------------------------------
4608 */
4609 GLOBAL void psi_initiate_read_complete_si ( void )
4610 {
4611 TRACE_FUNCTION( "psi_initiate_read_complete_si" );
4612
4613 psi_stop_60sec( TRUE );
4614 psi_stop_30sec( TRUE );
4615 sig_psi_ctrl_access_disabled( PSI_DC_OTHER );
4616
4617 } /* psi_initiate_read_complete_si */
4618
4619 /*
4620 +------------------------------------------------------------------------------
4621 | Function : psi_initiate_read_complete_psi
4622 +------------------------------------------------------------------------------
4623 | Description :
4624 |
4625 | Parameters :
4626 |
4627 +------------------------------------------------------------------------------
4628 */
4629 GLOBAL void psi_initiate_read_complete_psi ( UBYTE init_needed )
4630 {
4631 TRACE_FUNCTION( "psi_initiate_read_complete_psi" );
4632
4633 TRACE_EVENT( "PBCCH present" );
4634
4635 psi_stop_60sec( TRUE );
4636 psi_stop_30sec( TRUE );
4637 psi_update_data_to_request( init_needed );
4638 sig_psi_ctrl_access_disabled( PSI_DC_READ_PSI );
4639
4640 } /* psi_initiate_read_complete_psi */
4641
4642 /*
4643 +------------------------------------------------------------------------------
4644 | Function : psi_initiate_pbcch_switching
4645 +------------------------------------------------------------------------------
4646 | Description :
4647 |
4648 | Parameters :
4649 |
4650 +------------------------------------------------------------------------------
4651 */
4652 GLOBAL void psi_initiate_pbcch_switching ( T_PSI_DISABLE_CAUSE dc )
4653 {
4654 TRACE_FUNCTION( "psi_initiate_pbcch_switching" );
4655
4656 if( psc_db->acq_type NEQ NONE )
4657 {
4658 psi_stop_psi_reading(NONE);
4659 }
4660
4661 sig_psi_ctrl_access_disabled( dc );
4662 psi_stop_timer();
4663 psi_init_params();
4664 grr_set_pbcch( FALSE );
4665
4666 } /* psi_initiate_pbcch_switching */
4667
4668 /*
4669 +------------------------------------------------------------------------------
4670 | Function : psi_store_ncell_param
4671 +------------------------------------------------------------------------------
4672 | Description :
4673 | Parameters :
4674 +------------------------------------------------------------------------------
4675 */
4676 LOCAL UBYTE psi_store_ncell_param ( T_ncell_par *p_ncell_par,
4677 UBYTE c_ncell_par,
4678 UBYTE v_ncell_par,
4679 T_INFO_TYPE type,
4680 UBYTE instance )
4681 {
4682 UBYTE i, j;
4683 UBYTE number = 0;
4684 USHORT last_freq;
4685
4686 TRACE_FUNCTION( "psi_store_ncell_param" );
4687
4688 if( !v_ncell_par )
4689 {
4690 switch ( type )
4691 {
4692 case( INFO_TYPE_PSI3 ):
4693 TRACE_EVENT( "No ncell parameters in PSI3" );
4694 break;
4695
4696 case( INFO_TYPE_PSI3BIS ):
4697 TRACE_EVENT( "No ncell parameters in PSI3BIS" );
4698 break;
4699
4700 default:
4701 TRACE_EVENT( "Unexpected neighbour cell information source" );
4702 break;
4703 }
4704
4705 return( number ); /* no ncell parameters */
4706 }
4707
4708 switch ( type )
4709 {
4710 case( INFO_TYPE_PSI3 ):
4711 case( INFO_TYPE_PSI3BIS ):
4712 break;
4713
4714 default:
4715 TRACE_EVENT( "Unexpected neighbour cell information source" );
4716 return( number );
4717 }
4718
4719 for( i = 0; i < c_ncell_par; i++ )
4720 {
4721 last_freq = 0;
4722
4723 if( grr_store_cs_param
4724 ( &psc_db->nc_cw.list,
4725 TRUE,
4726 &p_ncell_par[i].cs_par,
4727 type,
4728 instance,
4729 &number,
4730 &last_freq,
4731 p_ncell_par[i].start_freq,
4732 p_ncell_par[i].bsic ) EQ FALSE )
4733 {
4734 TRACE_EVENT( "psi_store_ncell_param: NC_CW list full" );
4735
4736 return( number );
4737 }
4738
4739 for( j = 0; j < p_ncell_par[i].n_rest; j++ )
4740 {
4741 if( grr_store_cs_param
4742 ( &psc_db->nc_cw.list,
4743 TRUE,
4744 &p_ncell_par[i].ncell_par_rest[j].cs_par,
4745 type,
4746 instance,
4747 &number,
4748 &last_freq,
4749 p_ncell_par[i].ncell_par_rest[j].freq_diff_struct.freq_diff,
4750 p_ncell_par[i].ncell_par_rest[j].bsic ) EQ FALSE )
4751 {
4752 TRACE_EVENT( "psi_store_ncell_param: NC_CW list full" );
4753
4754 return( number );
4755 }
4756 }
4757 }
4758
4759 return( number );
4760 }/* psi_store_ncell_param */
4761
4762 /*
4763 +------------------------------------------------------------------------------
4764 | Function : psi_store_ncell_param2
4765 +------------------------------------------------------------------------------
4766 | Description :
4767 | Parameters :
4768 +------------------------------------------------------------------------------
4769 */
4770 LOCAL void psi_store_ncell_param2 ( T_PSI_3_BIS *psi3bis, UBYTE number )
4771 {
4772 T_ncell_par2_s1 *p_sub_1;
4773 T_ncell_par2_s2 *p_sub_2;
4774
4775 USHORT last_freq;
4776 UBYTE i, j, cell_params_ptr, x, y, n;
4777
4778 TRACE_FUNCTION( "psi_store_ncell_param2" );
4779
4780 if( !psi3bis->ncell_par_trnc_grp.v_ncell_par2 )
4781 {
4782 return;
4783 }
4784
4785 for( i = 0;
4786 i < psi3bis->ncell_par_trnc_grp.c_ncell_par2;
4787 i++ )
4788 {
4789 for( n = 0;
4790 n < psi3bis->ncell_par_trnc_grp.ncell_par2[i].c_ncell_par2_des;
4791 n++ )
4792 {
4793 cell_params_ptr = psi3bis->ncell_par_trnc_grp.ncell_par2[i].ncell_par2_des[n].para_ptr;
4794
4795 if( cell_params_ptr > psi3bis->ncell_par_trnc_grp.ncell_par2[i].c_ncell_par2_set )
4796 {
4797 TRACE_ERROR( "cell_params_ptr > psi3bis->ncell_par2[i].c_ncell_par2_set" );
4798
4799 return;
4800 }
4801
4802 for( j = 0;
4803 j < psi3bis->ncell_par_trnc_grp.ncell_par2[i].ncell_par2_des[n].c_ncell_par2_s1;
4804 j++ )
4805 {
4806 last_freq = 0;
4807 p_sub_1 = &psi3bis->ncell_par_trnc_grp.ncell_par2[i].ncell_par2_des[n].ncell_par2_s1[j];
4808
4809 if( psi_store_cs_param2
4810 ( &psc_db->nc_cw.list,
4811 &psi3bis->ncell_par_trnc_grp.ncell_par2[i].ncell_par2_set[cell_params_ptr],
4812 psi3bis->psi3bis_ind,
4813 &number,
4814 &last_freq,
4815 p_sub_1->start_freq,
4816 p_sub_1->same_ra_scell,
4817 p_sub_1->cell_ba,
4818 p_sub_1->bcc ) EQ FALSE )
4819 {
4820 TRACE_EVENT( "psi_store_ncell_param2: NC_CW list full" );
4821
4822 return;
4823 }
4824
4825 if( p_sub_1->n_r_cells NEQ 0 )
4826 {
4827 y = p_sub_1->c_ncell_par2_s2;
4828
4829 for( x = 0; x < y; x++ )
4830 {
4831 p_sub_2 = &p_sub_1->ncell_par2_s2[x];
4832
4833 if( psi_store_cs_param2
4834 ( &psc_db->nc_cw.list,
4835 &psi3bis->ncell_par_trnc_grp.ncell_par2[i].ncell_par2_set[cell_params_ptr],
4836 psi3bis->psi3bis_ind,
4837 &number,
4838 &last_freq,
4839 p_sub_2->freq_diff_struct.freq_diff,
4840 p_sub_2->same_ra_scell,
4841 p_sub_2->cell_ba,
4842 p_sub_2->bcc ) EQ FALSE )
4843 {
4844 TRACE_EVENT( "psi_store_ncell_param2: NC_CW list full" );
4845
4846 return;
4847 }
4848 }
4849 }
4850 }
4851 }
4852 }
4853 } /* psi_store_ncell_param2 */
4854
4855 /*
4856 +------------------------------------------------------------------------------
4857 | Function : psi_store_cs_param2
4858 +------------------------------------------------------------------------------
4859 | Description :
4860 | Parameters :
4861 +------------------------------------------------------------------------------
4862 */
4863 LOCAL BOOL psi_store_cs_param2 ( T_NC_LIST *nc_list,
4864 T_ncell_par2_set *cs_par2,
4865 UBYTE instance,
4866 UBYTE *number,
4867 USHORT *freq,
4868 USHORT freq_diff,
4869 UBYTE same_ra_scell,
4870 UBYTE cell_ba,
4871 UBYTE bcc )
4872 {
4873 T_INFO_SRC info_src = 0;
4874 T_ncell_info *ncell_info;
4875
4876 TRACE_FUNCTION( "psi_store_cs_param2" );
4877
4878 NC_SET_TYPE ( info_src, INFO_TYPE_PSI3BIS );
4879 NC_SET_INSTANCE( info_src, instance );
4880 NC_SET_NUMBER ( info_src, *number );
4881
4882 ncell_info = grr_get_next_ncell_param( MAX_NR_OF_NCELL,
4883 nc_list,
4884 info_src );
4885
4886 if( ncell_info EQ NULL )
4887 {
4888 return( FALSE );
4889 }
4890
4891 number++;
4892 nc_list->number++;
4893
4894 *freq = ( *freq + freq_diff ) % 1024;
4895
4896 ncell_info->info_src = info_src;
4897 ncell_info->arfcn = *freq;
4898
4899 if( cs_par2->v_ncc )
4900 {
4901 ncell_info->bsic = bcc | ( cs_par2->ncc << 3 );
4902 }
4903 else
4904 {
4905 ncell_info->bsic = bcc | ( psc_db->pbcch.bcch.bsic & BSIC_NCC_MASK );
4906 }
4907
4908 ncell_info->v_cr_par = TRUE;
4909 ncell_info->cr_par.same_ra_scell = same_ra_scell;
4910 ncell_info->cr_par.exc_acc = cs_par2->exc_acc;
4911 ncell_info->cr_par.cell_ba = cell_ba;
4912
4913 #if !defined (NTRACE)
4914 if( grr_data->cs.v_crp_trace EQ TRUE )
4915 {
4916 TRACE_EVENT_P2( "psi_store_cs_param2: cell barred status %d %d",
4917 ncell_info->arfcn, ncell_info->cr_par.cell_ba );
4918 }
4919 #endif /* #if !defined (NTRACE) */
4920
4921
4922
4923 SET_GPRS_RXLEV_ACCESS_MIN
4924 ( ncell_info->cr_par.cr_par_1.cr_pow_par.gprs_rxlev_access_min,
4925 cs_par2->v_gprs_rxlev_access_min, cs_par2->gprs_rxlev_access_min );
4926
4927 SET_GPRS_MS_TXPWR_MAX_CCH
4928 ( ncell_info->cr_par.cr_par_1.cr_pow_par.gprs_ms_txpwr_max_cch,
4929 cs_par2->v_txpwr_max_cch, cs_par2->txpwr_max_cch );
4930
4931 SET_GPRS_TEMP_OFFSET
4932 ( ncell_info->cr_par.cr_offset.gprs_temp_offset,
4933 TRUE, cs_par2->gprs_temp_offset );
4934
4935 SET_GPRS_PENALTY_TIME
4936 ( ncell_info->cr_par.cr_offset.gprs_penalty_time,
4937 TRUE, cs_par2->gprs_penalty_time );
4938
4939 SET_GPRS_RESEL_OFF
4940 ( ncell_info->cr_par.gprs_resel_off,
4941 TRUE, cs_par2->gprs_resel_off );
4942
4943 ncell_info->cr_par.cr_par_1.v_hcs_par =
4944 ( cs_par2->v_gprs_hcs_thr AND cs_par2->v_gprs_prio_class );
4945
4946 SET_GPRS_HCS_THR
4947 ( ncell_info->cr_par.cr_par_1.hcs_par.gprs_hcs_thr,
4948 cs_par2->v_gprs_hcs_thr, cs_par2->gprs_hcs_thr );
4949
4950 SET_GPRS_PRIO_CLASS
4951 ( ncell_info->cr_par.cr_par_1.hcs_par.gprs_prio_class,
4952 cs_par2->v_gprs_prio_class, cs_par2->gprs_prio_class );
4953
4954 grr_store_si13_pbcch_location( &ncell_info->cr_par,
4955 cs_par2->v_si13_pbcch,
4956 &cs_par2->si13_pbcch );
4957
4958 return( TRUE );
4959
4960 }/* psi_store_cs_param2 */
4961
4962 /*
4963 +------------------------------------------------------------------------------
4964 | Function : psi_restore_ncell_param
4965 +------------------------------------------------------------------------------
4966 | Description :
4967 | Parameters :
4968 +------------------------------------------------------------------------------
4969 */
4970 LOCAL void psi_restore_ncell_param ( void )
4971 {
4972 UBYTE idx_curr = 0;
4973 T_ncell_info *info_prev = NULL;
4974 T_ncell_info *info_curr;
4975 T_INFO_SRC info_src = 0;
4976
4977 TRACE_FUNCTION( "psi_restore_ncell_param" );
4978
4979 /* update change mark value */
4980 psc_db->nc_cw.list.chng_mrk.curr++;
4981
4982 while( ( info_curr = grr_get_next_bigger_ncell_param
4983 ( &psc_db->nc_cw.list, info_src ) ) NEQ NULL )
4984 {
4985 grr_restore_cs_param( info_curr, info_prev, idx_curr );
4986
4987 info_src = info_curr->info_src;
4988 info_prev = info_curr;
4989
4990 idx_curr++;
4991 }
4992 }/* psi_restore_ncell_param */
4993
4994
4995 /*
4996 +------------------------------------------------------------------------------
4997 | Function : psi_prepare_scell_pbcch_req
4998 +------------------------------------------------------------------------------
4999 | Description : The function psi_prepare_scell_pbcch_req() prepares the mphp_
5000 | scell_pbcch_req
5001 |
5002 | Parameters : T_MPHP_SCELL_PBCCH_REQ *mphp_scell_pbcch_req
5003 | UBYTE psi_reading_type
5004 |
5005 +------------------------------------------------------------------------------
5006 */
5007 GLOBAL void psi_prepare_scell_pbcch_req(T_MPHP_SCELL_PBCCH_REQ *mphp_scell_pbcch_req,
5008 UBYTE psi_reading_type)
5009 {
5010 #ifndef _TARGET_
5011
5012 UBYTE i, j;
5013
5014 #endif /* #ifndef _TARGET_ */
5015
5016 UBYTE hr, lr, *psi_nr;
5017 UBYTE *pos_array;
5018
5019 TRACE_FUNCTION( "psi_prepare_scell_pbcch_req" );
5020
5021
5022 memcpy(mphp_scell_pbcch_req,&psc_db->scell_pbcch,sizeof(T_MPHP_SCELL_PBCCH_REQ));
5023
5024 psi_nr = &mphp_scell_pbcch_req->psi_nr;
5025 pos_array = mphp_scell_pbcch_req->relative_pos_array;
5026
5027 *psi_nr = 0;
5028 memset(pos_array, 0, MAX_RELATIVE_POS);
5029
5030 hr = psc_db->psi1_params.psi_cnt_hr;
5031 lr = psc_db->psi1_params.psi_cnt_lr;
5032
5033
5034 TRACE_EVENT_P1("psi_reading_type:%d", psi_reading_type);
5035
5036 switch(psi_reading_type)
5037 {
5038 case READ_COMPLETE:
5039 /* attempt to receive messages shall be made each time
5040 * the message is scheduled on the broadcast channel.
5041 */
5042 mphp_scell_pbcch_req->psi_nr = 0;/*read all PSI in all PBCCH*/
5043 /*
5044 * mphp_scell_pbcch_req->relative_pos_array has no meaning,
5045 * if we want to receive all PSI
5046 */
5047 psi_reset_psi_pos();
5048 break;
5049 case READ_PSI1_IN_PSI1_REPEAT_PERIODS:
5050 /* attempt to receive PSI1 each time
5051 * the message is scheduled on the broadcast channel
5052 * with psi1_repeat_periods (only once in a multiframe, e.g. in PBCCH->B0)
5053 */
5054
5055 /* mphp_scell_pbcch_req->relative_pos_array will contain only one element,
5056 * because of mphp_scell_pbcch_req.psi_nr = 1
5057 */
5058 mphp_scell_pbcch_req->psi_nr = 1;
5059
5060 /*Read PSI1 only in BO in psi1 repeat period
5061 */
5062 mphp_scell_pbcch_req->relative_pos_array[0] = 0;
5063 break;
5064 case PSI_IN_HR: /* PSI in high repetition rate*/
5065 if(!hr) /* no HR */
5066 {
5067 TRACE_ERROR("no HR, read all");
5068 mphp_scell_pbcch_req->psi_nr = 0;/*read all PSI in all PBCCH*/
5069 }
5070 else
5071 {
5072 #ifdef _TARGET_
5073 mphp_scell_pbcch_req->psi_nr = 0;
5074 #else
5075 mphp_scell_pbcch_req->psi_nr = 0;
5076 i = (mphp_scell_pbcch_req->bs_pbcch_blks > 0) ? 1 : 0;
5077
5078 while(hr > 0)
5079 {
5080 mphp_scell_pbcch_req->relative_pos_array[mphp_scell_pbcch_req->psi_nr] = i + hr;
5081 if(mphp_scell_pbcch_req->psi_nr EQ 19)
5082 break;/* break condition*/
5083 mphp_scell_pbcch_req->psi_nr++;
5084 hr--;
5085 }
5086 #endif
5087 }
5088 break;
5089 case PSI_IN_LR: /* PSI in low repetition rate */
5090 if(!lr) /* no LR */
5091 {
5092 TRACE_ERROR("no LR, read all");
5093 mphp_scell_pbcch_req->psi_nr = 0;/*read all PSI in all PBCCH*/
5094 }
5095 else
5096 {
5097 #ifdef _TARGET_
5098 mphp_scell_pbcch_req->psi_nr = 0;
5099 #else
5100 mphp_scell_pbcch_req->psi_nr = 0;
5101 i = (mphp_scell_pbcch_req->bs_pbcch_blks > 0) ? 1 : 0;
5102
5103 while(lr > 0)
5104 {
5105 mphp_scell_pbcch_req->relative_pos_array[mphp_scell_pbcch_req->psi_nr] = i + hr + lr;
5106 if(mphp_scell_pbcch_req->psi_nr EQ 19)
5107 break;/* break condition*/
5108 mphp_scell_pbcch_req->psi_nr++;
5109 lr--;
5110 }
5111 #endif
5112 }
5113 break;
5114 case PSI_IN_HR_AND_LR: /* PSI in high and low repetition rate*/
5115 if(!(lr + hr)) /* no LR+HR */
5116 {
5117 TRACE_ERROR("no HR+LR, read all");
5118 mphp_scell_pbcch_req->psi_nr = 0;/*read all PSI in all PBCCH*/
5119 }
5120 else
5121 {
5122 #ifdef _TARGET_
5123 mphp_scell_pbcch_req->psi_nr = 0;
5124 #else
5125 mphp_scell_pbcch_req->psi_nr = 0;
5126 i = (mphp_scell_pbcch_req->bs_pbcch_blks > 0) ? 2 : 1;
5127 for(j=0; j<(lr + hr);j++)
5128 {
5129 mphp_scell_pbcch_req->relative_pos_array[mphp_scell_pbcch_req->psi_nr] = i + j;
5130 if(mphp_scell_pbcch_req->psi_nr EQ 19)
5131 break;/* break condition*/
5132 mphp_scell_pbcch_req->psi_nr++;
5133 }
5134 #endif
5135 }
5136 break;
5137 case READ_PSI1_AND_IN_HR:
5138 /* PSI in high repetition rate and PSI1*/
5139 #ifdef _TARGET_
5140 mphp_scell_pbcch_req->psi_nr = 0;
5141 #else
5142 mphp_scell_pbcch_req->psi_nr = 0;
5143 mphp_scell_pbcch_req->relative_pos_array[mphp_scell_pbcch_req->psi_nr++] = 0;
5144 i = (mphp_scell_pbcch_req->bs_pbcch_blks > 0) ? 1 : 0;
5145 if(i EQ 1)
5146 {
5147 mphp_scell_pbcch_req->relative_pos_array[mphp_scell_pbcch_req->psi_nr++] = 1;
5148 }
5149
5150 while(hr > 0)
5151 {
5152 mphp_scell_pbcch_req->relative_pos_array[mphp_scell_pbcch_req->psi_nr] = i + hr;
5153 if(mphp_scell_pbcch_req->psi_nr EQ 19)
5154 break;/* break condition*/
5155 mphp_scell_pbcch_req->psi_nr++;
5156 hr--;
5157 }
5158 #endif
5159 break;
5160 case READ_PSI1_AND_IN_LR:/* PSI in low repetition rate and PSI1*/
5161 #ifdef _TARGET_
5162 mphp_scell_pbcch_req->psi_nr = 0;
5163 #else
5164 mphp_scell_pbcch_req->psi_nr = 0;
5165 mphp_scell_pbcch_req->relative_pos_array[mphp_scell_pbcch_req->psi_nr++] = 0;
5166 i = (mphp_scell_pbcch_req->bs_pbcch_blks > 0) ? 1 : 0;
5167 if(i EQ 1)
5168 {
5169 mphp_scell_pbcch_req->relative_pos_array[mphp_scell_pbcch_req->psi_nr++] = 1;
5170 }
5171
5172 while(lr > 0)
5173 {
5174 mphp_scell_pbcch_req->relative_pos_array[mphp_scell_pbcch_req->psi_nr] = i + hr + lr;
5175 if(mphp_scell_pbcch_req->psi_nr EQ 19)
5176 break;/* break condition*/
5177 mphp_scell_pbcch_req->psi_nr++;
5178 lr--;
5179 }
5180 #endif
5181 break;
5182 case READ_PSI2:
5183 #ifdef _TARGET_
5184 mphp_scell_pbcch_req->psi_nr = 0;
5185 #else
5186 psi_fill_rel_pos(grr_data->psi.psi2_pos, MAX_NR_OF_INSTANCES_OF_PSI2, psi_nr, pos_array);
5187 #endif
5188 break;
5189 #if defined (REL99) AND defined (TI_PS_FF_EMR)
5190 case READ_PSI3TER:
5191 case READ_PSI3_3BIS_3TER:
5192 #endif
5193 case READ_PSI3_3BIS:
5194 #if defined (REL99) AND defined (TI_PS_FF_EMR)
5195 case READ_PSI3BIS:
5196 #endif
5197 #ifdef _TARGET_
5198 mphp_scell_pbcch_req->psi_nr = 0;
5199 #else
5200 #if defined (REL99) AND defined (TI_PS_FF_EMR)
5201 psi_fill_rel_pos(grr_data->psi.psi3_set_pos,
5202 MAX_NR_OF_INSTANCES_OF_PSI3TER + MAX_NR_OF_INSTANCES_OF_PSI3 +
5203 MAX_NR_OF_INSTANCES_OF_PSI3BIS, psi_nr, pos_array);
5204 #else
5205 psi_fill_rel_pos(grr_data->psi.psi3bis_pos,
5206 MAX_NR_OF_INSTANCES_OF_PSI3 + MAX_NR_OF_INSTANCES_OF_PSI3BIS,
5207 psi_nr, pos_array);
5208 #endif /* #ifdef REL99 AND TI_PS_FF_EMR */
5209 #endif /* ifdef _TARGET_ */
5210 break;
5211 case READ_PSI4:
5212 #ifdef _TARGET_
5213 mphp_scell_pbcch_req->psi_nr = 0;
5214 #else
5215 psi_fill_rel_pos(grr_data->psi.psi4_pos, MAX_NR_OF_INSTANCES_OF_PSI4, psi_nr, pos_array);
5216 #endif
5217 break;
5218 case READ_PSI5:
5219 #ifdef _TARGET_
5220 mphp_scell_pbcch_req->psi_nr = 0;
5221 #else
5222 psi_fill_rel_pos(grr_data->psi.psi5_pos, MAX_NR_OF_INSTANCES_OF_PSI5, psi_nr, pos_array);
5223 #endif
5224 break;
5225 #ifdef REL99
5226 case READ_PSI8:
5227 #ifdef _TARGET_
5228 mphp_scell_pbcch_req->psi_nr = 0;
5229 #else
5230 psi_fill_rel_pos(grr_data->psi.psi8_pos, MAX_NR_OF_INSTANCES_OF_PSI8, psi_nr, pos_array);
5231 #endif
5232 break;
5233 #endif
5234 default:
5235 TRACE_ERROR ("default in psi_prepare_scell_pbcch_req");
5236 break;
5237 }
5238 TRACE_EVENT_P7("psi_nr:%d blks:%d pb:%d per:%d pos[0]:%d pos[1]:%d pos[2]:%d",
5239 mphp_scell_pbcch_req->psi_nr,
5240 mphp_scell_pbcch_req->bs_pbcch_blks,
5241 mphp_scell_pbcch_req->pb,
5242 mphp_scell_pbcch_req->psi1_rep_period,
5243 mphp_scell_pbcch_req->relative_pos_array[0],
5244 mphp_scell_pbcch_req->relative_pos_array[1],
5245 mphp_scell_pbcch_req->relative_pos_array[2]);
5246 TRACE_EVENT_P4("tn:%d tsc:%d hop:%d arfcn:%d",
5247 mphp_scell_pbcch_req->p_ch_des.tn,
5248 mphp_scell_pbcch_req->p_ch_des.tsc,
5249 mphp_scell_pbcch_req->p_ch_des.p_chan_sel.hopping,
5250 mphp_scell_pbcch_req->p_ch_des.p_chan_sel.p_rf_ch.arfcn);
5251 TRACE_EVENT_P5("f_cnt:%d f1:%d f2:%d f3:%d f4:%d",
5252 mphp_scell_pbcch_req->p_freq_list.p_rf_chan_cnt,
5253 mphp_scell_pbcch_req->p_freq_list.p_rf_chan_no.p_radio_freq[0],
5254 mphp_scell_pbcch_req->p_freq_list.p_rf_chan_no.p_radio_freq[1],
5255 mphp_scell_pbcch_req->p_freq_list.p_rf_chan_no.p_radio_freq[2],
5256 mphp_scell_pbcch_req->p_freq_list.p_rf_chan_no.p_radio_freq[3]);
5257
5258
5259
5260
5261 } /* psi_prepare_scell_pbcch_req */
5262
5263
5264 /*
5265 +------------------------------------------------------------------------------
5266 | Function : psi_store_rel_pos
5267 +------------------------------------------------------------------------------
5268 | Description : The function psi_store_rel_pos () .stores the values relative
5269 | position for each PSI message
5270 | Parameters : dest: destination array; rel_pos: relative position; max_dest:
5271 | MAX size OF dest array
5272 |
5273 +------------------------------------------------------------------------------
5274 */
5275 GLOBAL void psi_store_rel_pos(UBYTE *dest, UBYTE rel_pos, UBYTE max_dest)
5276 {
5277 UBYTE i;
5278 TRACE_FUNCTION("psi_store_rel_pos");
5279
5280 for ( i = 0; i < max_dest; i++)
5281 {
5282 if(dest[i] EQ 0xFF)
5283 {
5284 dest[i] = rel_pos;
5285 break;
5286 }
5287 }
5288
5289 }/*psi_store_rel_pos*/
5290
5291 #ifndef _TARGET_
5292 /*
5293 +------------------------------------------------------------------------------
5294 | Function : psi_fill_rel_pos
5295 +------------------------------------------------------------------------------
5296 | Description : The function psi_fill_rel_pos () .fills the relative position
5297 | array and sets the psi_number
5298 | Parameters : src: array containing rel positions; max_src: MAX size of src
5299 | psi_nr: ptr to psi_number; pos_array: ptr to position_array
5300 |
5301 +------------------------------------------------------------------------------
5302 */
5303 LOCAL void psi_fill_rel_pos(UBYTE *src, UBYTE max_src, UBYTE *psi_nr, UBYTE *pos_array)
5304 {
5305 UBYTE i;
5306 TRACE_FUNCTION("psi_fill_rel_pos");
5307
5308 for(i = 0; i<max_src; i++)
5309 {
5310 if(src[i] NEQ 0xff)
5311 {
5312 pos_array[(*psi_nr)] = src[i];
5313 (*psi_nr)++;
5314 }
5315 }
5316 }/*psi_fill_rel_pos*/
5317 #endif /*_TARGET_*/
5318
5319 /*
5320 +------------------------------------------------------------------------------
5321 | Function : psi_reset_psi_pos
5322 +------------------------------------------------------------------------------
5323 | Description : The function spsi_reset_psi_pos () ....
5324 |
5325 | Parameters : -
5326 |
5327 +------------------------------------------------------------------------------
5328 */
5329 LOCAL void psi_reset_psi_pos ( void )
5330 {
5331 TRACE_FUNCTION( "psi_reset_psi_pos " );
5332
5333 memset(grr_data->psi.psi2_pos, 0xFF, MAX_NR_OF_INSTANCES_OF_PSI2);
5334
5335 #if defined (REL99) AND defined (TI_PS_FF_EMR)
5336 memset(grr_data->psi.psi3_set_pos, 0xFF, MAX_NR_OF_INSTANCES_OF_PSI3TER
5337 +MAX_NR_OF_INSTANCES_OF_PSI3BIS+MAX_NR_OF_INSTANCES_OF_PSI3);
5338 #else
5339 memset(grr_data->psi.psi3bis_pos, 0xFF, MAX_NR_OF_INSTANCES_OF_PSI3BIS+MAX_NR_OF_INSTANCES_OF_PSI3);
5340 #endif
5341
5342 memset(grr_data->psi.psi4_pos, 0xFF, MAX_NR_OF_INSTANCES_OF_PSI4);
5343 memset(grr_data->psi.psi5_pos, 0xFF, MAX_NR_OF_INSTANCES_OF_PSI5);
5344 #ifdef REL99
5345 memset(grr_data->psi.psi8_pos, 0xFF, MAX_NR_OF_INSTANCES_OF_PSI8);
5346 #endif
5347
5348 } /* psi_reset_psi_pos () */
5349
5350
5351 #ifdef REL99
5352 /*
5353 +------------------------------------------------------------------------------
5354 | Function : psi_update_bss_sgsn_rel
5355 +------------------------------------------------------------------------------
5356 | Description : The function psi_update_bss_sgsn_rel () updates BSS and SGSN
5357 | releases during the processing of SI13 message.
5358 |
5359 | Parameters : SI13 message, status of PBCCH presence in the cell
5360 |
5361 +------------------------------------------------------------------------------
5362 */
5363 LOCAL void psi_update_bss_sgsn_rel ( T_D_SYS_INFO_13 *si13,
5364 BOOL pbcch_status )
5365 {
5366 TRACE_FUNCTION( "psi_update_bss_sgsn_rel " );
5367
5368 /* Update the BSS release */
5369 if (si13->si13_rest_oct.si13_info.v_sgsnr)
5370 {
5371 psc_db->network_rel = BSS_NW_REL_99;
5372 psc_db->sgsn_rel =
5373 si13->si13_rest_oct.si13_info.sgsnr ? PS_SGSN_99_ONWARDS : PS_SGSN_98_OLDER;
5374 }
5375 else
5376 {
5377 psc_db->network_rel = BSS_NW_REL_97;
5378
5379 if(pbcch_status EQ PBCCH_NOT_PRESENT)
5380 {
5381 psc_db->sgsn_rel = PS_SGSN_98_OLDER;
5382 }
5383 else
5384 {
5385 psc_db->sgsn_rel = PS_SGSN_UNKNOWN;
5386 }
5387
5388 }
5389
5390 /* Update the SGSN release in the Common library context */
5391 cl_nwrl_set_sgsn_release(psc_db->sgsn_rel);
5392
5393
5394 } /* psi_update_bss_sgsn_rel () */
5395
5396 #endif
5397