comparison g23m-gsm/alr/alr_pch.c @ 0:75a11d740a02

initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 09 Jun 2016 00:02:41 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:75a11d740a02
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : GSM-PS
4 | Modul : ALR_PCH
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 Modul defines the SDL process PCH_Control.
18 +-----------------------------------------------------------------------------
19 */
20
21 #ifndef ALR_PCH_C
22 #define ALR_PCH_C
23
24 #include "config.h"
25 #include "fixedconf.h"
26 #include "condat-features.h"
27
28 #define ENTITY_PL
29
30 /*==== INCLUDES ===================================================*/
31 #include <string.h>
32 #include <stdlib.h>
33 #include <ctype.h>
34 #include "typedefs.h"
35 #include "pconst.cdg"
36 #include "mconst.cdg"
37 #include "message.h"
38 #include "ccdapi.h"
39 #include "vsi.h"
40 #include "custom.h"
41 #include "gsm.h"
42 #include "prim.h"
43 #include "cnf_alr.h"
44 #include "mon_alr.h"
45 #include "pei.h"
46 #include "tok.h"
47 #include "pcm.h"
48 #ifdef GPRS
49 #include "alr_gprs.h"
50 #endif
51
52 #include "alr.h"
53 #include "alr_em.h"
54
55 /*==== EXPORT =====================================================*/
56 typedef enum
57 {
58 IMSI_TYPE_1=1,
59 IMSI_TYPE_2
60 }T_IMSI_TYPE;
61 typedef enum
62 {
63 TMSI_TYPE_1=4,
64 TMSI_TYPE_2=8
65 }T_TMSI_TYPE;
66 /*==== PRIVAT =====================================================*/
67 LOCAL BOOL pch_frm_chan_imsi (UBYTE *frame,
68 UBYTE channel_needed,
69 T_IMSI_TYPE imsi_type,
70 UBYTE index,
71 UBYTE *frame_start);
72 LOCAL BOOL pch_tmsi_type (T_TMSI_TYPE tmsi_type,
73 UBYTE *frame,
74 UBYTE channel_needed);
75 /*==== VARIABLES ==================================================*/
76 UBYTE page_mode_before_hplmn_search = PGM_NORMAL;
77 /*==== CONSTANTS ==================================================*/
78 #define IMSI_ODD_FLAG 8
79 #define IMSI_EVEN_FLAG 0
80 #define IDENT_TYPE_MON 0
81 #define IDENT_TYPE_IMSI 1
82 #define IDENT_TYPE_IMEI 2
83 #define IDENT_TYPE_IMEISV 3
84 #define IDENT_TYPE_TMSI 4
85 #define END_MARK 0xF0
86
87 /*==== FUNCTIONS ==================================================*/
88
89 #define TRACING
90
91 #if defined (TRACING)
92 #define ALR_TRACE_PCH(a) ALR_TRACE(a)
93 #else
94 #define ALR_TRACE_PCH(a)
95 #endif
96
97 #ifdef TRACING
98 #define ALR_TRACE_PCH_CONFIG(b,a,c,t,p,m) \
99 TRACE_EVENT_P6 ("MFRMS: %d AG_RES: %d COMB: %d GRP: %d PGRP: %d PI: %d",b,a,c,t,p,m)
100 #define ALR_TRACE_PCH_PGM(p,x) \
101 TRACE_EVENT_P2 ("new_pgm: %d cur_pgm: %d",p,x)
102 #define ALR_TRACE_PCH_IMSI() \
103 { for (i=0; i<alr_data->pch_data.imsi[0]+1;i++) { \
104 TRACE_EVENT_P2 ("imsi[%d]=%x",i,alr_data->pch_data.imsi[i]);} }
105 #else
106 #define ALR_TRACE_PCH_CONFIG(b,a,c,t,p,m)
107 #define ALR_TRACE_PCH_PGM(p,x)
108 #define ALR_TRACE_PCH_IMSI()
109 #endif
110
111 /*
112 +--------------------------------------------------------------------+
113 | PROJECT : GSM-PS (6103) MODULE : ALR_PCH |
114 | STATE : code ROUTINE : pch_init |
115 +--------------------------------------------------------------------+
116
117 PURPOSE : Initialize PCH Control Process.
118
119 */
120 GLOBAL void pch_init (void)
121 {
122 GET_INSTANCE_DATA;
123 alr_data->pch_data.saved_page_mode = PGM_REORG;
124 alr_data->pch_data.reorg_bcch_reading = FALSE;
125 }
126
127 /*
128 +--------------------------------------------------------------------+
129 | PROJECT : GSM-PS (6103) MODULE : ALR_PCH |
130 | STATE : code ROUTINE : pch_start |
131 +--------------------------------------------------------------------+
132
133 PURPOSE : Process signal pch_start from SDL process
134 Main_Control.
135
136 */
137 static const UBYTE PAG_BLOCK_TABLE [2][8] =
138 {
139 /* not combined ccch */
140 9,8,7,6,5,4,3,2,
141 /* combined ccch */
142 3,2,1,1,1,1,1,1
143 };
144
145 /*
146 +--------------------------------------------------------------------+
147 | PROJECT : GSM-PS (6103) MODULE : ALR_PCH |
148 | STATE : code ROUTINE : pch_configure |
149 +--------------------------------------------------------------------+
150
151 PURPOSE : Configutes L1 for paging.
152
153 */
154 GLOBAL void pch_configure (T_MPH_IDLE_REQ *idle, UBYTE page_mode)
155 {
156 GET_INSTANCE_DATA;
157 UBYTE pag_blocks_per_mfr;
158
159 if(idle NEQ NULL)
160 {
161
162 alr_data->pch_data.dlt = idle->dlt;
163 alr_data->pch_data.act_dlt = idle->dlt;
164
165 ALR_EM_SET_EM_ACT_DLT;
166
167 pag_blocks_per_mfr = PAG_BLOCK_TABLE [idle->comb_ccch][idle->bs_ag_blocks_res];
168 /*
169 * pl_idle.bs_pa_mfrms has a range from 2-9.
170 * MPH_IDLE_REQ codes them from 0-7
171 */
172 alr_data->pch_data.pl_idle.bs_pa_mfrms = (UBYTE)(idle->bs_pa_mfrms + 2);
173 alr_data->pch_data.pl_idle.bs_ag_blks_res = idle->bs_ag_blocks_res;
174 alr_data->pch_data.pl_idle.bcch_combined = idle->comb_ccch;
175 alr_data->pch_data.pl_idle.ccch_group = (UBYTE)(idle->tn / 2);
176 alr_data->pch_data.pl_idle.page_group = idle->pg;
177 alr_data->pch_data.pl_idle.page_block_index = (UBYTE)(idle->pg % pag_blocks_per_mfr);
178
179 ALR_TRACE_PCH_CONFIG(idle->bs_pa_mfrms+2, idle->bs_ag_blocks_res,
180 idle->comb_ccch, idle->tn/2, idle->pg,
181 idle->pg % pag_blocks_per_mfr);
182 }
183
184 /*
185 * During cell reselection reading of PCH is started hard coded with
186 * page mode PGM_REORG because of the lack of parameters to calculate
187 * the right paging group. Detection of SI3 during cell reselection
188 * triggers the function pch_config_resel() to reconfigure PCH reading,
189 * detection of a changed page mode during cell reselection is handled
190 * by function pch_check_page_mode_cr() which needs to know whether SI3
191 * is read
192 */
193 if (GET_STATE (STATE_MA) EQ MA_CELL_RESELECTION)
194 alr_data->pch_data.si3_read = FALSE;
195
196
197 /* Ensure that L1 does not get initialised with PAGING EXTENDED */
198 switch( page_mode )
199 {
200 case SAVED_PGM:
201 if( alr_data->pch_data.saved_page_mode EQ PGM_EXTENDED )
202 {
203 alr_data->pch_data.saved_page_mode = PGM_REORG;
204 }
205 page_mode = alr_data->pch_data.saved_page_mode;
206 /*lint -fallthrough*/
207 default:
208 alr_data->pch_data.pl_idle.page_mode = page_mode;
209 }
210 }
211
212 /*
213 +--------------------------------------------------------------------+
214 | PROJECT : GSM-PS (6103) MODULE : ALR_PCH |
215 | STATE : code ROUTINE : pch_save_pgm |
216 +--------------------------------------------------------------------+
217 PURPOSE : Configure Paging
218 */
219 GLOBAL void pch_save_pgm(UBYTE mode)
220 {
221 GET_INSTANCE_DATA;
222 if(mode)
223 alr_data->pch_data.saved_page_mode = mode;
224 else
225 alr_data->pch_data.saved_page_mode = alr_data->pch_data.pl_idle.page_mode;
226 }
227
228
229 /*
230 +--------------------------------------------------------------------+
231 | PROJECT : GSM-PS (6103) MODULE : ALR_PCH |
232 | STATE : code ROUTINE : pch_start_ccch_req |
233 +--------------------------------------------------------------------+
234
235 PURPOSE : Configure Paging
236
237 */
238
239 GLOBAL void pch_start_ccch_req (void)
240 {
241 GET_INSTANCE_DATA;
242 PALLOC(pl_idle, MPHC_START_CCCH_REQ);
243 memset(pl_idle, 0, sizeof(T_MPHC_START_CCCH_REQ));
244
245 ALR_EM_PAGE_MODE_CHANGE;
246
247 switch (alr_data->pch_data.pl_idle.page_mode)
248 {
249 case PGM_REORG:
250 ALR_TRACE_PCH ("config REORG");
251 /* dummy values */
252 pl_idle->bs_pa_mfrms = 2;
253 pl_idle->bs_ag_blks_res = 7;
254 pl_idle->bcch_combined = 0;
255 pl_idle->ccch_group = 0;
256 pl_idle->page_group = 0;
257 pl_idle->page_block_index = 0;
258 pl_idle->page_mode = PGM_REORG;
259 break;
260 case PGM_REORG_CS:
261 ALR_TRACE_PCH ("config REORG_CS");
262
263 memcpy (pl_idle, &alr_data->pch_data.pl_idle,
264 sizeof (T_MPHC_START_CCCH_REQ));
265 /*
266 * if the page_mode is PGM_REORG_CS then
267 * we have to change this to PGM_REORG
268 * before we send it to L1
269 */
270 pl_idle->page_mode = PGM_REORG;
271 break;
272 case PGM_EXTENDED:
273 ALR_TRACE_PCH ("config EXT");
274
275 memcpy (pl_idle, &alr_data->pch_data.pl_idle,
276 sizeof (T_MPHC_START_CCCH_REQ));
277 pl_idle->page_mode = PGM_EXTENDED;
278 break;
279 case PGM_REORG_NC_SYNC:
280 /*this case is the same as the default - except for the TRACE*/
281 ALR_TRACE_PCH ("config PGM_REORG_NC_SYNC (NORMAL)");
282
283 memcpy (pl_idle, &alr_data->pch_data.pl_idle,
284 sizeof (T_MPHC_START_CCCH_REQ));
285 pl_idle->page_mode = PGM_NORMAL;
286 break;
287 default:
288 ALR_TRACE_PCH ("config NORMAL");
289
290 memcpy (pl_idle, &alr_data->pch_data.pl_idle,
291 sizeof (T_MPHC_START_CCCH_REQ));
292 pl_idle->page_mode = PGM_NORMAL;
293 break;
294 }
295
296 SET_STATE(STATE_PCH,PCH_ACTIVE);
297 ma_pch_start_ccch_req(pl_idle);
298
299 TRACE_EVENT_P1("reorg_bcch_reading = %d",alr_data->pch_data.reorg_bcch_reading);
300 if(alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG OR
301 alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG_CS OR
302 alr_data->pch_data.reorg_bcch_reading EQ TRUE)
303 { /*
304 * if we're going into reorg paging we also need to read the BCCH
305 * to read possibly changed channel configuration
306 * XXX but not at PGM_REORG_NC_SYNC (NORMAL)
307 */
308 ma_scell_full_nbcch();
309 #if defined (REL99) && defined (TI_PS_FF_EMR)
310 if (alr_data->nc_data.si2quater_status EQ SI2QUATER_CONFIGURE )
311 {
312 if(alr_data->ma_data.sys_info_2quater[1] EQ D_SYS_INFO_2QUATER)
313 {
314 ma_send_stored_SI2qtr(&alr_data->ma_data.sys_info_2quater[0]);
315 memset (alr_data->ma_data.sys_info_2quater, 0, 22);
316 }
317 alr_data->nc_data.si2quater_status = SI2QUATER_ACQ_FULL_BCCH;
318 }
319 #endif
320 }
321 else
322 { /*
323 * otherwise we stop the reading of the BCCH and start the periodic read.
324 * XXX but not if we have a PBCCH
325 */
326 #ifdef GPRS
327 if(alr_data->gprs_data.pbcch EQ FALSE)
328 #endif
329 #if defined (REL99) && defined (TI_PS_FF_EMR)
330 {
331 TRACE_EVENT_P1("SI2qtr status: %d", alr_data->nc_data.si2quater_status);
332 if ( (alr_data->nc_data.si2quater_status EQ SI2QUATER_ABSENT) OR
333 (alr_data->nc_data.si2quater_status EQ SI2QUATER_ACQ_WRONG_BAIND) OR
334 (alr_data->nc_data.si2quater_status EQ SI2QUATER_ACQ_COMP) )
335 sc_start_periodic();
336 else if ((alr_data->nc_data.si2quater_status EQ SI2QUATER_CONFIGURE ) OR
337 (alr_data->nc_data.si2quater_status EQ SI2QUATER_ACQ_FULL_BCCH))
338 {
339 if(alr_data->ma_data.sys_info_2quater[1] EQ D_SYS_INFO_2QUATER)
340 {
341 ma_send_stored_SI2qtr(&alr_data->ma_data.sys_info_2quater[0]);
342 memset (alr_data->ma_data.sys_info_2quater, 0, 22);
343 }
344 if (alr_data->nc_data.si2quater_pos EQ SI2QUATER_ON_NBCCH)
345 ma_scell_mon_si2quater_nbcch();
346 else
347 ma_scell_mon_si2quater_ebcch();
348 alr_data->nc_data.si2quater_status = SI2QUATER_ACQ_PENDING;
349 }
350 }
351 #else
352 sc_start_periodic();
353 #endif
354 }
355 }
356
357
358 /*
359 +--------------------------------------------------------------------+
360 | PROJECT : GSM-PS (6103) MODULE : ALR_PCH |
361 | STATE : code ROUTINE : pch_identity_req |
362 +--------------------------------------------------------------------+
363
364 PURPOSE : Get new mobile identity information from RR. Build IMSI
365 pattern and store TMSI.
366
367 */
368 GLOBAL void pch_identity_req (T_MPH_IDENTITY_REQ *mph_identity_req)
369 {
370 GET_INSTANCE_DATA;
371 UBYTE i;
372
373 /* the IMSI in the identity request is coded as a 15byte long array
374 and is stored for later usage in pch_data as the message representation
375 of the IMSI according to GSM4.08 10.5.1.4 */
376
377 if (mph_identity_req->mid.len_imsi EQ 0)
378 {
379 /*
380 * limited service, no paging
381 */
382 memset (alr_data->pch_data.imsi, 0, IMSI_LEN);
383 alr_data->pch_data.v_tmsi = FALSE;
384 alr_data->pch_data.tmsi = 0L;
385 }
386 else
387 {
388 /*
389 * The IMSI is available
390 */
391 /* store length */
392 alr_data->pch_data.imsi[0] = (UBYTE)((mph_identity_req->mid.len_imsi + 2) / 2);
393
394 if (mph_identity_req->mid.len_imsi & 1)
395 {
396 ALR_TRACE_PCH ("IMSI is odd");
397 /*
398 * odd number of digits
399 * first digit + odd flag + identity type IMSI
400 */
401 alr_data->pch_data.imsi[1] = (UBYTE)((mph_identity_req->mid.imsi[0] << 4) +
402 IMSI_ODD_FLAG +
403 IDENT_TYPE_IMSI);
404 }
405 else
406 {
407 ALR_TRACE_PCH ("IMSI is even");
408 /*
409 * even number of digits
410 * first digit + even flag + identity type IMSI
411 */
412 alr_data->pch_data.imsi[1] = (UBYTE)((mph_identity_req->mid.imsi[0] << 4) +
413 IMSI_EVEN_FLAG +
414 IDENT_TYPE_IMSI);
415 }
416 /*
417 * fill in the rest of digits
418 */
419 for (i=1;i<mph_identity_req->mid.len_imsi;i++)
420 {
421 if (i & 1)
422 alr_data->pch_data.imsi[(i/2)+2] = (UBYTE)(END_MARK + mph_identity_req->mid.imsi[i]);
423 else
424 {
425 alr_data->pch_data.imsi[(i/2)+1] &= ~END_MARK; /* remove end mark */
426 alr_data->pch_data.imsi[(i/2)+1] = (UBYTE)(alr_data->pch_data.imsi[(i/2)+1] +
427 (mph_identity_req->mid.imsi[i] << 4));
428 }
429 }
430 alr_data->pch_data.imsi_mod_1000 = (SHORT)
431 ( (mph_identity_req->mid.imsi[mph_identity_req->mid.len_imsi-1] +
432 mph_identity_req->mid.imsi[mph_identity_req->mid.len_imsi-2] * 10 +
433 mph_identity_req->mid.imsi[mph_identity_req->mid.len_imsi-3] * 100 ) % 1000);
434
435 ALR_TRACE_PCH_IMSI();
436
437 /*
438 * copy TMSI
439 */
440 alr_data->pch_data.v_tmsi = mph_identity_req->mid.v_tmsi;
441 alr_data->pch_data.tmsi = mph_identity_req->mid.tmsi;
442 #ifdef GPRS
443 gprs_alr_store_ptmsi(mph_identity_req->mid.v_ptmsi,
444 mph_identity_req->mid.ptmsi);
445 gprs_alr_store_ptmsi2(mph_identity_req->mid.v_ptmsi2,
446 mph_identity_req->mid.ptmsi2);
447 #endif
448 }
449 }
450
451 /*
452 +--------------------------------------------------------------------+
453 | PROJECT : GSM-PS (6103) MODULE : ALR_PCH |
454 | STATE : code ROUTINE : pch_increment_dlt |
455 +--------------------------------------------------------------------+
456
457 PURPOSE : Incrementation of downlink timeout counter after receiving
458 a valid PCH block.
459
460 */
461 GLOBAL void pch_increment_dlt (void)
462 {
463 GET_INSTANCE_DATA;
464 if (alr_data->pch_data.act_dlt <
465 alr_data->pch_data.dlt)
466 {
467 #if !defined NTRACE
468 trc_mon_counter_idle (alr_data->pch_data.act_dlt,
469 alr_data->pch_data.dlt);
470 #endif /* (!defined NTRACE) */
471 alr_data->pch_data.act_dlt++;
472
473 ALR_EM_SET_EM_ACT_DLT;
474
475 }
476 }
477
478 /*
479 +--------------------------------------------------------------------+
480 | PROJECT : GSM-PS (6103) MODULE : ALR_PCH |
481 | STATE : code ROUTINE : pch_decrement_dlt |
482 +--------------------------------------------------------------------+
483
484 PURPOSE : Decrementation of downlink timeout counter after receiving
485 an invalid PCH block.
486
487 */
488 GLOBAL void pch_decrement_dlt (void)
489 {
490 GET_INSTANCE_DATA;
491 if (alr_data->pch_data.act_dlt > 4)
492 {
493 #if !defined NTRACE
494 trc_mon_counter_idle (alr_data->pch_data.act_dlt,
495 alr_data->pch_data.dlt);
496 #endif /* (!defined NTRACE) */
497
498 alr_data->pch_data.act_dlt -= 4;
499
500 ALR_EM_SET_EM_ACT_DLT;
501
502 }
503 else
504 {
505 alr_data->pch_data.act_dlt = alr_data->pch_data.dlt;
506 #if !defined NTRACE
507 trc_mon_counter_idle (alr_data->pch_data.act_dlt,
508 alr_data->pch_data.dlt);
509 #endif
510
511 ALR_EM_SET_EM_ACT_DLT;
512
513 ALR_TRACE_PCH ("downlink fail");
514
515 ma_error_ind (CS_DOWN_LINK_FAIL, alr_data->serving_cell);
516 }
517 }
518
519
520 /*
521 +--------------------------------------------------------------------+
522 | PROJECT : GSM-PS (6103) MODULE : ALR_PCH |
523 | STATE : code ROUTINE : pch_check_page_mode |
524 +--------------------------------------------------------------------+
525
526 PURPOSE : Check the page mode of an incoming unacknowledged
527 message.
528 */
529 static const UBYTE PAGE_MODE_CHANGE [3][4] =
530 {
531 /* old mode = paging normal */
532 NONE, SWAP_TO_EXTEND, SWAP_TO_REORG, NONE,
533 /* old mode = extended paging */
534 SWAP_TO_NORMAL, NONE, SWAP_TO_REORG, NONE,
535 /* old mode = paging reorganisation */
536 SWAP_TO_NORMAL, SWAP_TO_EXTEND, NONE, NONE
537 };
538
539
540 GLOBAL void pch_check_page_mode (T_MPHC_DATA_IND *data_ind)
541 {
542 GET_INSTANCE_DATA;
543 UBYTE page_mode;
544 UBYTE cur_page_mode = alr_data->pch_data.pl_idle.page_mode;
545
546 page_mode = (UBYTE)(data_ind->l2_frame.content [3] & 3);
547
548 ALR_TRACE_PCH_PGM(page_mode, alr_data->pch_data.pl_idle.page_mode);
549
550 /*if HPLMN search is going on and we should be in REORG, we are really
551 in REORG_NC_SYNC (NORMAL). Otherwise we cannot synchronize to the NC's*/
552 if(alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG_NC_SYNC)
553 cur_page_mode = PGM_REORG;
554
555 if(alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG_CS)
556 cur_page_mode = PGM_REORG;
557
558 switch (PAGE_MODE_CHANGE [cur_page_mode][page_mode])
559 {
560 case SWAP_TO_NORMAL:
561 ALR_TRACE_PCH ("SWAP_TO_NORMAL");
562 alr_data->pch_data.pl_idle.page_mode = PGM_NORMAL;
563 pch_start_ccch_req ();
564 break;
565 case SWAP_TO_EXTEND:
566 ALR_TRACE_PCH ("SWAP_TO_EXT");
567 alr_data->pch_data.pl_idle.page_mode = PGM_EXTENDED;
568 pch_start_ccch_req ();
569 break;
570 case SWAP_TO_REORG:
571 ALR_TRACE_PCH ("SWAP_TO_REORG");
572 alr_data->pch_data.reorg_bcch_reading = TRUE;
573 alr_data->pch_data.si_bitmap = 0;
574 alr_data->pch_data.pl_idle.page_mode = PGM_REORG_CS;
575 pch_start_ccch_req ();
576 break;
577 default:
578 break;
579 }
580 }
581
582 GLOBAL void pch_check_page_mode_cr (T_MPHC_DATA_IND *data_ind)
583 {
584 GET_INSTANCE_DATA;
585 UBYTE page_mode;
586 UBYTE cur_page_mode = alr_data->pch_data.saved_page_mode;
587 UBYTE swap = TRUE;
588
589 page_mode = (UBYTE)(data_ind->l2_frame.content [3] & 3);
590 if(alr_data->pch_data.saved_page_mode EQ PGM_REORG_CS)
591 cur_page_mode = PGM_REORG;
592
593 switch (PAGE_MODE_CHANGE [cur_page_mode][page_mode])
594 {
595 case SWAP_TO_NORMAL:
596 ALR_TRACE_PCH ("CR:SWAP_TO_NORMAL");
597 alr_data->pch_data.saved_page_mode = PGM_NORMAL;
598 break;
599
600 case SWAP_TO_EXTEND:
601 ALR_TRACE_PCH ("CR:SWAP_TO_EXT");
602 alr_data->pch_data.saved_page_mode = PGM_EXTENDED;
603 break;
604
605 case SWAP_TO_REORG:
606 ALR_TRACE_PCH ("CR:SWAP_TO_REORG");
607 alr_data->pch_data.saved_page_mode = PGM_REORG_CS;
608 break;
609
610 default:
611 swap = FALSE;
612 break;
613 }
614
615 if (swap AND alr_data->pch_data.si3_read AND
616 alr_data->pch_data.last_start_ccch_req.bs_pa_mfrms NEQ NOT_PRESENT_8BIT)
617 {
618 PALLOC(pl_idle, MPHC_START_CCCH_REQ);
619 memcpy ( pl_idle,
620 &(alr_data->pch_data.last_start_ccch_req),
621 sizeof(T_MPHC_START_CCCH_REQ));
622 pl_idle->page_mode = alr_data->pch_data.saved_page_mode;
623 ma_pch_start_ccch_req (pl_idle);
624 }
625
626 }
627
628
629 /*
630 +--------------------------------------------------------------------+
631 | PROJECT : GSM-PS (6103) MODULE : ALR_PCH |
632 | STATE : code ROUTINE : pch_check_pag_1 |
633 +--------------------------------------------------------------------+
634
635 PURPOSE : The function checks a paging request type 1 message.
636
637 */
638 GLOBAL void pch_check_pag_1 (T_MPHC_DATA_IND *data_ind)
639 {
640 GET_INSTANCE_DATA;
641 UBYTE *frame = data_ind->l2_frame.content;
642 UBYTE channel_needed;
643
644 UBYTE *frame_start = data_ind->l2_frame.content;
645
646 /*ALR_TRACE_PCH ("p1");*/
647 /*
648 * Check only if IMSI available (len NEQ 0),
649 * ti and pd = 0x06 and
650 * l2 pseudolength is greater than 5 bytes
651 */
652 if (alr_data->pch_data.imsi[0] AND
653 frame[1] EQ 0x06 AND
654 frame[0] > 0x15)
655 {
656 /*
657 * store channel needed type
658 */
659 channel_needed = frame[3];
660 /*
661 * check type of identity for mobile identity 1
662 */
663 if(pch_frm_chan_imsi( frame, channel_needed, IMSI_TYPE_1, 5,frame_start))
664 return;
665 /*
666 * check type of identity for mobile identity 2
667 * set frame pointer to start of mobile identity 2 (id tag)
668 * old frame pointer (frame) +
669 * offset pseudo length etc (4) +
670 * length mobile identity 1 (frame [4]) +
671 * plus 1 byte for length field
672 */
673 frame = frame + 4 + frame[4] + 1;
674 if (frame[0] EQ 0x17)
675 {
676 /*
677 * mobile identity 2 is available
678 */
679 if(pch_frm_chan_imsi( frame, channel_needed, IMSI_TYPE_2, 2, frame_start))
680 return;
681 }
682 }
683 //ALR_TRACE_PCH("end p1");
684 }
685
686
687 /*
688 +--------------------------------------------------------------------+
689 | PROJECT : GSM-PS (6103) MODULE : ALR_PCH |
690 | STATE : code ROUTINE : pch_check_pag_2 |
691 +--------------------------------------------------------------------+
692
693 PURPOSE : The function checks a paging request type 2 message.
694
695 */
696
697 GLOBAL void pch_check_pag_2 (T_MPHC_DATA_IND *data_ind)
698 {
699 GET_INSTANCE_DATA;
700 UBYTE *frame = data_ind->l2_frame.content;
701 ULONG tmsi;
702 UBYTE i;
703 UBYTE channel_needed;
704
705 /*
706 * Check only if IMSI available (len NEQ 0) and
707 * ti and pd = 0x06 and
708 * l2 pseudolength is greater than 5 bytes
709 */
710 if (alr_data->pch_data.imsi[0] AND
711 frame[1] EQ 0x06 AND
712 frame[0] > 0x15)
713 {
714 /*
715 * store channel needed type
716 */
717 channel_needed = frame[3];
718 /*
719 * check mobile identity 1 only if TMSI is available
720 */
721 if(pch_tmsi_type(TMSI_TYPE_1, frame, channel_needed))
722 return;
723 #ifdef GPRS
724 if(GET_STATE(STATE_MA) NEQ MA_CON_EST)
725 {
726 tmsi = 0L;
727 for (i=0;i<4;i++)
728 tmsi += frame[i+4] << (8*(3-i));
729 if(gprs_alr_check_ptmsi(tmsi)) return;
730 }
731 #endif
732 /*
733 * check mobile identity 2 only if TMSI is available
734 */
735 if(pch_tmsi_type(TMSI_TYPE_2, frame, channel_needed))
736 return;
737 #ifdef GPRS
738 if(GET_STATE(STATE_MA) NEQ MA_CON_EST)
739 {
740 tmsi = 0L;
741 for (i=0;i<4;i++)
742 tmsi += frame[i+8] << (8*(3-i));
743 if(gprs_alr_check_ptmsi(tmsi)) return;
744 }
745 #endif
746
747 if (frame[12] EQ 0x17)
748 {
749 /*
750 * mobile identity 3 is available
751 * calculation of channel needed for
752 * mobile identity 3 from the rest octet.
753 */
754 channel_needed = frame [ frame[13]+14 ];
755 if (channel_needed & 0x80)
756 channel_needed = (UBYTE)((channel_needed >> 5) & 3);
757 else
758 channel_needed = 0;
759
760 switch (frame [14] & 7)
761 {
762 case 1:
763 /*
764 * IMSI
765 */
766 if (!memcmp (alr_data->pch_data.imsi, &frame[13],
767 alr_data->pch_data.imsi[0]+1))
768 {
769 /*
770 * IMSI matches
771 */
772 #ifdef GPRS
773 if(! gprs_alr_check_packet_paging_2(frame,3))
774 #endif
775 ma_pch_paging_ind (1, (UBYTE) channel_needed);
776 #ifdef GPRS
777 else if(GET_STATE(STATE_MA) NEQ MA_CON_EST)
778 ma_pch_paging_ind (ID_IMSI, CN_PACKET);
779 #endif
780 return;
781 }
782 break;
783 case 4:
784 /*
785 * TMSI
786 */
787 if (alr_data->pch_data.v_tmsi)
788 {
789 tmsi = 0L;
790 for (i=0;i<frame[13]-1;i++)
791 tmsi += frame[i+15] << ((8*(frame[13]-2-i)));
792 if (alr_data->pch_data.tmsi EQ tmsi)
793 {
794 /*
795 * TMSI matches
796 */
797 ma_pch_paging_ind (4, channel_needed);
798 return;
799 }
800 #ifdef GPRS
801 if(GET_STATE(STATE_MA) NEQ MA_CON_EST)
802 {
803 tmsi = 0L;
804 for (i=0;i<frame[13]-1;i++)
805 tmsi += frame[i+15] << ((8*(frame[13]-2-i)));
806 if(gprs_alr_check_ptmsi(tmsi)) return;
807 }
808 #endif
809 }
810 break;
811 }
812 }
813 }
814 }
815
816 /*
817 +--------------------------------------------------------------------+
818 | PROJECT : GSM-PS (6103) MODULE : ALR_PCH |
819 | STATE : code ROUTINE : pch_check_pag_3 |
820 +--------------------------------------------------------------------+
821
822 PURPOSE : The function checks a paging request type 3 message.
823
824 */
825
826 GLOBAL void pch_check_pag_3 (T_MPHC_DATA_IND *data_ind)
827 {
828 GET_INSTANCE_DATA;
829 UBYTE *frame = data_ind->l2_frame.content;
830 ULONG tmsi;
831 UBYTE i;
832 UBYTE channel_needed;
833
834 /*
835 * Check only if IMSI available (len NEQ 0) and
836 * ti and pd = 0x06 and
837 * l2 pseudolength is greater than 5 bytes
838 */
839 if (alr_data->pch_data.imsi[0] AND
840 frame[1] EQ 0x06 AND
841 frame[0] > 0x15)
842 {
843 /*
844 * store channel needed type
845 */
846 channel_needed = frame[3];
847 /*
848 * check mobile identity 1 only if TMSI is available
849 */
850 if(pch_tmsi_type(TMSI_TYPE_1, frame, channel_needed))
851 return;
852 #ifdef GPRS
853 if(GET_STATE(STATE_MA) NEQ MA_CON_EST)
854 {
855 tmsi = 0L;
856 for (i=0;i<4;i++)
857 tmsi += frame[i+4] << (8*(3-i));
858 if(gprs_alr_check_ptmsi(tmsi)) return;
859 }
860 #endif
861
862 /*
863 * check mobile identity 2 only if TMSI is available
864 */
865 if(pch_tmsi_type(TMSI_TYPE_2, frame, channel_needed))
866 return;
867 #ifdef GPRS
868 if(GET_STATE(STATE_MA) NEQ MA_CON_EST)
869 {
870 tmsi = 0L;
871 for (i=0;i<4;i++)
872 tmsi += frame[i+8] << (8*(3-i));
873 if(gprs_alr_check_ptmsi(tmsi)) return;
874 }
875 #endif
876 /*
877 * calculation of channel needed for
878 * mobile identity 3 and 4 from the rest octet.
879 */
880 channel_needed = frame [ 20 ];
881 if (channel_needed & 0x80)
882 channel_needed = (UBYTE)((channel_needed & 0x78) >> 3);
883 else
884 channel_needed = 0;
885 /*
886 * check mobile identity 3 only if TMSI is available
887 */
888 if (alr_data->pch_data.v_tmsi)
889 {
890 tmsi = 0L;
891 for (i=0;i<4;i++)
892 tmsi += frame[i+12] << (8*(3-i));
893 if (alr_data->pch_data.tmsi EQ tmsi)
894 {
895 /*
896 * TMSI matches
897 */
898 ma_pch_paging_ind (4, (UBYTE)(channel_needed >> 2));
899 return;
900 }
901 #ifdef GPRS
902 if(GET_STATE(STATE_MA) NEQ MA_CON_EST)
903 {
904 tmsi = 0L;
905 for (i=0;i<4;i++)
906 tmsi += frame[i+12] << (8*(3-i));
907 if(gprs_alr_check_ptmsi(tmsi)) return;
908 }
909 #endif
910 }
911 /*
912 * check mobile identity 4 only if TMSI is available
913 */
914 if (alr_data->pch_data.v_tmsi)
915 {
916 tmsi = 0L;
917 for (i=0;i<4;i++)
918 tmsi += frame[i+16] << (8*(3-i));
919 if (alr_data->pch_data.tmsi EQ tmsi)
920 {
921 /*
922 * TMSI matches
923 */
924 ma_pch_paging_ind (4, (UBYTE)(channel_needed & 3));
925 return;
926 }
927 }
928 #ifdef GPRS
929 if(GET_STATE(STATE_MA) NEQ MA_CON_EST)
930 {
931 tmsi = 0L;
932 for (i=0;i<4;i++)
933 tmsi += frame[i+16] << (8*(3-i));
934 if(gprs_alr_check_ptmsi(tmsi)) return;
935 }
936 #endif
937 }
938 }
939
940 /*
941 +--------------------------------------------------------------------+
942 | PROJECT : GSM-PS (6103) MODULE : ALR_PCH |
943 | STATE : code ROUTINE : pch_stop |
944 +--------------------------------------------------------------------+
945
946 PURPOSE : The function stops paging.
947
948 */
949 GLOBAL void pch_stop(void)
950 {
951 GET_INSTANCE_DATA;
952 if(GET_STATE(STATE_PCH) EQ PCH_ACTIVE)
953 {
954 SET_STATE(STATE_PCH,PCH_NULL);
955 if(alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG OR
956 alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG_CS)
957 {
958 ALR_TRACE_PCH ("stop sc for pch");
959 ma_stop_scell_bcch_req();
960 }
961
962 ma_pch_stop();
963 }
964 }
965
966 /*used for S13 - to stop BCCH reading*/
967
968 GLOBAL UBYTE pch_mode_reorg(void)
969 {
970 GET_INSTANCE_DATA;
971 if(alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG OR
972 alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG_CS OR
973 alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG_NC_SYNC)
974 return TRUE;
975 else
976 return FALSE;
977 }
978 /*
979 +--------------------------------------------------------------------+
980 | PROJECT : GSM-PS (6103) MODULE : ALR_PCH |
981 | STATE : code ROUTINE : pch_no_of_paging_blocks |
982 +--------------------------------------------------------------------+
983
984 PURPOSE : The function configures the paging reading during cell
985 reselection when reveived a SI3
986 */
987
988 LOCAL SHORT pch_no_of_paging_blocks (UBYTE ccch_conf,
989 UBYTE bs_ag_blks_res,
990 UBYTE bs_pa_mfrms)
991 {
992 /* in according to GSM 4.08 section 10.5.2.11, table 10.5.33 */
993 if (ccch_conf EQ COMB_CCCH_COMB)
994 {
995 /*
996 * combined CCCH,
997 *
998 * number of paging blocks = (3 - BS_AG_BLKS_RES) * BS_PA_MFRMS
999 *
1000 * Maximum function only for security reasons, BCCH coding range is 0..7,
1001 * but allowed is only 0..2.
1002 */
1003 return (( (1 > (UBYTE)(3 - bs_ag_blks_res) ? 1 : (UBYTE)(3 - bs_ag_blks_res)) ) *
1004 ((UBYTE)(2 + bs_pa_mfrms)));
1005 }
1006 else
1007 {
1008 /*
1009 * non-combined CCCH,
1010 *
1011 * number of paging blocks = (9 - BS_AG_BLKS_RES) * BS_PA_MFRMS
1012 */
1013 return ((9 - bs_ag_blks_res) *
1014 (2 + bs_pa_mfrms));
1015 }
1016 }
1017 /*
1018 +--------------------------------------------------------------------+
1019 | PROJECT : GSM-PS (6103) MODULE : ALR_PCH |
1020 | STATE : code ROUTINE : pch_config_resel |
1021 +--------------------------------------------------------------------+
1022
1023 PURPOSE : The function configures the L1 PCH reading during cell
1024 reselection when reveived an SI3
1025 */
1026
1027 GLOBAL void pch_config_resel (T_MPHC_DATA_IND *data_ind)
1028 {
1029 GET_INSTANCE_DATA;
1030 UBYTE *p_ctrl = &(data_ind->l2_frame.content[SI_CONTENTS_MSG_T+8]);
1031 UBYTE ccch_conf,
1032 bs_ag_blks_res,
1033 bs_pa_mfrms,
1034 pg,
1035 pag_blocks_per_mfr;
1036 SHORT n, b;
1037 PALLOC(pl_idle, MPHC_START_CCCH_REQ);
1038 memset(pl_idle, 0, sizeof(T_MPHC_START_CCCH_REQ));
1039
1040 bs_ag_blks_res = (UBYTE)(((*p_ctrl) & 0x38) >> 3);
1041 ccch_conf = (((*p_ctrl) & 0x07) EQ 0x01) ? COMB_CCCH_COMB : COMB_CCCH_NOT_COMB;
1042 p_ctrl++;
1043 bs_pa_mfrms = (UBYTE)(((*p_ctrl) & 0x07));
1044 /* TRACE_EVENT_P5("pch_config_resel IE: %02x %02x bs_ag_blks_res=%u ccch_conf=%u bs_pa_mfrms=%u",
1045 data_ind->l2_frame.content[SI_CONTENTS_MSG_T+8],
1046 *p_ctrl,
1047 bs_ag_blks_res,
1048 ccch_conf,
1049 bs_pa_mfrms);*/
1050
1051 n = pch_no_of_paging_blocks (ccch_conf, bs_ag_blks_res, bs_pa_mfrms);
1052 b = ((ccch_conf / 2) + 1) * n;
1053 pg = (UBYTE) ((alr_data->pch_data.imsi_mod_1000 % b) % n);
1054 pag_blocks_per_mfr = PAG_BLOCK_TABLE [ccch_conf][bs_ag_blks_res];
1055
1056 pl_idle->bs_ag_blks_res = bs_ag_blks_res;
1057 pl_idle->bs_pa_mfrms = (UBYTE)(bs_pa_mfrms + 2);
1058 pl_idle->bcch_combined = ccch_conf;
1059 pl_idle->ccch_group = (UBYTE) ((alr_data->pch_data.imsi_mod_1000 % b) / n);
1060 pl_idle->page_group = pg;
1061 pl_idle->page_block_index = (UBYTE)(pg % pag_blocks_per_mfr);
1062 pl_idle->page_mode = (alr_data->pch_data.saved_page_mode EQ PGM_REORG_CS)
1063 ? PGM_REORG
1064 : alr_data->pch_data.saved_page_mode;
1065
1066 /* TRACE_EVENT_P3("n=%u b=%u page_mode=%u", n, b, pl_idle->page_mode);*/
1067 ma_pch_start_ccch_req(pl_idle);
1068
1069 alr_data->pch_data.si3_read = TRUE;
1070 }
1071
1072 /*
1073 +--------------------------------------------------------------------+
1074 | PROJECT : MODULE : ALR_PCH |
1075 | STATE : code ROUTINE : pch_frm_chan_imsi |
1076 +--------------------------------------------------------------------+
1077
1078 PURPOSE : Function replacing the common switch-code in the function
1079 "pch_check_pag_1". This function checks for the IMSI types.
1080
1081 */
1082 LOCAL BOOL pch_frm_chan_imsi (UBYTE *frame,
1083 UBYTE channel_needed,
1084 T_IMSI_TYPE imsi_type,
1085 UBYTE index,
1086 UBYTE *frame_start)
1087 {
1088 GET_INSTANCE_DATA;
1089 UBYTE i;
1090 ULONG tmsi;
1091 ALR_TRACE_PCH ("pch_frm_chan_imsi");
1092 switch (frame[index] & 7)
1093 {
1094 case 1:
1095 /*
1096 * IMSI
1097 */
1098 if (!memcmp (alr_data->pch_data.imsi, &frame[index-1],
1099 alr_data->pch_data.imsi[0]+1))
1100 {
1101 /*ALR_TRACE_PCH ("p1 IMSI match");*/
1102 /*
1103 * IMSI matches
1104 */
1105 if(imsi_type EQ IMSI_TYPE_1)
1106 {
1107 #ifdef GPRS
1108 if(! gprs_alr_check_packet_paging(frame_start,1))
1109 #endif
1110 ma_pch_paging_ind (1, (UBYTE)((channel_needed & 0x30)>>4));
1111 #ifdef GPRS
1112 else if(GET_STATE(STATE_MA) NEQ MA_CON_EST)
1113 ma_pch_paging_ind (ID_IMSI, CN_PACKET);
1114 #endif
1115 return TRUE;
1116 }
1117 else if(imsi_type EQ IMSI_TYPE_2)
1118 {
1119 #ifdef GPRS
1120 if(! gprs_alr_check_packet_paging(frame_start,2))
1121 #endif
1122 ma_pch_paging_ind (1, (UBYTE)((channel_needed & 0xC0)>>6));
1123 #ifdef GPRS
1124 else if(GET_STATE(STATE_MA) NEQ MA_CON_EST)
1125 ma_pch_paging_ind (ID_IMSI, CN_PACKET);
1126 #endif
1127 return TRUE;
1128 }
1129 }
1130 break; /* for case-1 */
1131
1132 case 4:
1133 /*ALR_TRACE_PCH ("p1 TMSI");*/
1134 /*
1135 * TMSI
1136 */
1137 if (alr_data->pch_data.v_tmsi)
1138 {
1139 tmsi = 0L;
1140 for (i=0; i<frame[index-1]-1; i++)
1141 tmsi += frame[i+index+1] << ((8*(frame[index-1]-2-i)));
1142 if (alr_data->pch_data.tmsi EQ tmsi)
1143 {
1144 /*ALR_TRACE_PCH ("p1 TMSI match");*/
1145 /*
1146 * TMSI matches
1147 */
1148 if(imsi_type EQ IMSI_TYPE_1)
1149 ma_pch_paging_ind (4, (UBYTE)((channel_needed & 0x30)>>4));
1150 else if(imsi_type EQ IMSI_TYPE_2)
1151 ma_pch_paging_ind (4, (UBYTE)((channel_needed & 0xC0)>>6));
1152 return TRUE;
1153 }
1154 }
1155 #ifdef GPRS
1156 if(GET_STATE(STATE_MA) NEQ MA_CON_EST)
1157 {
1158 tmsi = 0L;
1159 for (i=0; i<frame[index-1]-1; i++)
1160 tmsi += frame[i+index+1] << ((8*(frame[index-1]-2-i)));
1161 if(gprs_alr_check_ptmsi(tmsi))
1162 return TRUE;
1163 }
1164 #endif
1165 break;/* for case-4 */
1166 } /* end of switch-case */
1167 return FALSE;
1168 }
1169 /*
1170 +--------------------------------------------------------------------+
1171 | PROJECT : MODULE : ALR_PCH |
1172 | STATE : code ROUTINE : pch_tmsi_type |
1173 +--------------------------------------------------------------------+
1174
1175 PURPOSE : Function replacing the common code from the function
1176 "pch_check_pag_2"
1177 */
1178
1179 LOCAL BOOL pch_tmsi_type (T_TMSI_TYPE tmsi_type,
1180 UBYTE *frame,
1181 UBYTE channel_needed)
1182 {
1183 GET_INSTANCE_DATA;
1184 UBYTE i;
1185 ULONG tmsi;
1186 ALR_TRACE_PCH ("pch_tmsi_type");
1187 if (alr_data->pch_data.v_tmsi)
1188 {
1189 tmsi = 0L;
1190 if (tmsi_type EQ TMSI_TYPE_1)
1191 for (i=0; i<4; i++)
1192 tmsi += frame[i+4] << (8*(3-i));
1193 else if (tmsi_type EQ TMSI_TYPE_2)
1194 for (i=0; i<4; i++)
1195 tmsi += frame[i+8] << (8*(3-i));
1196 if (alr_data->pch_data.tmsi EQ tmsi)
1197 {
1198 /*
1199 * TMSI matches
1200 */
1201 if (tmsi_type EQ TMSI_TYPE_1)
1202 ma_pch_paging_ind (4, (UBYTE)((channel_needed & 0x30)>>4));
1203 else if (tmsi_type EQ TMSI_TYPE_2)
1204 ma_pch_paging_ind (4, (UBYTE)((channel_needed & 0xC0)>>6));
1205 return TRUE;
1206 }
1207 }
1208 return FALSE;
1209 }
1210 #endif