diff options
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/gprs_ms.cpp | 3 | ||||
-rw-r--r-- | src/gprs_ms.h | 5 | ||||
-rw-r--r-- | src/gprs_ms_storage.cpp | 86 | ||||
-rw-r--r-- | src/gprs_ms_storage.h | 41 | ||||
-rw-r--r-- | tests/ms/MsTest.cpp | 54 | ||||
-rw-r--r-- | tests/ms/MsTest.err | 8 | ||||
-rw-r--r-- | tests/ms/MsTest.ok | 2 |
8 files changed, 200 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 0398028c..b5456e00 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 d9d74f4d..af9e834b 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 a59fc5be..3a8a2e17 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 00000000..7260f1bb --- /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 00000000..1eef28fc --- /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 03b1c18d..0895e4db 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 d2e20c43..091e0c85 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 a0d4e9e6..219eec1a 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 === |