aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmsc
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/libmsc')
-rw-r--r--openbsc/src/libmsc/a_iface.c8
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c31
-rw-r--r--openbsc/src/libmsc/gsm_subscriber.c20
-rw-r--r--openbsc/src/libmsc/msc_ifaces.c5
-rw-r--r--openbsc/src/libmsc/osmo_msc.c4
-rw-r--r--openbsc/src/libmsc/subscr_conn.c7
6 files changed, 51 insertions, 24 deletions
diff --git a/openbsc/src/libmsc/a_iface.c b/openbsc/src/libmsc/a_iface.c
index 1f471f97b..caf9d4b06 100644
--- a/openbsc/src/libmsc/a_iface.c
+++ b/openbsc/src/libmsc/a_iface.c
@@ -35,6 +35,14 @@ int a_tx(struct msgb *msg)
return -1;
}
+int a_page(const char *imsi, uint32_t tmsi, uint16_t lac)
+{
+ LOGP(DMSC, LOGL_ERROR, "Paging to be sent to BSC, but A-interface"
+ " not implemented: IMSI %s TMSI 0x%08x LAC %u\n",
+ imsi, tmsi, lac);
+ return -1;
+}
+
int msc_gsm0808_tx_cipher_mode(struct gsm_subscriber_connection *conn, int cipher,
const uint8_t *key, int len, int include_imeisv)
{
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 752a6d288..7b1a738be 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -778,19 +778,21 @@ static int gsm48_rx_mm_imsi_detach_ind(struct gsm_subscriber_connection *conn, s
* will be discarded anyway: */
conn->classmark.classmark1 = idi->classmark1;
- if (vsub)
+ if (vsub) {
+ conn->vsub = vlr_subscr_get(vsub);
subscr_update(vsub, GSM_SUBSCRIBER_UPDATE_DETACHED);
- else
+ vlr_subscr_put(vsub);
+ } else
DEBUGP(DMM, "Unknown Subscriber ?!?\n");
- /* FIXME: iterate over all transactions and release them,
- * imagine an IMSI DETACH happening during an active call! */
-
- msc_release_anchor(conn);
- conn = NULL;
+ /* If there's a conn_fsm, the conn may have been accepted and requests
+ * may be pending. But Detach Request may come in on an "uninitialized"
+ * conn, in which case we can simply dealloc it. */
+ if (conn->conn_fsm)
+ gsm0408_clear_request(conn, GSM_CAUSE_DEACT_REGULAR);
+ else
+ msc_subscr_con_free(conn);
- if (vsub)
- vlr_subscr_put(vsub);
return 0;
}
@@ -3610,6 +3612,16 @@ int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg)
return -EACCES;
}
+ if (conn->vsub && conn->vsub->cs.attached_via_ran != conn->via_ran) {
+ LOGP(DMM, LOGL_ERROR,
+ "%s: Illegal situation: RAN type mismatch:"
+ " attached via %s, received message via %s\n",
+ vlr_subscr_name(conn->vsub),
+ ran_type_name(conn->vsub->cs.attached_via_ran),
+ ran_type_name(conn->via_ran));
+ return -EACCES;
+ }
+
#if 0
if (silent_call_reroute(conn, msg))
return silent_call_rx(conn, msg);
@@ -3783,6 +3795,7 @@ static void msc_vlr_subscr_assoc(void *msc_conn_ref,
struct gsm_subscriber_connection *conn = msc_conn_ref;
OSMO_ASSERT(!conn->vsub);
conn->vsub = vlr_subscr_get(vsub);
+ conn->vsub->cs.attached_via_ran = conn->via_ran;
}
/* operations that we need to implement for libvlr */
diff --git a/openbsc/src/libmsc/gsm_subscriber.c b/openbsc/src/libmsc/gsm_subscriber.c
index 55a6f84d5..c57c76272 100644
--- a/openbsc/src/libmsc/gsm_subscriber.c
+++ b/openbsc/src/libmsc/gsm_subscriber.c
@@ -42,6 +42,7 @@
#include <openbsc/vlr.h>
#include <openbsc/iu.h>
#include <openbsc/osmo_msc.h>
+#include <openbsc/msc_ifaces.h>
void *tall_sub_req_ctx;
@@ -108,10 +109,21 @@ int msc_paging_request(struct vlr_subscr *vsub)
* SCCP connections (if any). */
/* TODO Implementing only RNC paging, since this is code on the iu branch.
* Need to add BSC paging at some point. */
- return iu_page_cs(vsub->imsi,
- vsub->tmsi == GSM_RESERVED_TMSI?
- NULL : &vsub->tmsi,
- vsub->lac);
+ switch (vsub->cs.attached_via_ran) {
+ case RAN_GERAN_A:
+ return a_page(vsub->imsi, vsub->tmsi, vsub->lac);
+ case RAN_UTRAN_IU:
+ return iu_page_cs(vsub->imsi,
+ vsub->tmsi == GSM_RESERVED_TMSI?
+ NULL : &vsub->tmsi,
+ vsub->lac);
+ default:
+ break;
+ }
+
+ LOGP(DPAG, LOGL_ERROR, "%s: Cannot page, subscriber not attached\n",
+ vlr_subscr_name(vsub));
+ return -EINVAL;
}
struct subscr_request *subscr_request_conn(struct vlr_subscr *vsub,
diff --git a/openbsc/src/libmsc/msc_ifaces.c b/openbsc/src/libmsc/msc_ifaces.c
index c8fda88d9..8cc91c614 100644
--- a/openbsc/src/libmsc/msc_ifaces.c
+++ b/openbsc/src/libmsc/msc_ifaces.c
@@ -39,8 +39,9 @@ extern struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id,
static int msc_tx(struct gsm_subscriber_connection *conn, struct msgb *msg)
{
- DEBUGP(DMSC, "msc_tx %u bytes via %s\n",
- msg->len, ran_type_name(conn->via_ran));
+ DEBUGP(DMSC, "msc_tx %u bytes to %s via %s\n",
+ msg->len, vlr_subscr_name(conn->vsub),
+ ran_type_name(conn->via_ran));
switch (conn->via_ran) {
case RAN_GERAN_A:
msg->dst = conn;
diff --git a/openbsc/src/libmsc/osmo_msc.c b/openbsc/src/libmsc/osmo_msc.c
index 6c4eeca94..d888c4819 100644
--- a/openbsc/src/libmsc/osmo_msc.c
+++ b/openbsc/src/libmsc/osmo_msc.c
@@ -55,10 +55,6 @@ int msc_compl_l3(struct gsm_subscriber_connection *conn,
{
gsm0408_dispatch(conn, msg);
- if (!conn->conn_fsm)
- /* The request didn't even meet basic entry requirements. */
- msc_subscr_con_free(conn);
-
/* Always return acceptance, because even if the conn was not accepted,
* we assumed ownership of it and the caller shall not interfere with
* that. We may even already have discarded the conn. */
diff --git a/openbsc/src/libmsc/subscr_conn.c b/openbsc/src/libmsc/subscr_conn.c
index 8a8ea8020..7a0b73568 100644
--- a/openbsc/src/libmsc/subscr_conn.c
+++ b/openbsc/src/libmsc/subscr_conn.c
@@ -90,7 +90,8 @@ void subscr_conn_fsm_new(struct osmo_fsm_inst *fi, uint32_t event, void *data)
LOGPFSM(fi, "Close event, cause %u\n",
*(uint32_t*)data);
case SUBSCR_CONN_E_CLOSE_CONF:
- osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_RELEASED, 0, 0);
+ /* will release further below, see
+ * 'if (fi->state != SUBSCR_CONN_S_ACCEPTED)' */
break;
default:
@@ -118,8 +119,6 @@ void subscr_conn_fsm_new(struct osmo_fsm_inst *fi, uint32_t event, void *data)
return;
}
- /* On success, handle pending requests and/or close conn */
-
if (from == SUBSCR_CONN_FROM_CM_SERVICE_REQ) {
conn->received_cm_service_request = true;
LOGPFSM(fi, "received_cm_service_request = true\n");
@@ -248,8 +247,6 @@ static void subscr_conn_fsm_cleanup(struct osmo_fsm_inst *fi,
* received from the UE, or a timeout expires. For now, the log
* says "unknown UE" for each release outcome. */
- DEBUGP(DMM, "%s calling bsc_subscr_con_free(), owned_by_msc = true\n",
- vlr_subscr_name(conn->vsub));
msc_subscr_con_free(conn);
}