FreeCalypso > hg > fc-magnetite
diff src/g23m-gsm/mm/mm_regs.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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/g23m-gsm/mm/mm_regs.c Tue Oct 04 18:24:05 2016 +0000 @@ -0,0 +1,566 @@ +/* ++----------------------------------------------------------------------------- +| Project : GSM-PS (8410) +| Modul : MM_REGS ++----------------------------------------------------------------------------- +| 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 functions for the registration +| capability of the module Mobility Managemant. ++----------------------------------------------------------------------------- +*/ + +#ifndef MM_REGS_C +#define MM_REGS_C + +#define ENTITY_MM + +/*==== INCLUDES ===================================================*/ +#if defined (NEW_FRAME) + +#include <string.h> +#include <stdlib.h> +#include <stddef.h> +#include "typedefs.h" +#include "pcm.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_mm.h" +#include "mon_mm.h" +#include "pei.h" +#include "tok.h" +#include "mm.h" + +#else + +#include <string.h> +#include <stdlib.h> +#include <stddef.h> +#include "stddefs.h" +#include "pcm.h" +#include "pconst.cdg" +#include "mconst.cdg" +#include "message.h" +#include "ccdapi.h" +#include "custom.h" +#include "gsm.h" +#include "prim.h" +#include "cnf_mm.h" +#include "mon_mm.h" +#include "vsi.h" +#include "pei.h" +#include "tok.h" +#include "mm.h" + +#endif +/*==== EXPORT =====================================================*/ + +/*==== PRIVAT =====================================================*/ + +/*==== VARIABLES ==================================================*/ + +/*==== FUNCTIONS ==================================================*/ + +/*==== TEST =====================================================*/ + +/* + * ------------------------------------------------------------------- + * SIGNAL Processing functions + * ------------------------------------------------------------------- + */ + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_mmr_auth_ind | ++--------------------------------------------------------------------+ + + PURPOSE : Process the signal MMR_AUTH_IND. + +*/ + +GLOBAL void reg_mmr_auth_ind (T_SIM_AUTHENTICATION_REQ *sim_auth_req) +{ + GET_INSTANCE_DATA; + MCAST (auth_req, D_AUTH_REQ); + TRACE_FUNCTION ("reg_mmr_auth_ind()"); + + if(mm_data->last_auth_req_id != NOT_PRESENT_8BIT) + { + mm_data->last_auth_req_id++; + } + else + { + mm_data->last_auth_req_id = 0; + } + + sim_auth_req->source = SRC_MM; + sim_auth_req->req_id = mm_data->last_auth_req_id; + sim_auth_req->cksn = auth_req->ciph_key_num.key_seq; + memcpy (sim_auth_req->rand, auth_req->auth_rand.rand, + sizeof (sim_auth_req->rand)); + PSENDX (SIM, sim_auth_req); + if (mm_data->last_auth_req_id != 0) + { + /* problem occurred!!!! */ +#ifdef WIN32 + vsi_o_ttrace (VSI_CALLER TC_FUNC, + "Authentication problem occurred %d", mm_data->last_auth_req_id); +#endif /* WIN32 */ + } + +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_net_list | ++--------------------------------------------------------------------+ + + PURPOSE : Build a list of available PLMNs for the MMI. + Use the information received from RR to update MM's + internal PLMN list used for MM's own operation. + +*/ + +#if 0 // The old code +GLOBAL void reg_net_list (const T_RR_ABORT_IND *rr_abort_ind) +{ + TRACE_FUNCTION ("reg_net_list()"); + + /* Create the PLMN list for the MMI and send it */ + reg_create_plmn_list (rr_abort_ind, WITH_ALL_PLMNS); + + if (mm_data->reg.plmn_cnt EQ 0) + { + if ((rr_abort_ind->op.service NEQ NO_SERVICE) AND + (rr_abort_ind->cause EQ RRCS_ABORT_CEL_SEL_FAIL)) + { + mm_mmgmm_plmn_ind (MMCS_PLMN_NOT_IDLE_MODE); + } + else + { + mm_mmgmm_plmn_ind (MMCS_SUCCESS); + } + } + else + { + mm_mmgmm_plmn_ind (MMCS_SUCCESS); + } + + /* Do not consider the forbidden PLMN's for MM's internal operation */ + reg_create_plmn_list (rr_abort_ind, WITH_OTHER_PLMNS); + + switch (rr_abort_ind->op.service) + { + case NO_SERVICE: + mm_mmgmm_nreg_ind (NREG_NO_SERVICE, + SEARCH_NOT_RUNNING, + FORB_PLMN_NOT_INCLUDED); + break; + + case LIMITED_SERVICE: + mm_mmgmm_nreg_ind (NREG_LIMITED_SERVICE, + SEARCH_NOT_RUNNING, + FORB_PLMN_NOT_INCLUDED); + break; + + case FULL_SERVICE: + break; + + default: /* All possible values caught, this is garbage */ + TRACE_ERROR (UNEXPECTED_DEFAULT); + break; + } +} +#else // The new code +GLOBAL void reg_net_list (const T_RR_ABORT_IND *rr_abort_ind) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("reg_net_list()"); + + if (rr_abort_ind->plmn_avail EQ 0) + { + /* + * Distinguish between "no PLMN found" and search aborted + * due to eg. paging in RR. In the future, we may introduce + * a proper cause in the RR_ABORT_IND to distinguish this, + * this here should work but is ugly. + */ + if ((rr_abort_ind->op.service NEQ NO_SERVICE) AND + (rr_abort_ind->cause EQ RRCS_ABORT_CEL_SEL_FAIL)) + { + mm_mmgmm_plmn_ind (MMCS_PLMN_NOT_IDLE_MODE, NULL); + } + else + { + mm_mmgmm_plmn_ind (MMCS_SUCCESS, rr_abort_ind); + } + mm_data->reg.plmn_cnt = 0; + } + else + { + mm_mmgmm_plmn_ind (MMCS_SUCCESS, rr_abort_ind); + } + + switch (rr_abort_ind->op.service) + { + case NO_SERVICE: + mm_mmgmm_nreg_ind (NREG_NO_SERVICE, + SEARCH_NOT_RUNNING, + FORB_PLMN_NOT_INCLUDED); + break; + + case LIMITED_SERVICE: + mm_mmgmm_nreg_ind (NREG_LIMITED_SERVICE, + SEARCH_NOT_RUNNING, + FORB_PLMN_NOT_INCLUDED); + break; + + case FULL_SERVICE: + break; + + default: /* All possible values caught, this is garbage */ + TRACE_ERROR (UNEXPECTED_DEFAULT); + break; + } +} +#endif + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_rr_failure | ++--------------------------------------------------------------------+ + + PURPOSE : Indication from MM/RR about unsuccessfull cell selection. + The new service and the found PLMN indications are for- + warded to MM. + +*/ + +GLOBAL void reg_rr_failure (T_RR_ABORT_IND *rr_abort_ind) +{ + GET_INSTANCE_DATA; + unsigned i; + BOOL actual_plmn_found; + + TRACE_FUNCTION ("reg_rr_failure()"); + +#if defined (WIN32) + { + TRACE_EVENT_P1 ("PLMN_AVAIL = %d", rr_abort_ind->plmn_avail); + + for (i = 0 ;i < rr_abort_ind->plmn_avail; i++) + { + TRACE_EVENT_P6 ("MCC=%x%x%x MNC=%x%x%x", + rr_abort_ind->plmn[i].mcc[0], + rr_abort_ind->plmn[i].mcc[1], + rr_abort_ind->plmn[i].mcc[2], + rr_abort_ind->plmn[i].mnc[0], + rr_abort_ind->plmn[i].mnc[1], + rr_abort_ind->plmn[i].mnc[2]); + } + } +#endif /* #if defined (WIN32) */ + + if (rr_abort_ind->plmn_avail EQ 0 OR + mm_data->reg.op.sim_ins EQ SIM_NO_INSRT) + { + /* + * No PLMN delivered by RR to build a PLMN list or no SIM present + */ + switch (rr_abort_ind->op.service) + { + case NO_SERVICE: + mm_mmgmm_nreg_ind (NREG_NO_SERVICE, + SEARCH_NOT_RUNNING, + FORB_PLMN_NOT_INCLUDED); + break; + + case LIMITED_SERVICE: + mm_mmgmm_nreg_ind (NREG_LIMITED_SERVICE, + SEARCH_NOT_RUNNING, + FORB_PLMN_NOT_INCLUDED); + break; + + default: /* eg. FULL_SERVICE and reg_rr_failure => nonsense */ + TRACE_ERROR (UNEXPECTED_DEFAULT); + break; + } + + /* Delete the PLMN list, currently no PLMN available */ + mm_data->reg.plmn_cnt = 0; + +/* + // First make sure to understand completely the underlying problem... + // Patch HM 11.06.01, clear PLMN list in ACI and MM >>> + mm_mmgmm_plmn_ind (MMCS_SUCCESS, rr_abort_ind); + // Patch HM 11.06.01, clear PLMN list in ACI and MM <<< +*/ + + } + else + { + /* + * At least one PLMN found and SIM present, create PLMN list. + * Depending on the selected mode (automatic or manual), + * either select the next available PLMN or present the + * list of PLMNs possibly providing full service to the user. + */ + switch (mm_data->reg.op.m) + { + case MODE_AUTO: + // Note: There are better algorithms to decide whether an update + // of the PLMN list is necessary or not, but for these we need the + // information from RR whether a found PLMN/location area is + // forbidden. This becomes especially TRUE for an exhausted PLMN + // list as we waste a lot of battery here if there is no location + // area suitable for full service available, but a lot of location + // areas on VPLMNs which are forbidden for roaming. In this case we + // run in a loop senseless activating VPLMN which don't provide + // full service at all. + /* + * Don't update the PLMN list if the actual PLMN is a member + * of the PLMN list delivered by RR and the current list is + * non-exhaused. + */ + actual_plmn_found = FALSE; + + if (mm_data->reg.plmn_cnt > mm_data->reg.plmn_index) + { + /* + * There is a non-exhausted list present in MM. + * Check whether the actual PLMN is a member. + */ + for (i = 0; i < rr_abort_ind->plmn_avail; i++) + { + if (reg_plmn_equal_sim (&rr_abort_ind->plmn[i], + &mm_data->reg.actual_plmn)) + { + actual_plmn_found = TRUE; + break; + } + } + if (!actual_plmn_found) + { + /* The requested PLMN was not found. Update outdated list. */ + reg_create_plmn_list (rr_abort_ind, WITH_OTHER_PLMNS); + } + else + { + TRACE_EVENT ("PLMN list ignored"); + } + } + else + { + /* No non-exhaused list present in MM. Take the new list from RR */ + reg_create_plmn_list (rr_abort_ind, WITH_OTHER_PLMNS); + } + + /* + * Select the next PLMN if available + * else indicate LIMITED SERVICE to MMI + */ + reg_plmn_select (FORB_PLMN_NOT_INCLUDED); + break; + + case MODE_MAN: + reg_create_plmn_list (rr_abort_ind, WITH_ALL_PLMNS); + + /* + * Forward the PLMN list to MMI for selection + */ + switch (rr_abort_ind->op.service) + { + case NO_SERVICE: + mm_mmgmm_nreg_ind (NREG_NO_SERVICE, + SEARCH_NOT_RUNNING, + FORB_PLMN_NOT_INCLUDED); + break; + + case LIMITED_SERVICE: + mm_mmgmm_nreg_ind (NREG_LIMITED_SERVICE, + SEARCH_NOT_RUNNING, + FORB_PLMN_NOT_INCLUDED); + break; + + default: /* eg. FULL_SERVICE and reg_rr_failure => nonsense */ + TRACE_ERROR (UNEXPECTED_DEFAULT); + break; + } + mm_data->plmn_scan_mmi = TRUE; + mm_mmgmm_plmn_ind (MMCS_SUCCESS, rr_abort_ind); + break; + + default: /* No mode left */ + TRACE_ERROR (UNEXPECTED_DEFAULT); + break; + } + } +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_mm_success | ++--------------------------------------------------------------------+ + + PURPOSE : MM indicates successfull registration. + +*/ + +GLOBAL void reg_mm_success (UBYTE service) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("reg_mm_success()"); + + if (mm_data->reg.op.sim_ins EQ SIM_NO_INSRT) + { + /* + * No SIM is inserted + */ + mm_mmgmm_nreg_ind (NREG_LIMITED_SERVICE, + SEARCH_NOT_RUNNING, + FORB_PLMN_NOT_INCLUDED); + } + else + { + /* + * SIM is inserted + */ + if (service EQ LIMITED_SERVICE) + { + mm_mmgmm_nreg_ind (NREG_LIMITED_SERVICE, + SEARCH_NOT_RUNNING, + FORB_PLMN_NOT_INCLUDED); + } + else + { + /* + * Send new PLMN identification to MMI or GMM. + * In case we compile for a GPRS protocol stack, + * we will not indicate end of procedure (entering IDLE state) + * by MMGMM_REG_CNF, but sending an intermediate result (full service) + * by MMGMM_LUP_ACCEPT_IND. + */ +#ifdef GPRS + if (mm_data->gprs.reg_cnf_on_idle_entry) + { + mm_mmgmm_lup_accept_ind (); + } + else +#endif + { + mm_mmgmm_reg_cnf (); + } + + /* Check HPLMN timer state */ + reg_check_hplmn_tim (mm_data->reg.thplmn); + + } + } +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_mm_cell_selected | ++--------------------------------------------------------------------+ + + PURPOSE : MM indicates successfull cell selection. + +*/ + +GLOBAL void reg_mm_cell_selected (void) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("reg_mm_cell_selected()"); + + if (mm_gsm_alone() AND + mm_data->reg.op.sim_ins EQ SIM_INSRT) + { + /* + * GPRS is inactive (GSM only mobile or GPRS deactivated) AND + * a valid SIM is inserted. These are the prerequisites to indicate + * full service to the MMI after cell selection. + */ + if (!mm_normal_upd_needed()) + { + /* + * If no normal update is needed, the next service state + * is "normal service" regardless of the need of an IMSI + * ATTACH. Normal calls are possible, so we have to indicate + * full service to the MMI. + */ + mm_mmgmm_reg_cnf (); + } + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : MM_REG | +| STATE : code ROUTINE : reg_mm_failure | ++--------------------------------------------------------------------+ + + PURPOSE : MM indicates an internal failure during location updating. + +*/ + +GLOBAL void reg_mm_failure (UBYTE forb_ind) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("reg_mm_failure()"); + + if (!mm_lup_allowed_by_gmm()) + { + /* + * Call of function caused by MMGMM_ATTACH_REJ_REQ + * and not by own failed LOCATION UPDATING ATTEMPT - or - + * by MMGMM_NREG_REQ with (cs EQ CS_DISABLE). + */ + + // This means, in automatic mode we wait for a + // GMM decision to try a location update in automatic + // mode if there are further networks present. + // We have to discuss this item for network mode I! + + /* + * Check whether the MM failure was caused by MMGMM_NREG_REQ. + */ + if (mm_data->nreg_request) + mm_mmgmm_nreg_cnf (mm_data->nreg_cause); + return; + } + + /* + * The MM failure was caused by MM's own location updating procedure, + * LOCATION UPDATING REJECT message has been received. + */ + + /* + * In automatic mode with valid SIM, select the next PLMN if available + */ + reg_plmn_select (forb_ind); +} + +#endif