diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-06-15 11:20:52 +0800 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-06-15 12:04:34 +0800 |
commit | 9c595b74742a0bee332c8b150d6832662a005c03 (patch) | |
tree | 870c8b7ee1eb3d8bb80783209f1f8af638f11a2e /openbsc/src/bsc_api.c | |
parent | 0cfbe26cb9fc07961f8d83ccdd13843433040b83 (diff) |
bsc_api: Implement transparent RLL establishment and SAPI n REJECT
When submitting a DTAP message, the BSC API will attempt to
establish the RLL layer and then send the message or send an
SAPI n REJECT. This will be used by the SMS code.
Diffstat (limited to 'openbsc/src/bsc_api.c')
-rw-r--r-- | openbsc/src/bsc_api.c | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/openbsc/src/bsc_api.c b/openbsc/src/bsc_api.c index 2837dbb0a..25b8b66c1 100644 --- a/openbsc/src/bsc_api.c +++ b/openbsc/src/bsc_api.c @@ -23,12 +23,16 @@ */ #include <openbsc/bsc_api.h> +#include <openbsc/bsc_rll.h> #include <openbsc/gsm_data.h> #include <openbsc/signal.h> #include <openbsc/abis_rsl.h> #include <osmocore/talloc.h> +static void rll_ind_cb(struct gsm_lchan *, uint8_t, void *, enum bsc_rllr_ind); +static void send_sapi_reject(struct gsm_subscriber_connection *conn, int link_id); + int bsc_api_init(struct gsm_network *network, struct bsc_api *api) { network->bsc_api = api; @@ -38,9 +42,21 @@ int bsc_api_init(struct gsm_network *network, struct bsc_api *api) int gsm0808_submit_dtap(struct gsm_subscriber_connection *conn, struct msgb *msg, int link_id) { + uint8_t sapi = link_id & 0x7; msg->lchan = conn->lchan; msg->trx = msg->lchan->ts->trx; - return rsl_data_request(msg, link_id); + + if (conn->lchan->sapis[sapi] == LCHAN_SAPI_UNUSED) { + OBSC_LINKID_CB(msg) = link_id; + if (rll_establish(msg->lchan, sapi, rll_ind_cb, msg) != 0) { + msgb_free(msg); + send_sapi_reject(conn, link_id); + return -1; + } + return 0; + } else { + return rsl_data_request(msg, link_id); + } } /* dequeue messages to layer 4 */ @@ -62,6 +78,34 @@ int bsc_upqueue(struct gsm_network *net) return work; } +static void send_sapi_reject(struct gsm_subscriber_connection *conn, int link_id) +{ + struct bsc_api *api; + + api = conn->bts->network->bsc_api; + if (!api || !api->sapi_n_reject) + return; + + api->sapi_n_reject(conn, link_id); +} + +static void rll_ind_cb(struct gsm_lchan *lchan, uint8_t link_id, void *_data, enum bsc_rllr_ind rllr_ind) +{ + struct msgb *msg = _data; + + switch (rllr_ind) { + case BSC_RLLR_IND_EST_CONF: + rsl_data_request(msg, OBSC_LINKID_CB(msg)); + break; + case BSC_RLLR_IND_REL_IND: + case BSC_RLLR_IND_ERR_IND: + case BSC_RLLR_IND_TIMEOUT: + send_sapi_reject(&lchan->conn, OBSC_LINKID_CB(msg)); + msgb_free(msg); + break; + } +} + static int bsc_handle_lchan_signal(unsigned int subsys, unsigned int signal, void *handler_data, void *signal_data) { |