diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-11-04 11:18:03 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-11-15 20:06:46 +0100 |
commit | 6c199e7d999573e0e575f03754122d405a87ef3a (patch) | |
tree | 90907a0b28a7451068e5fb563cf6964ce788d119 /openbsc/src/bsc_api.c | |
parent | fce9307553d84687dc4d51b897374193bfe94235 (diff) |
bsc_api: Look into the msg and call the right API functions
For certain messages we will need to call other GSM0808 functions. To
keep the bsc_hack working we will try to send this through the normal
messages first and then fallback to dtap if no handler is registered.
The gsm_04_08.c code is not forced to handle the IPA activation
and channel modify ack anymore. This is done transparently by the
BSC API now.
Diffstat (limited to 'openbsc/src/bsc_api.c')
-rw-r--r-- | openbsc/src/bsc_api.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/openbsc/src/bsc_api.c b/openbsc/src/bsc_api.c index e8f42d275..9a47264de 100644 --- a/openbsc/src/bsc_api.c +++ b/openbsc/src/bsc_api.c @@ -31,6 +31,8 @@ #include <openbsc/handover.h> #include <openbsc/debug.h> +#include <osmocore/protocol/gsm_08_08.h> + #include <osmocore/talloc.h> static LLIST_HEAD(sub_connections); @@ -147,6 +149,54 @@ int bsc_upqueue(struct gsm_network *net) return work; } +static void dispatch_dtap(struct gsm_subscriber_connection *conn, struct msgb *msg) +{ + struct bsc_api *api = msg->lchan->ts->trx->bts->network->bsc_api; + struct gsm48_hdr *gh; + uint8_t pdisc; + int rc; + + if (msgb_l3len(msg) < sizeof(*gh)) { + LOGP(DMSC, LOGL_ERROR, "Message too short for a GSM48 header.\n"); + return; + } + + gh = msgb_l3(msg); + pdisc = gh->proto_discr & 0x0f; + switch (pdisc) { + case GSM48_PDISC_RR: + switch (gh->msg_type) { + case GSM48_MT_RR_CIPH_M_COMPL: + if (api->cipher_mode_compl) + return api->cipher_mode_compl(conn, msg, + conn->lchan->encr.alg_id); + break; + case GSM48_MT_RR_ASS_COMPL: + LOGP(DMSC, LOGL_ERROR, "Assignment command is not handled.\n"); + break; + case GSM48_MT_RR_ASS_FAIL: + LOGP(DMSC, LOGL_ERROR, "Assignment failure is not handled.\n"); + break; + case GSM48_MT_RR_CHAN_MODE_MODIF_ACK: + rc = gsm48_rx_rr_modif_ack(msg); + if (rc < 0 && api->assign_fail) + api->assign_fail(conn, + GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE); + else if (rc >= 0 && api->assign_compl) + api->assign_compl(conn, 0); + return; + break; + } + break; + case GSM48_PDISC_MM: + break; + } + + /* default case */ + if (api->dtap) + api->dtap(conn, msg); +} + int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id) { int rc; @@ -161,7 +211,7 @@ int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id) if (lchan->conn) { - api->dtap(lchan->conn, msg); + dispatch_dtap(lchan->conn, msg); } else { rc = BSC_API_CONN_POL_REJECT; lchan->conn = subscr_con_allocate(msg->lchan); |