aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2016-10-11 02:24:53 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2016-11-12 16:06:46 +0100
commitfcdc026c8a6af3a4e77f417ea97cb15ada53bada (patch)
tree64346cec48c172e971aab15827fe1d0901dde880
parenta5e8069cca887b28b91f2f2c328e5727bd5af48f (diff)
IuCS: rapidly release connections
Do the same as we do in 2G: release the connection as soon as nothing else is pending for a given subscriber. Before, osmo-cscn would wait for the UE "to get bored" and send an Iu release. But the CN should stay lean on connections. Also, 25.413[1] in section 7, 6th point states: "While the Iu release is managed from the CN, the RNC has the capability to request the release of all Iu connection resources from the corresponding Iu connection." So far we did not manage Iu release from osmo-cscn at all. Use the same mechanism we use in 2G: from msc_release_connection(), just before freeing the gsm_subscriber_conn, invoke a CN initiated Iu Release command to the UE. This works around OS#1816 ("USSD only works when IuCS is released", on nano3G), because the Iu conn is now released right after every signalling, so that typically no two requests will use the same conn. In iu.h/iu.c, add iu_tx_release(), absorbing almost all of the code from ranap_handle_co_iu_rel_req(). Add stub to db_test.c, necessary to build it without linking libiu. [1] 3GPP TS 25.413 v12.4.0 Release 12 / ETSI TS 125 413 V12.4.0 (2015-04) Related: OS#1816 Change-Id: Ic12bd6f3666f6fd42bd6d9fdae1c93abee3b6786
-rw-r--r--openbsc/include/openbsc/iu.h2
-rw-r--r--openbsc/src/libiu/iu.c23
-rw-r--r--openbsc/src/libmsc/osmo_msc.c12
-rw-r--r--openbsc/tests/db/db_test.c3
4 files changed, 32 insertions, 8 deletions
diff --git a/openbsc/include/openbsc/iu.h b/openbsc/include/openbsc/iu.h
index c45fec576..2155790c1 100644
--- a/openbsc/include/openbsc/iu.h
+++ b/openbsc/include/openbsc/iu.h
@@ -8,6 +8,7 @@ struct gprs_ra_id;
struct RANAP_RAB_SetupOrModifiedItemIEs_s;
struct RANAP_GlobalRNC_ID;
+struct RANAP_Cause;
struct ue_conn_ctx {
struct llist_head list;
@@ -59,5 +60,6 @@ int iu_rab_deact(struct ue_conn_ctx *ue_ctx, uint8_t rab_id);
int iu_tx_sec_mode_cmd(struct ue_conn_ctx *uectx, struct gsm_auth_tuple *tp,
int send_ck, int new_key);
int iu_tx_common_id(struct ue_conn_ctx *ue_ctx, const char *imsi);
+int iu_tx_release(struct ue_conn_ctx *ctx, const struct RANAP_Cause *cause);
void iu_vty_init(int *asn_debug_p);
diff --git a/openbsc/src/libiu/iu.c b/openbsc/src/libiu/iu.c
index 0ce17e4e0..7ca999fa8 100644
--- a/openbsc/src/libiu/iu.c
+++ b/openbsc/src/libiu/iu.c
@@ -409,20 +409,35 @@ int iu_tx(struct msgb *msg_nas, uint8_t sapi)
return 0;
}
-static int ranap_handle_co_iu_rel_req(struct ue_conn_ctx *ctx, RANAP_Iu_ReleaseRequestIEs_t *ies)
+/* Send Iu Release for the given UE connection.
+ * If cause is NULL, the standard "No remaining RAB" cause is sent, otherwise
+ * the provided cause. */
+int iu_tx_release(struct ue_conn_ctx *ctx, const struct RANAP_Cause *cause)
{
struct msgb *msg;
struct osmo_scu_prim *prim;
+ static const struct RANAP_Cause default_cause = {
+ .present = RANAP_Cause_PR_radioNetwork,
+ .choice.radioNetwork = RANAP_CauseRadioNetwork_no_remaining_rab,
+ };
- LOGP(DRANAP, LOGL_INFO, "Received Iu Release Request, Sending Release Command\n");
- msg = ranap_new_msg_iu_rel_cmd(&ies->cause);
+ if (!cause)
+ cause = &default_cause;
+
+ msg = ranap_new_msg_iu_rel_cmd(cause);
msg->l2h = msg->data;
prim = (struct osmo_scu_prim *) msgb_push(msg, sizeof(*prim));
prim->u.data.conn_id = ctx->conn_id;
osmo_prim_init(&prim->oph, SCCP_SAP_USER,
OSMO_SCU_PRIM_N_DATA,
PRIM_OP_REQUEST, msg);
- osmo_sua_user_link_down(ctx->link, &prim->oph);
+ return osmo_sua_user_link_down(ctx->link, &prim->oph);
+}
+
+static int ranap_handle_co_iu_rel_req(struct ue_conn_ctx *ctx, RANAP_Iu_ReleaseRequestIEs_t *ies)
+{
+ LOGP(DRANAP, LOGL_INFO, "Received Iu Release Request, Sending Release Command\n");
+ iu_tx_release(ctx, &ies->cause);
return 0;
}
diff --git a/openbsc/src/libmsc/osmo_msc.c b/openbsc/src/libmsc/osmo_msc.c
index 2d5f94b56..37d389eee 100644
--- a/openbsc/src/libmsc/osmo_msc.c
+++ b/openbsc/src/libmsc/osmo_msc.c
@@ -26,6 +26,7 @@
#include <openbsc/debug.h>
#include <openbsc/transaction.h>
#include <openbsc/db.h>
+#include <openbsc/iu.h>
#include <openbsc/gsm_04_11.h>
@@ -149,10 +150,6 @@ struct bsc_api *msc_bsc_api() {
/* conn release handling */
void msc_release_connection(struct gsm_subscriber_connection *conn)
{
- /* For IuCS, always wait until the UE releases. */
- if (conn->via_iface == IFACE_IU)
- return;
-
/* skip when we are in release, e.g. due an error */
if (conn->in_release)
return;
@@ -179,5 +176,12 @@ void msc_release_connection(struct gsm_subscriber_connection *conn)
subscr_update_expire_lu(conn->subscr);
conn->in_release = 1;
+
+ if (conn->via_iface == IFACE_IU)
+ iu_tx_release(conn->iu.ue_ctx, NULL);
+ /* FIXME: keep the conn until the Iu Release Outcome is
+ * received from the UE, or a timeout expires. For now, the log
+ * says "unknown UE" for each release outcome. */
+
msc_subscr_con_free(conn);
}
diff --git a/openbsc/tests/db/db_test.c b/openbsc/tests/db/db_test.c
index ee579bc34..2aa4ecf4d 100644
--- a/openbsc/tests/db/db_test.c
+++ b/openbsc/tests/db/db_test.c
@@ -269,3 +269,6 @@ const char *mgcpgw_client_remote_addr_str(struct mgcpgw_client *mgcp)
{ return "0.0.0.0"; }
uint32_t mgcpgw_client_remote_addr_n(struct mgcpgw_client *mgcp)
{ return 0; }
+struct RANAP_Cause;
+int iu_tx_release(struct ue_conn_ctx *ctx, const struct RANAP_Cause *cause)
+{ return 0; }