FreeCalypso > hg > fc-selenite
diff src/g23m-gsm/cc/cc_est.c @ 1:d393cd9bb723
src/g23m-*: initial import from Magnetite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 15 Jul 2018 04:40:46 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/g23m-gsm/cc/cc_est.c Sun Jul 15 04:40:46 2018 +0000 @@ -0,0 +1,1878 @@ +/* ++----------------------------------------------------------------------------- +| Project : GSM-PS (6147) +| Modul : CC_EST ++----------------------------------------------------------------------------- +| 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 establishment +| phase of the call control process of the component CC. ++----------------------------------------------------------------------------- +*/ + +#ifndef CC_EST_C +#define CC_EST_C + +#define ENTITY_CC +/*==== INCLUDES ===================================================*/ + +#include <string.h> +#include "typedefs.h" +#include "pcm.h" +#include "vsi.h" +#include "custom.h" +#include "gsm.h" +#include "message.h" +#include "ccdapi.h" +#include "prim.h" +#include "cnf_cc.h" +#include "mon_cc.h" +#include "pei.h" +#include "tok.h" +#include "cc.h" +#include "cc_em.h" + +/*==== EXPORT =====================================================*/ +/*==== PROTOTYPE ==================================================*/ +/* Implements Measure# 19 */ +LOCAL void cc_send_release_cmp (USHORT cause); +LOCAL void cc_send_mncc_release_ind (UBYTE ti, USHORT cause); +/*==== PRIVAT =====================================================*/ + +/*==== VARIABLES ==================================================*/ + +/*==== FUNCTIONS ==================================================*/ + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_init | ++--------------------------------------------------------------------+ + + PURPOSE : Initialisation of CC data. + +*/ + +GLOBAL void cc_init (void) +{ +#ifdef OPTION_MULTIPLE_INSTANCES + + USHORT i; + + TRACE_FUNCTION ("cc_init()"); + + for (i=0;i<MAX_INSTANCES;i++) + cc_init_data (&data_base[i]); +} +#else + + TRACE_FUNCTION ("cc_init()"); + cc_init_data (); +#endif +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_init_data | ++--------------------------------------------------------------------+ + + PURPOSE : Initializes the data for one instance. + +*/ + +GLOBAL void cc_init_data (void) +{ + GET_INSTANCE_DATA; + USHORT i; + + TRACE_FUNCTION ("cc_init_data()"); + + memset (cc_data, 0, sizeof (T_CC_DATA)); + + /* No SETUP / EMERGENCY SETUP pending */ + cc_data->stored_setup = NULL; + + /* No CCBS SETUP pending */ + cc_data->stored_ccbs_setup = NULL; + + cc_data->channel_mode = NAS_CHM_SIG_ONLY; + + for (i=0;i<MAX_CC_CALLS;i++) + { + cc_data->stored_ti_values[i] = NOT_PRESENT_8BIT; + } + + cc_csf_ms_cap (); + + /* + * Initialise single numbering scheme + */ + cc_data->sns_bcpara.bearer_serv = MNCC_BEARER_SERV_SPEECH; + cc_data->sns_mode = MNCC_SNS_MODE_VOICE; + + /* + * Initialise connection element for MTC + */ + cc_data->conn_elem = MNCC_CONN_ELEM_NON_TRANS; + + /* + * Initialize setup_reattempt_ti to not present + */ + cc_data->setup_reattempt_ti = NOT_PRESENT_8BIT; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_mncc_configure_req | ++--------------------------------------------------------------------+ + + PURPOSE : Configuration of bearer capabilities and subaddress + by man machine interface. + +*/ + +static const UBYTE def_modem_type [8] = +{ + MNCC_MT_V21, /* user rate 300 Baud -> modem type V.21 */ + MNCC_MT_V22, /* user rate 1200 Baud -> modem type V.22 */ + MNCC_MT_V22_BIS, /* user rate 2400 Baud -> modem type V.22bis */ + MNCC_MT_V32, /* user rate 4800 Baud -> modem type V32 */ + MNCC_MT_V32, /* user rate 9600 Baud -> modem type V32 */ + MNCC_MT_V32, /* 12k transparent, not supported now by ACI */ + MNCC_MT_V23, /* user rate 12k/75 Baud -> modem type V23 */ + MNCC_MT_V21, /* user rate 14.4 kBaud -> modem type V21 ??? */ +}; + +GLOBAL void cc_mncc_configure_req (T_MNCC_CONFIGURE_REQ * config) +{ + + GET_INSTANCE_DATA; + + TRACE_FUNCTION ("cc_mncc_configure_req()"); + + /* + * store own subadress if available + * + * NOTE: T_called_party_sub is the wrong type here in MNCC_CONFIGURE_REQ, + * this should have been T_calling_party_sub as this is that what + * the subaddress is used for in the uplink SETUP message later. + * Doesn't really matter here as the types are identical, it's + * just somewhat confusing and could be occasionally be changed. + */ + if (config->called_party_sub.c_subaddr) + { + cc_data->my_party_subaddr.v_tos = TRUE; + cc_data->my_party_subaddr.tos = config->called_party_sub.tos; + cc_data->my_party_subaddr.v_odd_even = TRUE; + cc_data->my_party_subaddr.odd_even = config->called_party_sub.odd_even; + cc_data->my_party_subaddr.c_subaddr = config->called_party_sub.c_subaddr; + memcpy (cc_data->my_party_subaddr.subaddr, + config->called_party_sub.subaddr, + config->called_party_sub.c_subaddr); + } + else + memset (&cc_data->my_party_subaddr, 0, sizeof (T_M_CC_called_subaddr)); + /* + * Store CTM support + */ + cc_data->ctm_ena = config->ctm_ena; + /* + * Store Single Numbering Scheme BC parameter and mode + * if available + */ + if (config->sns_mode NEQ NOT_PRESENT_8BIT) + { + /* + * Store Connection Element for MTC + * Note that setting conditionally on sns_mode NEQ NOT_PRESENT_8BIT is + * possible because ACI always sets sns_mode to something different from + * NOT_PRESENT_8BIT when it sends an MNCC_CONFIGURE_REQ. + * For future proof use of MNCC_CONFIGURE_REQ (e.g. only subaddress is valid!) + * it is convenient and correct to consider parameters only if they + * are valid. + */ + + cc_data->conn_elem = config->bcpara.conn_elem; + + cc_data->sns_mode = config->sns_mode; + + if (cc_data->sns_mode EQ MNCC_SNS_MODE_VOICE) + { + memset (&cc_data->sns_bcpara, 0 /*NOT_PRESENT_8BIT*/, sizeof (T_MNCC_bcpara)); + cc_data->sns_bcpara.bearer_serv = (cc_data->ctm_ena EQ MNCC_CTM_ENABLED)? + MNCC_BEARER_SERV_SPEECH_CTM: MNCC_BEARER_SERV_SPEECH; + } + else + memcpy (&cc_data->sns_bcpara, &config->bcpara, sizeof (T_MNCC_bcpara)); + /* + * Set modem type to default values for single numbering scheme + */ + switch (cc_data->sns_bcpara.bearer_serv) + { + case MNCC_BEARER_SERV_FAX: + cc_data->sns_bcpara.modem_type = M_CC_MT_NONE; + break; + case MNCC_BEARER_SERV_SPEECH: + case MNCC_BEARER_SERV_AUX_SPEECH: + case MNCC_BEARER_SERV_SPEECH_CTM: + case MNCC_BEARER_SERV_AUX_SPEECH_CTM: + break; + default: + cc_data->sns_bcpara.modem_type = def_modem_type[config->bcpara.rate-1]; + if (config->bcpara.modem_type == MNCC_MT_V34) + { + cc_data->sns_bcpara.modem_type = MNCC_MT_V34; + } + break; + } + } + + /* + * define connection element if a preferred one is set by MMI + */ + if (cc_data->sns_bcpara.conn_elem EQ MNCC_CONN_ELEM_TRANS_PREF) + { + /* + * check only if transparent asynchronous data services are supported + */ + if (FldGet(cc_data->mscap.datCap1, AsySup)) + cc_data->sns_bcpara.conn_elem = M_CC_CE_TRANSPA; + else + cc_data->sns_bcpara.conn_elem = M_CC_CE_RLP; + } + + /* + * define connection element if a preferred one is set by MMI + */ + if (cc_data->sns_bcpara.conn_elem EQ MNCC_CONN_ELEM_NON_TRANS_PREF) + { + /* + * check only if non-transparent asynchronous data services are supported + */ + if (FldGet (cc_data->mscap.datCap1, RLPSup)) + cc_data->sns_bcpara.conn_elem = M_CC_CE_RLP; + else + cc_data->sns_bcpara.conn_elem = M_CC_CE_TRANSPA; + } + + PFREE (config); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_mncc_prompt_rsp | ++--------------------------------------------------------------------+ + + PURPOSE : A new transaction identifier during network initiated + mobile origination call establishment was assigned by + upper layers. Under normal conditions this causes the + emmission of an MMCC_DATA_REQ (START CC) + +*/ + +GLOBAL void cc_mncc_prompt_res (T_MNCC_PROMPT_RES * prompt) +{ + GET_INSTANCE_DATA; + + TRACE_FUNCTION ("cc_mncc_prompt_rsp()"); + + /* Check parameters */ + if (prompt->ti >= 7) + { + /* Invalid transaction identifier */ +/* Implements Measure# 36, 48 */ + cc_send_mncc_release_ind (prompt->ti, + CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + M_CC_CAUSE_INVALID_TI)); + + PFREE (prompt); + return; + } + + /* Assign ti and allocate a free entry in the call data */ + cc_data->ti = prompt->ti; + cc_data->index_ti = srv_define_ti(); + if (cc_data->index_ti EQ NOT_PRESENT_8BIT) + { + /* + * No call instance available + */ +/* Implements Measure# 36, 48 */ + cc_send_mncc_release_ind (prompt->ti, MNCC_CAUSE_MAX_NO_CALLS_REACHED); + + PFREE (prompt); + return; + } + + /* Send MMCC_PROMPT_RSP */ + { + PALLOC (prompt_rsp, MMCM_PROMPT_RES); // T_MMCM_ESTABLISH_REQ + prompt_rsp->ti = prompt->ti; + PSENDX (MM, prompt_rsp); + } + + /* Send MMCC_DATA_REQ (START CC) */ + + CCD_START; + { + MCAST (start_cc, U_START_CC); + cc_build_start_cc (start_cc); + for_start_cc (start_cc); + } + CCD_END; + + /* Start Timer T332 */ + TIMERSTART (T332, T332_VALUE); + + PFREE (prompt); + + /* Next state is WAIT FOR NETWORK INFO (U0.3) */ + cc_set_state (M_CC_CS_03); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_mncc_prompt_rej | ++--------------------------------------------------------------------+ + + PURPOSE : A new transaction identifier during network initiated + mobile origination call establishment could not be + assigned by upper layers. MM is informed by + MMCC_PROMPT_REJ. + +*/ + +GLOBAL void cc_mncc_prompt_rej (T_MNCC_PROMPT_REJ * prompt) +{ + TRACE_FUNCTION ("cc_mncc_prompt_rej()"); + + PFREE (prompt); + + { + PALLOC (reject, MMCM_PROMPT_REJ); + PSENDX (MM, reject); + } +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_mncc_setup_req | ++--------------------------------------------------------------------+ + + PURPOSE : Starting of mobile originated call. + +*/ + +GLOBAL void cc_mncc_setup_req (T_MNCC_SETUP_REQ * setup) +{ + GET_INSTANCE_DATA; + + TRACE_FUNCTION ("cc_mncc_setup_req()"); + cc_data->index_ti = srv_convert_ti (setup->ti); + if (cc_data->index_ti NEQ NOT_PRESENT_8BIT) + { + /* + * Transaction identifier already present, this means, we know this ti + * and CC is not in M_CC_CS_0 state. This is okay for M_CC_CS_06 (CCBS), + * for every other state this is an internal failure. + */ + switch (cc_data->state[cc_data->index_ti]) + { + case M_CC_CS_06: /* RECALL present */ + /* + * Don't use the setup parametes from ACI, instead use + * the stored SETUP message in CC. + */ + + cc_data->progress_desc[cc_data->index_ti] = NOT_PRESENT_8BIT; + + /* No ugly CC setup reattempts here */ + cc_data->setup_attempts = MAX_SETUP_ATTEMPTS; + cc_data->setup_reattempt_ti = NOT_PRESENT_8BIT; + + /* Send stored SETUP message to network and forget it */ + for_pd (cc_data->stored_ccbs_setup); + cc_data->stored_ccbs_setup = NULL; + + /* Set parameters in cc_data */ + cc_data->call_type [cc_data->index_ti] = CALL_TYPE_MOC; + + /* initialize disconnect collision flag */ + cc_data->disc_coll [cc_data->index_ti] = FALSE; + + cc_data->t308_counter [cc_data->index_ti] = 0; + cc_reset_dtmf (); + + /* Start T303 */ + TIMERSTART (T303, T303_VALUE); + + /* Next state is CALL INIT */ + cc_set_state (M_CC_CS_1); + break; + + default: /* The ti is already in use and it is not CCBS recall */ + { + PALLOC (rel, MNCC_RELEASE_IND); + rel->ti = setup->ti; + rel->cause = M_CC_CAUSE_INVALID_TI; + rel->c_raw_cause = 0; + PSENDX (MMI, rel); + } + break; + } + PFREE (setup); + return; + } + + if (setup->ti >= 7) + { + /* + * Invalid transaction identifier + */ +/* Implements Measure# 36, 48 */ + cc_send_mncc_release_ind (setup->ti, + CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + M_CC_CAUSE_INVALID_TI)); + PFREE (setup); + return; + } + + /* + * ti is valid here and not already in use + */ + cc_data->ti = setup->ti; + cc_data->index_ti = srv_define_ti (); + if (cc_data->index_ti EQ NOT_PRESENT_8BIT) + { + /* + * No call instance available + */ +/* Implements Measure# 36, 48 */ + cc_send_mncc_release_ind (setup->ti, MNCC_CAUSE_MAX_NO_CALLS_REACHED); + PFREE (setup); + return; + } + + /* + * Security check: if bcpara indicates not present, + * set service to speech + */ + if (setup->bcpara.bearer_serv EQ NOT_PRESENT_8BIT) + { + setup->bcpara.bearer_serv = (cc_data->ctm_ena EQ MNCC_CTM_ENABLED)? + MNCC_BEARER_SERV_SPEECH_CTM: MNCC_BEARER_SERV_SPEECH; + } + /* + * Security check: if prio indicates emergency call, + * set service to speech or speech with CTM + */ + if (setup->prio NEQ MNCC_PRIO_NORM_CALL) + { + switch (setup->bcpara.bearer_serv) + { + case MNCC_BEARER_SERV_SPEECH: + case MNCC_BEARER_SERV_SPEECH_CTM: + break; + case MNCC_BEARER_SERV_AUX_SPEECH_CTM: + setup->bcpara.bearer_serv = MNCC_BEARER_SERV_SPEECH_CTM; + break; + default: + setup->bcpara.bearer_serv = MNCC_BEARER_SERV_SPEECH; + break; + } + } + + if (cc_check_capabilities (&setup->bcpara) EQ FALSE OR + cc_check_capabilities ((T_MNCC_bcpara *)&setup->bcpara2) EQ FALSE) + { + /* + * MS doesn't support the requested services. + */ + PALLOC ( rel, MNCC_RELEASE_IND); + + rel->ti = setup->ti; + rel->cause = CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + M_CC_CAUSE_BEARER_NOT_IMPLEM); + rel->c_raw_cause = 0; + + PSENDX (MMI, rel); + + srv_free_ti (); + + PFREE (setup); + } + else + { + PALLOC (est, MMCM_ESTABLISH_REQ); /* T_MMCM_ESTABLISH_REQ */ + cc_build_bc (&cc_data->bc1, &cc_data->serv1, &setup->bcpara); + cc_data->ri = setup->ri; + cc_data->bcpara1 = setup->bcpara; + memcpy (&cc_data->bcpara2, &setup->bcpara2, sizeof (T_MNCC_bcpara)); + + if (cc_data->ri EQ NOT_PRESENT_8BIT) + cc_data->serv2 = NOT_PRESENT_8BIT; + else + cc_build_bc (&cc_data->bc2, &cc_data->serv2, (T_MNCC_bcpara *)&setup->bcpara2); + memcpy (&cc_data->bcpara2, &setup->bcpara2, sizeof (T_MNCC_bcpara)); + est->org_entity = NAS_ORG_ENTITY_CC; + est->ti = setup->ti; + + /* Set establ_serv according to chosen bearer capability */ + switch (cc_data->bcpara1.bearer_serv) + { + case MNCC_BEARER_SERV_SPEECH: + est->estcs = MMCM_ESTCS_MOB_ORIG_SPCH; + break; + + case MNCC_BEARER_SERV_ASYNC: + if (cc_data->bcpara1.conn_elem == MNCC_CONN_ELEM_TRANS || + cc_data->bcpara1.conn_elem == MNCC_CONN_ELEM_TRANS_PREF) + { + est->estcs = MMCM_ESTCS_MOB_ORIG_DATA; + } + else + { + est->estcs = MMCM_ESTCS_MOB_ORIG_DATA; + } + break; + + case MNCC_BEARER_SERV_FAX: + est->estcs = MMCM_ESTCS_MOB_ORIG_DATA; + break; + + default: + est->estcs = MMCM_ESTCS_MOB_ORIG_SPCH; + break; + } + + switch (cc_data->serv1) + { + case MNCC_SERV_DATA: + if (FldGet(cc_data->mscap.datCap2, DHRSup)) + { + /* + * Halfrate support for data + */ + switch (setup->bcpara.rate) + { + case M_CC_UR_0_3_KBIT: + case M_CC_UR_1_2_KBIT: + case M_CC_UR_2_4_KBIT: + case M_CC_UR_4_8_KBIT: + case M_CC_UR_1_2_KBIT_V23: + est->estcs = MMCM_ESTCS_MOB_ORIG_DATA; + break; + default: + est->estcs = MMCM_ESTCS_MOB_ORIG_DATA; + break; + } + } + else + est->estcs = MMCM_ESTCS_MOB_ORIG_DATA; + break; + + default: /* SERV_SPEECH */ + if (setup->prio EQ MNCC_PRIO_NORM_CALL) + est->estcs = MMCM_ESTCS_MOB_ORIG_SPCH; + else + est->estcs = MMCM_ESTCS_EMERGE; + break; + } + + /* Data solely needed for possible redial attempt */ + cc_data->estcs = est->estcs; + cc_data->setup_attempts = 0; + + srv_free_stored_setup (); + cc_data->progress_desc[cc_data->index_ti] = NOT_PRESENT_8BIT; + cc_data->call_type [cc_data->index_ti] = CALL_TYPE_MOC; + // PATCH LE 10.04.00 + // initialize disconnect collision flag + cc_data->disc_coll [cc_data->index_ti] = FALSE; + // END PATCH LE 10.04.00 + cc_data->t308_counter [cc_data->index_ti] = 0; + cc_reset_dtmf (); + + CCD_START; + if (setup->prio EQ MNCC_PRIO_NORM_CALL) + { + MCAST (setup_msg, U_SETUP); + + cc_build_setup (setup_msg, setup); + for_setup (setup_msg); + } + else + { + MCAST (emergency_setup_msg, U_EMERGE_SETUP); + + cc_build_emergency_setup (emergency_setup_msg); + for_emergency_setup (emergency_setup_msg); + } + CCD_END; + + cc_set_state (M_CC_CS_01); + for_est_req (est); + TIMERSTART (T303, T303_VALUE); + PFREE (setup); + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_mncc_alert_req | ++--------------------------------------------------------------------+ + + PURPOSE : The mobile side indicates alerting. + +*/ + +GLOBAL void cc_mncc_alert_req (T_MNCC_ALERT_REQ * alert) +{ + GET_INSTANCE_DATA; + + TRACE_FUNCTION ("cc_mncc_alert_req()"); + + if ((cc_data->index_ti = srv_convert_ti (alert->ti)) + EQ NOT_PRESENT_8BIT) + { + PFREE (alert); + return; + } + + switch (cc_data->state[cc_data->index_ti]) + { + case M_CC_CS_9: + CCD_START; + { + MCAST (alert_msg, U_ALERT); + + cc_build_alert (alert_msg); + cc_set_state (M_CC_CS_7); + for_alert (alert_msg); + } + CCD_END; + + EM_CC_ALERTING_SENT; + + PFREE (alert); + break; + + default: + PFREE (alert); + break; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_mncc_setup_res | ++--------------------------------------------------------------------+ + + PURPOSE : The mobile side indicates call acceptance. + +*/ + +GLOBAL void cc_mncc_setup_res (T_MNCC_SETUP_RES * setup_res) +{ + GET_INSTANCE_DATA; + + TRACE_FUNCTION ("cc_mncc_setup_res()"); + + if ((cc_data->index_ti = srv_convert_ti (setup_res->ti)) + EQ NOT_PRESENT_8BIT) + { + PFREE (setup_res); + return; + } + + switch (cc_data->state[cc_data->index_ti]) + { + case M_CC_CS_7: + case M_CC_CS_9: + CCD_START; + { + MCAST (connect, U_CONNECT); + cc_build_connect (connect); + cc_set_state (M_CC_CS_8); + TIMERSTART (T313, T313_VALUE); + for_connect (connect); + } + CCD_END; + + EM_CC_CONNECT_SENT; + + PFREE (setup_res); + break; + + default: + PFREE (setup_res); + break; + } +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_alert | ++--------------------------------------------------------------------+ + + PURPOSE : Processing an incoming alert message. + +*/ + +GLOBAL void cc_alert (T_D_ALERT * alert) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("cc_alert()"); + + EM_CC_ALERTING_RECEIVED; + + switch (cc_data->state[cc_data->index_ti]) + { + /* + * CS_0 is handled by the formatter + */ + case M_CC_CS_1: + case M_CC_CS_3: + if (cc_check_error_flag ()) + { + PALLOC (alert_ind, MNCC_ALERT_IND); + TIMERSTOP (TIMER_CC); + + if (alert->v_progress) + { + cc_data->progress_desc[cc_data->index_ti] = + alert->progress.progress_desc; + } + + cc_build_mncc_alert_ind (alert, alert_ind); + PSENDX (MMI, alert_ind); + + cc_build_facility_ind (MNCC_FAC_IN_ALERT, alert->v_facility, &alert->facility); + cc_build_user_user_ind (MNCC_USER_IN_ALERT, alert->v_user_user, + &alert->user_user); + CCD_END; + srv_free_stored_setup (); + cc_set_state (M_CC_CS_4); + } + break; + + default: + CCD_END; +/* Implements Measure# 3 and streamline encoding */ + cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT); + break; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_call_proceeding | ++--------------------------------------------------------------------+ + + PURPOSE : Processing an incoming call proceed message. + +*/ + +GLOBAL void cc_call_proceeding (T_D_CALL_PROCEED * proceed) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("cc_call_proceeding()"); + + EM_CC_CALL_PROCEEDING_RECEIVED; + + switch (cc_data->state[cc_data->index_ti]) + { + /* + * CS_0 is handled by the formatter + */ + case M_CC_CS_1: + if (cc_check_error_flag ()) + { + TIMERSTOP (TIMER_CC); /* timer T303 */ + if (cc_moc_compatibility (proceed) EQ OKAY) + { + PALLOC (proceed_ind, MNCC_CALL_PROCEED_IND); + + cc_build_mncc_proceed_ind (proceed, proceed_ind); + PSENDX (MMI, proceed_ind); + + cc_build_facility_ind (MNCC_FAC_IN_CALL_PROCEED, + proceed->v_facility, &proceed->facility); + if (proceed->v_progress) + { + cc_data->progress_desc[cc_data->index_ti] = + proceed->progress.progress_desc; + } + + CCD_END; + /* + * - start T310 unless the CALL PROCEEDING message contains a progress indicator IE + * specifying progress description #1, #2, Ph2 handling is not done yet (#64), see + * also issue 4967 + * - start T310 unless a PROGRESS message with #1, 2, 64 has been + * received, this is achieved by remembering the progress description in cc_data + * - the case when 1. PROGRESS and 2. CALL PROCEEDING with e.g. #4 is handled by + * interpreting 5.2.1.1.3 of 04.08 in the manner that a 2nd progress description + * superseeds the first one. See also issue 4965 / CC-FIX-4965. + */ + /* start T310 with Ph2 unless progress description value #1, #2 or #64 has been received */ + { + UBYTE prog_desc = cc_data->progress_desc[cc_data->index_ti]; + if ((prog_desc NEQ MNCC_PROG_NO_END_TO_END_PLMN) + AND + (prog_desc NEQ MNCC_PROG_DEST_NON_PLMN) + AND + (prog_desc NEQ MNCC_PROG_QUEUEING)) + { + TIMERSTART (T310, T310_VALUE); + } + } + if (proceed->v_progress AND + proceed->progress.v_progress_desc AND + proceed->progress.progress_desc EQ M_CC_PROG_INBAND_AVAIL) + { + /* + * Avoid more call establishment attempts if there was + * inband announcement heard by the user. + * The user should have no way to realize that more than one + * call attempt may be taken by CC. + */ + cc_data->setup_attempts = MAX_SETUP_ATTEMPTS; + } + + cc_set_state (M_CC_CS_3); + } + else /* bearer capability check on CALL PROCEEDING failed */ + { + CCD_END; + CCD_START; + { + MCAST (disconnect, U_DISCONNECT); + PALLOC (rej_ind, MNCC_REJECT_IND); + + rej_ind->ti = cc_data->ti; + /* + * GSM 04.08 does not specify what to do / which cause to use; + * Condat decided to use normal call clearing with cause #88 + */ + rej_ind->cause = CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + MNCC_CAUSE_INCOMPAT_DEST); + PSENDX (MMI, rej_ind); + + cc_build_disconnect (disconnect, + CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + MNCC_CAUSE_INCOMPAT_DEST), + NULL, MNCC_SS_VER_NOT_PRES); + cc_set_state (M_CC_CS_11); + for_disconnect (disconnect); + } + CCD_END; + TIMERSTART (T305, T305_VALUE); + } + } + break; + + default: + CCD_END; +/* Implements Measure# 3 and streamline encoding */ + cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT); + break; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_connect | ++--------------------------------------------------------------------+ + + PURPOSE : Processing an incoming connect message. + +*/ + +GLOBAL void cc_connect (T_D_CONNECT * connect) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("cc_connect()"); + + switch (cc_data->state[cc_data->index_ti]) + { + /* + * CS_0 is handled by the formatter + */ + case M_CC_CS_1: + case M_CC_CS_3: + case M_CC_CS_4: + if (cc_check_error_flag ()) + { + PALLOC (setup_cnf, MNCC_SETUP_CNF); + + TIMERSTOP (TIMER_CC); + + if (connect->v_progress) + { + cc_data->progress_desc[cc_data->index_ti] = + connect->progress.progress_desc; + } + + cc_build_mncc_setup_cnf (connect, setup_cnf); + PSENDX (MMI, setup_cnf); + cc_build_facility_ind (MNCC_FAC_IN_CONNECT, connect->v_facility, + &connect->facility); + cc_build_user_user_ind (MNCC_USER_IN_CONNECT, connect->v_user_user, + &connect->user_user); + CCD_END; + CCD_START; + { + MCAST (connect_ack, B_CONNECT_ACK); + + connect_ack->msg_type = B_CONNECT_ACK; + for_connect_ack (connect_ack); + } + CCD_END; + srv_free_stored_setup (); + cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_IDLE; + cc_data->mpty_state[cc_data->index_ti] = M_CC_MPTY_IDLE; + cc_set_state (M_CC_CS_10); + } + + EM_CC_CONNECT_RECEIVED; + + break; + + default: +/* Implements Measure# 3 and streamline encoding */ + CCD_END; + cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT); + break; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_connect_ack | ++--------------------------------------------------------------------+ + + PURPOSE : Processing an incoming connect acknowledge message. + +*/ + +GLOBAL void cc_connect_ack (void) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("cc_connect_ack()"); + + switch (cc_data->state[cc_data->index_ti]) + { + /* + * CS_0 is handled by the formatter + */ + case M_CC_CS_8: + if (cc_check_error_flag ()) + { + PALLOC (setup_comp, MNCC_SETUP_COMPL_IND); + + CCD_END; + + TIMERSTOP (TIMER_CC); + + setup_comp->ti = cc_data->ti; + setup_comp->cause = MNCC_CAUSE_SUCCESS; + PSENDX (MMI, setup_comp); + + cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_IDLE; + cc_data->mpty_state[cc_data->index_ti] = M_CC_MPTY_IDLE; + cc_set_state (M_CC_CS_10); + + EM_CC_CONNECT_ACKNOWLEDGE_RECEIVED; + + } + break; + + default: + CCD_END; +/* Implements Measure# 3 and streamline encoding */ + cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT); + break; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_progress | ++--------------------------------------------------------------------+ + + PURPOSE : Processing of an incoming progress message. + +*/ + +GLOBAL void cc_progress (T_D_PROGRESS * progress) +{ + GET_INSTANCE_DATA; + + TRACE_FUNCTION ("cc_progress()"); + + switch (cc_data->state[cc_data->index_ti]) + { + /* + * CS_0 is handled by the formatter + */ + case M_CC_CS_1: + case M_CC_CS_3: + case M_CC_CS_4: + case M_CC_CS_6: + case M_CC_CS_7: + case M_CC_CS_8: + case M_CC_CS_9: + case M_CC_CS_11: + case M_CC_CS_12: + case M_CC_CS_19: + if (cc_check_error_flag ()) + { + PALLOC (progress_ind, MNCC_PROGRESS_IND); + + TIMERSTOP (TIMER_CC); + + /* Progress indicator IE here is mandatory IE, so no + * checks for presence need to be done here */ + cc_data->progress_desc[cc_data->index_ti] = + progress->progress.progress_desc; + + cc_build_mncc_progress_ind (progress, progress_ind); + PSENDX (MMI, progress_ind); + cc_build_user_user_ind (MNCC_USER_IN_PROGRESS, progress->v_user_user, + &progress->user_user); + CCD_END; + } + + EM_CC_PROGRESS_RECEIVED; + + break; + + default: + CCD_END; +/* Implements Measure# 3 and streamline encoding */ + cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT); + break; + } +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_cc_establishment | ++--------------------------------------------------------------------+ + + PURPOSE : Processing of an incoming CC ESTABLISHMENT message. + Because the only interesting part in this message + is the setup container, only the decoded SETUP message + is delivered here. + +*/ + +GLOBAL void cc_cc_establishment (T_U_SETUP * setup) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("cc_cc_establishment()"); + + switch (cc_data->state[cc_data->index_ti]) + { + case M_CC_CS_03: /* WAIT FOR NW INFO */ + + /* Check errors delivered by formatter */ + switch (cc_data->error) + { + case M_CC_CAUSE_INVALID_MAND_INFO: + case M_CC_CAUSE_COND_INFO_ELEM: + CCD_END; + /* Implements Measure# 7 and streamline encoding*/ + cc_send_status (cc_data->error); + return; + + default: /* No error until now */ + /* Stop TIMER T332 */ + TIMERSTOP (TIMER_CC); + + if (cc_data->stored_ccbs_setup NEQ NULL) + { + /* + * There is only room for one stored CCBS SETUP message + * for all instances. In case this is already occupied, + * the call is released with cause "user busy". + * In this case the CCBS recall is not lost, but suspended + * by the network until the mobile becomes idle. + */ + CCD_END; + + /* Send RELEASE COMPLETE */ + CCD_START; + { + MCAST (rel_com, U_RELEASE_COMP); + cc_build_release_complete (rel_com, CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + MNCC_CAUSE_USER_BUSY)); + for_release_complete (rel_com); + } + CCD_END; + + /* Inform MMI */ + { + PALLOC (release, MNCC_RELEASE_IND); + release->ti = cc_data->ti; + release->cause = MNCC_CAUSE_MAX_NO_RECALLS_REACHED; + release->c_raw_cause = 0; + PSENDX (MMI, release); + } + + /* Release MM connection */ + for_rel_req (); + + /* Next state is NULL */ + cc_set_state (M_CC_CS_0); + return; + } + + /* Check bearer capabilities, do basic recall alignment */ + if (cc_basic_service_align (setup) EQ ERROR) + { + /* Incompatible bearer capabilities. Clear call. */ + CCD_END; + /* Implements Measure# 19 */ + cc_send_release_cmp (CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + MNCC_CAUSE_INCOMPAT_DEST)); + return; + } + + /* + * "If the CC Capabilities in the Setup Container IE is different + * to that supported by the mobile station, the mobile station + * shall modify the CC Capabilities in the SETUP message to indicate + * the true capabilities of the mobile station" [GSM 04.08 5.2.3.2] + */ + setup->call_ctrl_cap = cc_data->call_ctrl_cap; /* Struct copy */ + + /* + * Handle facility alignment + * ("Simple recall alignment", + * "Advanced recall alignment" and + * "Recall alignment not essential"). + */ + + /* "Simple recall alignment" handled automatically, do nothing */ + + if (setup->v_fac_adv) + { + /* Advanced recall alignment not supported. Reject call. */ + CCD_END; + /* Implements Measure# 19 */ + cc_send_release_cmp (CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + MNCC_CAUSE_FACILITY_REJECT)); + + return; + } + + /* + * The recall alignment not essential facility IE + * need not be handled directly here, it is simply + * an optional IE which was ignored by CCD. + * The only handling we do is to delete the SS-Version + * indicator if there are no remaining facility elements. + */ + if (!setup->v_facility) + setup->v_ss_version = FALSE; + + /* Store coded setup message in cc_data */ + { + /* No assumtions made about length of this foreign message */ + PALLOC_SDU (data, MMCM_DATA_REQ, M_CC_L3MAX << 3); + data->sdu.o_buf = CC_ENCODE_OFFSET; + ccd_codeMsg (CCDENT_CC, + UPLINK, + (T_MSGBUF *) &data->sdu, + (UBYTE *) setup, + NOT_PRESENT_8BIT); + cc_data->stored_ccbs_setup = data; + } + CCD_END; + + /* Send MMCC_DATA_REQ (CC EST. CONFIRMED) */ + CCD_START; + { + MCAST (est_cnf, U_CC_EST_CONF); + if (cc_count_active_connections () EQ 0) + cc_build_cc_est_confirm (est_cnf, CAUSE_MAKE(DEFBY_CONDAT, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + NOT_PRESENT_8BIT)); + else + cc_build_cc_est_confirm (est_cnf, CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + MNCC_CAUSE_USER_BUSY)); + for_cc_est_confirm (est_cnf); + } + CCD_END; + + /* Start TIMER T335 */ + TIMERSTART (T335, T335_VALUE); + + /* Enter the "CC-establishment confirmed" state */ + cc_set_state (M_CC_CS_05); + break; + } + break; + + default: + /* Message not compatible with protocol state */ + CCD_END; + + /* Implements Measure# 3 and streamline encoding */ + cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT); + break; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_recall | ++--------------------------------------------------------------------+ + + PURPOSE : Processing of an incoming recall message. + +*/ + +GLOBAL void cc_recall (T_D_RECALL * recall) +{ + GET_INSTANCE_DATA; + + TRACE_FUNCTION ("cc_recall"); + + switch (cc_data->state[cc_data->index_ti]) + { + case M_CC_CS_05: /* CC ESTABLISHMENT CONFIRMED */ + switch(cc_data->error) + { + case M_CC_CAUSE_INVALID_MAND_INFO: + case M_CC_CAUSE_COND_INFO_ELEM: + CCD_END; + /* Implements Measure# 7 and streamline encoding*/ + cc_send_status (cc_data->error); + return; + + default: + /* Stop Timer T335 */ + TIMERSTOP (TIMER_CC); + { + T_U_SETUP * setup; + UBYTE result; + PALLOC (fac_ind, MNCC_FACILITY_IND); + + /* Process facility element. may be not present */ + fac_ind->ti = cc_data->ti; + fac_ind->fac_context = MNCC_FAC_IN_RECALL; + fac_ind->fac_inf.l_fac = recall->facility.c_fac << 3; + fac_ind->fac_inf.o_fac = 0; + memcpy (fac_ind->fac_inf.fac, + recall->facility.fac, + recall->facility.c_fac); + + { + PALLOC (rec_ind, MNCC_RECALL_IND); /* T_MNCC_RECALL_IND */ + + rec_ind->ti = cc_data->ti; + rec_ind->rcl_type = recall->recall_type.rcl_type; + CCD_END; + + /* + * Unpack coded setup container. + * Conserving memory, so already processed parameters are + * processed for a second time now. No errors expected. + */ + assert (cc_data->stored_ccbs_setup NEQ NULL); + CCD_START; + result = ccd_decodeMsg (CCDENT_CC, + UPLINK, + (T_MSGBUF *) &cc_data->stored_ccbs_setup->sdu, + (UBYTE *) _decodedMsg, + NOT_PRESENT_8BIT); + assert (result EQ ccdOK); + setup = (T_U_SETUP *)_decodedMsg; + result = cc_basic_service_align (setup); + assert (result NEQ ERROR); + + /* Process repeat indicator, BC I and BC II */ + rec_ind->ri = cc_data->neg_ri; + memcpy (&rec_ind->bcpara, &cc_data->neg_bcpara1, + sizeof (T_MNCC_bcpara)); + memcpy (&rec_ind->bcpara2, &cc_data->neg_bcpara2, + sizeof (T_MNCC_bcpara)); + + /* Process called party address */ + rec_ind->called_party.ton = setup->ul_called_num.ton; + rec_ind->called_party.npi = setup->ul_called_num.npi; + rec_ind->called_party.c_called_num = setup->ul_called_num.c_num; + memcpy (rec_ind->called_party.called_num, + setup->ul_called_num.num, + setup->ul_called_num.c_num); + + /* Process called party subaddress */ + if (setup->v_called_subaddr) + { + rec_ind->called_party_sub.tos = + setup->called_subaddr.tos; + rec_ind->called_party_sub.odd_even = + setup->called_subaddr.odd_even; + rec_ind->called_party_sub.c_subaddr = + setup->called_subaddr.c_subaddr; + memcpy (rec_ind->called_party_sub.subaddr, + setup->called_subaddr.subaddr, MNCC_SUB_LENGTH); + } + else + { + rec_ind->called_party_sub.tos = MNCC_TOS_NOT_PRES; + rec_ind->called_party_sub.c_subaddr = 0; + } + CCD_END; + + /* Send MNCC_RECALL_IND */ + PSENDX (MMI, rec_ind); + } + + /* Handle MNCC_FACILITY_IND */ + if (fac_ind->fac_inf.l_fac) + { + PSENDX (MMI, fac_ind); + } + else + PFREE (fac_ind); + + /* Next state is RECALL PRESENT */ + cc_set_state (M_CC_CS_06); + } + break; + } + break; /* esac CS_05 */ + default: + CCD_END; + /* Message not compatible with protocol state */ +/* Implements Measure# 3 and streamline encoding*/ + cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT); + break; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_setup | ++--------------------------------------------------------------------+ + + PURPOSE : Processing of an incoming setup message. + +*/ + +GLOBAL void cc_setup (T_D_SETUP * setup) +{ + GET_INSTANCE_DATA; + + TRACE_FUNCTION ("cc_setup()"); + + switch (cc_data->state[cc_data->index_ti]) + { + case M_CC_CS_0: + if (cc_data->ti < 8) + { + /* + * This values are reserved for mobile originated calls. + */ + CCD_END; + for_rel_req (); + break; + } + + switch (cc_data->error) + { + case M_CC_CAUSE_INVALID_MAND_INFO: + case M_CC_CAUSE_COND_INFO_ELEM: + CCD_END; + CCD_START; + { + MCAST (rel_com, U_RELEASE_COMP); + + cc_build_release_complete (rel_com, CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + cc_data->error)); + for_release_complete (rel_com); + } + CCD_END; + for_rel_req (); + break; + + default: + switch (cc_compatibility_check (setup)) + { + case BAD_SUBADDRESS: + CCD_END; + CCD_START; + { + MCAST (rel_com, U_RELEASE_COMP); + cc_build_release_complete (rel_com, CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + MNCC_CAUSE_NO_ROUTE)); + for_release_complete (rel_com); + } + CCD_END; + for_rel_req (); + cc_set_state (M_CC_CS_0); + break; + + case ERROR: + CCD_END; + CCD_START; + { + MCAST (rel_com, U_RELEASE_COMP); + cc_build_release_complete (rel_com, CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + MNCC_CAUSE_INCOMPAT_DEST)); + for_release_complete (rel_com); + } + CCD_END; + for_rel_req (); + cc_set_state (M_CC_CS_0); + break; + + case OKAY: + case NEGOTIATION: + { + PALLOC (setup_ind, MNCC_SETUP_IND); + + cc_data->progress_desc[cc_data->index_ti] = NOT_PRESENT_8BIT; + + if (setup->v_progress) + { + cc_data->progress_desc[cc_data->index_ti] = + setup->progress.progress_desc; + } + + cc_data->call_type [cc_data->index_ti] = CALL_TYPE_MTC; + // PATCH LE 10.04.00 + // initialize disconnect collision flag + cc_data->disc_coll [cc_data->index_ti] = FALSE; + // END PATCH LE 10.04.00 + cc_build_mncc_setup_ind (setup, setup_ind); + + PSENDX (MMI, setup_ind); + cc_build_facility_ind (MNCC_FAC_IN_SETUP, setup->v_facility, + &setup->facility); + cc_build_user_user_ind (MNCC_USER_IN_SETUP, setup->v_user_user, + &setup->user_user); + + + + CCD_END; + CCD_START; + { + MCAST (call_cnf, U_CALL_CONF); + + if (cc_count_active_connections () EQ 0) + cc_build_call_confirm (call_cnf, CAUSE_MAKE(DEFBY_CONDAT, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + NOT_PRESENT_8BIT)); + else + cc_build_call_confirm (call_cnf, CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + MNCC_CAUSE_USER_BUSY)); + for_call_confirm (call_cnf); + } + CCD_END; + cc_set_state (M_CC_CS_9); + + EM_CC_MM_CONNECTION_ESTABLISHED_MT; + + break; + } + + default: + CCD_END; + break; + } + break; + } + break; + + default: + CCD_END; + break; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_sync_ind | ++--------------------------------------------------------------------+ + + PURPOSE : Processing of an incoming sync indication from + mobility management. + +*/ + +GLOBAL void cc_sync_ind (T_MMCM_SYNC_IND * mmcm_sync) +{ + GET_INSTANCE_DATA; + PALLOC ( mncc_sync, MNCC_SYNC_IND ); + + TRACE_FUNCTION ("cc_sync_ind()"); + + + cc_data->channel_type = mmcm_sync->sync_info.ch_info.ch_type; + cc_data->channel_mode = mmcm_sync->sync_info.ch_info.ch_mode; + + mncc_sync->ti = mmcm_sync->ti; + + mncc_sync->ch_info.ch_mode = mmcm_sync->sync_info.ch_info.ch_mode; + mncc_sync->ch_info.ch_type = mmcm_sync->sync_info.ch_info.ch_type; + + mncc_sync->cause = MNCC_CAUSE_CHANNEL_SYNC; + PSENDX (MMI, mncc_sync); + PFREE (mmcm_sync); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_est_cnf | ++--------------------------------------------------------------------+ + + PURPOSE : Processing of an incoming establish confirm from + mobility management. + +*/ + +GLOBAL void cc_est_cnf (void) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("cc_est_cnf()"); + + switch (cc_data->state[cc_data->index_ti]) + { + case M_CC_CS_01: + { + /* + * As CC may potentially do some ugly things like + * MAX_SETUP_ATTEMPTS > 1, we cannot use the stored + * SETUP or EMERGENCY SETUP message, but have to copy. + */ + PALLOC_SDU (data, MMCM_DATA_REQ, cc_data->stored_setup->sdu.l_buf); + + data->sdu.l_buf = cc_data->stored_setup->sdu.l_buf; + data->sdu.o_buf = cc_data->stored_setup->sdu.o_buf; + memcpy (&data->sdu.buf[data->sdu.o_buf >> 3], + &cc_data->stored_setup->sdu.buf[data->sdu.o_buf >> 3], + data->sdu.l_buf >> 3); + + /* Forward the SETUP or EMERGENCY SETUP message to MM */ + for_pd (data); + } + + cc_set_state (M_CC_CS_1); + srv_use_stored_prim (); + break; + + default: + break; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_reest_cnf | ++--------------------------------------------------------------------+ + + PURPOSE : Processing of an incoming re-establish confirm from + mobility management. + +*/ + +GLOBAL void cc_reest_cnf (void) +{ + GET_INSTANCE_DATA; + + PALLOC (sync, MNCC_SYNC_IND); + + TRACE_FUNCTION ("cc_reest_cnf()"); + + switch (cc_data->state[cc_data->index_ti]) + { + case CS_101: + sync->ti = cc_data->ti; + sync->cause = MNCC_CAUSE_REEST_FINISHED; + sync->ch_info.ch_mode = NOT_PRESENT_8BIT; + sync->ch_info.ch_type = NOT_PRESENT_8BIT; + PSENDX (MMI, sync); + + cc_set_state (M_CC_CS_10); + srv_use_stored_prim (); + break; + + case CS_261: + sync->ti = cc_data->ti; + sync->cause = MNCC_CAUSE_REEST_FINISHED; + sync->ch_info.ch_mode = NOT_PRESENT_8BIT; + sync->ch_info.ch_type = NOT_PRESENT_8BIT; + PSENDX (MMI, sync); + + TIMERSTART (T323, T323_VALUE); + cc_set_state (M_CC_CS_26); + srv_use_stored_prim (); + break; + + default: + PFREE (sync); + break; + } +} + +#ifdef SIM_TOOLKIT +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_mncc_bearer_cap_req | ++--------------------------------------------------------------------+ + + PURPOSE: Checks the compatibility of bearer capabilities. + Bearer capabilities in coded form are tranformed to + parameter form and vice versa. +*/ + +GLOBAL void cc_mncc_bearer_cap_req (T_MNCC_BEARER_CAP_REQ * bc_req) +{ + PALLOC (bc_conf, MNCC_BEARER_CAP_CNF); + + TRACE_FUNCTION ("cc_mncc_bearer_cap_req()"); + + /* Copy input parameters */ + bc_conf->req_id = bc_req->req_id; + bc_conf->bc_mod = bc_req->bc_mod; + + /* Set default values to no bcpara to set valid values in case cc_bearer_cap_decode returns OKAY */ + memset (&bc_conf->bcpara2, 0, sizeof (T_MNCC_bcpara)); + bc_conf->bcpara2.bearer_serv = MNCC_BEARER_SERV_NOT_PRES; + + if (bc_req->bc_mod EQ MNCC_BC_MOD_DECODE) + { + /* Transform coded form into parameter form */ + + /* Copy input parameters */ + bc_conf->bcconf = bc_req->bcconf; + bc_conf->bcconf2 = bc_req->bcconf2; + + if (cc_bearer_cap_decode(&bc_req->bcconf, + &bc_conf->bcpara) + EQ ERROR) + { + /* Bearer capabilities not supported */ + PFREE (bc_req); + bc_conf->cause = CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + MNCC_CAUSE_INCOMPAT_DEST); + PSENDX (MMI, bc_conf); + return; + } + + if (cc_bearer_cap_decode((T_MNCC_bcconf *)&bc_req->bcconf2, + (T_MNCC_bcpara *)&bc_conf->bcpara2) + EQ ERROR) + { + /* Bearer capabilities not supported */ + PFREE (bc_req); + bc_conf->cause = CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + MNCC_CAUSE_INCOMPAT_DEST); + PSENDX (MMI, bc_conf); + return; + } + } + else + { + /* Transform parameter form into coded form */ + + /* Copy input parameters */ + bc_conf->bcpara = bc_req->bcpara; + bc_conf->bcpara2 = bc_req->bcpara2; + + if (cc_bearer_cap_code(&bc_req->bcpara, + &bc_conf->bcconf) + EQ ERROR) + { + /* Bearer capabilities not supported */ + PFREE (bc_req); + bc_conf->cause = CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + MNCC_CAUSE_INCOMPAT_DEST); + PSENDX (MMI, bc_conf); + return; + } + + if (cc_bearer_cap_code((T_MNCC_bcpara *)&bc_req->bcpara2, + (T_MNCC_bcconf *)&bc_conf->bcconf2) + EQ ERROR) + { + /* Bearer capabilities not supported */ + PFREE (bc_req); + bc_conf->cause = CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + MNCC_CAUSE_INCOMPAT_DEST); + PSENDX (MMI, bc_conf); + return; + } + } + + bc_conf->cause = MNCC_CAUSE_SUCCESS; /* Positive result */ + PSENDX (MMI, bc_conf); + PFREE (bc_req); +} + +#endif /*SIM_TOOLKIT */ + + +/* Implements Measure# 3 and streamline encoding*/ +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_send_status | ++--------------------------------------------------------------------+ + + PURPOSE : Calls CCD Start and then cc_build_and_send_status + for sending status message +*/ +GLOBAL void cc_send_status (USHORT cause) +{ + TRACE_FUNCTION ("cc_send_status()"); + + CCD_START; + { + MCAST (status, B_STATUS); + cc_build_status (status, CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + cause)); + for_status (status); + } + CCD_END; +} + +/* Implements Measure# 19 */ +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_send_release_cmp | ++--------------------------------------------------------------------+ + + PURPOSE : Send release complete message. + +*/ + +LOCAL void cc_send_release_cmp (USHORT cause) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("cc_send_release_cmp()"); + + /* Send RELEASE COMPLETE */ + CCD_START; + { + MCAST (rel_com, U_RELEASE_COMP); + cc_build_release_complete (rel_com, cause); + for_release_complete (rel_com); + } + CCD_END; + + /* Inform MMI */ + { + PALLOC (release, MNCC_RELEASE_IND); + release->ti = cc_data->ti; + release->cause = cause; + release->c_raw_cause = cause; + PSENDX (MMI, release); + } + + /* Release MM connection */ + for_rel_req (); + + /* Next state is NULL */ + cc_set_state (M_CC_CS_0); + +} + +/* Implements Measure# 36, 48 */ +/* ++--------------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_EST | +| STATE : code ROUTINE : cc_send_mncc_release_ind | ++--------------------------------------------------------------------------+ + + PURPOSE : Send release complete message with cause invalid ti. + +*/ + +LOCAL void cc_send_mncc_release_ind(UBYTE ti, USHORT cause) +{ + TRACE_FUNCTION ("cc_send_mncc_release_ind"); + { + PALLOC (release, MNCC_RELEASE_IND); + release->ti = ti; + release->cause = cause; + release->c_raw_cause = 0; + PSENDX (MMI, release); + } +} +#endif