aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2021-04-12 20:19:30 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2021-04-19 12:12:31 +0200
commit5bc54d6ce88fb25bfd211d1659b2aa366ae8077e (patch)
treef101b718432eb3105d128fe05767e80acdf20729
parent6be9e42a1d56d0c00c6e85920005f26dab3c6daf (diff)
Send EUTRAN neighs based on whether Common Id msg contained Last used E-UTRAN PLMN ID
From 3GPP TS 48.008 sec 3.1.30 "Common ID": """ If the SCCP connection is established due to CSFB from E-UTRAN and the MSC supports return to the last used PLMN after CS fallback, then it should send the COMMON ID message to the BSS including the Last used E-UTRAN PLMN ID information element if available at the MSC immediately following the successful SCCP connection setup. """ Furthermore, 3GPP TS 48.008 version 16.0.0 Release 16 "3.2.1.21 CLEAR COMMAND", for field CSFB Indication, states: """ NOTE: This information element doesn't serve any useful purpose. MSCs should not send the information element unless it is required by the recipients (due to the need to interwork with older versions of the protocol). It is expected that in future versions of the present document, this information element will be deleted from this message. """ Hence, build up the EUTRAN neighbor list based on whether we received the Last E-UTRAN PLMN ID IE during Common Id. In the future, we should probably filter the list while populating it based on the received IE. This change will also allow reusing same mechanism for SRVCC EUTRAN->GERAN support, where te Last E-UTRAN PLMN ID IE can be found inside "Old BSS to New BSS information" IE in msg HANDOVER REQUEST. Related: SYS#5337 Change-Id: I5d290ac55eca5adde1c33396422f4c10b83c03d5
-rw-r--r--include/osmocom/bsc/bsc_subscr_conn_fsm.h13
-rw-r--r--include/osmocom/bsc/gsm_data.h8
-rw-r--r--include/osmocom/bsc/lchan_fsm.h3
-rw-r--r--src/osmo-bsc/abis_rsl.c5
-rw-r--r--src/osmo-bsc/assignment_fsm.c5
-rw-r--r--src/osmo-bsc/bsc_subscr_conn_fsm.c17
-rw-r--r--src/osmo-bsc/bsc_vty.c4
-rw-r--r--src/osmo-bsc/gsm_04_08_rr.c10
-rw-r--r--src/osmo-bsc/gsm_08_08.c3
-rw-r--r--src/osmo-bsc/handover_fsm.c8
-rw-r--r--src/osmo-bsc/lchan_fsm.c23
-rw-r--r--src/osmo-bsc/osmo_bsc_bssap.c22
-rw-r--r--tests/handover/handover_test.c2
13 files changed, 76 insertions, 47 deletions
diff --git a/include/osmocom/bsc/bsc_subscr_conn_fsm.h b/include/osmocom/bsc/bsc_subscr_conn_fsm.h
index 142d535c2..a681bc4aa 100644
--- a/include/osmocom/bsc/bsc_subscr_conn_fsm.h
+++ b/include/osmocom/bsc/bsc_subscr_conn_fsm.h
@@ -2,6 +2,7 @@
#include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/core/fsm.h>
+#include "osmocom/bsc/gsm_data.h"
#define BSUB_USE_CONN "conn"
@@ -48,11 +49,6 @@ enum gscon_fsm_event {
GSCON_EV_LCS_LOC_REQ_END,
};
-struct gscon_clear_cmd_data {
- enum gsm0808_cause cause_0808;
- bool is_csfb;
-};
-
struct gsm_subscriber_connection;
struct gsm_network;
struct msgb;
@@ -93,3 +89,10 @@ void gscon_forget_mgw_endpoint_ci(struct gsm_subscriber_connection *conn, struct
bool gscon_is_aoip(struct gsm_subscriber_connection *conn);
bool gscon_is_sccplite(struct gsm_subscriber_connection *conn);
+
+
+static inline const struct osmo_plmn_id *gscon_last_eutran_plmn(const struct gsm_subscriber_connection *conn)
+{
+ return (conn && conn->last_eutran_plmn_valid) ?
+ &conn->last_eutran_plmn : NULL;
+}
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 2a9da26bc..448098b9b 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -334,6 +334,9 @@ struct gsm_subscriber_connection {
struct gsm48_classmark3 cm3;
bool cm3_valid;
+
+ bool last_eutran_plmn_valid;
+ struct osmo_plmn_id last_eutran_plmn;
};
@@ -614,6 +617,8 @@ struct gsm_lchan {
bool requested;
bool do_rr_release;
enum gsm48_rr_cause rr_cause;
+ bool last_eutran_plmn_valid;
+ struct osmo_plmn_id last_eutran_plmn;
/* There is an RSL error cause of value 0, so we need a separate flag. */
bool in_error;
@@ -623,9 +628,6 @@ struct gsm_lchan {
/* If a release event is being handled, ignore other ricocheting release events until that
* release handling has concluded. */
bool in_release_handler;
-
- /* is this release at the end of a CSFB call? */
- bool is_csfb;
} release;
/* The logical channel type */
diff --git a/include/osmocom/bsc/lchan_fsm.h b/include/osmocom/bsc/lchan_fsm.h
index 9fe7db107..ded7f5481 100644
--- a/include/osmocom/bsc/lchan_fsm.h
+++ b/include/osmocom/bsc/lchan_fsm.h
@@ -53,7 +53,8 @@ void lchan_fsm_init();
void lchan_fsm_alloc(struct gsm_lchan *lchan);
void lchan_release(struct gsm_lchan *lchan, bool do_rr_release,
- bool err, enum gsm48_rr_cause cause_rr);
+ bool err, enum gsm48_rr_cause cause_rr,
+ const struct osmo_plmn_id *last_eutran_plmn);
void lchan_activate(struct gsm_lchan *lchan, struct lchan_activate_info *info);
void lchan_ready_to_switch_rtp(struct gsm_lchan *lchan);
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index 6445b6deb..20fb759e9 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -998,7 +998,7 @@ static int rsl_rx_conn_fail(struct msgb *msg)
* the connection will presumably be torn down and lead to an lchan release. During initial
* Channel Request from the MS, an lchan has no conn yet, so in that case release now. */
if (!lchan->conn)
- lchan_release(lchan, false, true, *cause_p);
+ lchan_release(lchan, false, true, *cause_p, NULL);
else
osmo_fsm_inst_dispatch(lchan->conn->fi, GSCON_EV_RSL_CONN_FAIL, (void*)cause_p);
@@ -1672,7 +1672,8 @@ static bool force_free_lchan_for_emergency(struct chan_rqd *rqd)
"CHAN RQD/EMERGENCY-PRIORITY: inducing termination of lchan %s (state:%s) in favor of incoming EMERGENCY CALL!\n",
gsm_lchan_name(rqd->release_lchan), osmo_fsm_inst_state_name(rqd->release_lchan->fi));
- lchan_release(rqd->release_lchan, !!(rqd->release_lchan->conn), true, 0);
+ lchan_release(rqd->release_lchan, !!(rqd->release_lchan->conn), true, 0,
+ gscon_last_eutran_plmn(rqd->release_lchan->conn));
} else {
/* BTS is shutting down, give up... */
if (rqd->release_lchan->ts->fi->state == TS_ST_NOT_INITIALIZED)
diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c
index 2f241e3c3..faaec535e 100644
--- a/src/osmo-bsc/assignment_fsm.c
+++ b/src/osmo-bsc/assignment_fsm.c
@@ -117,7 +117,7 @@ void assignment_reset(struct gsm_subscriber_connection *conn)
if (conn->assignment.new_lchan) {
struct gsm_lchan *lchan = conn->assignment.new_lchan;
conn->assignment.new_lchan = NULL;
- lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL);
+ lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL, NULL);
}
if (conn->assignment.created_ci_for_msc) {
@@ -262,7 +262,8 @@ static void assignment_success(struct gsm_subscriber_connection *conn)
if (!conn->assignment.fi) {
/* The lchan was ready, and we failed to tell the MSC about it. By releasing this lchan,
* the conn will notice that its primary lchan is gone and should clean itself up. */
- lchan_release(conn->lchan, true, true, RSL_ERR_EQUIPMENT_FAIL);
+ lchan_release(conn->lchan, true, true, RSL_ERR_EQUIPMENT_FAIL,
+ gscon_last_eutran_plmn(conn));
return;
}
diff --git a/src/osmo-bsc/bsc_subscr_conn_fsm.c b/src/osmo-bsc/bsc_subscr_conn_fsm.c
index a0c53cb84..f169c3247 100644
--- a/src/osmo-bsc/bsc_subscr_conn_fsm.c
+++ b/src/osmo-bsc/bsc_subscr_conn_fsm.c
@@ -195,7 +195,8 @@ static void gscon_release_lchan(struct gsm_subscriber_connection *conn, struct g
conn->ho.new_lchan = NULL;
if (conn->assignment.new_lchan == lchan)
conn->assignment.new_lchan = NULL;
- lchan_release(lchan, do_rr_release, err, cause_rr);
+ lchan_release(lchan, do_rr_release, err, cause_rr,
+ gscon_last_eutran_plmn(conn));
}
void gscon_release_lchans(struct gsm_subscriber_connection *conn, bool do_rr_release, enum gsm48_rr_cause cause_rr)
@@ -808,7 +809,7 @@ void gscon_forget_mgw_endpoint_ci(struct gsm_subscriber_connection *conn, struct
static void gscon_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
struct gsm_subscriber_connection *conn = fi->priv;
- const struct gscon_clear_cmd_data *ccd;
+ const enum gsm0808_cause *cause_0808;
const struct tlv_parsed *tp;
struct osmo_mobile_identity mi_imsi;
@@ -826,14 +827,12 @@ static void gscon_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *d
osmo_fsm_inst_dispatch(conn->lcs.loc_req->fi, LCS_LOC_REQ_EV_CONN_CLEAR, NULL);
OSMO_ASSERT(data);
- ccd = data;
- if (conn->lchan)
- conn->lchan->release.is_csfb = ccd->is_csfb;
+ cause_0808 = data;
/* MSC tells us to cleanly shut down */
if (conn->fi->state != ST_CLEARING)
osmo_fsm_inst_state_chg(fi, ST_CLEARING, 60, -4);
LOGPFSML(fi, LOGL_DEBUG, "Releasing all lchans (if any) after BSSMAP Clear Command\n");
- gscon_release_lchans(conn, true, bsc_gsm48_rr_cause_from_gsm0808_cause(ccd->cause_0808));
+ gscon_release_lchans(conn, true, bsc_gsm48_rr_cause_from_gsm0808_cause(*cause_0808));
/* FIXME: Release all terestrial resources in ST_CLEARING */
/* According to 3GPP 48.008 3.1.9.1. "The BSS need not wait for the radio channel
* release to be completed or for the guard timer to expire before returning the
@@ -883,6 +882,12 @@ static void gscon_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *d
if (!conn->bsub->imsi[0])
bsc_subscr_set_imsi(conn->bsub, mi_imsi.imsi);
}
+ if (TLVP_PRESENT(tp, GSM0808_IE_LAST_USED_EUTRAN_PLMN_ID)) {
+ conn->last_eutran_plmn_valid = true;
+ osmo_plmn_from_bcd(TLVP_VAL(tp, GSM0808_IE_LAST_USED_EUTRAN_PLMN_ID), &conn->last_eutran_plmn);
+ LOGPFSML(fi, LOGL_DEBUG, "subscr comes from E-UTRAN PLMN %s\n",
+ osmo_plmn_name(&conn->last_eutran_plmn));
+ }
gscon_update_id(conn);
break;
default:
diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c
index 1d29f1ba2..3c60f5f42 100644
--- a/src/osmo-bsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -77,6 +77,7 @@
#include <osmocom/bsc/osmo_bsc.h>
#include <osmocom/bsc/bts.h>
#include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h>
+#include <osmocom/bsc/bsc_subscr_conn_fsm.h>
#include <inttypes.h>
@@ -6111,7 +6112,8 @@ static int lchan_act_single(struct vty *vty, struct gsm_lchan *lchan, const char
}
vty_out(vty, "%% Asking for release of %s in state %s%s", gsm_lchan_name(lchan),
osmo_fsm_inst_state_name(lchan->fi), VTY_NEWLINE);
- lchan_release(lchan, !!(lchan->conn), false, 0);
+ lchan_release(lchan, !!(lchan->conn), false, 0,
+ gscon_last_eutran_plmn(lchan->conn));
}
return CMD_SUCCESS;
diff --git a/src/osmo-bsc/gsm_04_08_rr.c b/src/osmo-bsc/gsm_04_08_rr.c
index 58913e277..5e9bc6907 100644
--- a/src/osmo-bsc/gsm_04_08_rr.c
+++ b/src/osmo-bsc/gsm_04_08_rr.c
@@ -313,10 +313,10 @@ int gsm48_send_rr_release(struct gsm_lchan *lchan)
cause = msgb_put(msg, 1);
cause[0] = lchan->release.rr_cause;
- if (lchan->release.is_csfb) {
+ if (lchan->release.last_eutran_plmn_valid) {
uint8_t buf[CELL_SEL_IND_AFTER_REL_MAX_BYTES];
int len;
-
+ /* FIXME: so far we assume all configured neigbhors match last_eutran_plmn */
len = generate_cell_sel_ind_after_rel(buf, sizeof(buf), lchan->ts->trx->bts);
if (len == 0) {
LOGPLCHAN(lchan, DRR, LOGL_NOTICE, "MSC indicated CSFB Fast Return, but "
@@ -996,13 +996,15 @@ static void dispatch_dtap(struct gsm_subscriber_connection *conn,
if (msg->lchan->ts->trx->bts->si_common.rach_control.t2 & 0x4) {
LOG_LCHAN(msg->lchan, LOGL_NOTICE, "MS attempts EMERGENCY SETUP although EMERGENCY CALLS"
" are not allowed in sysinfo (spec violation by MS!)\n");
- lchan_release(msg->lchan, true, true, GSM48_RR_CAUSE_PREMPTIVE_REL);
+ lchan_release(msg->lchan, true, true, GSM48_RR_CAUSE_PREMPTIVE_REL,
+ gscon_last_eutran_plmn(msg->lchan->conn));
break;
}
if (!conn->sccp.msc->allow_emerg) {
LOG_LCHAN(msg->lchan, LOGL_NOTICE, "MS attempts EMERGENCY SETUP, but EMERGENCY CALLS are"
" denied on this BSC (check BTS config!)\n");
- lchan_release(msg->lchan, true, true, GSM48_RR_CAUSE_PREMPTIVE_REL);
+ lchan_release(msg->lchan, true, true, GSM48_RR_CAUSE_PREMPTIVE_REL,
+ gscon_last_eutran_plmn(msg->lchan->conn));
break;
}
}
diff --git a/src/osmo-bsc/gsm_08_08.c b/src/osmo-bsc/gsm_08_08.c
index 52a92c8f8..e943ec111 100644
--- a/src/osmo-bsc/gsm_08_08.c
+++ b/src/osmo-bsc/gsm_08_08.c
@@ -541,7 +541,8 @@ int bsc_compl_l3(struct gsm_lchan *lchan, struct msgb *msg, uint16_t chosen_chan
early_exit:
if (release_lchan)
- lchan_release(lchan, true, true, RSL_ERR_EQUIPMENT_FAIL);
+ lchan_release(lchan, true, true, RSL_ERR_EQUIPMENT_FAIL,
+ gscon_last_eutran_plmn(conn));
log_set_context(LOG_CTX_BSC_SUBSCR, NULL);
return rc;
}
diff --git a/src/osmo-bsc/handover_fsm.c b/src/osmo-bsc/handover_fsm.c
index 70e479f08..f6dad9d0f 100644
--- a/src/osmo-bsc/handover_fsm.c
+++ b/src/osmo-bsc/handover_fsm.c
@@ -272,7 +272,8 @@ static void handover_reset(struct gsm_subscriber_connection *conn)
struct osmo_mgcpc_ep_ci *ci;
if (conn->ho.new_lchan)
/* New lchan was activated but never passed to a conn */
- lchan_release(conn->ho.new_lchan, false, true, RSL_ERR_EQUIPMENT_FAIL);
+ lchan_release(conn->ho.new_lchan, false, true, RSL_ERR_EQUIPMENT_FAIL,
+ NULL);
ci = conn->ho.created_ci_for_msc;
if (ci) {
@@ -908,7 +909,8 @@ void handover_end(struct gsm_subscriber_connection *conn, enum handover_result r
/* 3GPP TS 48.008 3.1.5.3.3 "Abnormal Conditions": if neither MS reports
* HO Failure nor the MSC sends a Clear Command, we should release the
* dedicated radio resources and send a Clear Request to the MSC. */
- lchan_release(conn->lchan, true, true, GSM48_RR_CAUSE_ABNORMAL_TIMER);
+ lchan_release(conn->lchan, true, true, GSM48_RR_CAUSE_ABNORMAL_TIMER,
+ gscon_last_eutran_plmn(conn));
/* Once the channel release is through, the BSSMAP Clear will follow. */
break;
}
@@ -964,7 +966,7 @@ void handover_end(struct gsm_subscriber_connection *conn, enum handover_result r
/* Detach the new_lchan last, so we can still see it in above logging */
if (ho->new_lchan) {
/* Release new lchan, it didn't work out */
- lchan_release(ho->new_lchan, false, true, RSL_ERR_EQUIPMENT_FAIL);
+ lchan_release(ho->new_lchan, false, true, RSL_ERR_EQUIPMENT_FAIL, NULL);
ho->new_lchan = NULL;
}
diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c
index 0e2eb826c..d58aac5f0 100644
--- a/src/osmo-bsc/lchan_fsm.c
+++ b/src/osmo-bsc/lchan_fsm.c
@@ -165,14 +165,14 @@ static void lchan_on_fully_established(struct gsm_lchan *lchan)
LOG_LCHAN(lchan, LOGL_ERROR,
"lchan activation for assignment succeeded, but lchan has no conn:"
" cannot trigger appropriate actions. Release.\n");
- lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL);
+ lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL, NULL);
break;
}
if (!lchan->conn->assignment.fi) {
LOG_LCHAN(lchan, LOGL_ERROR,
"lchan activation for assignment succeeded, but lchan has no"
" assignment ongoing: cannot trigger appropriate actions. Release.\n");
- lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL);
+ lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL, NULL);
break;
}
osmo_fsm_inst_dispatch(lchan->conn->assignment.fi, ASSIGNMENT_EV_LCHAN_ESTABLISHED,
@@ -186,14 +186,14 @@ static void lchan_on_fully_established(struct gsm_lchan *lchan)
if (!lchan->conn) {
LOG_LCHAN(lchan, LOGL_ERROR,
"lchan activation for handover succeeded, but lchan has no conn\n");
- lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL);
+ lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL, NULL);
break;
}
if (!lchan->conn->ho.fi) {
LOG_LCHAN(lchan, LOGL_ERROR,
"lchan activation for handover succeeded, but lchan has no"
" handover ongoing\n");
- lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL);
+ lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL, NULL);
break;
}
osmo_fsm_inst_dispatch(lchan->conn->ho.fi, HO_EV_LCHAN_ESTABLISHED, lchan);
@@ -793,14 +793,14 @@ static void lchan_fsm_post_activ_ack(struct osmo_fsm_inst *fi)
LOG_LCHAN(lchan, LOGL_ERROR,
"lchan activation for assignment succeeded, but lchan has no conn:"
" cannot trigger appropriate actions. Release.\n");
- lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL);
+ lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL, NULL);
break;
}
if (!lchan->conn->assignment.fi) {
LOG_LCHAN(lchan, LOGL_ERROR,
"lchan activation for assignment succeeded, but lchan has no"
" assignment ongoing: cannot trigger appropriate actions. Release.\n");
- lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL);
+ lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL, NULL);
break;
}
/* After the Chan Activ Ack, the MS expects to receive an RR Assignment Command.
@@ -813,14 +813,14 @@ static void lchan_fsm_post_activ_ack(struct osmo_fsm_inst *fi)
LOG_LCHAN(lchan, LOGL_ERROR,
"lchan activation for handover succeeded, but lchan has no conn:"
" cannot trigger appropriate actions. Release.\n");
- lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL);
+ lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL, NULL);
break;
}
if (!lchan->conn->ho.fi) {
LOG_LCHAN(lchan, LOGL_ERROR,
"lchan activation for handover succeeded, but lchan has no"
" handover ongoing: cannot trigger appropriate actions. Release.\n");
- lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL);
+ lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL, NULL);
break;
}
/* After the Chan Activ Ack of the new lchan, send the MS an RR Handover Command on the
@@ -1589,7 +1589,8 @@ static int lchan_fsm_timer_cb(struct osmo_fsm_inst *fi)
}
void lchan_release(struct gsm_lchan *lchan, bool do_rr_release,
- bool err, enum gsm48_rr_cause cause_rr)
+ bool err, enum gsm48_rr_cause cause_rr,
+ const struct osmo_plmn_id *last_eutran_plmn)
{
if (!lchan || !lchan->fi)
return;
@@ -1603,6 +1604,10 @@ void lchan_release(struct gsm_lchan *lchan, bool do_rr_release,
lchan->release.in_error = err;
lchan->release.do_rr_release = do_rr_release;
lchan->release.rr_cause = cause_rr;
+ if (last_eutran_plmn) {
+ lchan->release.last_eutran_plmn_valid = true;
+ memcpy(&lchan->release.last_eutran_plmn, last_eutran_plmn, sizeof(*last_eutran_plmn));
+ }
/* States waiting for events will notice the desire to release when done waiting, so it is enough
* to mark for release. */
diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c
index b558fae43..fc1484e4f 100644
--- a/src/osmo-bsc/osmo_bsc_bssap.c
+++ b/src/osmo-bsc/osmo_bsc_bssap.c
@@ -448,23 +448,27 @@ static int bssmap_handle_clear_cmd(struct gsm_subscriber_connection *conn,
struct msgb *msg, unsigned int length)
{
struct tlv_parsed tp;
- struct gscon_clear_cmd_data ccd = {
- .is_csfb = false,
- };
+ enum gsm0808_cause cause_0808;
tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l4h + 1, length - 1, 0, 0);
- ccd.cause_0808 = gsm0808_get_cause(&tp);
- if (ccd.cause_0808 < 0) {
+ cause_0808 = gsm0808_get_cause(&tp);
+ if (cause_0808 < 0) {
LOGPFSML(conn->fi, LOGL_ERROR, "Clear Command: Mandatory Cause IE not present.\n");
/* Clear anyway, but without a proper cause. */
- ccd.cause_0808 = GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE;
+ cause_0808 = GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE;
}
- if (TLVP_PRESENT(&tp, GSM0808_IE_CSFB_INDICATION))
- ccd.is_csfb = true;
+ if (TLVP_PRESENT(&tp, GSM0808_IE_CSFB_INDICATION) &&
+ !conn->last_eutran_plmn_valid) {
+ LOGPFSML(conn->fi, LOGL_NOTICE,
+ "Clear Command: CSFB Indication present, "
+ "but subscriber has no Last Used E-UTRAN PLMN Id! "
+ "This probably means MSC doesn't support proper return "
+ "to the last used PLMN after CS fallback.\n");
+ }
- osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_A_CLEAR_CMD, &ccd);
+ osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_A_CLEAR_CMD, &cause_0808);
return 0;
}
diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c
index 332c94cd1..917372bac 100644
--- a/tests/handover/handover_test.c
+++ b/tests/handover/handover_test.c
@@ -449,7 +449,7 @@ static void lchan_release_ack(struct gsm_lchan *lchan)
static void lchan_clear(struct gsm_lchan *lchan)
{
- lchan_release(lchan, true, false, 0);
+ lchan_release(lchan, true, false, 0, NULL);
lchan_release_ack(lchan);
}