ms: Add MS storage class

Currently the MS objects are contained in the TBF objects only. To
allow for an extended life time after the TBF objects have been freed
and to find them based on TLLI, a container for the MS objects is
needed.

This commit adds the container class and also adds the corresponding
m_list member to GprsMs. Further integration into the PCU code is not
yet done.

Ticket: #1674
Sponsored-by: On-Waves ehf
This commit is contained in:
Jacob Erlbeck 2015-05-12 17:54:33 +02:00
parent dfef28de88
commit 5367086175
8 changed files with 200 additions and 1 deletions

View File

@ -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 \

View File

@ -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);
}

View File

@ -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;
};

86
src/gprs_ms_storage.cpp Normal file
View File

@ -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;
}

41
src/gprs_ms_storage.h Normal file
View File

@ -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;
};

View File

@ -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);

View File

@ -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

View File

@ -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 ===