blob: af9e834b86a8d258075462d98fb4a082d47cc04a [file] [log] [blame]
Jacob Erlbecke04e0b02015-05-06 18:30:48 +02001/* gprs_ms.cpp
2 *
3 * Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH
4 * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21
22#include "gprs_ms.h"
23
24#include "tbf.h"
25#include "gprs_debug.h"
26
27extern "C" {
28 #include <osmocom/core/talloc.h>
29 #include <osmocom/core/utils.h>
30}
31
32extern void *tall_pcu_ctx;
33
34struct GprsMsDefaultCallback: public GprsMs::Callback {
35 virtual void ms_idle(class GprsMs *ms) {
36 delete ms;
37 }
38 virtual void ms_active(class GprsMs *) {}
39};
40
41static GprsMsDefaultCallback gprs_default_cb;
42
43
44GprsMs::Guard::Guard(GprsMs *ms) : m_ms(ms)
45{
46 if (m_ms)
47 m_ms->ref();
48}
49
50GprsMs::Guard::~Guard()
51{
52 if (m_ms)
53 m_ms->unref();
54}
55
56GprsMs::GprsMs(uint32_t tlli) :
57 m_cb(&gprs_default_cb),
58 m_ul_tbf(NULL),
59 m_dl_tbf(NULL),
60 m_tlli(tlli),
61 m_is_idle(true),
Jacob Erlbeck53670862015-05-12 17:54:33 +020062 m_ref(0),
63 m_list(this)
Jacob Erlbecke04e0b02015-05-06 18:30:48 +020064{
65 LOGP(DRLCMAC, LOGL_INFO, "Creating MS object, TLLI = 0x%08x\n", tlli);
66}
67
68GprsMs::~GprsMs()
69{
70 LOGP(DRLCMAC, LOGL_INFO, "Destroying MS object, TLLI = 0x%08x\n", tlli());
Jacob Erlbeckfecece02015-05-08 12:13:08 +020071
72 if (m_ul_tbf) {
73 m_ul_tbf->set_ms(NULL);
74 m_ul_tbf = NULL;
75 }
76
77 if (m_dl_tbf) {
78 m_dl_tbf->set_ms(NULL);
79 m_dl_tbf = NULL;
80 }
Jacob Erlbecke04e0b02015-05-06 18:30:48 +020081}
82
83void* GprsMs::operator new(size_t size)
84{
85 static void *tall_ms_ctx = NULL;
86 if (!tall_ms_ctx)
87 tall_ms_ctx = talloc_named_const(tall_pcu_ctx, 0, __PRETTY_FUNCTION__);
88
89 return talloc_size(tall_ms_ctx, size);
90}
91
92void GprsMs::operator delete(void* p)
93{
94 talloc_free(p);
95}
96
97void GprsMs::ref()
98{
99 m_ref += 1;
100}
101
102void GprsMs::unref()
103{
104 OSMO_ASSERT(m_ref >= 0);
105 m_ref -= 1;
106 if (m_ref == 0)
107 update_status();
108}
109
110void GprsMs::attach_tbf(struct gprs_rlcmac_tbf *tbf)
111{
112 if (tbf->direction == GPRS_RLCMAC_DL_TBF)
113 attach_dl_tbf(static_cast<gprs_rlcmac_dl_tbf *>(tbf));
114 else
115 attach_ul_tbf(static_cast<gprs_rlcmac_ul_tbf *>(tbf));
116}
117
118void GprsMs::attach_ul_tbf(struct gprs_rlcmac_ul_tbf *tbf)
119{
120 if (m_ul_tbf == tbf)
121 return;
122
123 LOGP(DRLCMAC, LOGL_INFO, "Attaching TBF to MS object, TLLI = 0x%08x, TBF = %s\n",
124 tlli(), tbf->name());
125
126 Guard guard(this);
127
128 if (m_ul_tbf)
129 detach_tbf(m_ul_tbf);
130
131 m_ul_tbf = tbf;
132}
133
134void GprsMs::attach_dl_tbf(struct gprs_rlcmac_dl_tbf *tbf)
135{
136 if (m_dl_tbf == tbf)
137 return;
138
139 LOGP(DRLCMAC, LOGL_INFO, "Attaching TBF to MS object, TLLI = 0x%08x, TBF = %s\n",
140 tlli(), tbf->name());
141
142 Guard guard(this);
143
144 if (m_dl_tbf)
145 detach_tbf(m_dl_tbf);
146
147 m_dl_tbf = tbf;
148}
149
150void GprsMs::detach_tbf(gprs_rlcmac_tbf *tbf)
151{
152 if (m_ul_tbf && tbf == static_cast<gprs_rlcmac_tbf *>(m_ul_tbf))
153 m_ul_tbf = NULL;
154 else if (m_dl_tbf && tbf == static_cast<gprs_rlcmac_tbf *>(m_dl_tbf))
155 m_dl_tbf = NULL;
156 else
157 return;
158
159 LOGP(DRLCMAC, LOGL_INFO, "Detaching TBF from MS object, TLLI = 0x%08x, TBF = %s\n",
160 tlli(), tbf->name());
161
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200162 if (tbf->ms() == this)
163 tbf->set_ms(NULL);
164
Jacob Erlbecke04e0b02015-05-06 18:30:48 +0200165 update_status();
166}
167
168void GprsMs::update_status()
169{
170 if (m_ref > 0)
171 return;
172
173 if (is_idle() && !m_is_idle) {
174 m_is_idle = true;
175 m_cb->ms_idle(this);
176 /* this can be deleted by now, do not access it */
177 return;
178 }
179
180 if (!is_idle() && m_is_idle) {
181 m_is_idle = false;
182 m_cb->ms_active(this);
183 }
184}
185
186void GprsMs::set_tlli(uint32_t tlli)
187{
188 if (tlli == m_tlli)
189 return;
190
191 LOGP(DRLCMAC, LOGL_INFO,
192 "Modifying MS object, TLLI: 0x%08x -> 0x%08x\n",
193 m_tlli, tlli);
194
195 m_tlli = tlli;
196}