aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libbsc/bsc_api.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2012-01-23 16:40:24 +0100
committerHarald Welte <laforge@gnumonks.org>2012-01-23 16:40:24 +0100
commitcf149eebb69ac015dc0f4a3eed57821c862300de (patch)
treeb917593640e00d1a23fbb7285a6e3980240d3a91 /openbsc/src/libbsc/bsc_api.c
parent95e862cab42e41568ba11599aa3e78d92f54bdf8 (diff)
Move the bulk of RR processing from MSC into BSC
RR Messages like STATUS, GPRS SUSPEND, HANDOVER COMPLETE/FAIL, ... should be processed on the BSC side of things, not on the MSC side. This is among other things required in preparation of intra-BSC hand-over support in osmo-bsc.
Diffstat (limited to 'openbsc/src/libbsc/bsc_api.c')
-rw-r--r--openbsc/src/libbsc/bsc_api.c83
1 files changed, 72 insertions, 11 deletions
diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c
index bb1374776..9d301f002 100644
--- a/openbsc/src/libbsc/bsc_api.c
+++ b/openbsc/src/libbsc/bsc_api.c
@@ -438,24 +438,55 @@ static void handle_classmark_chg(struct gsm_subscriber_connection *conn,
/* we must have a classmark3 */
if (gh->data[cm2_len+1] != 0x20) {
DEBUGPC(DRR, "ERR CM3 TAG\n");
- return -EINVAL;
+ return;
}
if (cm2_len > 3) {
DEBUGPC(DRR, "CM2 too long!\n");
- return -EINVAL;
+ return;
}
cm3_len = gh->data[cm2_len+2];
cm3 = &gh->data[cm2_len+3];
if (cm3_len > 14) {
DEBUGPC(DRR, "CM3 len %u too long!\n", cm3_len);
- return -EINVAL;
+ return;
}
DEBUGPC(DRR, "CM3(len=%u)\n", cm3_len);
}
api->classmark_chg(conn, cm2, cm2_len, cm3, cm3_len);
}
+/* Chapter 9.1.16 Handover complete */
+static void handle_rr_ho_compl(struct msgb *msg)
+{
+ struct lchan_signal_data sig;
+ struct gsm48_hdr *gh = msgb_l3(msg);
+
+ DEBUGP(DRR, "HANDOVER COMPLETE cause = %s\n",
+ rr_cause_name(gh->data[0]));
+
+ sig.lchan = msg->lchan;
+ sig.mr = NULL;
+ osmo_signal_dispatch(SS_LCHAN, S_LCHAN_HANDOVER_COMPL, &sig);
+ /* FIXME: release old channel */
+}
+
+/* Chapter 9.1.17 Handover Failure */
+static void handle_rr_ho_fail(struct msgb *msg)
+{
+ struct lchan_signal_data sig;
+ struct gsm48_hdr *gh = msgb_l3(msg);
+
+ DEBUGP(DRR, "HANDOVER FAILED cause = %s\n",
+ rr_cause_name(gh->data[0]));
+
+ sig.lchan = msg->lchan;
+ sig.mr = NULL;
+ osmo_signal_dispatch(SS_LCHAN, S_LCHAN_HANDOVER_FAIL, &sig);
+ /* FIXME: release allocated new channel */
+}
+
+
static void dispatch_dtap(struct gsm_subscriber_connection *conn,
uint8_t link_id, struct msgb *msg)
{
@@ -471,12 +502,38 @@ static void dispatch_dtap(struct gsm_subscriber_connection *conn,
gh = msgb_l3(msg);
pdisc = gh->proto_discr & 0x0f;
+
+ /* the idea is to handle all RR messages here, and only hand
+ * MM/CC/SMS-CP/LCS up to the MSC. Some messages like PAGING
+ * RESPONSE or CM SERVICE REQUEST will not be covered here, as
+ * they are only possible in the first L3 message of each L2
+ * channel, i.e. 'conn' will not exist and gsm0408_rcvmsg()
+ * will call api->compl_l3() for it */
switch (pdisc) {
case GSM48_PDISC_RR:
switch (gh->msg_type) {
+ case GSM48_MT_RR_GPRS_SUSP_REQ:
+ DEBUGP(DRR, "GRPS SUSPEND REQUEST\n");
+ break;
+ case GSM48_MT_RR_STATUS:
+ DEBUGP(DRR, "RR STATUS (cause: %s)\n",
+ rr_cause_name(gh->data[0]));
+ break;
+ case GSM48_MT_RR_MEAS_REP:
+ /* This shouldn't actually end up here, as RSL treats
+ * L3 Info of 08.58 MEASUREMENT REPORT different by calling
+ * directly into gsm48_parse_meas_rep */
+ LOGP(LOGL_ERROR, DMEAS, "DIRECT GSM48 MEASUREMENT REPORT ?!? ");
+ break;
+ case GSM48_MT_RR_HANDO_COMPL:
+ handle_rr_ho_compl(msg);
+ break;
+ case GSM48_MT_RR_HANDO_FAIL:
+ handle_rr_ho_fail(msg);
+ break;
case GSM48_MT_RR_CIPH_M_COMPL:
if (api->cipher_mode_compl)
- return api->cipher_mode_compl(conn, msg,
+ api->cipher_mode_compl(conn, msg,
conn->lchan->encr.alg_id);
break;
case GSM48_MT_RR_ASS_COMPL:
@@ -498,21 +555,25 @@ static void dispatch_dtap(struct gsm_subscriber_connection *conn,
conn->lchan->encr.alg_id,
chan_mode_to_speech(conn->lchan));
}
- return;
break;
case GSM48_MT_RR_CLSM_CHG:
handle_classmark_chg(conn, msg);
- return;
break;
+ default:
+ /* Normally, a MSC should never receive RR
+ * messages, but we'd rather forward what we
+ * don't know than drop it... */
+ LOGP(DRR, LOGL_NOTICE, "BSC: Passing unknown 04.08 "
+ "RR message type 0x%02x to MSC\n", gh->msg_type);
+ if (api->dtap)
+ api->dtap(conn, link_id, msg);
}
break;
- case GSM48_PDISC_MM:
+ default:
+ if (api->dtap)
+ api->dtap(conn, link_id, msg);
break;
}
-
- /* default case */
- if (api->dtap)
- api->dtap(conn, link_id, msg);
}
/*! \brief RSL has received a DATA INDICATION with L3 from MS */