aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libcommon
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2014-11-07 14:07:48 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-11-11 22:52:21 +0100
commit3911880b68ddd92c9dd89d6ac20c26807e33f905 (patch)
treee6f15cd028a1c96879d78218b8ae29edf6d6a6c0 /openbsc/src/libcommon
parentcdd4302c6dde84693a16b33362a75061480333cd (diff)
bsc: Move gsm_subscriber_base.c to libcommon
Since it is planned to use struct gsm_subscriber to manage subscriber data in the SGSN, this file which contains the generic subscriber related methods is moved to libcommon. Sponsored-by: On-Waves ehf
Diffstat (limited to 'openbsc/src/libcommon')
-rw-r--r--openbsc/src/libcommon/Makefile.am4
-rw-r--r--openbsc/src/libcommon/gsm_subscriber_base.c156
2 files changed, 159 insertions, 1 deletions
diff --git a/openbsc/src/libcommon/Makefile.am b/openbsc/src/libcommon/Makefile.am
index e41326f12..75f40eea7 100644
--- a/openbsc/src/libcommon/Makefile.am
+++ b/openbsc/src/libcommon/Makefile.am
@@ -4,4 +4,6 @@ AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) \
noinst_LIBRARIES = libcommon.a
-libcommon_a_SOURCES = bsc_version.c common_vty.c debug.c gsm_data.c gsm_data_shared.c socket.c talloc_ctx.c
+libcommon_a_SOURCES = bsc_version.c common_vty.c debug.c gsm_data.c \
+ gsm_data_shared.c socket.c talloc_ctx.c \
+ gsm_subscriber_base.c
diff --git a/openbsc/src/libcommon/gsm_subscriber_base.c b/openbsc/src/libcommon/gsm_subscriber_base.c
new file mode 100644
index 000000000..5e00443c2
--- /dev/null
+++ b/openbsc/src/libcommon/gsm_subscriber_base.c
@@ -0,0 +1,156 @@
+/* The concept of a subscriber as seen by the BSC */
+
+/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010 by On-Waves
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <osmocom/core/talloc.h>
+#include <openbsc/gsm_subscriber.h>
+#include <openbsc/debug.h>
+
+LLIST_HEAD(active_subscribers);
+void *tall_subscr_ctx;
+
+/* for the gsm_subscriber.c */
+struct llist_head *subscr_bsc_active_subscribers(void)
+{
+ return &active_subscribers;
+}
+
+
+char *subscr_name(struct gsm_subscriber *subscr)
+{
+ if (strlen(subscr->name))
+ return subscr->name;
+
+ return subscr->imsi;
+}
+
+struct gsm_subscriber *subscr_alloc(void)
+{
+ struct gsm_subscriber *s;
+
+ s = talloc_zero(tall_subscr_ctx, struct gsm_subscriber);
+ if (!s)
+ return NULL;
+
+ llist_add_tail(&s->entry, &active_subscribers);
+ s->use_count = 1;
+ s->tmsi = GSM_RESERVED_TMSI;
+
+ INIT_LLIST_HEAD(&s->requests);
+
+ return s;
+}
+
+static void subscr_free(struct gsm_subscriber *subscr)
+{
+ llist_del(&subscr->entry);
+ talloc_free(subscr);
+}
+
+void subscr_direct_free(struct gsm_subscriber *subscr)
+{
+ OSMO_ASSERT(subscr->use_count == 1);
+ subscr_free(subscr);
+}
+
+struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr)
+{
+ subscr->use_count++;
+ DEBUGP(DREF, "subscr %s usage increases usage to: %d\n",
+ subscr->extension, subscr->use_count);
+ return subscr;
+}
+
+struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr)
+{
+ subscr->use_count--;
+ DEBUGP(DREF, "subscr %s usage decreased usage to: %d\n",
+ subscr->extension, subscr->use_count);
+ if (subscr->use_count <= 0 && !subscr->net->keep_subscr)
+ subscr_free(subscr);
+ return NULL;
+}
+
+struct gsm_subscriber *subscr_get_or_create(struct gsm_network *net,
+ const char *imsi)
+{
+ struct gsm_subscriber *subscr;
+
+ llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
+ if (strcmp(subscr->imsi, imsi) == 0 && subscr->net == net)
+ return subscr_get(subscr);
+ }
+
+ subscr = subscr_alloc();
+ if (!subscr)
+ return NULL;
+
+ strncpy(subscr->imsi, imsi, GSM_IMSI_LENGTH);
+ subscr->imsi[GSM_IMSI_LENGTH - 1] = '\0';
+ subscr->net = net;
+ return subscr;
+}
+
+struct gsm_subscriber *subscr_active_by_tmsi(struct gsm_network *net, uint32_t tmsi)
+{
+ struct gsm_subscriber *subscr;
+
+ llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
+ if (subscr->tmsi == tmsi && subscr->net == net)
+ return subscr_get(subscr);
+ }
+
+ return NULL;
+}
+
+struct gsm_subscriber *subscr_active_by_imsi(struct gsm_network *net, const char *imsi)
+{
+ struct gsm_subscriber *subscr;
+
+ llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
+ if (strcmp(subscr->imsi, imsi) == 0 && subscr->net == net)
+ return subscr_get(subscr);
+ }
+
+ return NULL;
+}
+
+int subscr_purge_inactive(struct gsm_network *net)
+{
+ struct gsm_subscriber *subscr, *tmp;
+ int purged = 0;
+
+ llist_for_each_entry_safe(subscr, tmp, subscr_bsc_active_subscribers(), entry) {
+ if (subscr->net == net && subscr->use_count <= 0) {
+ subscr_free(subscr);
+ purged += 1;
+ }
+ }
+
+ return purged;
+}