FreeCalypso > hg > freecalypso-sw
diff gsm-fw/g23m-gsm/cc/cc_rel.c @ 673:2f7df7a314f8
gsm-fw/g23m-gsm subtree: initial import from LoCosto source
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 28 Sep 2014 23:20:04 +0000 |
parents | |
children | 7204091241d0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gsm-fw/g23m-gsm/cc/cc_rel.c Sun Sep 28 23:20:04 2014 +0000 @@ -0,0 +1,1224 @@ +/* ++----------------------------------------------------------------------------- +| Project : GSM-PS (6147) +| Modul : CC_REL ++----------------------------------------------------------------------------- +| 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 call release +| of the component CC of the mobile station. ++----------------------------------------------------------------------------- +*/ + +#ifndef CC_REL_C +#define CC_REL_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 =====================================================*/ + +/*==== PROTOTYPES =================================================*/ +/* Implements Measure# 8 */ +LOCAL void cc_mncc_release_ind (T_PRIM * prim); +/* Implements Measure# 9 */ +LOCAL void cc_mncc_release_cnf (T_PRIM * prim); +/* Implements Measure# 41 */ +LOCAL void cc_mncc_sync_ind ( UBYTE ti, + UBYTE new_state); +/*==== PRIVAT =====================================================*/ + +/*==== VARIABLES ==================================================*/ + +/*==== FUNCTIONS ==================================================*/ + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_REL | +| STATE : code ROUTINE : cc_check_setup_reattempt | ++--------------------------------------------------------------------+ + + PURPOSE : This function checks whether a the mobile originated setup + may be reattempted. This will be done for some certain + reasons which may indicate network failure. + This function is considered as a hack only + for networks which tend to deliver a poor quality + of service only (e.g. typically in China). + This behaviour or the algorithm is not specified / implied + by GSM but driven by customer requests and the desire + to have a good, working product. +*/ + +LOCAL void cc_check_setup_reattempt ( const T_M_CC_cc_cause *cc_cause) +{ + GET_INSTANCE_DATA; + EXTERN BOOL poor_quality_network; + + TRACE_FUNCTION ("cc_check_setup_reattempt()"); + +#ifdef WIN32 + /* + * Set poor_quality_network for test, pei_config() is the appropriate place, + * but this seems not to be working for some strange reasons + */ + poor_quality_network = TRUE; +#endif + + /* reattempt already "running", see cc_setup_reattempt for further reasoning */ + if (cc_data->setup_reattempt_ti NEQ NOT_PRESENT_8BIT) + return; + + switch (cc_data->state[cc_data->index_ti]) + { + case M_CC_CS_1: /* call initiated */ + case M_CC_CS_3: /* mobile originating call proceeding */ + cc_data->setup_attempts++; + if (poor_quality_network AND + (cc_data->setup_attempts < MAX_SETUP_ATTEMPTS) AND + (cc_cause->v_cause)) + { + /* + * Mobile originated call got disconnect, + * max. number of setup attempts not reached. + * New dial attempt for certain disconnect reasons + */ + switch (cc_cause->cause) + { + case M_CC_CAUSE_NO_CHAN_AVAIL: /* #34 */ + case M_CC_CAUSE_NETWORK_ORDER: /* #38 */ + case M_CC_CAUSE_TEMP_FAIL: /* #41 */ + case M_CC_CAUSE_SWITCH_CONGEST: /* #42 */ + case M_CC_CAUSE_INFO_DISCARD: /* #43 */ + case M_CC_CAUSE_REQ_CHAN_UNAVAIL: /* #44 */ + case M_CC_CAUSE_RESOURCE_UNAVAIL: /* #47 */ + case M_CC_CAUSE_QOS_UNAVAIL: /* #49 */ + case M_CC_CAUSE_BEARER_CAP_UNAVAIL: /* #58 */ + case M_CC_CAUSE_TIMER: /* #102 */ + case M_CC_CAUSE_INTERWORKING: /* #127 */ + /* + * Maybe some more causes to added here + * which indicate network failure + */ + + /* try setup reattempt, remember this by setting setup_reattempt_ti */ + cc_data->setup_reattempt_ti = cc_data->ti; + break; + + default: /* Don't try setup reattempt, no appropriate cause */ + srv_free_stored_setup (); + break; + } + } + break; + + default: /* Don't try setup reattempt in other states */ + break; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_REL | +| STATE : code ROUTINE : cc_setup_reattempt | ++--------------------------------------------------------------------+ + + PURPOSE : This function reattempts the mobile originated setup + for some certain reasons which may indicate network + failure. This function is considered as a hack only + for networks which tend to deliver a poor quality + of service only. + +*/ + +LOCAL void cc_setup_reattempt (void) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("cc_setup_reattempt()"); + + if (cc_data->ti EQ cc_data->setup_reattempt_ti) + { + PALLOC (est, MMCM_ESTABLISH_REQ); /* T_MMCM_ESTABLISH_REQ */ + est->ti = cc_data->ti; + est->estcs = cc_data->estcs; + for_est_req (est); + + cc_data->setup_reattempt_ti = NOT_PRESENT_8BIT; + cc_data->progress_desc[cc_data->index_ti] = NOT_PRESENT_8BIT; + cc_set_state (M_CC_CS_01); + TIMERSTART (T303, T303_VALUE); + } +} + +/*==== VARIABLES ==================================================*/ + +/*==== FUNCTIONS ==================================================*/ +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_REL | +| STATE : code ROUTINE : cc_mncc_disconnect_req | ++--------------------------------------------------------------------+ + + PURPOSE : Disconnection of call by the mobile side. + +*/ + +GLOBAL void cc_mncc_disconnect_req (T_MNCC_DISCONNECT_REQ * disc) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("cc_mncc_disconnect_req()"); + + if ((cc_data->index_ti = srv_convert_ti (disc->ti)) + EQ NOT_PRESENT_8BIT) + { + PFREE (disc); + return; + } + if (cc_data->ti EQ cc_data->setup_reattempt_ti) + { + srv_free_stored_setup (); + } + switch (cc_data->state[cc_data->index_ti]) + { + case M_CC_CS_03: /* WAIT FOR NW. INFO */ + case M_CC_CS_05: /* CC ESTABLISHMENT CONFIRMED */ + case M_CC_CS_06: /* RECALL PRESENT */ + /* Forget stored CCBS setup */ + if (cc_data->stored_ccbs_setup NEQ NULL) + { + PFREE (cc_data->stored_ccbs_setup); + cc_data->stored_ccbs_setup = NULL; + } + + /* Send a (faked) MNCC_RELEASE_IND to MMI */ + { + PALLOC (rel, MNCC_RELEASE_IND); + rel->ti = disc->ti; + rel->cause = disc->cause; + rel->c_raw_cause = 0; + PSENDX (MMI, rel); + } + + /* Send RELEASE COMPLETE to network */ + CCD_START; + { + MCAST (rel_com, U_RELEASE_COMP); + cc_build_release_complete (rel_com, disc->cause); + for_release_complete (rel_com); + } + CCD_END; + + /* Release MM connection */ + for_rel_req (); + + PFREE (disc); + + /* Stop all running timers */ + TIMERSTOP (TIMER_CC); + + /* Next state is NULL */ + cc_set_state (M_CC_CS_0); + break; + + case M_CC_CS_01: + case CS_101: + case CS_261: + { + TIMERSTOP (TIMER_CC); + + cc_reset_dtmf (); + + { + PALLOC (rel, MNCC_RELEASE_IND); + rel->ti = disc->ti; + rel->cause = disc->cause; + rel->c_raw_cause = 0; + PSENDX (MMI, rel); + } + + for_rel_req (); + cc_set_state (M_CC_CS_0); + srv_use_stored_prim (); + PFREE (disc); + } + break; + + case M_CC_CS_1: + case M_CC_CS_3: + case M_CC_CS_4: + case M_CC_CS_7: + case M_CC_CS_8: + case M_CC_CS_9: + case M_CC_CS_10: + case M_CC_CS_26: + TIMERSTOP (TIMER_CC); + + CCD_START; + { + MCAST (disconnect, U_DISCONNECT); + + cc_build_disconnect (disconnect, disc->cause, + &disc->fac_inf, disc->ss_version); + cc_set_state (M_CC_CS_11); + for_disconnect (disconnect); + } + CCD_END; + TIMERSTART (T305, T305_VALUE); + PFREE (disc); + break; + + case M_CC_CS_12: /* DISCONNECT INDICATION, this is clear collision here */ + CCD_START; + { + MCAST (release, U_RELEASE); + + cc_build_release (release, disc->cause, + NULL, MNCC_SS_VER_NOT_PRES); + cc_set_state (M_CC_CS_19); + for_release (release); + + } + CCD_END; + TIMERSTART (T308, T308_VALUE); + PFREE (disc); + break; + + default: + PFREE (disc); + break; + + } +} +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_REL | +| STATE : code ROUTINE : cc_mncc_reject_req | ++--------------------------------------------------------------------+ + + PURPOSE : Release of call by the mobile side by sending + a RELEASE COMPLETE message. + +*/ + +GLOBAL void cc_mncc_reject_req (T_MNCC_REJECT_REQ * rej) +{ + GET_INSTANCE_DATA; + + TRACE_FUNCTION ("cc_mncc_reject_req"); + + if ((cc_data->index_ti = srv_convert_ti (rej->ti)) + EQ NOT_PRESENT_8BIT) + { + PFREE (rej); + return; + } + + if (cc_data->ti EQ cc_data->setup_reattempt_ti) + { + srv_free_stored_setup (); + } + + switch (cc_data->state[cc_data->index_ti]) + { + case M_CC_CS_03: /* WAIT FOR NW. INFO */ + case M_CC_CS_05: /* CC ESTABLISHMENT CONFIRMED */ + case M_CC_CS_06: /* RECALL PRESENT */ + /* Forget stored CCBS setup */ + if (cc_data->stored_ccbs_setup NEQ NULL) + { + PFREE (cc_data->stored_ccbs_setup); + cc_data->stored_ccbs_setup = NULL; + } + + /* Send RELEASE COMPLETE */ + CCD_START; + { + MCAST (rel_com, U_RELEASE_COMP); + cc_build_release_complete (rel_com, rej->cause); + for_release_complete (rel_com); + } + CCD_END; + + /* Release MM connection */ + for_rel_req (); + + PFREE (rej); + + /* Stop all running timers */ + TIMERSTOP (TIMER_CC); + + /* Next state is NULL */ + cc_set_state (M_CC_CS_0); + break; + default: + PFREE (rej); + break; + } +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_REL | +| STATE : code ROUTINE : cc_mncc_release_req | ++--------------------------------------------------------------------+ + + PURPOSE : Release of call by the mobile side. + +*/ +GLOBAL void cc_mncc_release_req (T_MNCC_RELEASE_REQ * rel) +{ + GET_INSTANCE_DATA; + + TRACE_FUNCTION ("cc_mncc_release_req()"); + + if ((cc_data->index_ti = srv_convert_ti (rel->ti)) + EQ NOT_PRESENT_8BIT) + { + PFREE (rel); + return; + } + + if (cc_data->ti EQ cc_data->setup_reattempt_ti) + { + srv_free_stored_setup (); + } + + switch (cc_data->state[cc_data->index_ti]) + { + case M_CC_CS_12: /* DISCONNECT INDICATION */ + + CCD_START; + { + MCAST (release, U_RELEASE); + + cc_build_release (release, rel->cause, + &rel->fac_inf, rel->ss_version); + cc_set_state (M_CC_CS_19); + for_release (release); + + } + CCD_END; + TIMERSTART (T308, T308_VALUE); + PFREE (rel); + break; + + default: + PFREE (rel); + break; + + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_REL | +| STATE : code ROUTINE : cc_disconnect | ++--------------------------------------------------------------------+ + + PURPOSE : Processing an incoming disconnect message. + +*/ + +GLOBAL void cc_disconnect (T_D_DISCONNECT * disconnect) +{ + GET_INSTANCE_DATA; + + TRACE_FUNCTION ("cc_disconnect()"); + + /* The cause is in DISCONNECT a mandatory IE (given intact message) */ + TRACE_EVENT_P1 ("DISCONNECT cause: %02x", disconnect->cc_cause.cause); + + EM_CC_DISCONNECT_RECEIVED; + + switch (cc_data->state[cc_data->index_ti]) + { + case M_CC_CS_11: /* DISCONNECT REQUEST, this is clear collision here */ + CCD_END; + CCD_START; + { + MCAST (release, U_RELEASE); + + TIMERSTOP (TIMER_CC); + /* PATCH LE 10.04.00 + * set disconnect collision flag + */ + cc_data->disc_coll [cc_data->index_ti] = TRUE; + /* END PATCH LE 10.04.00 */ + + switch (cc_data->error) + { + case M_CC_CAUSE_INVALID_MAND_INFO: + case M_CC_CAUSE_COND_INFO_ELEM: + cc_build_release (release, CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + cc_data->error), + NULL, MNCC_SS_VER_NOT_PRES); + cc_set_state (M_CC_CS_19); + for_release (release); + TIMERSTART (T308, T308_VALUE); + break; + + default: + if (disconnect->v_progress) + { + cc_data->progress_desc[cc_data->index_ti] = + disconnect->progress.progress_desc; + } + cc_build_release (release, CAUSE_MAKE(DEFBY_CONDAT, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + NOT_PRESENT_8BIT), + NULL, MNCC_SS_VER_NOT_PRES); + cc_set_state (M_CC_CS_19); + for_release (release); + TIMERSTART (T308, T308_VALUE); + break; + } + } + CCD_END; + break; + + case M_CC_CS_12: /* DISCONNECT INDICATION */ + case M_CC_CS_19: /* RELEASE REQUEST */ + /* NULL (M_CC_CS_0) is handled by the formatter */ + CCD_END; +/* Implements Measure# 3 and streamline encoding */ + cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT); + break; + + default: + /* any "normal" state */ + TIMERSTOP (TIMER_CC); + + switch (cc_data->error) + { + case M_CC_CAUSE_INVALID_MAND_INFO: + case M_CC_CAUSE_COND_INFO_ELEM: + CCD_END; + CCD_START; + { + USHORT curr_cause; /* local variable to avoid repeated CAUSE_MAKEs for the same cause */ + + MCAST (release, U_RELEASE); + PALLOC (disc_ind, MNCC_DISCONNECT_IND); + + disc_ind->ti = cc_data->ti; + curr_cause = CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + cc_data->error); + disc_ind->cause = curr_cause; + /* Setting raw_cause to empty as this is a local release + * of MM connection,CC is not receiving any cause value + * from Network + */ + disc_ind->c_raw_cause = 0; + + disc_ind->diagnostic = NOT_PRESENT_8BIT; + disc_ind->progress_desc = MNCC_PROG_NOT_PRES; + /* CQ 23619: get the ss diagnostic >> */ + disc_ind->ss_diag = MNCC_SS_DIAG_NOT_PROVIDED; + /* CQ 23619 << */ + PSENDX (MMI, disc_ind); + + /* Patch HM 29-Jan-02 >>> */ + cc_build_facility_ind (MNCC_FAC_IN_DISCONNECT, + disconnect->v_facility, &disconnect->facility); + /* Patch HM 29-Jan-02 <<< */ + cc_build_release (release, cc_data->error, + NULL, MNCC_SS_VER_NOT_PRES); + cc_set_state (M_CC_CS_19); + for_release (release); + TIMERSTART (T308, T308_VALUE); + } + CCD_END; + break; + + default: + if (disconnect->v_progress) + { + cc_data->progress_desc[cc_data->index_ti] = + disconnect->progress.progress_desc; + } + cc_check_setup_reattempt (&disconnect->cc_cause); + + if (cc_data->ti NEQ cc_data->setup_reattempt_ti) + { + /* + * We don't perform setup reattempt, so send disconnect to MMI + */ + USHORT curr_cause; /* local variable to avoid repeated CAUSE_MAKEs for the same cause */ + PALLOC (disc_ind, MNCC_DISCONNECT_IND); /* T_MNCC_DISCONNECT_IND */ + disc_ind->ti = cc_data->ti; + disc_ind->cause = curr_cause = CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_NET, + MNCC_CC_ORIGINATING_ENTITY, + disconnect->cc_cause.cause); + disc_ind->c_raw_cause = cc_build_cause (&disconnect->cc_cause, + disc_ind->raw_cause); + disc_ind->diagnostic = NOT_PRESENT_8BIT; + + if (disconnect->v_progress) + disc_ind->progress_desc = disconnect->progress.progress_desc; + else + disc_ind->progress_desc = MNCC_PROG_NOT_PRES; + + /* Handle CCBS possible flag */ + if ((cc_data->call_ctrl_cap.pcp NEQ 0) AND + (disconnect->v_allowed_actions NEQ 0) AND + (disconnect->allowed_actions.ccbs_act EQ M_CC_CCBS_YES)) + { + /* CCBS indicated as possible by the network */ + disc_ind->diagnostic = MNCC_DIAG_CCBS_POSSIBLE; + } + /* CQ 23619: get the ss diagnostic */ + disc_ind->ss_diag = cc_get_ss_diag(curr_cause, disconnect); + /* CQ 23619 << */ + PSENDX (MMI, disc_ind); + /* Patch HM 29-Jan-02 >>> */ + cc_build_facility_ind (MNCC_FAC_IN_DISCONNECT, + disconnect->v_facility, &disconnect->facility); + /* Patch HM 29-Jan-02 <<< */ + } + if ((cc_data->ti NEQ cc_data->setup_reattempt_ti) AND + (((disconnect->v_progress AND + (disconnect->progress.progress_desc EQ M_CC_PROG_INBAND_AVAIL) AND + (cc_data->channel_mode != NAS_CHM_SIG_ONLY))) + OR + ((cc_data->call_ctrl_cap.pcp NEQ 0) AND + (disconnect->v_allowed_actions NEQ 0) AND + (disconnect->allowed_actions.ccbs_act EQ M_CC_CCBS_YES)))) + { + /* + * Hook on tone is generated by the + * infrastructure and signalled via TCH OR CCBS is possible + */ + CCD_END; + cc_set_state (M_CC_CS_12); + } + else + { + CCD_END; + CCD_START; + { + MCAST (release, U_RELEASE); + + /* + * Hook on tone is generated internally by the mobile station + * and no CCBS possible, the connection is released + */ + cc_build_release (release, CAUSE_MAKE(DEFBY_CONDAT, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + NOT_PRESENT_8BIT), + NULL, MNCC_SS_VER_NOT_PRES); + cc_set_state (M_CC_CS_19); + for_release (release); + TIMERSTART (T308, T308_VALUE); + } + CCD_END; + } + break; + } + break; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_REL | +| STATE : code ROUTINE : cc_release | ++--------------------------------------------------------------------+ + + PURPOSE : Processing an incoming release message. + +*/ + +GLOBAL void cc_release (T_D_RELEASE * release) +{ + GET_INSTANCE_DATA; + + TRACE_FUNCTION ("cc_release()"); + + if (release->cc_cause.v_cause) + { + /* The cause is in RELEASE an optional IE */ + TRACE_EVENT_P1 ("RELEASE cause: %02x", release->cc_cause.cause); + } + else + { + TRACE_EVENT ("RELEASE cause: --"); + } + + switch (cc_data->state[cc_data->index_ti]) + { + /* + * M_CC_CS_0 is handled by the formatter + */ + case M_CC_CS_19: /* Release Request */ + { + cc_reset_dtmf (); + /* PATCH LE 10.04.00 + * in disconnect collision case send + * MNCC_RELEASE_IND instead of MNCC_RELEASE_CNF +.... */ + TIMERSTOP (TIMER_CC); + if (cc_data->disc_coll [cc_data->index_ti]) + { +/* Implements Measure# 8 */ + cc_mncc_release_ind ((T_PRIM *)D2P(release)); + } + else + { +/* Implements Measure# 9 */ + cc_mncc_release_cnf ((T_PRIM *)D2P(release)); + } + // END PATCH LE 10.04.00 + + for_rel_req (); + cc_set_state (M_CC_CS_0); + /* END PATCH LE 10.04.00 */ + CCD_END; + break; + } + + case M_CC_CS_1: /* call initiated */ + case M_CC_CS_3: /* mobile originating call proceeding */ + cc_check_setup_reattempt (&release->cc_cause); + /*FALLTHROUGH*/ /*lint -fallthrough*/ + default: + cc_reset_dtmf (); /* China change HM 11.07.00 */ + CCD_END; + CCD_START; + { + MCAST (rel_com, U_RELEASE_COMP); + + TIMERSTOP (TIMER_CC); + switch (cc_data->error) + { + case M_CC_CAUSE_INVALID_MAND_INFO: + case M_CC_CAUSE_COND_INFO_ELEM: + { + USHORT curr_cause; /* local variable to avoid repeated CAUSE_MAKEs for the same cause */ + curr_cause = CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + cc_data->error); + + if (cc_data->ti NEQ cc_data->setup_reattempt_ti) + { + PALLOC (rel_ind, MNCC_RELEASE_IND); + rel_ind->ti = cc_data->ti; + rel_ind->cause = curr_cause; + rel_ind->c_raw_cause = 0; + PSENDX (MMI, rel_ind); + } + cc_build_release_complete (rel_com, curr_cause); + } + break; + + default: + if (cc_data->ti NEQ cc_data->setup_reattempt_ti) + { +/* Implements Measure# 8 */ + cc_mncc_release_ind ((T_PRIM *)D2P(release)); + } + cc_build_release_complete (rel_com, CAUSE_MAKE(DEFBY_CONDAT, + ORIGSIDE_MS, + MNCC_CC_ORIGINATING_ENTITY, + NOT_PRESENT_8BIT)); + break; + } + + for_release_complete (rel_com); + } + CCD_END; + for_rel_req (); + cc_set_state (M_CC_CS_0); + cc_setup_reattempt (); + break; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_REL | +| STATE : code ROUTINE : cc_release_complete | ++--------------------------------------------------------------------+ + + PURPOSE : Processing an incoming release complete message. + +*/ + +GLOBAL void cc_release_complete (T_D_RELEASE_COMP * rel_com) +{ + GET_INSTANCE_DATA; + + TRACE_FUNCTION ("cc_release_complete()"); + + if (rel_com->cc_cause.v_cause) + { + /* The cause is in RELEASE COMPLETE an optional IE */ + TRACE_EVENT_P1 ("RELEASE COMPLETE cause: %02x", rel_com->cc_cause.cause); + } + else + { + TRACE_EVENT ("RELEASE COMPLETE cause: --"); + } + + EM_CC_RELEASE_COMPLETE_RECEIVED; + + switch (cc_data->state[cc_data->index_ti]) + { + case M_CC_CS_0: /* NULL */ + CCD_END; + for_rel_req (); + break; + + case M_CC_CS_03: /* WAIT FOR NETWORK INFO*/ + /* Stop all running CC timers */ + TIMERSTOP (TIMER_CC); + + /* Inform MMI */ + { + PALLOC (release, MNCC_RELEASE_IND); + release->ti = cc_data->ti; + if (rel_com->v_cc_cause AND rel_com->cc_cause.v_cause) + { + release->cause = CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_NET, + MNCC_CC_ORIGINATING_ENTITY, + rel_com->cc_cause.cause); + release->c_raw_cause = cc_build_cause (&rel_com->cc_cause, + release->raw_cause); + } + else + { + release->cause = CAUSE_MAKE(DEFBY_CONDAT, + ORIGSIDE_NET, + MNCC_CC_ORIGINATING_ENTITY, + NOT_PRESENT_8BIT); + release->c_raw_cause = 0; + } + PSENDX (MMI, release); + } + + CCD_END; + + /* Release MM connection */ + for_rel_req (); + + /* Next state is NULL */ + cc_set_state (M_CC_CS_0); + break; + + case M_CC_CS_05: /* CC ESTABLISHMENT CONFIRMED */ + case M_CC_CS_06: /* RECALL PRESENT */ + /* Forget stored CCBS setup */ + PFREE (cc_data->stored_ccbs_setup); + cc_data->stored_ccbs_setup = NULL; + + /* Stop all running CC timers */ + TIMERSTOP (TIMER_CC); + + /* Inform MMI */ + { + PALLOC (release, MNCC_RELEASE_IND); + release->ti = cc_data->ti; + if (rel_com->v_cc_cause AND rel_com->cc_cause.v_cause) + { + release->cause = CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_NET, + MNCC_CC_ORIGINATING_ENTITY, + rel_com->cc_cause.cause); + release->c_raw_cause = cc_build_cause (&rel_com->cc_cause, + release->raw_cause); + } + else + { + release->cause = CAUSE_MAKE(DEFBY_CONDAT, + ORIGSIDE_NET, + MNCC_CC_ORIGINATING_ENTITY, + NOT_PRESENT_8BIT); + release->c_raw_cause = 0; + } + PSENDX (MMI, release); + } + + CCD_END; + + /* Release MM connection */ + for_rel_req (); + + /* Next state is NULL */ + cc_set_state (M_CC_CS_0); + break; + + case M_CC_CS_19: /* RELEASE REQUEST */ + cc_reset_dtmf (); + /* PATCH LE 10.04.00 + * in disconnect collision case send + * MNCC_RELEASE_IND instead of MNCC_RELEASE_CNF + */ + TIMERSTOP (TIMER_CC); + + if (cc_data->ti NEQ cc_data->setup_reattempt_ti) + { + /* Inform MMI only if no setup reattempt for this ti */ + if (cc_data->disc_coll [cc_data->index_ti]) + { +/* Implements Measure# 9 */ + cc_mncc_release_ind ((T_PRIM *)D2P(rel_com)); + } + else + { +/* Implements Measure# 9 */ + cc_mncc_release_cnf ((T_PRIM *)D2P(rel_com)); + } + /* END PATCH LE 10.04.00 */ + + } + + for_rel_req (); + cc_set_state (M_CC_CS_0); + CCD_END; + cc_setup_reattempt (); + break; + + case M_CC_CS_1: /* call initiated */ + case M_CC_CS_3: /* mobile originating call proceeding */ + cc_check_setup_reattempt (&rel_com->cc_cause); + /*FALLTHROUGH*/ /*lint -fallthrough*/ + default: + cc_reset_dtmf (); /* China change HM 11.07.00 */ + if (cc_data->ti NEQ cc_data->setup_reattempt_ti) + { + /* Implements Measure# 10 */ + cc_mncc_release_ind ((T_PRIM *)D2P(rel_com)); + } + for_rel_req (); + CCD_END; + cc_set_state (M_CC_CS_0); + cc_setup_reattempt (); + break; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_REL | +| STATE : code ROUTINE : cc_rel_ind | ++--------------------------------------------------------------------+ + + PURPOSE : Processing of an incoming release indication from + mobility management. + +*/ + +GLOBAL void cc_rel_ind (USHORT cause) +{ + GET_INSTANCE_DATA; + + TRACE_FUNCTION ("cc_rel_ind()"); + + switch (cc_data->state[cc_data->index_ti]) + { + case M_CC_CS_0: + break; + + case M_CC_CS_05: /* CC ESTABLISHMENT CONFIRMED */ + case M_CC_CS_06: /* RECALL PRESENT */ + /* Stop all timers */ + TIMERSTOP (TIMER_CC); + + /* Forget stored CCBS setup message */ + PFREE (cc_data->stored_ccbs_setup); + cc_data->stored_ccbs_setup = NULL; + + /* Inform MMI */ + { + PALLOC (release, MNCC_RELEASE_IND); + release->ti = cc_data->ti; + release->cause = cause; /* provide cause from lower layers transparently to higher layers */ + release->c_raw_cause = 0; + PSENDX (MMI, release); + } + + cc_set_state (M_CC_CS_0); + srv_use_stored_prim (); + break; + + case CS_101: /* Re-establishment request in state M_CC_CS_10 */\ + case CS_261: /* Re-establishment request in state CS_26 */\ + EM_CC_REESTABLISHED_FAILED; + /*FALLTHROUGH*/ /*lint -fallthrough*/ + + default: + cc_reset_dtmf (); /* China change HM 11.07.00 */ + if (cc_data->ti NEQ cc_data->setup_reattempt_ti) + { + PALLOC (rej_ind, MNCC_REJECT_IND); + rej_ind->ti = cc_data->ti; + rej_ind->cause = cause; + PSENDX (MMI, rej_ind); + } + + cc_set_state (M_CC_CS_0); + if (cc_data->ti EQ cc_data->setup_reattempt_ti) + { + cc_setup_reattempt(); + } + else + { + srv_use_stored_prim (); + } + break; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_REL | +| STATE : code ROUTINE : cc_err_ind | ++--------------------------------------------------------------------+ + + PURPOSE : Processing of an incoming error indication from + mobility management. + +*/ + +GLOBAL void cc_err_ind (T_MMCM_ERROR_IND * err_ind) +{ + GET_INSTANCE_DATA; + + TRACE_FUNCTION ("cc_err_ind()"); + + switch (cc_data->state[cc_data->index_ti]) + { + case M_CC_CS_0: + break; + + case M_CC_CS_10: + { +/* Implements Measure# 41 */ + cc_mncc_sync_ind(err_ind->ti, CS_101); + + EM_CC_REESTABLISHED_STARTED; + + } + break; + + case M_CC_CS_26: + { +/* Implements Measure# 41 */ + cc_mncc_sync_ind(err_ind->ti, CS_261); + + EM_CC_REESTABLISHED_STARTED; + + } + break; + + default: + cc_reset_dtmf (); + if (cc_data->ti NEQ cc_data->setup_reattempt_ti) + { + PALLOC (rel_ind, MNCC_RELEASE_IND); + rel_ind->cause = err_ind->cause; + rel_ind->ti = cc_data->ti; + rel_ind->c_raw_cause = 0; + PSENDX (MMI, rel_ind); + } + cc_set_state (M_CC_CS_0); + for_rel_req (); + cc_setup_reattempt (); + break; + } + PFREE (err_ind); +} +/* Implements Measure# 8 */ +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_REL | +| STATE : code ROUTINE : cc_mncc_release_ind | ++--------------------------------------------------------------------+ + + PURPOSE : send mncc_release_ind + +*/ + +LOCAL void cc_mncc_release_ind (T_PRIM * prim) +{ + GET_INSTANCE_DATA; + UBYTE v_cc_cause; + T_M_CC_cc_cause *cc_cause; + + TRACE_FUNCTION ("cc_mncc_release_ind()"); + + if (prim->custom.opc EQ D_RELEASE) + { + v_cc_cause = ((T_D_RELEASE *)P2D(prim))->v_cc_cause; + cc_cause = &((T_D_RELEASE *)P2D(prim))->cc_cause; + cc_build_facility_ind (MNCC_FAC_IN_RELEASE, + ((T_D_RELEASE *)P2D(prim))->v_facility, + &((T_D_RELEASE *)P2D(prim))->facility); + } + else + { + v_cc_cause = ((T_D_RELEASE_COMP *)P2D(prim))->v_cc_cause; + cc_cause = &((T_D_RELEASE_COMP *)P2D(prim))->cc_cause; + cc_build_facility_ind (MNCC_FAC_IN_RELEASE_COMP, + ((T_D_RELEASE_COMP *)P2D(prim))->v_facility, + &((T_D_RELEASE_COMP *)P2D(prim))->facility); + } + + /* Patch HM 29-Jan-02 <<< */ + { + PALLOC (rel_ind, MNCC_RELEASE_IND); + rel_ind->ti = cc_data->ti; + if (v_cc_cause) + { + rel_ind->cause = CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_NET, + MNCC_CC_ORIGINATING_ENTITY, + cc_cause->cause); + rel_ind->c_raw_cause = cc_build_cause (cc_cause, + rel_ind->raw_cause); + } + else + { + rel_ind->cause = CAUSE_MAKE(DEFBY_CONDAT, + ORIGSIDE_NET, + MNCC_CC_ORIGINATING_ENTITY, + NOT_PRESENT_8BIT); + /* Setting raw_cause to empty as this is a local release + * of MM connection,CC is not receiving any cause value + * from Network + */ + rel_ind->c_raw_cause = 0; + } + PSENDX (MMI, rel_ind); + } +} + +/* Implements Measure# 9 */ +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_REL | +| STATE : code ROUTINE : cc_mncc_release_cnf | ++--------------------------------------------------------------------+ + + PURPOSE : send mncc_release_cnf + +*/ + +LOCAL void cc_mncc_release_cnf (T_PRIM * prim) +{ + GET_INSTANCE_DATA; + UBYTE v_cc_cause; + T_M_CC_cc_cause *cc_cause; + + TRACE_FUNCTION ("cc_mncc_release_cnf()"); + + if (prim->custom.opc EQ D_RELEASE) + { + v_cc_cause = ((T_D_RELEASE *)P2D(prim))->v_cc_cause; + cc_cause = &((T_D_RELEASE *)P2D(prim))->cc_cause; + cc_build_facility_ind (MNCC_FAC_IN_RELEASE_COMP, /* A little bit dirty */ + ((T_D_RELEASE *)P2D(prim))->v_facility, + &((T_D_RELEASE *)P2D(prim))->facility); + } + else + { + v_cc_cause = ((T_D_RELEASE_COMP *)P2D(prim))->v_cc_cause; + cc_cause = &((T_D_RELEASE_COMP *)P2D(prim))->cc_cause; + cc_build_facility_ind (MNCC_FAC_IN_RELEASE_COMP, + ((T_D_RELEASE_COMP *)P2D(prim))->v_facility, + &((T_D_RELEASE_COMP *)P2D(prim))->facility); + } + + /* Patch HM 29-Jan-02 <<< */ + { + PALLOC (rel_cnf, MNCC_RELEASE_CNF); + rel_cnf->ti = cc_data->ti; + if (v_cc_cause) + { + rel_cnf->cause = CAUSE_MAKE(DEFBY_STD, + ORIGSIDE_NET, + MNCC_CC_ORIGINATING_ENTITY, + cc_cause->cause); + rel_cnf->c_raw_cause = cc_build_cause (cc_cause, + rel_cnf->raw_cause); + } + else + { + rel_cnf->cause = CAUSE_MAKE(DEFBY_CONDAT, + ORIGSIDE_NET, + MNCC_CC_ORIGINATING_ENTITY, + NOT_PRESENT_8BIT); + /* Setting raw_cause to empty as this is a local release + * of MM connection,CC is not receiving any cause value + * from Network + */ + rel_cnf->c_raw_cause = 0; + } + PSENDX (MMI, rel_cnf); + } +} + + +/* Implements Measure# 41 */ +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CC_REL | +| STATE : code ROUTINE : cc_mncc_sync_ind | ++--------------------------------------------------------------------+ + + PURPOSE : send cc_mncc_sync_ind + +*/ + +LOCAL void cc_mncc_sync_ind (UBYTE ti, UBYTE new_state) +{ + TRACE_FUNCTION ("cc_mncc_sync_ind()"); + { + PALLOC (sync_ind, MNCC_SYNC_IND); /* T_MNCC_SYNC_IND */ + + sync_ind->ti = ti; + sync_ind->cause = MNCC_CAUSE_REEST_STARTED; + sync_ind->ch_info.ch_mode=NOT_PRESENT_8BIT; + sync_ind->ch_info.ch_type=NOT_PRESENT_8BIT; + + PSENDX (MMI, sync_ind); + + for_reest_req (); + cc_set_state (new_state); + } + +} +#endif