diff options
author | Harald Welte <laforge@gnumonks.org> | 2012-01-23 16:40:24 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2012-01-23 16:40:24 +0100 |
commit | cf149eebb69ac015dc0f4a3eed57821c862300de (patch) | |
tree | b917593640e00d1a23fbb7285a6e3980240d3a91 /openbsc/src/libbsc | |
parent | 95e862cab42e41568ba11599aa3e78d92f54bdf8 (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')
-rw-r--r-- | openbsc/src/libbsc/bsc_api.c | 83 |
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 */ |