FreeCalypso > hg > fc-tourmaline
view src/g23m-gsm/cc/cc_rel.c @ 301:4bb5772a05a3
AT%SPVER: new command for setting custom speech version lists
The speech version list in the Bearer Capability IE tells the network
which speech codecs are supported by the MS, and in which order of
preference. The standard behaviour is to list all codecs that are
supported by the hw+fw platform, and the standard preference order
is newer over older, FR over HR. But sometimes it is desirable
(for network testing) to artificially restrict which codecs the test MS
will declare as supported, and/or to list them in some peculiar
non-standard order of preference. Add a new private AT command,
AT%SPVER, allowing the user to set and clear custom speech version
lists for the Bearer Capability IE composer in CC.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 21 May 2023 21:43:10 +0000 |
parents | fa8dc04885d8 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | 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