aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am2
-rw-r--r--src/gprs_ms.cpp3
-rw-r--r--src/gprs_ms.h5
-rw-r--r--src/gprs_ms_storage.cpp86
-rw-r--r--src/gprs_ms_storage.h41
-rw-r--r--tests/ms/MsTest.cpp54
-rw-r--r--tests/ms/MsTest.err8
-rw-r--r--tests/ms/MsTest.ok2
8 files changed, 200 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 0398028..b5456e0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -38,6 +38,7 @@ libgprs_la_SOURCES = \
gprs_rlcmac_meas.cpp \
gprs_rlcmac_ts_alloc.cpp \
gprs_ms.cpp \
+ gprs_ms_storage.cpp \
gsm_timer.cpp \
bitvector.cpp \
pcu_l1_if.cpp \
@@ -79,6 +80,7 @@ noinst_HEADERS = \
gprs_bssgp_pcu.h \
gprs_rlcmac.h \
gprs_ms.h \
+ gprs_ms_storage.h \
pcuif_proto.h \
pcu_l1_if.h \
gsm_timer.h \
diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp
index d9d74f4..af9e834 100644
--- a/src/gprs_ms.cpp
+++ b/src/gprs_ms.cpp
@@ -59,7 +59,8 @@ GprsMs::GprsMs(uint32_t tlli) :
m_dl_tbf(NULL),
m_tlli(tlli),
m_is_idle(true),
- m_ref(0)
+ m_ref(0),
+ m_list(this)
{
LOGP(DRLCMAC, LOGL_INFO, "Creating MS object, TLLI = 0x%08x\n", tlli);
}
diff --git a/src/gprs_ms.h b/src/gprs_ms.h
index a59fc5b..3a8a2e1 100644
--- a/src/gprs_ms.h
+++ b/src/gprs_ms.h
@@ -24,6 +24,7 @@ struct gprs_rlcmac_tbf;
struct gprs_rlcmac_dl_tbf;
struct gprs_rlcmac_ul_tbf;
+#include "cxx_linuxlist.h"
#include <stdint.h>
#include <stddef.h>
@@ -64,6 +65,9 @@ public:
void* operator new(size_t num);
void operator delete(void* p);
+ LListHead<GprsMs>& list() {return this->m_list;}
+ const LListHead<GprsMs>& list() const {return this->m_list;}
+
protected:
void update_status();
void ref();
@@ -76,4 +80,5 @@ private:
uint32_t m_tlli;
bool m_is_idle;
int m_ref;
+ LListHead<GprsMs> m_list;
};
diff --git a/src/gprs_ms_storage.cpp b/src/gprs_ms_storage.cpp
new file mode 100644
index 0000000..7260f1b
--- /dev/null
+++ b/src/gprs_ms_storage.cpp
@@ -0,0 +1,86 @@
+/* gprs_ms_storage.cpp
+ *
+ * Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH
+ * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
+ *
+ * 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_ms_storage.h"
+
+#include "tbf.h"
+#include "gprs_debug.h"
+
+GprsMsStorage::GprsMsStorage()
+{
+}
+
+GprsMsStorage::~GprsMsStorage()
+{
+ LListHead<GprsMs> *pos, *tmp;
+
+ llist_for_each_safe(pos, tmp, &m_list) {
+ GprsMs *ms = pos->entry();
+ ms->set_callback(NULL);
+ ms_idle(ms);
+ }
+}
+
+void GprsMsStorage::ms_idle(class GprsMs *ms)
+{
+ llist_del(&ms->list());
+ if (ms->is_idle())
+ delete ms;
+}
+
+void GprsMsStorage::ms_active(class GprsMs *ms)
+{
+ /* Nothing to do */
+}
+
+GprsMs *GprsMsStorage::get_ms(uint32_t tlli, uint32_t old_tlli, const char *imsi) const
+{
+ GprsMs *ms = NULL;
+ LListHead<GprsMs> *pos;
+
+ llist_for_each(pos, &m_list) {
+ ms = pos->entry();
+ if (tlli && ms->tlli() == tlli)
+ break;
+ if (old_tlli && ms->tlli() == old_tlli)
+ break;
+ /* TODO: Check for IMSI */
+
+ /* not found */
+ ms = NULL;
+ }
+
+ return ms;
+}
+
+GprsMs *GprsMsStorage::get_or_create_ms(uint32_t tlli, uint32_t old_tlli, const char *imsi)
+{
+ GprsMs *ms = get_ms(tlli, old_tlli, imsi);
+
+ if (ms)
+ return ms;
+
+ ms = new GprsMs(tlli);
+ ms->set_callback(this);
+ llist_add(&ms->list(), &m_list);
+
+ return ms;
+}
diff --git a/src/gprs_ms_storage.h b/src/gprs_ms_storage.h
new file mode 100644
index 0000000..1eef28f
--- /dev/null
+++ b/src/gprs_ms_storage.h
@@ -0,0 +1,41 @@
+/* gprs_ms_storage.h
+ *
+ * Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH
+ * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include "gprs_ms.h"
+#include "cxx_linuxlist.h"
+#include <stdint.h>
+#include <stddef.h>
+
+class GprsMsStorage : public GprsMs::Callback {
+public:
+ GprsMsStorage();
+ ~GprsMsStorage();
+
+ virtual void ms_idle(class GprsMs *);
+ virtual void ms_active(class GprsMs *);
+
+ GprsMs *get_ms(uint32_t tlli, uint32_t old_tlli = 0, const char *imsi = 0) const;
+ GprsMs *get_or_create_ms(uint32_t tlli, uint32_t old_tlli = 0, const char *imsi = 0);
+
+private:
+ LListHead<GprsMs> m_list;
+};
diff --git a/tests/ms/MsTest.cpp b/tests/ms/MsTest.cpp
index 03b1c18..0895e4d 100644
--- a/tests/ms/MsTest.cpp
+++ b/tests/ms/MsTest.cpp
@@ -23,6 +23,7 @@
#include "tbf.h"
#include "gprs_debug.h"
#include "gprs_ms.h"
+#include "gprs_ms_storage.h"
extern "C" {
#include "pcu_vty.h"
@@ -231,6 +232,58 @@ static void test_ms_replace_tbf()
printf("=== end %s ===\n", __func__);
}
+static void test_ms_storage()
+{
+ uint32_t tlli = 0xffeeddbb;
+ gprs_rlcmac_ul_tbf *ul_tbf;
+ GprsMs *ms;
+ GprsMsStorage store;
+
+ printf("=== start %s ===\n", __func__);
+
+ ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
+ ul_tbf->direction = GPRS_RLCMAC_UL_TBF;
+
+ ms = store.get_ms(tlli + 0);
+ OSMO_ASSERT(ms == NULL);
+
+ ms = store.get_or_create_ms(tlli + 0);
+ OSMO_ASSERT(ms->tlli() == tlli + 0);
+
+ ms = store.get_ms(tlli + 0);
+ OSMO_ASSERT(ms != NULL);
+ OSMO_ASSERT(ms->tlli() == tlli + 0);
+
+ ms = store.get_or_create_ms(tlli + 1);
+ OSMO_ASSERT(ms->tlli() == tlli + 1);
+
+ ms = store.get_ms(tlli + 1);
+ OSMO_ASSERT(ms != NULL);
+ OSMO_ASSERT(ms->tlli() == tlli + 1);
+
+ /* delete ms */
+ ms = store.get_ms(tlli + 0);
+ OSMO_ASSERT(ms != NULL);
+ ms->attach_tbf(ul_tbf);
+ ms->detach_tbf(ul_tbf);
+ ms = store.get_ms(tlli + 0);
+ OSMO_ASSERT(ms == NULL);
+ ms = store.get_ms(tlli + 1);
+ OSMO_ASSERT(ms != NULL);
+
+ /* delete ms */
+ ms = store.get_ms(tlli + 1);
+ OSMO_ASSERT(ms != NULL);
+ ms->attach_tbf(ul_tbf);
+ ms->detach_tbf(ul_tbf);
+ ms = store.get_ms(tlli + 1);
+ OSMO_ASSERT(ms == NULL);
+
+ talloc_free(ul_tbf);
+
+ printf("=== end %s ===\n", __func__);
+}
+
static const struct log_info_cat default_categories[] = {
{"DPCU", "", "GPRS Packet Control Unit (PCU)", LOGL_INFO, 1},
};
@@ -267,6 +320,7 @@ int main(int argc, char **argv)
test_ms_state();
test_ms_callback();
test_ms_replace_tbf();
+ test_ms_storage();
if (getenv("TALLOC_REPORT_FULL"))
talloc_report_full(tall_pcu_ctx, stderr);
diff --git a/tests/ms/MsTest.err b/tests/ms/MsTest.err
index d2e20c4..091e0c8 100644
--- a/tests/ms/MsTest.err
+++ b/tests/ms/MsTest.err
@@ -18,3 +18,11 @@ Attaching TBF to MS object, TLLI = 0xffeeddbb, TBF = TBF(TFI=0 TLLI=0x00000000 D
Detaching TBF from MS object, TLLI = 0xffeeddbb, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL)
Detaching TBF from MS object, TLLI = 0xffeeddbb, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL)
Destroying MS object, TLLI = 0xffeeddbb
+Creating MS object, TLLI = 0xffeeddbb
+Creating MS object, TLLI = 0xffeeddbc
+Attaching TBF to MS object, TLLI = 0xffeeddbb, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL)
+Detaching TBF from MS object, TLLI = 0xffeeddbb, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL)
+Destroying MS object, TLLI = 0xffeeddbb
+Attaching TBF to MS object, TLLI = 0xffeeddbc, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL)
+Detaching TBF from MS object, TLLI = 0xffeeddbc, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=UL STATE=NULL)
+Destroying MS object, TLLI = 0xffeeddbc
diff --git a/tests/ms/MsTest.ok b/tests/ms/MsTest.ok
index a0d4e9e..219eec1 100644
--- a/tests/ms/MsTest.ok
+++ b/tests/ms/MsTest.ok
@@ -8,3 +8,5 @@
ms_active() was called
ms_idle() was called
=== end test_ms_replace_tbf ===
+=== start test_ms_storage ===
+=== end test_ms_storage ===