comparison src/g23m-gsm/alr2/alr_pch.c @ 3:b4c81ea2d291

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