aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-06-15 11:20:52 +0800
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-06-15 12:04:34 +0800
commit9c595b74742a0bee332c8b150d6832662a005c03 (patch)
tree870c8b7ee1eb3d8bb80783209f1f8af638f11a2e /openbsc
parent0cfbe26cb9fc07961f8d83ccdd13843433040b83 (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')
-rw-r--r--openbsc/include/openbsc/gsm_data.h2
-rw-r--r--openbsc/src/bsc_api.c46
2 files changed, 47 insertions, 1 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 119c02adc..4292bb11b 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -105,6 +105,8 @@ struct openbsc_msgb_cb {
#define msgb_bcid(__x) OBSC_MSGB_CB(__x)->bssgp_cell_id
#define msgb_llch(__x) OBSC_MSGB_CB(__x)->llch
+#define OBSC_LINKID_CB(__msgb) (__msgb)->cb[3]
+
enum gsm_security_event {
GSM_SECURITY_NOAVAIL,
GSM_SECURITY_AUTH_FAILED,
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)
{