FreeCalypso > hg > fc-selenite
comparison src/g23m-gprs/grr/grr_pgf.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 PG of | |
18 | entity GRR. | |
19 +----------------------------------------------------------------------------- | |
20 */ | |
21 | |
22 #ifndef GRR_PGF_C | |
23 #define GRR_PGF_C | |
24 #endif | |
25 | |
26 #define ENTITY_GRR | |
27 | |
28 /*==== INCLUDES =============================================================*/ | |
29 | |
30 #include "typedefs.h" /* to get Condat data types */ | |
31 | |
32 #include "vsi.h" /* to get a lot of macros */ | |
33 #include "macdef.h" | |
34 #include "gprs.h" | |
35 #include "gsm.h" /* to get a lot of macros */ | |
36 #include "ccdapi.h" /* to get CCD API */ | |
37 #include "cnf_grr.h" /* to get cnf-definitions */ | |
38 #include "mon_grr.h" /* to get mon-definitions */ | |
39 #include "prim.h" /* to get the definitions of used SAP and directions */ | |
40 #include "message.h" | |
41 #include "grr.h" /* to get the global entity definitions */ | |
42 | |
43 #include "grr_f.h" /* */ | |
44 #include "grr_pgf.h" /* */ | |
45 | |
46 #include "grr_ctrls.h" /* */ | |
47 #include "grr_meass.h" | |
48 #include "grr_css.h" | |
49 #include "grr_em.h" /*for Engineering mode*/ | |
50 | |
51 #include <string.h> /* for memcpy*/ | |
52 #include <stdio.h> /* for memcpy*/ | |
53 | |
54 /*==== CONST ================================================================*/ | |
55 | |
56 const USHORT NC2_NON_DRX_TABLE[8] = {0, 240, 480, 720, 960, 1200, 1440, 1920}; | |
57 | |
58 /*==== LOCAL VARS ===========================================================*/ | |
59 static UBYTE NON_DRX_TABLE[] = {0, 1, 2, 4, 8, 16, 32, 64}; | |
60 | |
61 /*==== GLOBAL VARS ===========================================================*/ | |
62 | |
63 | |
64 | |
65 /*==== PRIVATE FUNCTIONS ====================================================*/ | |
66 LOCAL void pg_stop_t_nc2_ndrx( void ); | |
67 LOCAL void pg_stop_non_drx_timer( void ); | |
68 LOCAL void pg_start_non_drx_timer(USHORT milliseconds); | |
69 LOCAL BOOL pg_decode_imsi(T_ms_id ms_id, UBYTE *digits, UBYTE *nr_digits); | |
70 /*==== PUBLIC FUNCTIONS =====================================================*/ | |
71 | |
72 | |
73 | |
74 /* | |
75 +------------------------------------------------------------------------------ | |
76 | Function : pg_init | |
77 +------------------------------------------------------------------------------ | |
78 | Description : The function pg_init() .... | |
79 | | |
80 | Parameters : void | |
81 | | |
82 +------------------------------------------------------------------------------ | |
83 */ | |
84 GLOBAL void pg_init ( void ) | |
85 { | |
86 TRACE_FUNCTION( "pg_init" ); | |
87 | |
88 pg_init_params(); | |
89 | |
90 grr_data->pg.v_emlpp_prio = FALSE; /* valid flag for emlpp_priority*/ | |
91 grr_data->pg.packet_mode = PACKET_MODE_NULL; | |
92 | |
93 INIT_STATE(PG,PG_NULL); | |
94 } /* pg_init() */ | |
95 | |
96 /* | |
97 +------------------------------------------------------------------------------ | |
98 | Function : pg_init_params | |
99 +------------------------------------------------------------------------------ | |
100 | Description : The function pg_init_params() .... | |
101 | | |
102 | Parameters : void | |
103 | | |
104 +------------------------------------------------------------------------------ | |
105 */ | |
106 GLOBAL void pg_init_params ( void ) | |
107 { | |
108 TRACE_FUNCTION( "pg_init_params" ); | |
109 | |
110 psc_db->last_pg_mode = psc_db->network_pg_mode = REORG_PAGING; | |
111 | |
112 } /* pg_init_params() */ | |
113 | |
114 /* | |
115 +------------------------------------------------------------------------------ | |
116 | Function : pg_process_pp_req | |
117 +------------------------------------------------------------------------------ | |
118 | Description : The function pg_process_pp_req() .... | |
119 | | |
120 | Parameters : T_D_PAGING_REQ *paging_req: pointer to the decoded message, | |
121 UBYTE state: state of pg state machine: IDLE, TRANSFER, TIMER_3172 | |
122 | | |
123 +------------------------------------------------------------------------------ | |
124 */ | |
125 GLOBAL void pg_process_pp_req ( T_D_PAGING_REQ *paging_req, UBYTE state ) | |
126 { | |
127 char i; | |
128 ULONG ul; | |
129 | |
130 TRACE_FUNCTION( "pg_process_pp_req" ); | |
131 | |
132 if(paging_req->v_pers_lev) | |
133 { /*copy persistence level parameters into database*/ | |
134 grr_save_persistence_level (&(paging_req->pers_lev)); | |
135 } | |
136 /*if(paging_req->v_nln) | |
137 { message contains at least one page request for RR connection establishment | |
138 04.08: NLN(PCH) Notification List Number | |
139 "The presence of the NLN(PCH) field indicates that if an NCH is present, reduced NCH monitoring can be used, and | |
140 gives the NLN(PCH) value, to be used as specified in 3.3.3." | |
141 This is used by VGCS MSs... | |
142 | |
143 }*/ | |
144 if(paging_req->rep_page_info_trnc_grp.v_rep_page_info) | |
145 { | |
146 for (i=0; i < paging_req->rep_page_info_trnc_grp.c_rep_page_info; i++) | |
147 { | |
148 if(paging_req->rep_page_info_trnc_grp.rep_page_info[i].v_rep_page_s1 | |
149 AND | |
150 grr_t_status( T3172_1 ) EQ 0 /* T3172 is not running*/ | |
151 ) | |
152 { | |
153 /* | |
154 * page request for TBF establishment | |
155 */ | |
156 switch(state) | |
157 { | |
158 case PG_IDLE: | |
159 if(paging_req->rep_page_info_trnc_grp.rep_page_info[i].rep_page_s1.v_ptmsi) | |
160 { | |
161 /* | |
162 *Paging with PTMSI | |
163 */ | |
164 if(grr_data->db.ms_id.new_ptmsi NEQ GMMRR_TMSI_INVALID) | |
165 { | |
166 if(grr_check_ptmsi(&(paging_req->rep_page_info_trnc_grp.rep_page_info[i].rep_page_s1.ptmsi))) | |
167 { | |
168 TRACE_EVENT("Paging with PTIMSI for TBF"); | |
169 sig_pg_ctrl_downlink_transfer ( GMMRR_PTMSI ); | |
170 i = paging_req->rep_page_info_trnc_grp.c_rep_page_info; /* break condition for for loop*/ | |
171 } | |
172 else | |
173 { | |
174 TRACE_EVENT("Paging with wrong PTIMSI for TBF: IGNORE"); | |
175 } | |
176 } | |
177 else | |
178 { | |
179 TRACE_EVENT("Paging with PTMSI, but no valid PTMSI in MS"); | |
180 } | |
181 } | |
182 else | |
183 { | |
184 /* | |
185 *Paging with Mobile Identity (IMSI) | |
186 */ | |
187 UBYTE dummy_digits[MAX_IMSI_DIGITS]; | |
188 UBYTE dummy_nr_digits = 0; | |
189 | |
190 if(pg_decode_imsi(paging_req->rep_page_info_trnc_grp.rep_page_info[i].rep_page_s1.ms_id, | |
191 dummy_digits, &dummy_nr_digits)) | |
192 { | |
193 | |
194 if( dummy_nr_digits | |
195 EQ | |
196 grr_data->db.ms_id.imsi.number_of_digits)/* check the number of digits*/ | |
197 { | |
198 if( !memcmp | |
199 ( grr_data->db.ms_id.imsi.digit, /* IMSI stored in the data_base*/ | |
200 dummy_digits, /* received IMSI*/ | |
201 grr_data->db.ms_id.imsi.number_of_digits | |
202 ) | |
203 ) | |
204 { | |
205 /* The MS was paged with the IMSI*/ | |
206 TRACE_EVENT("Paging with Mobile Identity (IMSI) for TBF"); | |
207 sig_pg_ctrl_downlink_transfer ( GMMRR_IMSI ); | |
208 i = paging_req->rep_page_info_trnc_grp.c_rep_page_info; /* break condition for for loop*/ | |
209 } | |
210 else | |
211 { | |
212 TRACE_EVENT("Paging with wrong IMSI for TBF: IGNORE"); | |
213 } | |
214 | |
215 } | |
216 } | |
217 } | |
218 break; | |
219 default: | |
220 /* | |
221 * ignore paging request for TBF establishment, do | |
222 * not check the content | |
223 */ | |
224 break; | |
225 } | |
226 } | |
227 | |
228 if(paging_req->rep_page_info_trnc_grp.rep_page_info[i].v_rep_page_s2) | |
229 { | |
230 /* | |
231 * page request for RR connection establishment | |
232 */ | |
233 /* | |
234 * In packet access mode, class A or B shall respond to a pp_req for | |
235 * RR connection est. | |
236 * During the time T3172 is running, the mobile station shall ignore all | |
237 * received PACKET PAGING REQUEST messages except paging request to trigger | |
238 * RR connection establishment. | |
239 */ | |
240 switch(state) | |
241 { | |
242 case PG_IDLE: | |
243 case PG_TRANSFER: | |
244 case PG_ACCESS: | |
245 if(paging_req->rep_page_info_trnc_grp.rep_page_info[i].rep_page_s2.v_tmsi_field) | |
246 { | |
247 /* | |
248 *Paging with TMSI | |
249 */ | |
250 if(grr_data->db.ms_id.tmsi NEQ GMMRR_TMSI_INVALID) | |
251 { | |
252 ul = grr_buffer2ulong((BUF_ptmsi *)&(paging_req->rep_page_info_trnc_grp.rep_page_info[i].rep_page_s2.tmsi_field)); | |
253 if(ul EQ grr_data->db.ms_id.tmsi) | |
254 { | |
255 TRACE_EVENT("Paging with Mobile Identity (TMSI) for RR est"); | |
256 | |
257 /* Set some parameters needed RR connection establishment*/ | |
258 grr_data->pg.ch_needed = paging_req->rep_page_info_trnc_grp.rep_page_info[i].rep_page_s2.chan_need; | |
259 grr_data->pg.v_emlpp_prio = paging_req->rep_page_info_trnc_grp.rep_page_info[i].rep_page_s2.v_emlpp_prio; | |
260 grr_data->pg.emlpp_prio = paging_req->rep_page_info_trnc_grp.rep_page_info[i].rep_page_s2.emlpp_prio; | |
261 | |
262 /* MS was paged with TMSI for RR connection establishment*/ | |
263 grr_data->pg.type = ID_TMSI; | |
264 sig_pg_ctrl_rr_est_req ( PG_ON_PCCCH); | |
265 i = paging_req->rep_page_info_trnc_grp.c_rep_page_info; /* break condition for for loop*/ | |
266 } | |
267 else | |
268 { | |
269 TRACE_EVENT("Paging with wrong TMSI for RR: IGNORE"); | |
270 } | |
271 } | |
272 else | |
273 { | |
274 TRACE_EVENT("Paging with TMSI, but no valid TMSI in MS"); | |
275 } | |
276 } | |
277 else | |
278 { | |
279 /* | |
280 *Paging with Mobile Identity (IMSI) | |
281 */ | |
282 UBYTE dummy_digits[MAX_IMSI_DIGITS]; | |
283 UBYTE dummy_nr_digits = 0; | |
284 | |
285 if(pg_decode_imsi(paging_req->rep_page_info_trnc_grp.rep_page_info[i].rep_page_s2.ms_id, | |
286 dummy_digits, &dummy_nr_digits)) | |
287 { | |
288 | |
289 if( dummy_nr_digits | |
290 EQ | |
291 grr_data->db.ms_id.imsi.number_of_digits)/* check the number of digits*/ | |
292 { | |
293 if( !memcmp | |
294 ( grr_data->db.ms_id.imsi.digit, /* IMSI stored in the data_base*/ | |
295 dummy_digits, /* received IMSI*/ | |
296 grr_data->db.ms_id.imsi.number_of_digits | |
297 ) | |
298 ) | |
299 { | |
300 /* The MS was paged with the IMSI*/ | |
301 TRACE_EVENT("Paging with Mobile Identity (IMSI) for RR est"); | |
302 | |
303 /* Set some parameters needed RR connection establishment*/ | |
304 grr_data->pg.ch_needed = paging_req->rep_page_info_trnc_grp.rep_page_info[i].rep_page_s2.chan_need; | |
305 grr_data->pg.v_emlpp_prio = paging_req->rep_page_info_trnc_grp.rep_page_info[i].rep_page_s2.v_emlpp_prio; | |
306 grr_data->pg.emlpp_prio = paging_req->rep_page_info_trnc_grp.rep_page_info[i].rep_page_s2.emlpp_prio; | |
307 | |
308 /* MS was paged with IMSI for RR connection establishment*/ | |
309 grr_data->pg.type = ID_IMSI; | |
310 sig_pg_ctrl_rr_est_req ( PG_ON_PCCCH ); | |
311 i = paging_req->rep_page_info_trnc_grp.c_rep_page_info; /* break condition for for loop*/ | |
312 } | |
313 else | |
314 { | |
315 TRACE_EVENT("Paging with wrong IMSI for RR: IGNORE"); | |
316 } | |
317 } | |
318 } | |
319 } | |
320 break; | |
321 default: | |
322 /* | |
323 * ignore paging request for RR connection establishment, do | |
324 * not check the content | |
325 */ | |
326 break; | |
327 } | |
328 } | |
329 } | |
330 } | |
331 } /* pg_process_pp_req() */ | |
332 | |
333 | |
334 | |
335 /* | |
336 +------------------------------------------------------------------------------ | |
337 | Function : pg_send_stop | |
338 +------------------------------------------------------------------------------ | |
339 | Description : The function pg_send_stop() .... | |
340 | | |
341 | Parameters : void | |
342 | | |
343 +------------------------------------------------------------------------------ | |
344 */ | |
345 GLOBAL void pg_send_stop ( void ) | |
346 { | |
347 TRACE_FUNCTION( "pg_send_stop" ); | |
348 | |
349 if (grr_data->is_pg_started EQ TRUE) | |
350 { | |
351 PALLOC (mphp_stop_pccch_req, MPHP_STOP_PCCCH_REQ); | |
352 PSEND (hCommL1, mphp_stop_pccch_req); | |
353 } | |
354 grr_data->is_pg_started = FALSE; | |
355 | |
356 pg_stop_non_drx_timer(); | |
357 pg_stop_t_nc2_ndrx(); | |
358 | |
359 } /* pg_send_stop() */ | |
360 | |
361 | |
362 | |
363 /* | |
364 +------------------------------------------------------------------------------ | |
365 | Function : pg_send_start | |
366 +------------------------------------------------------------------------------ | |
367 | Description : The function pg_send_start() .... | |
368 | | |
369 | Parameters : UBYTE page_mode | |
370 | | |
371 +------------------------------------------------------------------------------ | |
372 */ | |
373 GLOBAL void pg_send_start ( UBYTE page_mode ) | |
374 { | |
375 UBYTE pccch_group; /* 0 .. KC-1*/ | |
376 USHORT dummy; | |
377 | |
378 TRACE_FUNCTION( "pg_send_start" ); | |
379 | |
380 if(grr_is_non_drx_period()) | |
381 page_mode = REORG_PAGING; | |
382 | |
383 switch(page_mode) | |
384 { | |
385 case NORMAL_PAGING: | |
386 case EXT_PAGING: | |
387 case REORG_PAGING: | |
388 case SAME_PAGING: | |
389 break;/*O.K.*/ | |
390 default: | |
391 /* same as before: nothing to do return*/ | |
392 TRACE_EVENT("page_mode is corrupt: assume same as before: return"); | |
393 return; | |
394 } | |
395 | |
396 if(psc_db->paging_group.kc EQ 0) | |
397 { | |
398 /* | |
399 * No PCCCH description: return | |
400 */ | |
401 TRACE_ERROR("psc_db->paging_group.kc EQ 0"); | |
402 return; | |
403 } | |
404 | |
405 { | |
406 PALLOC( start_pccch, MPHP_START_PCCCH_REQ ); | |
407 | |
408 start_pccch->imsi_mod = grr_imsi_mod( ); | |
409 pccch_group = ( UBYTE )( start_pccch->imsi_mod % psc_db->paging_group.kc ); | |
410 | |
411 if( !grr_get_pccch_freq_par( pccch_group, | |
412 &start_pccch->p_ch_des.p_chan_sel, | |
413 &start_pccch->p_freq_list ) ) | |
414 { | |
415 PFREE( start_pccch ); | |
416 | |
417 return; | |
418 } | |
419 | |
420 start_pccch->kcn = psc_db->paging_group.kc; /*< KC multiplied by N */ | |
421 start_pccch->split_pg_cycle = grr_data->ms.split_pg_cycle; /*< Split paging cycle */ | |
422 start_pccch->bs_pag_blks_res = psc_db->pccch.bs_pag_blks; /*< No paging no PBCCH */ | |
423 start_pccch->bs_pbcch_blks = psc_db->pccch.bs_pbcch_blks; /*< Number of PBCCH per multiframe */ | |
424 start_pccch->pb = psc_db->g_pwr_par.pb; /*< Power reduction value */ | |
425 start_pccch->p_ch_des.tsc = psc_db->paging_group.pccch[pccch_group].tsc; /*< Training sequence code */ | |
426 start_pccch->p_ch_des.tn = psc_db->paging_group.pccch[pccch_group].tn; | |
427 | |
428 if( start_pccch->p_ch_des.p_chan_sel.hopping ) | |
429 { | |
430 TRACE_EVENT_P8( "Hopping PCCCH - ma_num:%d hsn/maio:%ld tsc:%d tn:%d f1:%d f2:%d f3:%d f4:%d", | |
431 psc_db->paging_group.pccch[pccch_group].ma_num, | |
432 start_pccch->p_ch_des.p_chan_sel.p_rf_ch.arfcn, | |
433 start_pccch->p_ch_des.tsc, | |
434 start_pccch->p_ch_des.tn, | |
435 start_pccch->p_freq_list.p_rf_chan_no.p_radio_freq[0], | |
436 start_pccch->p_freq_list.p_rf_chan_no.p_radio_freq[1], | |
437 start_pccch->p_freq_list.p_rf_chan_no.p_radio_freq[2], | |
438 start_pccch->p_freq_list.p_rf_chan_no.p_radio_freq[3] ); | |
439 } | |
440 else | |
441 { | |
442 TRACE_EVENT_P3( "Static PCCCH - arfcn:%ld tsc:%d tn:%d", | |
443 start_pccch->p_ch_des.p_chan_sel.p_rf_ch.arfcn, | |
444 start_pccch->p_ch_des.tsc, | |
445 start_pccch->p_ch_des.tn ); | |
446 | |
447 start_pccch->p_ch_des.p_chan_sel.p_rf_ch.arfcn = | |
448 grr_g23_arfcn_to_l1( start_pccch->p_ch_des.p_chan_sel.p_rf_ch.arfcn ); | |
449 } | |
450 | |
451 /* | |
452 * Calculate downlink signalling counter | |
453 */ | |
454 /* DRX period is used, there is a valid SPILT_PG_CYCLE value */ | |
455 dummy = grr_data->ms.split_pg_cycle; | |
456 | |
457 | |
458 /* Downlink signalling counter*/ | |
459 dummy = ( ( 90 * dummy ) / 64 < 10 ) ? 10 : ( 90 * dummy ) / 64; | |
460 | |
461 if(!grr_data->is_pg_started) | |
462 { | |
463 grr_data->pg.initial_dsc = dummy; | |
464 grr_data->pg.dsc = dummy; | |
465 | |
466 GRR_EM_SET_DSC_VAL(dummy); | |
467 | |
468 } | |
469 if( grr_data->pg.is_l1_ref_tn_changed NEQ psc_db->paging_group.pccch[pccch_group].tn ) | |
470 { | |
471 sig_pg_cs_pause( ); | |
472 } | |
473 | |
474 /*Read PCCCH */ | |
475 { | |
476 start_pccch->page_mode = page_mode; | |
477 PSEND(hCommL1, start_pccch); | |
478 } | |
479 if( grr_data->pg.is_l1_ref_tn_changed NEQ psc_db->paging_group.pccch[pccch_group].tn ) | |
480 { | |
481 sig_pg_cs_resume( ); | |
482 | |
483 grr_data->pg.is_l1_ref_tn_changed = psc_db->paging_group.pccch[pccch_group].tn; | |
484 } | |
485 | |
486 psc_db->last_pg_mode = page_mode; | |
487 | |
488 switch(page_mode) | |
489 { | |
490 case NORMAL_PAGING: | |
491 TRACE_EVENT("page mode NORMAL"); | |
492 break;/*O.K.*/ | |
493 case EXT_PAGING: | |
494 TRACE_EVENT("page mode EXT"); | |
495 break;/*O.K.*/ | |
496 case REORG_PAGING: | |
497 TRACE_EVENT("page mode REORG"); | |
498 break;/*O.K.*/ | |
499 case SAME_PAGING: | |
500 TRACE_EVENT("page mode SAME"); | |
501 break;/*O.K.*/ | |
502 } | |
503 | |
504 } | |
505 grr_data->is_pg_started = TRUE; | |
506 | |
507 } /* pg_send_start() */ | |
508 | |
509 /* | |
510 +------------------------------------------------------------------------------ | |
511 | Function : pg_start_non_drx_timer | |
512 +------------------------------------------------------------------------------ | |
513 | Description : The function pg_start_non_drx_timer() starts the timer for | |
514 | non DRX period | |
515 | | |
516 | Parameters : USHORT milliseconds | |
517 | | |
518 +------------------------------------------------------------------------------ | |
519 */ | |
520 LOCAL void pg_start_non_drx_timer(USHORT milliseconds) | |
521 { | |
522 TRACE_FUNCTION( "pg_start_non_drx_timer"); | |
523 | |
524 psc_db->non_drx_timer_running = TRUE; | |
525 vsi_t_start(GRR_handle,T_TRANS_NON_DRX, milliseconds); | |
526 }/* pg_start_non_drx_timer*/ | |
527 | |
528 /* | |
529 +------------------------------------------------------------------------------ | |
530 | Function : pg_stop_non_drx_timer | |
531 +------------------------------------------------------------------------------ | |
532 | Description : The function pg_stop_non_drx_timer() stops the timer for | |
533 | non DRX period | |
534 | | |
535 | Parameters : void | |
536 | | |
537 +------------------------------------------------------------------------------ | |
538 */ | |
539 GLOBAL void pg_stop_non_drx_timer(void) | |
540 { | |
541 TRACE_FUNCTION( "pg_stop_non_drx_timer"); | |
542 | |
543 if(psc_db->non_drx_timer_running) | |
544 { | |
545 psc_db->non_drx_timer_running = FALSE; | |
546 vsi_t_stop(GRR_handle,T_TRANS_NON_DRX); | |
547 } | |
548 }/* pg_stop_non_drx_timer*/ | |
549 | |
550 /* | |
551 +------------------------------------------------------------------------------ | |
552 | Function : pg_start_t_nc2_ndrx | |
553 +------------------------------------------------------------------------------ | |
554 | Description : ... | |
555 | | |
556 | Parameters : void | |
557 | | |
558 +------------------------------------------------------------------------------ | |
559 */ | |
560 GLOBAL void pg_start_t_nc2_ndrx( UBYTE nc_non_drx_period ) | |
561 { | |
562 TRACE_FUNCTION( "pg_start_t_nc2_ndrx"); | |
563 | |
564 if( nc_non_drx_period NEQ 0 ) | |
565 { | |
566 USHORT nc2_drx_period = NC2_NON_DRX_TABLE[nc_non_drx_period]; | |
567 | |
568 psc_db->nc2_non_drx_period_running = TRUE; | |
569 | |
570 vsi_t_start( GRR_handle, T_NC2_NON_DRX, nc2_drx_period ); | |
571 | |
572 TRACE_EVENT_P1( "Timer T_NC2_NON_DRX started: %d", nc2_drx_period ); | |
573 } | |
574 }/* pg_start_t_nc2_ndrx */ | |
575 | |
576 /* | |
577 +------------------------------------------------------------------------------ | |
578 | Function : pg_stop_t_nc2_ndrx | |
579 +------------------------------------------------------------------------------ | |
580 | Description : ... | |
581 | | |
582 | Parameters : void | |
583 | | |
584 +------------------------------------------------------------------------------ | |
585 */ | |
586 GLOBAL void pg_stop_t_nc2_ndrx( void ) | |
587 { | |
588 TRACE_FUNCTION( "pg_stop_t_nc2_ndrx" ); | |
589 | |
590 if( psc_db->nc2_non_drx_period_running EQ TRUE ) | |
591 { | |
592 psc_db->nc2_non_drx_period_running = FALSE; | |
593 | |
594 vsi_t_stop( GRR_handle, T_NC2_NON_DRX ); | |
595 | |
596 TRACE_EVENT( "Timer T_NC2_NON_DRX stopped" ); | |
597 } | |
598 } /* pg_stop_t_nc2_ndrx */ | |
599 | |
600 /* | |
601 +------------------------------------------------------------------------------ | |
602 | Function : pg_handle_non_drx_timers | |
603 +------------------------------------------------------------------------------ | |
604 | Description : ... | |
605 | | |
606 | Parameters : void | |
607 | | |
608 +------------------------------------------------------------------------------ | |
609 */ | |
610 GLOBAL void pg_handle_non_drx_timers(void) | |
611 { | |
612 USHORT non_drx_timer = 0; | |
613 TRACE_FUNCTION("pg_handle_non_drx_timers"); | |
614 | |
615 non_drx_timer = ( psc_db->non_drx_timer < psc_db->gprs_cell_opt.drx_t_max ) ? | |
616 psc_db->non_drx_timer : psc_db->gprs_cell_opt.drx_t_max; | |
617 | |
618 non_drx_timer = (USHORT)(NON_DRX_TABLE[non_drx_timer]*1000);/* in milliseconds*/ | |
619 | |
620 pg_start_non_drx_timer(non_drx_timer); | |
621 | |
622 }/* pg_handle_non_drx_timers */ | |
623 | |
624 /* | |
625 +------------------------------------------------------------------------------ | |
626 | Function : pg_non_drx | |
627 +------------------------------------------------------------------------------ | |
628 | Description : Handles the timer of non DRX mode | |
629 | | |
630 | Parameters : void | |
631 | | |
632 +------------------------------------------------------------------------------ | |
633 */ | |
634 GLOBAL void pg_non_drx ( void ) | |
635 { | |
636 TRACE_FUNCTION( "pg_non_drx" ); | |
637 | |
638 switch( GET_STATE( PG ) ) | |
639 { | |
640 case PG_IDLE: | |
641 /* | |
642 * To ensure that the paging mode is not set to page normal in other states | |
643 * than packet idle mode, the function grr_is_packet_idle_mode is called in | |
644 * advance. | |
645 * | |
646 * State PG_IDLE not necessarily means that GRR is in packet idle mode. In | |
647 * case GRR is currently executing the RRGRR_STOP_TASK_REQ/CNF procedure, | |
648 * just the services CPAP and TC changes their states. All other services | |
649 * remain in state IDLE, which is not quite correct. A similar scenario | |
650 * occurs during execution of the MPHP_ASSIGNMENT_REQ/CON procedure. | |
651 */ | |
652 if( grr_is_packet_idle_mode( ) EQ TRUE ) | |
653 { | |
654 pg_handle_idle_mode( PTM_IDLE ); | |
655 } | |
656 else | |
657 { | |
658 TRACE_EVENT( "pg_non_drx: Timeout T_TRANS_NON_DRX handled by next packet idle mode" ); | |
659 } | |
660 break; | |
661 default: | |
662 TRACE_EVENT( "pg_non_drx: Timeout T_TRANS_NON_DRX handled by next PG_IDLE" ); | |
663 break; | |
664 } | |
665 }/* pg_non_drx*/ | |
666 | |
667 /* | |
668 +------------------------------------------------------------------------------ | |
669 | Function : pg_decode_imsi | |
670 +------------------------------------------------------------------------------ | |
671 | Description : Handles the timer of non DRX mode | |
672 | | |
673 | Parameters : void | |
674 | | |
675 +------------------------------------------------------------------------------ | |
676 */ | |
677 LOCAL BOOL pg_decode_imsi(T_ms_id ms_id, UBYTE *digits, UBYTE *nr_digits) | |
678 { | |
679 UBYTE odd_even_type, i; | |
680 BOOL is_odd; | |
681 TRACE_FUNCTION("pg_decode_imsi"); | |
682 | |
683 *nr_digits = 0; | |
684 if(ms_id.ms_id_len > 0) | |
685 { | |
686 odd_even_type = (ms_id.ident_digit[0] & 0x0f); | |
687 | |
688 if(odd_even_type & 1) /* Check IMSI or not*/ | |
689 { | |
690 is_odd = odd_even_type & 0x08; /* odd: ung.*/ | |
691 digits[0] = (ms_id.ident_digit[0] >> 4); | |
692 *nr_digits = 1; | |
693 | |
694 for(i=1; i< ms_id.ms_id_len; i++) | |
695 { | |
696 if(!is_odd AND (i EQ (ms_id.ms_id_len-1))) | |
697 { | |
698 digits[*nr_digits] = (ms_id.ident_digit[i] & 0x0f); | |
699 *nr_digits = (*nr_digits) + 1; | |
700 } | |
701 else | |
702 { | |
703 digits[*nr_digits] = (ms_id.ident_digit[i] & 0x0f); | |
704 *nr_digits = (*nr_digits) + 1; | |
705 digits[*nr_digits] = (ms_id.ident_digit[i] >> 4); | |
706 *nr_digits = (*nr_digits) + 1; | |
707 } | |
708 } | |
709 } | |
710 else | |
711 { | |
712 /*No IMSI, ignore*/ | |
713 return FALSE; | |
714 } | |
715 } | |
716 else | |
717 { | |
718 /* No mobile identity: strange*/ | |
719 return FALSE; | |
720 } | |
721 return TRUE; | |
722 }/* pg_decode_imsi*/ | |
723 | |
724 /* | |
725 +------------------------------------------------------------------------------ | |
726 | Function : pg_handle_classB_NMO_III | |
727 +------------------------------------------------------------------------------ | |
728 | Description : Handles NMO III for Class B mobile | |
729 | | |
730 | Parameters : void | |
731 | | |
732 +------------------------------------------------------------------------------ | |
733 */ | |
734 GLOBAL void pg_handle_classB_NMO_III(T_PG_TRANS transition) | |
735 { | |
736 TRACE_FUNCTION("pg_handle_classB_NMO_III"); | |
737 | |
738 switch(transition) | |
739 { | |
740 case T3172_PTM: | |
741 case ACCESS_PTM: | |
742 case IDLE_PTM: | |
743 if(grr_data->ms.reverts_NMO_III) | |
744 { | |
745 /* | |
746 * The MS reverts to CC or CG in NMO III | |
747 * In this state IDLE->TRANSFER it can be only a CG mobile | |
748 * it shall stop PCCCH reading, if available | |
749 * it shall stop also CCCH reading, if running | |
750 */ | |
751 TRACE_EVENT("IDLE/ACCESS->PTM: NMO III Class B reverts. Stop CCCH (and PCCCH)"); | |
752 if(grr_is_pbcch_present()) | |
753 { | |
754 /* | |
755 * Stop monitoring PCCCH | |
756 */ | |
757 pg_send_stop(); | |
758 } | |
759 /* | |
760 * Stop monitoring CCCH | |
761 */ | |
762 sig_pg_ctrl_stop_mon_ccch(); | |
763 } | |
764 else | |
765 { | |
766 /* | |
767 * This is non reverting Class B | |
768 * If PBCCH is present it should stop PCCCH and start CCCH | |
769 * else it should only monitor CCCH | |
770 */ | |
771 TRACE_EVENT("IDLE/ACCESS->PTM: NMO III Class B. Start CCCH (and stop PCCCH)"); | |
772 if(grr_is_pbcch_present()) | |
773 { | |
774 /* | |
775 * Stop monitoring PCCCH | |
776 */ | |
777 pg_send_stop(); | |
778 } | |
779 /* | |
780 * Start monitoring CCCH (Normal Paging) | |
781 */ | |
782 if( grr_data->ms.tbf_mon_ccch | |
783 #ifdef REL99 | |
784 AND | |
785 !psc_db->gprs_cell_opt.gprs_ext_bits.gprs_ext_info.bss_paging_coord | |
786 #endif | |
787 ) | |
788 { | |
789 sig_pg_ctrl_start_mon_ccch(PAG_MODE_PTM_NP); | |
790 } | |
791 } | |
792 break; | |
793 case NULL_IDLE: | |
794 case PTM_IDLE: | |
795 if(grr_data->ms.reverts_NMO_III) | |
796 { | |
797 /* | |
798 * The MS reverts to CC or CG in NMO III | |
799 * In this state TRANSFER/NULL->IDLE it can be only a CG mobile | |
800 * it shall start PCCCH reading, if available | |
801 * it shall start also CCCH reading, if NO PBCCH | |
802 */ | |
803 TRACE_EVENT("PTM/NULL->IDLE: NMO III Class B reverts. Start (P) or CCCH"); | |
804 if(grr_is_pbcch_present()) | |
805 { | |
806 /* | |
807 * Start monitoring PCCCH | |
808 */ | |
809 pg_send_start( psc_db->last_pg_mode ); | |
810 | |
811 } | |
812 else | |
813 { | |
814 /* | |
815 * Start monitoring CCCH (Normal Paging) | |
816 */ | |
817 sig_pg_ctrl_start_mon_ccch(PAG_MODE_DEFAULT); | |
818 } | |
819 } | |
820 else | |
821 { | |
822 /* | |
823 * This is non reverting Class B | |
824 * If PBCCH is present it should start PCCCH and start CCCH | |
825 * else it should only monitor CCCH | |
826 */ | |
827 TRACE_EVENT("PTM/NULL->IDLE: NMO III Class B. Start (P) and CCCH"); | |
828 if(grr_is_pbcch_present()) | |
829 { | |
830 /* | |
831 * Start monitoring PCCCH | |
832 */ | |
833 pg_send_start( psc_db->last_pg_mode ); | |
834 /* | |
835 * Start monitoring CCCH (Normal Paging), before doing this use PAG_MODE_PIM_NP | |
836 * to enter later to idle mode | |
837 * Exceptional situation: if NON DRX is used, REORG is only for PCCCH | |
838 */ | |
839 sig_pg_ctrl_start_mon_ccch(PAG_MODE_PIM_NP); | |
840 } | |
841 else | |
842 { | |
843 /* | |
844 * Start monitoring CCCH (Normal Paging) | |
845 * Normal Paging | |
846 */ | |
847 sig_pg_ctrl_start_mon_ccch(PAG_MODE_DEFAULT); | |
848 } | |
849 } | |
850 break; | |
851 case ACCESS_IDLE: | |
852 if(grr_data->ms.reverts_NMO_III) | |
853 { | |
854 /* | |
855 * The MS reverts to CC or CG in NMO III | |
856 * In this state ACCESS->IDLE it can be only a CG mobile | |
857 * it shall start PCCCH reading, if available | |
858 * it shall start CCCH reading, if NO PBCCH | |
859 */ | |
860 TRACE_EVENT("ACCESS->IDLE: NMO III Class B reverts. Start (P) or CCCH"); | |
861 if(!grr_is_pbcch_present()) | |
862 { | |
863 /* | |
864 * Start monitoring CCCH (Normal Paging) | |
865 */ | |
866 sig_pg_ctrl_start_mon_ccch(PAG_MODE_DEFAULT); | |
867 } | |
868 } | |
869 else | |
870 { | |
871 /* | |
872 * This is non reverting Class B | |
873 * If PBCCH is present it should start PCCCH and start CCCH | |
874 * else it should only monitor CCCH | |
875 */ | |
876 TRACE_EVENT("ACCESS->IDLE: NMO III Class B. Start (P) and CCCH"); | |
877 if(grr_is_pbcch_present()) | |
878 { | |
879 /* | |
880 * Start monitoring PCCCH | |
881 */ | |
882 pg_send_start( psc_db->last_pg_mode ); | |
883 /* | |
884 * Start monitoring CCCH (Normal Paging) | |
885 * Exceptional situation: if NON DRX is used, we RORG is only for PCCCH | |
886 */ | |
887 if(grr_data->ms.tbf_mon_ccch | |
888 #ifdef REL99 | |
889 AND | |
890 !psc_db->gprs_cell_opt.gprs_ext_bits.gprs_ext_info.bss_paging_coord | |
891 #endif | |
892 ) | |
893 { | |
894 sig_pg_ctrl_start_mon_ccch(PAG_MODE_PTM_NP); | |
895 } | |
896 } | |
897 else | |
898 { | |
899 /* | |
900 * Start monitoring CCCH (Normal Paging) | |
901 * Normal Paging | |
902 */ | |
903 sig_pg_ctrl_start_mon_ccch(PAG_MODE_DEFAULT); | |
904 } | |
905 } | |
906 break; | |
907 case PTM_ACCESS: | |
908 case IDLE_ACCESS: | |
909 /* | |
910 * Not necessary | |
911 */ | |
912 break; | |
913 }/*switch*/ | |
914 } | |
915 | |
916 /* | |
917 +------------------------------------------------------------------------------ | |
918 | Function : pg_handle_access_mode | |
919 +------------------------------------------------------------------------------ | |
920 | Description : Handles the paging when entering the packet access mode. | |
921 | | |
922 | Parameters : void | |
923 | | |
924 +------------------------------------------------------------------------------ | |
925 */ | |
926 GLOBAL void pg_handle_access_mode ( void ) | |
927 { | |
928 TRACE_FUNCTION( "pg_handle_access_mode" ); | |
929 | |
930 | |
931 if( grr_is_pbcch_present( ) ) | |
932 { | |
933 if( !grr_data->is_pg_started OR psc_db->last_pg_mode NEQ REORG_PAGING ) | |
934 { | |
935 /* | |
936 * enable the L1 reading USF values | |
937 */ | |
938 pg_send_start( PG_REORG ); | |
939 } | |
940 } | |
941 else | |
942 { | |
943 /* | |
944 * start monitoring CCCH | |
945 */ | |
946 sig_pg_ctrl_start_mon_ccch( PAG_MODE_REORG ); | |
947 } | |
948 } /* pg_handle_access_mode() */ | |
949 | |
950 /* | |
951 +------------------------------------------------------------------------------ | |
952 | Function : pg_set_l1_ref_tn | |
953 +------------------------------------------------------------------------------ | |
954 | Description : The function pg_set_l1_ref_tn () .... | |
955 | | |
956 | Parameters : | |
957 | | |
958 +------------------------------------------------------------------------------ | |
959 */ | |
960 GLOBAL void pg_set_l1_ref_tn ( UBYTE* out_tn, UBYTE in_tn ) | |
961 { | |
962 TRACE_FUNCTION( "pg_set_l1_ref_tn" ); | |
963 | |
964 if( in_tn NEQ *out_tn ) | |
965 { | |
966 grr_data->pg.is_l1_ref_tn_changed = TRUE; | |
967 } | |
968 | |
969 *out_tn = in_tn; | |
970 | |
971 } /* pg_set_l1_ref_tn */ | |
972 | |
973 /* | |
974 +------------------------------------------------------------------------------ | |
975 | Function : pg_handle_idle_mode | |
976 +------------------------------------------------------------------------------ | |
977 | Description : | |
978 | | |
979 | Parameters : | |
980 | | |
981 +------------------------------------------------------------------------------ | |
982 */ | |
983 GLOBAL void pg_handle_idle_mode ( T_PG_TRANS transition ) | |
984 { | |
985 TRACE_FUNCTION( "pg_handle_idle_mode" ); | |
986 | |
987 switch( grr_data->pg.nmo ) | |
988 { | |
989 case GMMRR_NET_MODE_I: | |
990 /* | |
991 * NMOI: | |
992 * ==== | |
993 * Paging on ( CCCH or PCCCH ) and PACCH, GPRS attached MS should | |
994 * monitor one paging channel, so we have to stop monitoring CCCH | |
995 * channel if PCCCH is present. | |
996 */ | |
997 if( grr_is_pbcch_present( ) ) | |
998 { | |
999 pg_send_start( psc_db->last_pg_mode ); | |
1000 } | |
1001 else | |
1002 { | |
1003 sig_pg_ctrl_start_mon_ccch( PAG_MODE_DEFAULT ); | |
1004 } | |
1005 break; | |
1006 | |
1007 case GMMRR_NET_MODE_II: | |
1008 /* | |
1009 * NMOII: | |
1010 * ===== | |
1011 * Paging on CCCH, paging for both circuit switched and packet data | |
1012 * will be sent on CCCH, PCCCH has been not allocated in the cell. | |
1013 */ | |
1014 switch( grr_data->ms.class_of_mode ) | |
1015 { | |
1016 case GMMRR_CLASS_A: | |
1017 /* BEGIN GRR_NMO_III */ | |
1018 case GMMRR_CLASS_B: | |
1019 /* END GRR_NMO_III */ | |
1020 case GMMRR_CLASS_BG: | |
1021 case GMMRR_CLASS_BC: | |
1022 case GMMRR_CLASS_CG: | |
1023 case GMMRR_CLASS_CC: | |
1024 sig_pg_ctrl_start_mon_ccch( PAG_MODE_DEFAULT ); | |
1025 break; | |
1026 } | |
1027 break; | |
1028 | |
1029 case GMMRR_NET_MODE_III: | |
1030 /* | |
1031 * NMOIII: | |
1032 * ======= | |
1033 * If PBCCH not present paging for both circuit switched and packet | |
1034 * data will be sent on CCCH, | |
1035 * if PBCCH is present paging for circuit switched data is sent on | |
1036 * CCCH and for packet data on PCCCH. | |
1037 */ | |
1038 if( grr_is_pbcch_present( ) ) | |
1039 { | |
1040 TRACE_EVENT( "GMMRR_NET_MODE_III PBCCH" ); | |
1041 | |
1042 switch(grr_data->ms.class_of_mode) | |
1043 { | |
1044 case GMMRR_CLASS_A: | |
1045 pg_send_start( psc_db->last_pg_mode ); | |
1046 sig_pg_ctrl_start_mon_ccch( PAG_MODE_PIM_NP ); | |
1047 break; | |
1048 | |
1049 /* | |
1050 * We need to check whether the MS class B mobile | |
1051 * reverts to CG or CC in NMO III. If not it should monitor PCCCH and CCCH | |
1052 * else it needs to monitor either CCCH or PCCCH | |
1053 */ | |
1054 /* BEGIN GRR_NMO_III */ | |
1055 case GMMRR_CLASS_B: | |
1056 /* END GRR_NMO_III */ | |
1057 case GMMRR_CLASS_BG: | |
1058 case GMMRR_CLASS_BC: | |
1059 pg_handle_classB_NMO_III( transition ); | |
1060 break; | |
1061 | |
1062 case GMMRR_CLASS_CG: | |
1063 sig_pg_ctrl_stop_mon_ccch( ); | |
1064 pg_send_start( psc_db->last_pg_mode ); | |
1065 break; | |
1066 | |
1067 case GMMRR_CLASS_CC: | |
1068 sig_pg_ctrl_start_mon_ccch( PAG_MODE_DEFAULT ); | |
1069 break; | |
1070 } | |
1071 } | |
1072 else | |
1073 { | |
1074 TRACE_EVENT ( "GMMRR_NET_MODE_III BCCH" ); | |
1075 | |
1076 sig_pg_ctrl_start_mon_ccch( PAG_MODE_DEFAULT ); | |
1077 } | |
1078 break; | |
1079 } | |
1080 } /* pg_handle_idle_mode() */ | |
1081 | |
1082 /* | |
1083 +------------------------------------------------------------------------------ | |
1084 | Function : pg_handle_transfer_mode | |
1085 +------------------------------------------------------------------------------ | |
1086 | Description : | |
1087 | | |
1088 | Parameters : | |
1089 | | |
1090 +------------------------------------------------------------------------------ | |
1091 */ | |
1092 GLOBAL void pg_handle_transfer_mode ( T_PG_TRANS transition ) | |
1093 { | |
1094 TRACE_FUNCTION( "pg_handle_transfer_mode" ); | |
1095 | |
1096 switch( grr_data->pg.nmo ) | |
1097 { | |
1098 case GMMRR_NET_MODE_I: | |
1099 /* | |
1100 * NMOI: | |
1101 * ==== | |
1102 * Paging on ( CCCH or PCCCH ) and PACCH, GPRS attached MS should | |
1103 * monitor one paging channel, so we have to stop monitoring CCCH | |
1104 * channel if PCCCH is present. | |
1105 */ | |
1106 if( grr_is_pbcch_present( ) ) | |
1107 { | |
1108 pg_send_stop( ); | |
1109 } | |
1110 else | |
1111 { | |
1112 sig_pg_ctrl_stop_mon_ccch( ); | |
1113 } | |
1114 break; | |
1115 | |
1116 case GMMRR_NET_MODE_II: | |
1117 /* | |
1118 * NMOII: | |
1119 * ===== | |
1120 * Paging on CCCH, paging for both circuit switched and packet data | |
1121 * will be sent on CCCH, PCCCH has been not allocated in the cell. | |
1122 * | |
1123 * The MS should monitor CCCH except for the CLASS_CG. | |
1124 */ | |
1125 switch( grr_data->ms.class_of_mode ) | |
1126 { | |
1127 case GMMRR_CLASS_A: | |
1128 /* BEGIN GRR_NMO_III*/ | |
1129 case GMMRR_CLASS_B: | |
1130 /* END GRR_NMO_III*/ | |
1131 case GMMRR_CLASS_BG: | |
1132 case GMMRR_CLASS_BC: | |
1133 if( grr_data->ms.tbf_mon_ccch | |
1134 #ifdef REL99 | |
1135 AND | |
1136 !psc_db->gprs_cell_opt.gprs_ext_bits.gprs_ext_info.bss_paging_coord | |
1137 #endif | |
1138 ) | |
1139 { | |
1140 sig_pg_ctrl_start_mon_ccch( PAG_MODE_PTM_NP ); | |
1141 } | |
1142 else | |
1143 { | |
1144 sig_pg_ctrl_stop_mon_ccch( ); | |
1145 } | |
1146 break; | |
1147 | |
1148 case GMMRR_CLASS_CG: | |
1149 sig_pg_ctrl_stop_mon_ccch( ); | |
1150 break; | |
1151 } | |
1152 break; | |
1153 | |
1154 case GMMRR_NET_MODE_III: | |
1155 /* | |
1156 * NMOIII: | |
1157 * ======= | |
1158 * If PBCCH not present paging for both circuit switched and packet | |
1159 * data will be sent on CCCH, | |
1160 * if PBCCH is present paging for circuit switched data is sent on | |
1161 * CCCH and for packet data on PCCCH. | |
1162 */ | |
1163 switch( grr_data->ms.class_of_mode ) | |
1164 { | |
1165 case GMMRR_CLASS_A: | |
1166 if( grr_is_pbcch_present( ) ) | |
1167 { | |
1168 pg_send_stop( ); | |
1169 } | |
1170 | |
1171 sig_pg_ctrl_start_mon_ccch( PAG_MODE_PTM_NP ); | |
1172 break; | |
1173 | |
1174 /* BEGIN GRR_NMO_III*/ | |
1175 case GMMRR_CLASS_B: | |
1176 /* END GRR_NMO_III*/ | |
1177 case GMMRR_CLASS_BG: | |
1178 case GMMRR_CLASS_BC: | |
1179 pg_handle_classB_NMO_III( transition ); | |
1180 break; | |
1181 | |
1182 case GMMRR_CLASS_CG: | |
1183 if( grr_is_pbcch_present( ) ) | |
1184 { | |
1185 pg_send_stop( ); | |
1186 } | |
1187 else | |
1188 { | |
1189 sig_pg_ctrl_stop_mon_ccch( ); | |
1190 } | |
1191 break; | |
1192 } | |
1193 break; | |
1194 } | |
1195 } /* pg_handle_transfer_mode() */ |