FreeCalypso > hg > fc-tourmaline
view src/g23m-gsm/mm/mm_regs.c @ 223:740a8e8fc9d7
startup sync logic rework for the new PWON button boot scheme
Previously we added logic to the MMI task to hold off PEI init until
R2D is running, and then extended that condition to wait for FCHG
init too. However, the dependencies of MMI upon R2D and FCHG don't
start until mmiInit(), and that call is driven by Switch_ON() code,
hence the wait for R2D and FCHG init can be made in that code path
instead of the MMI task. Furthermore, with our new way of signaling
PWON button boot to MMI, we need a new wait to ensure that the MMI
task is up - previously this assurance was provided by the wait for
Kp pointers to be set.
Solution: revert our previous PEI init hold-off additions to MMI,
add a new flag indicating MMI task init done, and put the combined
wait for all needed conditions into our new PWON button boot code
in power.c.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 27 Apr 2021 06:24:52 +0000 |
parents | fa8dc04885d8 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | 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