aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/bsc_rll.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2009-08-09 13:47:35 +0200
committerHarald Welte <laforge@gnumonks.org>2009-08-09 13:47:35 +0200
commitedcc5273713b92b37b02ae95e5ff70d44af63e76 (patch)
tree3b069a4e39fcd53f815e8c57394b075de20a5b57 /openbsc/src/bsc_rll.c
parent42b4557fca47c07ea68cbfd691589c2346ec52bb (diff)
Add new BSC RLL layer of code
A caller can call rll_establish(lchan, link_id) and a callback to the GSM RLL code. He will get called back if the RLL link is established or receives some error message, or the establishment times out. We need this for proper SMS implementation, where we need to restablish a SAPI3 RLL link before transmitting the actual CP-DATA messages.
Diffstat (limited to 'openbsc/src/bsc_rll.c')
-rw-r--r--openbsc/src/bsc_rll.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/openbsc/src/bsc_rll.c b/openbsc/src/bsc_rll.c
new file mode 100644
index 000000000..09c3bc254
--- /dev/null
+++ b/openbsc/src/bsc_rll.c
@@ -0,0 +1,104 @@
+/* GSM BSC Radio Link Layer API
+ * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
+
+/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <errno.h>
+
+#include <openbsc/debug.h>
+#include <openbsc/talloc.h>
+#include <openbsc/timer.h>
+#include <openbsc/linuxlist.h>
+#include <openbsc/bsc_rll.h>
+#include <openbsc/gsm_data.h>
+#include <openbsc/chan_alloc.h>
+#include <openbsc/abis_rsl.h>
+
+struct bsc_rll_req {
+ struct llist_head list;
+ struct timer_list timer;
+
+ struct gsm_lchan *lchan;
+ u_int8_t link_id;
+
+ void (*cb)(struct gsm_lchan *lchan, u_int8_t link_id,
+ void *data, enum bsc_rllr_ind);
+ void *data;
+};
+
+/* we only compare C1, C2 and SAPI */
+#define LINKID_MASK 0xC7
+
+static LLIST_HEAD(bsc_rll_reqs);
+
+static void complete_rllr(struct bsc_rll_req *rllr, enum bsc_rllr_ind type)
+{
+ llist_del(&rllr->list);
+ put_lchan(rllr->lchan);
+ rllr->cb(rllr->lchan, rllr->link_id, rllr->data, type);
+ talloc_free(rllr);
+}
+
+static void timer_cb(void *_rllr)
+{
+ struct bsc_rll_req *rllr = _rllr;
+
+ complete_rllr(rllr, BSC_RLLR_IND_TIMEOUT);
+}
+
+/* establish a RLL connection with given SAPI / priority */
+int rll_establish(struct gsm_lchan *lchan, u_int8_t link_id,
+ void (*cb)(struct gsm_lchan *, u_int8_t, void *,
+ enum bsc_rllr_ind),
+ void *data)
+{
+ struct bsc_rll_req *rllr = talloc_zero(tall_bsc_ctx, struct bsc_rll_req);
+ if (!rllr)
+ return -ENOMEM;
+
+ use_lchan(lchan);
+ rllr->lchan = lchan;
+ rllr->link_id = link_id;
+ rllr->cb = cb;
+ rllr->data = data;
+
+ rllr->timer.cb = &timer_cb;
+ /* start some timer? */
+ bsc_schedule_timer(&rllr->timer, 10, 0);
+
+ /* send the RSL RLL ESTablish REQuest */
+ return rsl_establish_request(rllr->lchan, rllr->link_id);
+}
+
+/* Called from RSL code in case we have received an indication regarding
+ * any RLL link */
+void rll_indication(struct gsm_lchan *lchan, u_int8_t link_id, u_int8_t type)
+{
+ struct bsc_rll_req *rllr, *rllr2;
+
+ llist_for_each_entry_safe(rllr, rllr2, &bsc_rll_reqs, list) {
+ if (rllr->lchan == lchan &&
+ (rllr->link_id & LINKID_MASK) == (link_id & LINKID_MASK)) {
+ complete_rllr(rllr, type);
+ return;
+ }
+ }
+}