comparison src/g23m-gsm/alr/alr_pch.c @ 104:27a4235405c6

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