From 95e862cab42e41568ba11599aa3e78d92f54bdf8 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 23 Jan 2012 10:28:35 +0100 Subject: Move processing of CLASSMARK CHANGE behind bsc_api This prevents osmo-bsc from sending RR messages to the MSC and rather process them inside the BSC and turn them into BSSAP CM UPDATE. --- openbsc/src/libbsc/bsc_api.c | 42 +++++++++++++++++++++++++++++++ openbsc/src/libmsc/gsm_04_08.c | 50 ------------------------------------- openbsc/src/libmsc/osmo_msc.c | 21 ++++++++++++++++ openbsc/src/osmo-bsc/osmo_bsc_api.c | 14 +++++++++++ 4 files changed, 77 insertions(+), 50 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c index ad4391d1a..bb1374776 100644 --- a/openbsc/src/libbsc/bsc_api.c +++ b/openbsc/src/libbsc/bsc_api.c @@ -418,6 +418,44 @@ static void handle_ass_fail(struct gsm_subscriber_connection *conn, rr_failure); } +static void handle_classmark_chg(struct gsm_subscriber_connection *conn, + struct msgb *msg) +{ + struct bsc_api *api = msg->lchan->ts->trx->bts->network->bsc_api; + struct gsm48_hdr *gh = msgb_l3(msg); + unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); + uint8_t cm2_len, cm3_len = 0; + uint8_t *cm2, *cm3 = NULL; + + DEBUGP(DRR, "CLASSMARK CHANGE "); + + /* classmark 2 */ + cm2_len = gh->data[0]; + cm2 = &gh->data[1]; + DEBUGPC(DRR, "CM2(len=%u) ", cm2_len); + + if (payload_len > cm2_len + 1) { + /* we must have a classmark3 */ + if (gh->data[cm2_len+1] != 0x20) { + DEBUGPC(DRR, "ERR CM3 TAG\n"); + return -EINVAL; + } + if (cm2_len > 3) { + DEBUGPC(DRR, "CM2 too long!\n"); + return -EINVAL; + } + + 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; + } + DEBUGPC(DRR, "CM3(len=%u)\n", cm3_len); + } + api->classmark_chg(conn, cm2, cm2_len, cm3, cm3_len); +} + static void dispatch_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg) { @@ -462,6 +500,10 @@ static void dispatch_dtap(struct gsm_subscriber_connection *conn, } return; break; + case GSM48_MT_RR_CLSM_CHG: + handle_classmark_chg(conn, msg); + return; + break; } break; case GSM48_PDISC_MM: diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 7c0d62895..a2a49aa9a 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1101,53 +1101,6 @@ static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct m return rc; } -static int gsm48_rx_rr_classmark(struct gsm_subscriber_connection *conn, struct msgb *msg) -{ - struct gsm48_hdr *gh = msgb_l3(msg); - struct gsm_subscriber *subscr = conn->subscr; - unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); - uint8_t cm2_len, cm3_len = 0; - uint8_t *cm2, *cm3 = NULL; - - DEBUGP(DRR, "CLASSMARK CHANGE "); - - /* classmark 2 */ - cm2_len = gh->data[0]; - cm2 = &gh->data[1]; - DEBUGPC(DRR, "CM2(len=%u) ", cm2_len); - - if (payload_len > cm2_len + 1) { - /* we must have a classmark3 */ - if (gh->data[cm2_len+1] != 0x20) { - DEBUGPC(DRR, "ERR CM3 TAG\n"); - return -EINVAL; - } - if (cm2_len > 3) { - DEBUGPC(DRR, "CM2 too long!\n"); - return -EINVAL; - } - - 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; - } - DEBUGPC(DRR, "CM3(len=%u)\n", cm3_len); - } - if (subscr) { - subscr->equipment.classmark2_len = cm2_len; - memcpy(subscr->equipment.classmark2, cm2, cm2_len); - if (cm3) { - subscr->equipment.classmark3_len = cm3_len; - memcpy(subscr->equipment.classmark3, cm3, cm3_len); - } - db_sync_equipment(&subscr->equipment); - } - - return 0; -} - static int gsm48_rx_rr_status(struct msgb *msg) { struct gsm48_hdr *gh = msgb_l3(msg); @@ -1258,9 +1211,6 @@ static int gsm0408_rcv_rr(struct gsm_subscriber_connection *conn, struct msgb *m int rc = 0; switch (gh->msg_type) { - case GSM48_MT_RR_CLSM_CHG: - rc = gsm48_rx_rr_classmark(conn, msg); - break; case GSM48_MT_RR_GPRS_SUSP_REQ: DEBUGP(DRR, "GRPS SUSPEND REQUEST\n"); break; diff --git a/openbsc/src/libmsc/osmo_msc.c b/openbsc/src/libmsc/osmo_msc.c index 154386b13..121de679c 100644 --- a/openbsc/src/libmsc/osmo_msc.c +++ b/openbsc/src/libmsc/osmo_msc.c @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -83,6 +84,25 @@ static void msc_assign_fail(struct gsm_subscriber_connection *conn, "Assignment fail should not have been reached.\n"); } +static void msc_classmark_chg(struct gsm_subscriber_connection *conn, + const uint8_t *cm2, uint8_t cm2_len, + const uint8_t *cm3, uint8_t cm3_len) +{ + struct gsm_subscriber *subscr = conn->subscr; + + if (subscr) { + subscr->equipment.classmark2_len = cm2_len; + memcpy(subscr->equipment.classmark2, cm2, cm2_len); + if (cm3) { + subscr->equipment.classmark3_len = cm3_len; + memcpy(subscr->equipment.classmark3, cm3, cm3_len); + } + db_sync_equipment(&subscr->equipment); + } +} + + + static struct bsc_api msc_handler = { .sapi_n_reject = msc_sapi_n_reject, .compl_l3 = msc_compl_l3, @@ -90,6 +110,7 @@ static struct bsc_api msc_handler = { .clear_request = msc_clear_request, .assign_compl = msc_assign_compl, .assign_fail = msc_assign_fail, + .classmark_chg = msc_classmark_chg, }; struct bsc_api *msc_bsc_api() { diff --git a/openbsc/src/osmo-bsc/osmo_bsc_api.c b/openbsc/src/osmo-bsc/osmo_bsc_api.c index 2869f4756..72e7b9b78 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_api.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_api.c @@ -183,6 +183,19 @@ static int bsc_clear_request(struct gsm_subscriber_connection *conn, uint32_t ca return 1; } +static void bsc_cm_update(struct gsm_subscriber_connection *conn, + const uint8_t *cm2, uint8_t cm2_len, + const uint8_t *cm3, uint8_t cm3_len) +{ + struct osmo_bsc_sccp_con *sccp; + struct msgb *resp; + return_when_not_connected_val(conn, 1); + + resp = gsm0808_create_classmark_update(cm2, cm2_len, cm3, cm3_len); + + queue_msg_or_return(resp); +} + static struct bsc_api bsc_handler = { .sapi_n_reject = bsc_sapi_n_reject, .cipher_mode_compl = bsc_cipher_mode_compl, @@ -191,6 +204,7 @@ static struct bsc_api bsc_handler = { .assign_compl = bsc_assign_compl, .assign_fail = bsc_assign_fail, .clear_request = bsc_clear_request, + .classmark_chg = bsc_cm_update, }; struct bsc_api *osmo_bsc_api() -- cgit v1.2.3