aboutsummaryrefslogtreecommitdiffstats
path: root/src/ta.cpp
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2013-10-19 19:50:00 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2013-10-30 21:24:10 +0100
commitd6ef5345e570cf2a725e2d73bb0146b72a063f30 (patch)
tree2300d5148d25c930b6495c80300b9cb5b3688fb4 /src/ta.cpp
parent63f29d6f73d069479b5269b924df0638da6c88e5 (diff)
ta: Move timing advance related code into the ta.cpp file
Diffstat (limited to 'src/ta.cpp')
-rw-r--r--src/ta.cpp133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/ta.cpp b/src/ta.cpp
new file mode 100644
index 00000000..7aef867c
--- /dev/null
+++ b/src/ta.cpp
@@ -0,0 +1,133 @@
+/*
+ * ta.cpp timing advance handling
+ * Copyright (C) 2012 Ivan Klyuchnikov
+ * Copyright (C) 2012 Andreas Eversberg <jolly@eversberg.eu>
+ * Copyright (C) 2013 by Holger Hans Peter Freyther
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gprs_rlcmac.h>
+
+extern "C" {
+ #include <osmocom/core/talloc.h>
+}
+
+#include <errno.h>
+
+extern void *tall_pcu_ctx;
+
+/*
+ * timing advance memory
+ */
+
+/* enable to debug timing advance memory */
+//#define DEBUG_TA
+
+static LLIST_HEAD(gprs_rlcmac_ta_list);
+static int gprs_rlcmac_ta_num = 0;
+
+struct gprs_rlcmac_ta {
+ struct llist_head list;
+ uint32_t tlli;
+ uint8_t ta;
+};
+
+/* remember timing advance of a given TLLI */
+int remember_timing_advance(uint32_t tlli, uint8_t ta)
+{
+ struct gprs_rlcmac_ta *ta_entry;
+
+ /* check for existing entry */
+ llist_for_each_entry(ta_entry, &gprs_rlcmac_ta_list, list) {
+ if (ta_entry->tlli == tlli) {
+#ifdef DEBUG_TA
+ fprintf(stderr, "update %08x %d\n", tlli, ta);
+#endif
+ ta_entry->ta = ta;
+ /* relink to end of list */
+ llist_del(&ta_entry->list);
+ llist_add_tail(&ta_entry->list, &gprs_rlcmac_ta_list);
+ return 0;
+ }
+ }
+
+#ifdef DEBUG_TA
+ fprintf(stderr, "remember %08x %d\n", tlli, ta);
+#endif
+ /* if list is full, remove oldest entry */
+ if (gprs_rlcmac_ta_num == 30) {
+ ta_entry = llist_entry(gprs_rlcmac_ta_list.next,
+ struct gprs_rlcmac_ta, list);
+ llist_del(&ta_entry->list);
+ talloc_free(ta_entry);
+ gprs_rlcmac_ta_num--;
+ }
+
+ /* create new TA entry */
+ ta_entry = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ta);
+ if (!ta_entry)
+ return -ENOMEM;
+
+ ta_entry->tlli = tlli;
+ ta_entry->ta = ta;
+ llist_add_tail(&ta_entry->list, &gprs_rlcmac_ta_list);
+ gprs_rlcmac_ta_num++;
+
+ return 0;
+}
+
+int recall_timing_advance(uint32_t tlli)
+{
+ struct gprs_rlcmac_ta *ta_entry;
+ uint8_t ta;
+
+ llist_for_each_entry(ta_entry, &gprs_rlcmac_ta_list, list) {
+ if (ta_entry->tlli == tlli) {
+ ta = ta_entry->ta;
+#ifdef DEBUG_TA
+ fprintf(stderr, "recall %08x %d\n", tlli, ta);
+#endif
+ return ta;
+ }
+ }
+#ifdef DEBUG_TA
+ fprintf(stderr, "no entry for %08x\n", tlli);
+#endif
+
+ return -EINVAL;
+}
+
+int flush_timing_advance(void)
+{
+ struct gprs_rlcmac_ta *ta_entry;
+ int count = 0;
+
+ while (!llist_empty(&gprs_rlcmac_ta_list)) {
+ ta_entry = llist_entry(gprs_rlcmac_ta_list.next,
+ struct gprs_rlcmac_ta, list);
+#ifdef DEBUG_TA
+ fprintf(stderr, "flush entry %08x %d\n", ta_entry->tlli,
+ ta_entry->ta);
+#endif
+ llist_del(&ta_entry->list);
+ talloc_free(ta_entry);
+ count++;
+ }
+ gprs_rlcmac_ta_num = 0;
+
+ return count;
+}
+