FreeCalypso > hg > fc-magnetite
view src/aci2/alr/alr_pch.c @ 600:8f50b202e81f
board preprocessor conditionals: prep for more FC hw in the future
This change eliminates the CONFIG_TARGET_FCDEV3B preprocessor symbol and
all preprocessor conditionals throughout the code base that tested for it,
replacing them with CONFIG_TARGET_FCFAM or CONFIG_TARGET_FCMODEM. These
new symbols are specified as follows:
CONFIG_TARGET_FCFAM is intended to cover all hardware designs created by
Mother Mychaela under the FreeCalypso trademark. This family will include
modem products (repackagings of the FCDEV3B, possibly with RFFE or even
RF transceiver changes), and also my desired FreeCalypso handset product.
CONFIG_TARGET_FCMODEM is intended to cover all FreeCalypso modem products
(which will be firmware-compatible with the FCDEV3B if they use TI Rita
transceiver, or will require a different fw build if we switch to one of
Silabs Aero transceivers), but not the handset product. Right now this
CONFIG_TARGET_FCMODEM preprocessor symbol is used to conditionalize
everything dealing with MCSI.
At the present moment the future of FC hardware evolution is still unknown:
it is not known whether we will ever have any beyond-FCDEV3B hardware at all
(contingent on uncertain funding), and if we do produce further FC hardware
designs, it is not known whether they will retain the same FIC modem core
(triband), if we are going to have a quadband design that still retains the
classic Rita transceiver, or if we are going to switch to Silabs Aero II
or some other transceiver. If we produce a quadband modem that still uses
Rita, it will run exactly the same fw as the FCDEV3B thanks to the way we
define TSPACT signals for the RF_FAM=12 && CONFIG_TARGET_FCFAM combination,
and the current fcdev3b build target will be renamed to fcmodem. OTOH, if
that putative quadband modem will be Aero-based, then it will require a
different fw build target, the fcdev3b target will stay as it is, and the
two targets will both define CONFIG_TARGET_FCFAM and CONFIG_TARGET_FCMODEM,
but will have different RF_FAM numbers. But no matter which way we are
going to evolve, it is not right to have conditionals on CONFIG_TARGET_FCDEV3B
in places like ACI, and the present change clears the way for future
evolution.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 01 Apr 2019 01:05:24 +0000 |
parents | 93999a60b835 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : GSM-PS | Modul : ALR_PCH +----------------------------------------------------------------------------- | Copyright 2002 Texas Instruments Berlin, AG | All rights reserved. | | This file is confidential and a trade secret of Texas | Instruments Berlin, AG | The receipt of or possession of this file does not convey | any rights to reproduce or disclose its contents or to | manufacture, use, or sell anything it may describe, in | whole, or in part, without the specific written consent of | Texas Instruments Berlin, AG. +----------------------------------------------------------------------------- | Purpose : This Modul defines the SDL process PCH_Control. +----------------------------------------------------------------------------- */ #ifndef ALR_PCH_C #define ALR_PCH_C #define ENTITY_PL /*==== INCLUDES ===================================================*/ #include <string.h> #include <stdlib.h> #include <ctype.h> #include "typedefs.h" #include "pconst.cdg" #include "mconst.cdg" #include "message.h" #include "ccdapi.h" #include "vsi.h" #include "custom.h" #include "gsm.h" #include "prim.h" #include "cnf_alr.h" #include "mon_alr.h" #include "pei.h" #include "tok.h" #include "pcm.h" #ifdef GPRS #include "alr_gprs.h" #endif #include "alr.h" #include "alr_em.h" /*==== EXPORT =====================================================*/ /*==== PRIVAT =====================================================*/ /*==== VARIABLES ==================================================*/ UBYTE page_mode_before_hplmn_search = PGM_NORMAL; /*==== CONSTANTS ==================================================*/ #define IMSI_ODD_FLAG 8 #define IMSI_EVEN_FLAG 0 #define IDENT_TYPE_MON 0 #define IDENT_TYPE_IMSI 1 #define IDENT_TYPE_IMEI 2 #define IDENT_TYPE_IMEISV 3 #define IDENT_TYPE_TMSI 4 #define END_MARK 0xF0 /*==== FUNCTIONS ==================================================*/ #define TRACING #if defined (TRACING) #define ALR_TRACE_PCH(a) ALR_TRACE(a) #else #define ALR_TRACE_PCH(a) #endif #ifdef TRACING #define ALR_TRACE_PCH_CONFIG(b,a,c,t,p,m) \ TRACE_EVENT_P6 ("MFRMS: %d AG_RES: %d COMB: %d GRP: %d PGRP: %d PI: %d",b,a,c,t,p,m) #define ALR_TRACE_PCH_PGM(p,x) \ TRACE_EVENT_P2 ("new_pgm: %d cur_pgm: %d",p,x) #define ALR_TRACE_PCH_IMSI() \ { for (i=0; i<alr_data->pch_data.imsi[0]+1;i++) { \ TRACE_EVENT_P2 ("imsi[%d]=%x",i,alr_data->pch_data.imsi[i]);} } #else #define ALR_TRACE_PCH_CONFIG(b,a,c,t,p,m) #define ALR_TRACE_PCH_PGM(p,x) #define ALR_TRACE_PCH_IMSI() #endif /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6103) MODULE : ALR_PCH | | STATE : code ROUTINE : pch_init | +--------------------------------------------------------------------+ PURPOSE : Initialize PCH Control Process. */ GLOBAL void pch_init (void) { alr_data->pch_data.saved_page_mode = PGM_REORG; alr_data->pch_data.reorg_bcch_reading = FALSE; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6103) MODULE : ALR_PCH | | STATE : code ROUTINE : pch_start | +--------------------------------------------------------------------+ PURPOSE : Process signal pch_start from SDL process Main_Control. */ static const UBYTE PAG_BLOCK_TABLE [2][8] = { /* not combined ccch */ 9,8,7,6,5,4,3,2, /* combined ccch */ 3,2,1,1,1,1,1,1 }; /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6103) MODULE : ALR_PCH | | STATE : code ROUTINE : pch_configure | +--------------------------------------------------------------------+ PURPOSE : Configutes L1 for paging. */ GLOBAL void pch_configure (T_MPH_IDLE_REQ *idle, UBYTE page_mode) { UBYTE pag_blocks_per_mfr; if(idle NEQ NULL) { alr_data->pch_data.dlt = idle->dlt; alr_data->pch_data.act_dlt = idle->dlt; ALR_EM_SET_EM_ACT_DLT; pag_blocks_per_mfr = PAG_BLOCK_TABLE [idle->comb_ccch][idle->bs_ag_blocks_res]; /* * pl_idle.bs_pa_mfrms has a range from 2-9. * MPH_IDLE_REQ codes them from 0-7 */ alr_data->pch_data.pl_idle.bs_pa_mfrms = (UBYTE)(idle->bs_pa_mfrms + 2); alr_data->pch_data.pl_idle.bs_ag_blks_res = idle->bs_ag_blocks_res; alr_data->pch_data.pl_idle.bcch_combined = idle->comb_ccch; alr_data->pch_data.pl_idle.ccch_group = (UBYTE)(idle->tn / 2); alr_data->pch_data.pl_idle.page_group = idle->pg; alr_data->pch_data.pl_idle.page_block_index = (UBYTE)(idle->pg % pag_blocks_per_mfr); ALR_TRACE_PCH_CONFIG(idle->bs_pa_mfrms+2, idle->bs_ag_blocks_res, idle->comb_ccch, idle->tn/2, idle->pg, idle->pg % pag_blocks_per_mfr); } /* * During cell reselection reading of PCH is started hard coded with * page mode PGM_REORG because of the lack of parameters to calculate * the right paging group. Detection of SI3 during cell reselection * triggers the function pch_config_resel() to reconfigure PCH reading, * detection of a changed page mode during cell reselection is handled * by function pch_check_page_mode_cr() which needs to know whether SI3 * is read */ if (GET_STATE (STATE_MA) EQ MA_CELL_RESELECTION) alr_data->pch_data.si3_read = FALSE; /* Ensure that L1 does not get initialised with PAGING EXTENDED */ switch( page_mode ) { case SAVED_PGM: if( alr_data->pch_data.saved_page_mode EQ PGM_EXTENDED ) { alr_data->pch_data.saved_page_mode = PGM_REORG; } page_mode = alr_data->pch_data.saved_page_mode; /*lint -fallthrough*/ default: alr_data->pch_data.pl_idle.page_mode = page_mode; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6103) MODULE : ALR_PCH | | STATE : code ROUTINE : pch_save_pgm | +--------------------------------------------------------------------+ PURPOSE : Configure Paging */ GLOBAL void pch_save_pgm(UBYTE mode) { if(mode) alr_data->pch_data.saved_page_mode = mode; else alr_data->pch_data.saved_page_mode = alr_data->pch_data.pl_idle.page_mode; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6103) MODULE : ALR_PCH | | STATE : code ROUTINE : pch_start_ccch_req | +--------------------------------------------------------------------+ PURPOSE : Configure Paging */ GLOBAL void pch_start_ccch_req (void) { PALLOC(pl_idle, MPHC_START_CCCH_REQ); memset(pl_idle, 0, sizeof(T_MPHC_START_CCCH_REQ)); ALR_EM_PAGE_MODE_CHANGE; switch (alr_data->pch_data.pl_idle.page_mode) { case PGM_REORG: ALR_TRACE_PCH ("config REORG"); /* dummy values */ pl_idle->bs_pa_mfrms = 2; pl_idle->bs_ag_blks_res = 7; pl_idle->bcch_combined = 0; pl_idle->ccch_group = 0; pl_idle->page_group = 0; pl_idle->page_block_index = 0; pl_idle->page_mode = PGM_REORG; break; case PGM_REORG_CS: ALR_TRACE_PCH ("config REORG_CS"); memcpy (pl_idle, &alr_data->pch_data.pl_idle, sizeof (T_MPHC_START_CCCH_REQ)); /* * if the page_mode is PGM_REORG_CS then * we have to change this to PGM_REORG * before we send it to L1 */ pl_idle->page_mode = PGM_REORG; break; case PGM_EXTENDED: ALR_TRACE_PCH ("config EXT"); memcpy (pl_idle, &alr_data->pch_data.pl_idle, sizeof (T_MPHC_START_CCCH_REQ)); pl_idle->page_mode = PGM_EXTENDED; break; case PGM_REORG_NC_SYNC: /*this case is the same as the default - except for the TRACE*/ ALR_TRACE_PCH ("config PGM_REORG_NC_SYNC (NORMAL)"); memcpy (pl_idle, &alr_data->pch_data.pl_idle, sizeof (T_MPHC_START_CCCH_REQ)); pl_idle->page_mode = PGM_NORMAL; break; default: ALR_TRACE_PCH ("config NORMAL"); memcpy (pl_idle, &alr_data->pch_data.pl_idle, sizeof (T_MPHC_START_CCCH_REQ)); pl_idle->page_mode = PGM_NORMAL; break; } SET_STATE(STATE_PCH,PCH_ACTIVE); ma_pch_start_ccch_req(pl_idle); TRACE_EVENT_P1("reorg_bcch_reading = %d",alr_data->pch_data.reorg_bcch_reading); if(alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG OR alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG_CS OR alr_data->pch_data.reorg_bcch_reading EQ TRUE) { /* * if we're going into reorg paging we also need to read the BCCH * to read possibly changed channel configuration * XXX but not at PGM_REORG_NC_SYNC (NORMAL) */ ma_scell_full_nbcch(); } else { /* * otherwise we stop the reading of the BCCH and start the periodic read. * XXX but not if we have a PBCCH */ #ifdef GPRS if(alr_data->gprs_data.pbcch EQ FALSE) #endif sc_start_periodic(); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6103) MODULE : ALR_PCH | | STATE : code ROUTINE : pch_identity_req | +--------------------------------------------------------------------+ PURPOSE : Get new mobile identity information from RR. Build IMSI pattern and store TMSI. */ GLOBAL void pch_identity_req (T_MPH_IDENTITY_REQ *mph_identity_req) { UBYTE i; /* the IMSI in the identity request is coded as a 15byte long array and is stored for later usage in pch_data as the message representation of the IMSI according to GSM4.08 10.5.1.4 */ if (mph_identity_req->mid.len_imsi EQ 0) { /* * limited service, no paging */ memset (alr_data->pch_data.imsi, 0, IMSI_LEN); alr_data->pch_data.v_tmsi = FALSE; alr_data->pch_data.tmsi = 0L; } else { /* * The IMSI is available */ /* store length */ alr_data->pch_data.imsi[0] = (UBYTE)((mph_identity_req->mid.len_imsi + 2) / 2); if (mph_identity_req->mid.len_imsi & 1) { ALR_TRACE_PCH ("IMSI is odd"); /* * odd number of digits * first digit + odd flag + identity type IMSI */ alr_data->pch_data.imsi[1] = (UBYTE)((mph_identity_req->mid.imsi[0] << 4) + IMSI_ODD_FLAG + IDENT_TYPE_IMSI); } else { ALR_TRACE_PCH ("IMSI is even"); /* * even number of digits * first digit + even flag + identity type IMSI */ alr_data->pch_data.imsi[1] = (UBYTE)((mph_identity_req->mid.imsi[0] << 4) + IMSI_EVEN_FLAG + IDENT_TYPE_IMSI); } /* * fill in the rest of digits */ for (i=1;i<mph_identity_req->mid.len_imsi;i++) { if (i & 1) alr_data->pch_data.imsi[(i/2)+2] = (UBYTE)(END_MARK + mph_identity_req->mid.imsi[i]); else { alr_data->pch_data.imsi[(i/2)+1] &= ~END_MARK; /* remove end mark */ alr_data->pch_data.imsi[(i/2)+1] = (UBYTE)(alr_data->pch_data.imsi[(i/2)+1] + (mph_identity_req->mid.imsi[i] << 4)); } } alr_data->pch_data.imsi_mod_1000 = (SHORT) ( (mph_identity_req->mid.imsi[mph_identity_req->mid.len_imsi-1] + mph_identity_req->mid.imsi[mph_identity_req->mid.len_imsi-2] * 10 + mph_identity_req->mid.imsi[mph_identity_req->mid.len_imsi-3] * 100 ) % 1000); ALR_TRACE_PCH_IMSI(); /* * copy TMSI */ alr_data->pch_data.v_tmsi = mph_identity_req->mid.v_tmsi; alr_data->pch_data.tmsi = mph_identity_req->mid.tmsi; #ifdef GPRS gprs_alr_store_ptmsi(mph_identity_req->mid.v_ptmsi, mph_identity_req->mid.ptmsi); gprs_alr_store_ptmsi2(mph_identity_req->mid.v_ptmsi2, mph_identity_req->mid.ptmsi2); #endif } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6103) MODULE : ALR_PCH | | STATE : code ROUTINE : pch_increment_dlt | +--------------------------------------------------------------------+ PURPOSE : Incrementation of downlink timeout counter after receiving a valid PCH block. */ GLOBAL void pch_increment_dlt (void) { if (alr_data->pch_data.act_dlt < alr_data->pch_data.dlt) { #if !defined NTRACE trc_mon_counter_idle (alr_data->pch_data.act_dlt, alr_data->pch_data.dlt); #endif /* (!defined NTRACE) */ alr_data->pch_data.act_dlt++; ALR_EM_SET_EM_ACT_DLT; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6103) MODULE : ALR_PCH | | STATE : code ROUTINE : pch_decrement_dlt | +--------------------------------------------------------------------+ PURPOSE : Decrementation of downlink timeout counter after receiving an invalid PCH block. */ GLOBAL void pch_decrement_dlt (void) { if (alr_data->pch_data.act_dlt > 4) { #if !defined NTRACE trc_mon_counter_idle (alr_data->pch_data.act_dlt, alr_data->pch_data.dlt); #endif /* (!defined NTRACE) */ alr_data->pch_data.act_dlt -= 4; ALR_EM_SET_EM_ACT_DLT; } else { alr_data->pch_data.act_dlt = alr_data->pch_data.dlt; #if !defined NTRACE trc_mon_counter_idle (alr_data->pch_data.act_dlt, alr_data->pch_data.dlt); #endif ALR_EM_SET_EM_ACT_DLT; ALR_TRACE_PCH ("downlink fail"); ma_error_ind (CS_DOWN_LINK_FAIL, alr_data->serving_cell); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6103) MODULE : ALR_PCH | | STATE : code ROUTINE : pch_check_page_mode | +--------------------------------------------------------------------+ PURPOSE : Check the page mode of an incoming unacknowledged message. */ static const UBYTE PAGE_MODE_CHANGE [3][4] = { /* old mode = paging normal */ NONE, SWAP_TO_EXTEND, SWAP_TO_REORG, NONE, /* old mode = extended paging */ SWAP_TO_NORMAL, NONE, SWAP_TO_REORG, NONE, /* old mode = paging reorganisation */ SWAP_TO_NORMAL, SWAP_TO_EXTEND, NONE, NONE }; GLOBAL void pch_check_page_mode (T_MPHC_DATA_IND *data_ind) { UBYTE page_mode; UBYTE cur_page_mode = alr_data->pch_data.pl_idle.page_mode; page_mode = (UBYTE)(data_ind->l2_frame.content [3] & 3); ALR_TRACE_PCH_PGM(page_mode, alr_data->pch_data.pl_idle.page_mode); /*if HPLMN search is going on and we should be in REORG, we are really in REORG_NC_SYNC (NORMAL). Otherwise we cannot synchronize to the NC's*/ if(alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG_NC_SYNC) cur_page_mode = PGM_REORG; if(alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG_CS) cur_page_mode = PGM_REORG; switch (PAGE_MODE_CHANGE [cur_page_mode][page_mode]) { case SWAP_TO_NORMAL: ALR_TRACE_PCH ("SWAP_TO_NORMAL"); alr_data->pch_data.pl_idle.page_mode = PGM_NORMAL; pch_start_ccch_req (); break; case SWAP_TO_EXTEND: ALR_TRACE_PCH ("SWAP_TO_EXT"); alr_data->pch_data.pl_idle.page_mode = PGM_EXTENDED; pch_start_ccch_req (); break; case SWAP_TO_REORG: ALR_TRACE_PCH ("SWAP_TO_REORG"); alr_data->pch_data.reorg_bcch_reading = TRUE; alr_data->pch_data.si_bitmap = 0; alr_data->pch_data.pl_idle.page_mode = PGM_REORG_CS; pch_start_ccch_req (); break; default: break; } } GLOBAL void pch_check_page_mode_cr (T_MPHC_DATA_IND *data_ind) { UBYTE page_mode; UBYTE cur_page_mode = alr_data->pch_data.saved_page_mode; UBYTE swap = TRUE; page_mode = (UBYTE)(data_ind->l2_frame.content [3] & 3); if(alr_data->pch_data.saved_page_mode EQ PGM_REORG_CS) cur_page_mode = PGM_REORG; switch (PAGE_MODE_CHANGE [cur_page_mode][page_mode]) { case SWAP_TO_NORMAL: ALR_TRACE_PCH ("CR:SWAP_TO_NORMAL"); alr_data->pch_data.saved_page_mode = PGM_NORMAL; break; case SWAP_TO_EXTEND: ALR_TRACE_PCH ("CR:SWAP_TO_EXT"); alr_data->pch_data.saved_page_mode = PGM_EXTENDED; break; case SWAP_TO_REORG: ALR_TRACE_PCH ("CR:SWAP_TO_REORG"); alr_data->pch_data.saved_page_mode = PGM_REORG_CS; break; default: swap = FALSE; break; } if (swap AND alr_data->pch_data.si3_read AND alr_data->pch_data.last_start_ccch_req.bs_pa_mfrms NEQ NOT_PRESENT_8BIT) { PALLOC(pl_idle, MPHC_START_CCCH_REQ); memcpy ( pl_idle, &(alr_data->pch_data.last_start_ccch_req), sizeof(T_MPHC_START_CCCH_REQ)); pl_idle->page_mode = alr_data->pch_data.saved_page_mode; ma_pch_start_ccch_req (pl_idle); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6103) MODULE : ALR_PCH | | STATE : code ROUTINE : pch_check_pag_1 | +--------------------------------------------------------------------+ PURPOSE : The function checks a paging request type 1 message. */ GLOBAL void pch_check_pag_1 (T_MPHC_DATA_IND *data_ind) { UBYTE *frame = data_ind->l2_frame.content; ULONG tmsi; UBYTE i; UBYTE channel_needed; UBYTE *frame_start = data_ind->l2_frame.content; //ALR_TRACE_PCH ("p1"); /* * Check only if IMSI available (len NEQ 0), * ti and pd = 0x06 and * l2 pseudolength is greater than 5 bytes */ if (alr_data->pch_data.imsi[0] AND frame[1] EQ 0x06 AND frame[0] > 0x15) { /* * store channel needed type */ channel_needed = frame[3]; /* * check type of identity for mobile identity 1 */ switch (frame [5] & 7) { case 1: //ALR_TRACE_PCH ("p1 IMSI"); /* * IMSI */ if (!memcmp (alr_data->pch_data.imsi, &frame[4], alr_data->pch_data.imsi[0]+1)) { //ALR_TRACE_PCH ("p1 IMSI match"); /* * IMSI matches */ #ifdef GPRS if(!gprs_alr_check_packet_paging(frame_start,1)) #endif ma_pch_paging_ind (1, (UBYTE)((channel_needed & 0x30)>>4)); #ifdef GPRS else if(GET_STATE(STATE_MA) NEQ MA_CON_EST) ma_pch_paging_ind (ID_IMSI, CN_PACKET); #endif return; } break; case 4: //ALR_TRACE_PCH ("p1 TMSI"); /* * TMSI */ if (alr_data->pch_data.v_tmsi) { tmsi = 0L; for (i=0;i<frame[4]-1;i++) tmsi += frame[i+6] << ((8*(frame[4]-2-i))); if (alr_data->pch_data.tmsi EQ tmsi) { //ALR_TRACE_PCH ("p1 TMSI match"); /* * TMSI matches */ ma_pch_paging_ind (4, (UBYTE)((channel_needed & 0x30)>>4)); return; } } #ifdef GPRS if(GET_STATE(STATE_MA) NEQ MA_CON_EST) { tmsi = 0L; for (i=0;i<frame[4]-1;i++) tmsi += frame[i+6] << ((8*(frame[4]-2-i))); if(gprs_alr_check_ptmsi(tmsi)) return; } #endif break; } /* * check type of identity for mobile identity 2 * set frame pointer to start of mobile identity 2 (id tag) * old frame pointer (frame) + * offset pseudo length etc (4) + * length mobile identity 1 (frame [4]) + * plus 1 byte for length field */ frame = frame + 4 + frame[4] + 1; if (frame[0] EQ 0x17) { /* * mobile identity 2 is available */ switch (frame [2] & 7) { case 1: //ALR_TRACE_PCH ("p1 IMSI2"); /* * IMSI */ if (!memcmp (alr_data->pch_data.imsi, &frame[1], alr_data->pch_data.imsi[0]+1)) { //ALR_TRACE_PCH ("p1 IMSI2 match"); /* * IMSI matches */ #ifdef GPRS if(! gprs_alr_check_packet_paging(frame_start,2)) #endif ma_pch_paging_ind (1, (UBYTE)((channel_needed & 0xC0)>>6)); #ifdef GPRS else if(GET_STATE(STATE_MA) NEQ MA_CON_EST) ma_pch_paging_ind (ID_IMSI, CN_PACKET); #endif return; } break; case 4: // ALR_TRACE_PCH ("p1 TMSI2"); /* * TMSI */ if (alr_data->pch_data.v_tmsi) { tmsi = 0L; for (i=0;i<frame[1]-1;i++) tmsi += frame[i+3] << ((8*(frame[1]-2-i))); if (alr_data->pch_data.tmsi EQ tmsi) { ALR_TRACE_PCH ("p1 IMSI2"); /* * TMSI matches */ ma_pch_paging_ind (4, (UBYTE)((channel_needed & 0xC0)>>6)); return; } } #ifdef GPRS if(GET_STATE(STATE_MA) NEQ MA_CON_EST) { tmsi = 0L; for (i=0;i<frame[4]-1;i++) tmsi += frame[i+6] << ((8*(frame[4]-2-i))); if(gprs_alr_check_ptmsi(tmsi)) return; } #endif break; } } } //ALR_TRACE_PCH("end p1"); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6103) MODULE : ALR_PCH | | STATE : code ROUTINE : pch_check_pag_2 | +--------------------------------------------------------------------+ PURPOSE : The function checks a paging request type 2 message. */ GLOBAL void pch_check_pag_2 (T_MPHC_DATA_IND *data_ind) { UBYTE *frame = data_ind->l2_frame.content; ULONG tmsi; UBYTE i; UBYTE channel_needed; /* * Check only if IMSI available (len NEQ 0) and * ti and pd = 0x06 and * l2 pseudolength is greater than 5 bytes */ if (alr_data->pch_data.imsi[0] AND frame[1] EQ 0x06 AND frame[0] > 0x15) { /* * store channel needed type */ channel_needed = frame[3]; /* * check mobile identity 1 only if TMSI is available */ if (alr_data->pch_data.v_tmsi) { tmsi = 0L; for (i=0;i<4;i++) tmsi += frame[i+4] << (8*(3-i)); if (alr_data->pch_data.tmsi EQ tmsi) { /* * TMSI matches */ ma_pch_paging_ind (4, (UBYTE)((channel_needed & 0x30)>>4)); return; } } #ifdef GPRS if(GET_STATE(STATE_MA) NEQ MA_CON_EST) { tmsi = 0L; for (i=0;i<4;i++) tmsi += frame[i+4] << (8*(3-i)); if(gprs_alr_check_ptmsi(tmsi)) return; } #endif /* * check mobile identity 2 only if TMSI is available */ if (alr_data->pch_data.v_tmsi) { tmsi = 0L; for (i=0;i<4;i++) tmsi += frame[i+8] << (8*(3-i)); if (alr_data->pch_data.tmsi EQ tmsi) { /* * TMSI matches */ ma_pch_paging_ind (4, (UBYTE)((channel_needed & 0xC0)>>6)); return; } } #ifdef GPRS if(GET_STATE(STATE_MA) NEQ MA_CON_EST) { tmsi = 0L; for (i=0;i<4;i++) tmsi += frame[i+8] << (8*(3-i)); if(gprs_alr_check_ptmsi(tmsi)) return; } #endif if (frame[12] EQ 0x17) { /* * mobile identity 3 is available * calculation of channel needed for * mobile identity 3 from the rest octet. */ channel_needed = frame [ frame[13]+14 ]; if (channel_needed & 0x80) channel_needed = (UBYTE)((channel_needed >> 5) & 3); else channel_needed = 0; switch (frame [14] & 7) { case 1: /* * IMSI */ if (!memcmp (alr_data->pch_data.imsi, &frame[13], alr_data->pch_data.imsi[0]+1)) { /* * IMSI matches */ #ifdef GPRS if(! gprs_alr_check_packet_paging_2(frame,3)) #endif ma_pch_paging_ind (1, (UBYTE) channel_needed); #ifdef GPRS else if(GET_STATE(STATE_MA) NEQ MA_CON_EST) ma_pch_paging_ind (ID_IMSI, CN_PACKET); #endif return; } break; case 4: /* * TMSI */ if (alr_data->pch_data.v_tmsi) { tmsi = 0L; for (i=0;i<frame[13]-1;i++) tmsi += frame[i+15] << ((8*(frame[13]-2-i))); if (alr_data->pch_data.tmsi EQ tmsi) { /* * TMSI matches */ ma_pch_paging_ind (4, channel_needed); return; } #ifdef GPRS if(GET_STATE(STATE_MA) NEQ MA_CON_EST) { tmsi = 0L; for (i=0;i<frame[13]-1;i++) tmsi += frame[i+15] << ((8*(frame[13]-2-i))); if(gprs_alr_check_ptmsi(tmsi)) return; } #endif } break; } } } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6103) MODULE : ALR_PCH | | STATE : code ROUTINE : pch_check_pag_3 | +--------------------------------------------------------------------+ PURPOSE : The function checks a paging request type 3 message. */ GLOBAL void pch_check_pag_3 (T_MPHC_DATA_IND *data_ind) { UBYTE *frame = data_ind->l2_frame.content; ULONG tmsi; UBYTE i; UBYTE channel_needed; /* * Check only if IMSI available (len NEQ 0) and * ti and pd = 0x06 and * l2 pseudolength is greater than 5 bytes */ if (alr_data->pch_data.imsi[0] AND frame[1] EQ 0x06 AND frame[0] > 0x15) { /* * store channel needed type */ channel_needed = frame[3]; /* * check mobile identity 1 only if TMSI is available */ if (alr_data->pch_data.v_tmsi) { tmsi = 0L; for (i=0;i<4;i++) tmsi += frame[i+4] << (8*(3-i)); if (alr_data->pch_data.tmsi EQ tmsi) { /* * TMSI matches */ ma_pch_paging_ind (4, (UBYTE)((channel_needed & 0x30)>>4)); return; } } #ifdef GPRS if(GET_STATE(STATE_MA) NEQ MA_CON_EST) { tmsi = 0L; for (i=0;i<4;i++) tmsi += frame[i+4] << (8*(3-i)); if(gprs_alr_check_ptmsi(tmsi)) return; } #endif /* * check mobile identity 2 only if TMSI is available */ if (alr_data->pch_data.v_tmsi) { tmsi = 0L; for (i=0;i<4;i++) tmsi += frame[i+8] << (8*(3-i)); if (alr_data->pch_data.tmsi EQ tmsi) { /* * TMSI matches */ ma_pch_paging_ind (4, (UBYTE)((channel_needed & 0xC0)>>6)); return; } } #ifdef GPRS if(GET_STATE(STATE_MA) NEQ MA_CON_EST) { tmsi = 0L; for (i=0;i<4;i++) tmsi += frame[i+8] << (8*(3-i)); if(gprs_alr_check_ptmsi(tmsi)) return; } #endif /* * calculation of channel needed for * mobile identity 3 and 4 from the rest octet. */ channel_needed = frame [ 20 ]; if (channel_needed & 0x80) channel_needed = (UBYTE)((channel_needed & 0x78) >> 3); else channel_needed = 0; /* * check mobile identity 3 only if TMSI is available */ if (alr_data->pch_data.v_tmsi) { tmsi = 0L; for (i=0;i<4;i++) tmsi += frame[i+12] << (8*(3-i)); if (alr_data->pch_data.tmsi EQ tmsi) { /* * TMSI matches */ ma_pch_paging_ind (4, (UBYTE)(channel_needed >> 2)); return; } #ifdef GPRS if(GET_STATE(STATE_MA) NEQ MA_CON_EST) { tmsi = 0L; for (i=0;i<4;i++) tmsi += frame[i+12] << (8*(3-i)); if(gprs_alr_check_ptmsi(tmsi)) return; } #endif } /* * check mobile identity 4 only if TMSI is available */ if (alr_data->pch_data.v_tmsi) { tmsi = 0L; for (i=0;i<4;i++) tmsi += frame[i+16] << (8*(3-i)); if (alr_data->pch_data.tmsi EQ tmsi) { /* * TMSI matches */ ma_pch_paging_ind (4, (UBYTE)(channel_needed & 3)); return; } } #ifdef GPRS if(GET_STATE(STATE_MA) NEQ MA_CON_EST) { tmsi = 0L; for (i=0;i<4;i++) tmsi += frame[i+16] << (8*(3-i)); if(gprs_alr_check_ptmsi(tmsi)) return; } #endif } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6103) MODULE : ALR_PCH | | STATE : code ROUTINE : pch_stop | +--------------------------------------------------------------------+ PURPOSE : The function stops paging. */ GLOBAL void pch_stop(void) { if(GET_STATE(STATE_PCH) EQ PCH_ACTIVE) { SET_STATE(STATE_PCH,PCH_NULL); if(alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG OR alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG_CS) { ALR_TRACE_PCH ("stop sc for pch"); ma_stop_scell_bcch_req(); } ma_pch_stop(); } } /*used for S13 - to stop BCCH reading*/ GLOBAL UBYTE pch_mode_reorg(void) { if(alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG OR alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG_CS OR alr_data->pch_data.pl_idle.page_mode EQ PGM_REORG_NC_SYNC) return TRUE; else return FALSE; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6103) MODULE : ALR_PCH | | STATE : code ROUTINE : pch_no_of_paging_blocks | +--------------------------------------------------------------------+ PURPOSE : The function configures the paging reading during cell reselection when reveived a SI3 */ LOCAL SHORT pch_no_of_paging_blocks (UBYTE ccch_conf, UBYTE bs_ag_blks_res, UBYTE bs_pa_mfrms) { /* in according to GSM 4.08 section 10.5.2.11, table 10.5.33 */ if (ccch_conf EQ COMB_CCCH_COMB) { /* * combined CCCH, * * number of paging blocks = (3 - BS_AG_BLKS_RES) * BS_PA_MFRMS * * Maximum function only for security reasons, BCCH coding range is 0..7, * but allowed is only 0..2. */ return (( (1 > (UBYTE)(3 - bs_ag_blks_res) ? 1 : (UBYTE)(3 - bs_ag_blks_res)) ) * ((UBYTE)(2 + bs_pa_mfrms))); } else { /* * non-combined CCCH, * * number of paging blocks = (9 - BS_AG_BLKS_RES) * BS_PA_MFRMS */ return ((9 - bs_ag_blks_res) * (2 + bs_pa_mfrms)); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6103) MODULE : ALR_PCH | | STATE : code ROUTINE : pch_config_resel | +--------------------------------------------------------------------+ PURPOSE : The function configures the L1 PCH reading during cell reselection when reveived an SI3 */ GLOBAL void pch_config_resel (T_MPHC_DATA_IND *data_ind) { UBYTE *p_ctrl = &(data_ind->l2_frame.content[SI_CONTENTS_MSG_T+8]); UBYTE ccch_conf, bs_ag_blks_res, bs_pa_mfrms, pg, pag_blocks_per_mfr; SHORT n, b; PALLOC(pl_idle, MPHC_START_CCCH_REQ); memset(pl_idle, 0, sizeof(T_MPHC_START_CCCH_REQ)); bs_ag_blks_res = (UBYTE)(((*p_ctrl) & 0x38) >> 3); ccch_conf = (((*p_ctrl) & 0x07) EQ 0x01) ? COMB_CCCH_COMB : COMB_CCCH_NOT_COMB; p_ctrl++; bs_pa_mfrms = (UBYTE)(((*p_ctrl) & 0x07)); /* TRACE_EVENT_P5("pch_config_resel IE: %02x %02x bs_ag_blks_res=%u ccch_conf=%u bs_pa_mfrms=%u", data_ind->l2_frame.content[SI_CONTENTS_MSG_T+8], *p_ctrl, bs_ag_blks_res, ccch_conf, bs_pa_mfrms);*/ n = pch_no_of_paging_blocks (ccch_conf, bs_ag_blks_res, bs_pa_mfrms); b = ((ccch_conf / 2) + 1) * n; pg = (UBYTE) ((alr_data->pch_data.imsi_mod_1000 % b) % n); pag_blocks_per_mfr = PAG_BLOCK_TABLE [ccch_conf][bs_ag_blks_res]; pl_idle->bs_ag_blks_res = bs_ag_blks_res; pl_idle->bs_pa_mfrms = (UBYTE)(bs_pa_mfrms + 2); pl_idle->bcch_combined = ccch_conf; pl_idle->ccch_group = (UBYTE) ((alr_data->pch_data.imsi_mod_1000 % b) / n); pl_idle->page_group = pg; pl_idle->page_block_index = (UBYTE)(pg % pag_blocks_per_mfr); pl_idle->page_mode = (alr_data->pch_data.saved_page_mode EQ PGM_REORG_CS) ? PGM_REORG : alr_data->pch_data.saved_page_mode; /* TRACE_EVENT_P3("n=%u b=%u page_mode=%u", n, b, pl_idle->page_mode);*/ ma_pch_start_ccch_req(pl_idle); alr_data->pch_data.si3_read = TRUE; } #endif