~ubuntu-branches/debian/sid/osmo-pcu/sid

« back to all changes in this revision

Viewing changes to src/tbf.cpp

  • Committer: Package Import Robot
  • Author(s): Thorsten Alteholz
  • Date: 2017-12-12 19:07:49 UTC
  • Revision ID: package-import@ubuntu.com-20171212190749-h4lfqf29yw1bi6v5
Tags: upstream-0.4.0
ImportĀ upstreamĀ versionĀ 0.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copied from gprs_bssgp_pcu.cpp
 
2
 *
 
3
 * Copyright (C) 2012 Ivan Klyuchnikov
 
4
 * Copyright (C) 2012 Andreas Eversberg <jolly@eversberg.eu>
 
5
 * Copyright (C) 2013 by Holger Hans Peter Freyther
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU General Public License
 
9
 * as published by the Free Software Foundation; either version 2
 
10
 * of the License, or (at your option) any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
20
 */
 
21
 
 
22
#include <bts.h>
 
23
#include <tbf.h>
 
24
#include <rlc.h>
 
25
#include <encoding.h>
 
26
#include <gprs_rlcmac.h>
 
27
#include <gprs_debug.h>
 
28
#include <gprs_bssgp_pcu.h>
 
29
#include <gprs_ms.h>
 
30
#include <decoding.h>
 
31
#include <pcu_utils.h>
 
32
 
 
33
extern "C" {
 
34
#include <osmocom/core/msgb.h>
 
35
#include <osmocom/core/talloc.h>
 
36
#include <osmocom/core/stats.h>
 
37
}
 
38
 
 
39
#include <errno.h>
 
40
#include <string.h>
 
41
 
 
42
extern void *tall_pcu_ctx;
 
43
 
 
44
static void tbf_timer_cb(void *_tbf);
 
45
 
 
46
const struct value_string gprs_rlcmac_tbf_dl_ass_state_names[] = {
 
47
        OSMO_VALUE_STRING(GPRS_RLCMAC_DL_ASS_NONE),
 
48
        OSMO_VALUE_STRING(GPRS_RLCMAC_DL_ASS_SEND_ASS),
 
49
        OSMO_VALUE_STRING(GPRS_RLCMAC_DL_ASS_WAIT_ACK),
 
50
        { 0, NULL }
 
51
};
 
52
 
 
53
const struct value_string gprs_rlcmac_tbf_ul_ass_state_names[] = {
 
54
        OSMO_VALUE_STRING(GPRS_RLCMAC_UL_ASS_NONE),
 
55
        OSMO_VALUE_STRING(GPRS_RLCMAC_UL_ASS_SEND_ASS),
 
56
        OSMO_VALUE_STRING(GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ),
 
57
        OSMO_VALUE_STRING(GPRS_RLCMAC_UL_ASS_WAIT_ACK),
 
58
        { 0, NULL }
 
59
};
 
60
 
 
61
static const struct rate_ctr_desc tbf_ctr_description[] = {
 
62
        { "rlc.nacked",                     "RLC Nacked " },
 
63
};
 
64
 
 
65
static const struct rate_ctr_desc tbf_dl_gprs_ctr_description[] = {
 
66
        { "gprs.downlink.cs1",              "CS1        " },
 
67
        { "gprs.downlink.cs2",              "CS2        " },
 
68
        { "gprs.downlink.cs3",              "CS3        " },
 
69
        { "gprs.downlink.cs4",              "CS4        " },
 
70
};
 
71
 
 
72
static const struct rate_ctr_desc tbf_dl_egprs_ctr_description[] = {
 
73
        { "egprs.downlink.mcs1",            "MCS1        " },
 
74
        { "egprs.downlink.mcs2",            "MCS2        " },
 
75
        { "egprs.downlink.mcs3",            "MCS3        " },
 
76
        { "egprs.downlink.mcs4",            "MCS4        " },
 
77
        { "egprs.downlink.mcs5",            "MCS5        " },
 
78
        { "egprs.downlink.mcs6",            "MCS6        " },
 
79
        { "egprs.downlink.mcs7",            "MCS7        " },
 
80
        { "egprs.downlink.mcs8",            "MCS8        " },
 
81
        { "egprs.downlink.mcs9",            "MCS9        " },
 
82
};
 
83
 
 
84
static const struct rate_ctr_desc tbf_ul_gprs_ctr_description[] = {
 
85
        { "gprs.uplink.cs1",              "CS1        " },
 
86
        { "gprs.uplink.cs2",              "CS2        " },
 
87
        { "gprs.uplink.cs3",              "CS3        " },
 
88
        { "gprs.uplink.cs4",              "CS4        " },
 
89
};
 
90
 
 
91
static const struct rate_ctr_desc tbf_ul_egprs_ctr_description[] = {
 
92
        { "egprs.uplink.mcs1",            "MCS1        " },
 
93
        { "egprs.uplink.mcs2",            "MCS2        " },
 
94
        { "egprs.uplink.mcs3",            "MCS3        " },
 
95
        { "egprs.uplink.mcs4",            "MCS4        " },
 
96
        { "egprs.uplink.mcs5",            "MCS5        " },
 
97
        { "egprs.uplink.mcs6",            "MCS6        " },
 
98
        { "egprs.uplink.mcs7",            "MCS7        " },
 
99
        { "egprs.uplink.mcs8",            "MCS8        " },
 
100
        { "egprs.uplink.mcs9",            "MCS9        " },
 
101
};
 
102
 
 
103
static const struct rate_ctr_group_desc tbf_ctrg_desc = {
 
104
        "pcu.tbf",
 
105
        "TBF Statistics",
 
106
        OSMO_STATS_CLASS_SUBSCRIBER,
 
107
        ARRAY_SIZE(tbf_ctr_description),
 
108
        tbf_ctr_description,
 
109
};
 
110
 
 
111
static const struct rate_ctr_group_desc tbf_dl_gprs_ctrg_desc = {
 
112
        "tbf.gprs",
 
113
        "Data Blocks",
 
114
        OSMO_STATS_CLASS_SUBSCRIBER,
 
115
        ARRAY_SIZE(tbf_dl_gprs_ctr_description),
 
116
        tbf_dl_gprs_ctr_description,
 
117
};
 
118
 
 
119
static const struct rate_ctr_group_desc tbf_dl_egprs_ctrg_desc = {
 
120
        "tbf.egprs",
 
121
        "Data Blocks",
 
122
        OSMO_STATS_CLASS_SUBSCRIBER,
 
123
        ARRAY_SIZE(tbf_dl_egprs_ctr_description),
 
124
        tbf_dl_egprs_ctr_description,
 
125
};
 
126
 
 
127
static const struct rate_ctr_group_desc tbf_ul_gprs_ctrg_desc = {
 
128
        "tbf.gprs",
 
129
        "Data Blocks",
 
130
        OSMO_STATS_CLASS_SUBSCRIBER,
 
131
        ARRAY_SIZE(tbf_ul_gprs_ctr_description),
 
132
        tbf_ul_gprs_ctr_description,
 
133
};
 
134
 
 
135
static const struct rate_ctr_group_desc tbf_ul_egprs_ctrg_desc = {
 
136
        "tbf.egprs",
 
137
        "Data Blocks",
 
138
        OSMO_STATS_CLASS_SUBSCRIBER,
 
139
        ARRAY_SIZE(tbf_ul_egprs_ctr_description),
 
140
        tbf_ul_egprs_ctr_description,
 
141
};
 
142
 
 
143
gprs_rlcmac_tbf::Meas::Meas() :
 
144
        rssi_sum(0),
 
145
        rssi_num(0)
 
146
{
 
147
        timerclear(&rssi_tv);
 
148
}
 
149
 
 
150
gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, gprs_rlcmac_tbf_direction dir) :
 
151
        state_flags(0),
 
152
        direction(dir),
 
153
        trx(NULL),
 
154
        first_ts(0),
 
155
        first_common_ts(0),
 
156
        control_ts(0xff),
 
157
        dl_ass_state(GPRS_RLCMAC_DL_ASS_NONE),
 
158
        ul_ass_state(GPRS_RLCMAC_UL_ASS_NONE),
 
159
        ul_ack_state(GPRS_RLCMAC_UL_ACK_NONE),
 
160
        poll_state(GPRS_RLCMAC_POLL_NONE),
 
161
        poll_fn(0),
 
162
        poll_ts(0),
 
163
        n3105(0),
 
164
        T(0),
 
165
        num_T_exp(0),
 
166
        fT(0),
 
167
        num_fT_exp(0),
 
168
        state(GPRS_RLCMAC_NULL),
 
169
        was_releasing(0),
 
170
        upgrade_to_multislot(0),
 
171
        bts(bts_),
 
172
        m_tfi(0),
 
173
        m_created_ts(0),
 
174
        m_ctrs(NULL),
 
175
        m_ms(NULL),
 
176
        m_ta(GSM48_TA_INVALID),
 
177
        m_ms_class(0),
 
178
        m_list(this),
 
179
        m_ms_list(this),
 
180
        m_egprs_enabled(false)
 
181
{
 
182
        /* The classes of these members do not have proper constructors yet.
 
183
         * Just set them to 0 like talloc_zero did */
 
184
        memset(&pdch, 0, sizeof(pdch));
 
185
        memset(&timer, 0, sizeof(timer));
 
186
        memset(&m_rlc, 0, sizeof(m_rlc));
 
187
        memset(&gsm_timer, 0, sizeof(gsm_timer));
 
188
 
 
189
        m_llc.init();
 
190
 
 
191
        m_name_buf[0] = '\0';
 
192
}
 
193
 
 
194
gprs_rlcmac_bts *gprs_rlcmac_tbf::bts_data() const
 
195
{
 
196
        return bts->bts_data();
 
197
}
 
198
 
 
199
uint32_t gprs_rlcmac_tbf::tlli() const
 
200
{
 
201
        return m_ms ? m_ms->tlli() : 0;
 
202
}
 
203
 
 
204
const char *gprs_rlcmac_tbf::imsi() const
 
205
{
 
206
        static const char nullc = 0;
 
207
        return m_ms ? m_ms->imsi() : &nullc;
 
208
}
 
209
 
 
210
void gprs_rlcmac_tbf::assign_imsi(const char *imsi_)
 
211
{
 
212
        GprsMs *old_ms;
 
213
 
 
214
        if (!imsi_ || !m_ms) {
 
215
                LOGP(DRLCMAC, LOGL_ERROR,
 
216
                        "%s failed to assign IMSI: missing IMSI or MS object\n",
 
217
                        name());
 
218
                return;
 
219
        }
 
220
 
 
221
        if (strcmp(imsi_, imsi()) == 0)
 
222
                return;
 
223
 
 
224
        /* really change the IMSI */
 
225
 
 
226
        old_ms = bts->ms_store().get_ms(0, 0, imsi_);
 
227
        if (old_ms) {
 
228
                /* We cannot find m_ms by IMSI since we know that it has a
 
229
                 * different IMSI */
 
230
                OSMO_ASSERT(old_ms != m_ms);
 
231
 
 
232
                LOGP(DRLCMAC, LOGL_INFO,
 
233
                        "%s the IMSI '%s' was already assigned to another "
 
234
                        "MS object: TLLI = 0x%08x, that IMSI will be removed\n",
 
235
                        name(), imsi_, old_ms->tlli());
 
236
 
 
237
                merge_and_clear_ms(old_ms);
 
238
        }
 
239
 
 
240
        m_ms->set_imsi(imsi_);
 
241
}
 
242
 
 
243
uint8_t gprs_rlcmac_tbf::ta() const
 
244
{
 
245
        return m_ms ? m_ms->ta() : m_ta;
 
246
}
 
247
 
 
248
void gprs_rlcmac_tbf::set_ta(uint8_t ta)
 
249
{
 
250
        if (ms())
 
251
                ms()->set_ta(ta);
 
252
 
 
253
        if (gsm48_ta_is_valid(ta))
 
254
                m_ta = ta;
 
255
}
 
256
 
 
257
uint8_t gprs_rlcmac_tbf::ms_class() const
 
258
{
 
259
        return m_ms ? m_ms->ms_class() : m_ms_class;
 
260
}
 
261
 
 
262
void gprs_rlcmac_tbf::set_ms_class(uint8_t ms_class_)
 
263
{
 
264
        if (ms())
 
265
                ms()->set_ms_class(ms_class_);
 
266
 
 
267
        m_ms_class = ms_class_;
 
268
}
 
269
 
 
270
GprsCodingScheme gprs_rlcmac_tbf::current_cs() const
 
271
{
 
272
        GprsCodingScheme cs;
 
273
        if (direction == GPRS_RLCMAC_UL_TBF)
 
274
                cs = m_ms ? m_ms->current_cs_ul() : GprsCodingScheme();
 
275
        else
 
276
                cs = m_ms ? m_ms->current_cs_dl() : GprsCodingScheme();
 
277
 
 
278
        return cs;
 
279
}
 
280
 
 
281
gprs_llc_queue *gprs_rlcmac_tbf::llc_queue()
 
282
{
 
283
        return m_ms ? m_ms->llc_queue() : NULL;
 
284
}
 
285
 
 
286
const gprs_llc_queue *gprs_rlcmac_tbf::llc_queue() const
 
287
{
 
288
        return m_ms ? m_ms->llc_queue() : NULL;
 
289
}
 
290
 
 
291
int gprs_rlcmac_tbf::llc_queue_size() const
 
292
{
 
293
        /* m_ms->llc_queue() never returns NULL: GprsMs::m_llc_queue is a
 
294
         * member instance. */
 
295
        return m_ms ? m_ms->llc_queue()->size() : 0;
 
296
}
 
297
 
 
298
void gprs_rlcmac_tbf::set_ms(GprsMs *ms)
 
299
{
 
300
        if (m_ms == ms)
 
301
                return;
 
302
 
 
303
        if (m_ms) {
 
304
                /* Save the TA locally. This will also be called, if the MS
 
305
                 * object detaches itself from the TBF, for instance if
 
306
                 * attach_tbf() is called */
 
307
                m_ta = m_ms->ta();
 
308
 
 
309
                m_ms->detach_tbf(this);
 
310
        }
 
311
 
 
312
        m_ms = ms;
 
313
 
 
314
        if (m_ms)
 
315
                m_ms->attach_tbf(this);
 
316
}
 
317
 
 
318
void gprs_rlcmac_tbf::merge_and_clear_ms(GprsMs *old_ms)
 
319
{
 
320
        if (old_ms == ms())
 
321
                return;
 
322
 
 
323
        GprsMs::Guard guard_old(old_ms);
 
324
 
 
325
        /* Clean up the old MS object */
 
326
        /* TODO: Use timer? */
 
327
        if (old_ms->ul_tbf() && old_ms->ul_tbf()->T == 0) {
 
328
                if (old_ms->ul_tbf() == this) {
 
329
                        LOGP(DRLCMAC, LOGL_ERROR,
 
330
                                "%s is referred by the old MS "
 
331
                                "and will not be deleted\n",
 
332
                                name());
 
333
                        set_ms(NULL);
 
334
                } else {
 
335
                        tbf_free(old_ms->ul_tbf());
 
336
                }
 
337
        }
 
338
        if (old_ms->dl_tbf() && old_ms->dl_tbf()->T == 0) {
 
339
                if (old_ms->dl_tbf() == this) {
 
340
                        LOGP(DRLCMAC, LOGL_ERROR,
 
341
                                "%s is referred by the old MS "
 
342
                                "and will not be deleted\n",
 
343
                                name());
 
344
                        set_ms(NULL);
 
345
                } else {
 
346
                        tbf_free(old_ms->dl_tbf());
 
347
                }
 
348
        }
 
349
 
 
350
        ms()->merge_old_ms(old_ms);
 
351
}
 
352
 
 
353
void gprs_rlcmac_tbf::update_ms(uint32_t tlli, enum gprs_rlcmac_tbf_direction dir)
 
354
{
 
355
        if (!ms())
 
356
                return;
 
357
 
 
358
        if (!tlli)
 
359
                return;
 
360
 
 
361
        /* TODO: When the TLLI does not match the ms, check if there is another
 
362
         * MS object that belongs to that TLLI and if yes make sure one of them
 
363
         * gets deleted. This is the same problem that can arise with
 
364
         * assign_imsi() so there should be a unified solution */
 
365
        if (!ms()->check_tlli(tlli)) {
 
366
                GprsMs *old_ms;
 
367
 
 
368
                old_ms = bts->ms_store().get_ms(tlli, 0, NULL);
 
369
                if (old_ms)
 
370
                        merge_and_clear_ms(old_ms);
 
371
        }
 
372
 
 
373
        if (dir == GPRS_RLCMAC_UL_TBF)
 
374
                ms()->set_tlli(tlli);
 
375
        else
 
376
                ms()->confirm_tlli(tlli);
 
377
}
 
378
 
 
379
gprs_rlcmac_ul_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts,
 
380
        int8_t use_trx, uint8_t ms_class, uint8_t egprs_ms_class,
 
381
        uint32_t tlli, uint8_t ta, GprsMs *ms)
 
382
{
 
383
        struct gprs_rlcmac_ul_tbf *tbf;
 
384
 
 
385
/* FIXME: Copy and paste with tbf_new_dl_assignment */
 
386
        /* create new TBF, use same TRX as DL TBF */
 
387
        /* use multislot class of downlink TBF */
 
388
        tbf = tbf_alloc_ul_tbf(bts, ms, use_trx, ms_class, egprs_ms_class, 0);
 
389
        if (!tbf) {
 
390
                LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n");
 
391
                /* FIXME: send reject */
 
392
                return NULL;
 
393
        }
 
394
        tbf->m_contention_resolution_done = 1;
 
395
        tbf->set_state(GPRS_RLCMAC_ASSIGN);
 
396
        tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH);
 
397
        tbf_timer_start(tbf, 3169, bts->t3169, 0);
 
398
        tbf->update_ms(tlli, GPRS_RLCMAC_UL_TBF);
 
399
        OSMO_ASSERT(tbf->ms());
 
400
 
 
401
        tbf->ms()->set_ta(ta);
 
402
 
 
403
        return tbf;
 
404
}
 
405
 
 
406
static void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf)
 
407
{
 
408
        int ts;
 
409
 
 
410
        for (ts = 0; ts < 8; ts++) {
 
411
                if (!tbf->pdch[ts])
 
412
                        continue;
 
413
 
 
414
                tbf->pdch[ts]->detach_tbf(tbf);
 
415
                tbf->pdch[ts] = NULL;
 
416
        }
 
417
}
 
418
 
 
419
void tbf_free(struct gprs_rlcmac_tbf *tbf)
 
420
{
 
421
        /* update counters */
 
422
        if (tbf->direction == GPRS_RLCMAC_UL_TBF) {
 
423
                gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(tbf);
 
424
                tbf->bts->tbf_ul_freed();
 
425
                if (tbf->state_is(GPRS_RLCMAC_FLOW))
 
426
                        tbf->bts->tbf_ul_aborted();
 
427
                rate_ctr_group_free(ul_tbf->m_ul_egprs_ctrs);
 
428
                rate_ctr_group_free(ul_tbf->m_ul_gprs_ctrs);
 
429
        } else {
 
430
                gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(tbf);
 
431
                if (tbf->is_egprs_enabled()) {
 
432
                        rate_ctr_group_free(dl_tbf->m_dl_egprs_ctrs);
 
433
                } else {
 
434
                        rate_ctr_group_free(dl_tbf->m_dl_gprs_ctrs);
 
435
                }
 
436
                tbf->bts->tbf_dl_freed();
 
437
                if (tbf->state_is(GPRS_RLCMAC_FLOW))
 
438
                        tbf->bts->tbf_dl_aborted();
 
439
        }
 
440
 
 
441
        /* Give final measurement report */
 
442
        gprs_rlcmac_rssi_rep(tbf);
 
443
        if (tbf->direction == GPRS_RLCMAC_DL_TBF) {
 
444
                gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(tbf);
 
445
 
 
446
                dl_tbf->abort();
 
447
                dl_tbf->cleanup();
 
448
        }
 
449
 
 
450
        LOGP(DRLCMAC, LOGL_INFO, "%s free\n", tbf_name(tbf));
 
451
        if (tbf->ul_ass_state != GPRS_RLCMAC_UL_ASS_NONE)
 
452
                LOGP(DRLCMAC, LOGL_ERROR, "%s Software error: Pending uplink "
 
453
                     "assignment in state %s. This may not happen, because the "
 
454
                        "assignment message never gets transmitted. Please "
 
455
                        "be sure not to free in this state. PLEASE FIX!\n",
 
456
                     tbf_name(tbf),
 
457
                     get_value_string(gprs_rlcmac_tbf_ul_ass_state_names,
 
458
                                      tbf->ul_ass_state));
 
459
        if (tbf->dl_ass_state != GPRS_RLCMAC_DL_ASS_NONE)
 
460
                LOGP(DRLCMAC, LOGL_ERROR, "%s Software error: Pending downlink "
 
461
                     "assignment in state %s. This may not happen, because the "
 
462
                        "assignment message never gets transmitted. Please "
 
463
                        "be sure not to free in this state. PLEASE FIX!\n",
 
464
                     tbf_name(tbf),
 
465
                     get_value_string(gprs_rlcmac_tbf_dl_ass_state_names,
 
466
                                      tbf->dl_ass_state));
 
467
        tbf->stop_timer();
 
468
        /* TODO: Could/Should generate  bssgp_tx_llc_discarded */
 
469
        tbf_unlink_pdch(tbf);
 
470
        llist_del(&tbf->list());
 
471
 
 
472
        if (tbf->ms())
 
473
                tbf->set_ms(NULL);
 
474
 
 
475
        rate_ctr_group_free(tbf->m_ctrs);
 
476
 
 
477
        LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF ends here **********\n");
 
478
        talloc_free(tbf);
 
479
}
 
480
 
 
481
int gprs_rlcmac_tbf::update()
 
482
{
 
483
        struct gprs_rlcmac_bts *bts_data = bts->bts_data();
 
484
        int rc;
 
485
 
 
486
        LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF update **********\n");
 
487
 
 
488
        if (direction != GPRS_RLCMAC_DL_TBF)
 
489
                return -EINVAL;
 
490
 
 
491
        tbf_unlink_pdch(this);
 
492
        rc = bts_data->alloc_algorithm(bts_data, ms(), this,
 
493
                bts_data->alloc_algorithm_curst, 0, -1);
 
494
        /* if no resource */
 
495
        if (rc < 0) {
 
496
                LOGP(DRLCMAC, LOGL_ERROR, "No resource after update???\n");
 
497
                return -rc;
 
498
        }
 
499
 
 
500
        if (is_egprs_enabled()) {
 
501
                gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this);
 
502
                if (dl_tbf)
 
503
                        dl_tbf->egprs_calc_window_size();
 
504
        }
 
505
 
 
506
        return 0;
 
507
}
 
508
 
 
509
int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf)
 
510
{
 
511
        if (tbf->control_ts == 0xff)
 
512
                LOGP(DRLCMAC, LOGL_INFO, "- Setting Control TS %d\n",
 
513
                        tbf->first_common_ts);
 
514
        else if (tbf->control_ts != tbf->first_common_ts)
 
515
                LOGP(DRLCMAC, LOGL_INFO, "- Changing Control TS %d\n",
 
516
                        tbf->first_common_ts);
 
517
        tbf->control_ts = tbf->first_common_ts;
 
518
 
 
519
        return 0;
 
520
}
 
521
 
 
522
const char *gprs_rlcmac_tbf::tbf_state_name[] = {
 
523
        "NULL",
 
524
        "ASSIGN",
 
525
        "FLOW",
 
526
        "FINISHED",
 
527
        "WAIT RELEASE",
 
528
        "RELEASING",
 
529
};
 
530
 
 
531
void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T,
 
532
                        unsigned int seconds, unsigned int microseconds)
 
533
{
 
534
        if (!osmo_timer_pending(&tbf->timer))
 
535
                LOGP(DRLCMAC, LOGL_DEBUG, "%s starting timer %u.\n",
 
536
                        tbf_name(tbf), T);
 
537
        else
 
538
                LOGP(DRLCMAC, LOGL_DEBUG, "%s restarting timer %u "
 
539
                        "while old timer %u pending \n",
 
540
                        tbf_name(tbf), T, tbf->T);
 
541
 
 
542
        tbf->T = T;
 
543
        tbf->num_T_exp = 0;
 
544
 
 
545
        /* Tunning timers can be safely re-scheduled. */
 
546
        tbf->timer.data = tbf;
 
547
        tbf->timer.cb = &tbf_timer_cb;
 
548
 
 
549
        osmo_timer_schedule(&tbf->timer, seconds, microseconds);
 
550
}
 
551
 
 
552
void gprs_rlcmac_tbf::stop_t3191()
 
553
{
 
554
        return stop_timer();
 
555
}
 
556
 
 
557
void gprs_rlcmac_tbf::stop_timer()
 
558
{
 
559
        if (osmo_timer_pending(&timer)) {
 
560
                LOGP(DRLCMAC, LOGL_DEBUG, "%s stopping timer %u.\n",
 
561
                        tbf_name(this), T);
 
562
                osmo_timer_del(&timer);
 
563
        }
 
564
}
 
565
 
 
566
int gprs_rlcmac_tbf::check_polling(uint32_t fn, uint8_t ts,
 
567
        uint32_t *poll_fn_, unsigned int *rrbp_)
 
568
{
 
569
        uint32_t new_poll_fn = next_fn(fn, 13);
 
570
 
 
571
        if (!is_control_ts(ts)) {
 
572
                LOGP(DRLCMAC, LOGL_DEBUG, "Polling cannot be "
 
573
                        "scheduled in this TS %d (first control TS %d)\n",
 
574
                        ts, control_ts);
 
575
                return -EINVAL;
 
576
        }
 
577
        if (poll_state != GPRS_RLCMAC_POLL_NONE) {
 
578
                LOGP(DRLCMAC, LOGL_DEBUG,
 
579
                        "Polling is already scheduled for %s\n",
 
580
                        name());
 
581
                return -EBUSY;
 
582
        }
 
583
        if (bts->sba()->find(trx->trx_no, ts, next_fn(fn, 13))) {
 
584
                LOGP(DRLCMAC, LOGL_DEBUG, "%s: Polling is already scheduled "
 
585
                        "for single block allocation at FN %d TS %d ...\n",
 
586
                        name(), new_poll_fn, ts);
 
587
                return -EBUSY;
 
588
        }
 
589
 
 
590
        *poll_fn_ = new_poll_fn;
 
591
        *rrbp_ = 0;
 
592
 
 
593
        return 0;
 
594
}
 
595
 
 
596
void gprs_rlcmac_tbf::set_polling(uint32_t new_poll_fn, uint8_t ts, enum gprs_rlcmac_tbf_poll_type t)
 
597
{
 
598
        const char *chan = "UNKNOWN";
 
599
 
 
600
        if (state_flags & (1 << (GPRS_RLCMAC_FLAG_CCCH)))
 
601
                chan = "CCCH";
 
602
 
 
603
        if (state_flags & (1 << (GPRS_RLCMAC_FLAG_PACCH)))
 
604
                chan = "PACCH";
 
605
 
 
606
        if ((state_flags & (1 << (GPRS_RLCMAC_FLAG_PACCH))) && (state_flags & (1 << (GPRS_RLCMAC_FLAG_CCCH))))
 
607
                LOGP(DRLCMACDL, LOGL_ERROR,
 
608
                     "%s Attempt to schedule polling on %s (FN=%d, TS=%d) with both CCCH and PACCH flags set - FIXME!\n",
 
609
                     name(), chan, poll_fn, poll_ts);
 
610
 
 
611
        /* schedule polling */
 
612
        poll_state = GPRS_RLCMAC_POLL_SCHED;
 
613
        poll_fn = new_poll_fn;
 
614
        poll_ts = ts;
 
615
 
 
616
        switch (t) {
 
617
        case GPRS_RLCMAC_POLL_UL_ASS:
 
618
                ul_ass_state = GPRS_RLCMAC_UL_ASS_WAIT_ACK;
 
619
 
 
620
                LOGP(DRLCMACDL, LOGL_INFO, "%s Scheduled UL Assignment polling on %s (FN=%d, TS=%d)\n",
 
621
                     name(), chan, poll_fn, poll_ts);
 
622
                break;
 
623
        case GPRS_RLCMAC_POLL_DL_ASS:
 
624
                dl_ass_state = GPRS_RLCMAC_DL_ASS_WAIT_ACK;
 
625
 
 
626
                LOGP(DRLCMACDL, LOGL_INFO, "%s Scheduled DL Assignment polling on %s (FN=%d, TS=%d)\n",
 
627
                     name(), chan, poll_fn, poll_ts);
 
628
                break;
 
629
        case GPRS_RLCMAC_POLL_UL_ACK:
 
630
                ul_ack_state = GPRS_RLCMAC_UL_ACK_WAIT_ACK;
 
631
 
 
632
                LOGP(DRLCMACUL, LOGL_DEBUG, "%s Scheduled UL Acknowledgement polling on %s (FN=%d, TS=%d)\n",
 
633
                     name(), chan, poll_fn, poll_ts);
 
634
                break;
 
635
        case GPRS_RLCMAC_POLL_DL_ACK:
 
636
                LOGP(DRLCMACDL, LOGL_DEBUG, "%s Scheduled DL Acknowledgement polling on %s (FN=%d, TS=%d)\n",
 
637
                     name(), chan, poll_fn, poll_ts);
 
638
                break;
 
639
        }
 
640
}
 
641
 
 
642
void gprs_rlcmac_tbf::poll_timeout()
 
643
{
 
644
        gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(this);
 
645
 
 
646
        LOGP(DRLCMAC, LOGL_NOTICE, "%s poll timeout for FN=%d, TS=%d (curr FN %d)\n",
 
647
                tbf_name(this), poll_fn, poll_ts, bts->current_frame_number());
 
648
 
 
649
        poll_state = GPRS_RLCMAC_POLL_NONE;
 
650
 
 
651
        if (ul_tbf && ul_tbf->handle_ctrl_ack()) {
 
652
                if (!ul_tbf->ctrl_ack_to_toggle()) {
 
653
                        LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling PACKET CONTROL ACK for PACKET UPLINK ACK\n");
 
654
                        rlcmac_diag();
 
655
                }
 
656
                bts->rlc_ack_timedout();
 
657
                bts->pkt_ul_ack_nack_poll_timedout();
 
658
                if (state_is(GPRS_RLCMAC_FINISHED)) {
 
659
                        ul_tbf->m_n3103++;
 
660
                        if (ul_tbf->m_n3103 == ul_tbf->bts->bts_data()->n3103) {
 
661
                                LOGP(DRLCMAC, LOGL_NOTICE,
 
662
                                     "- N3103 exceeded\n");
 
663
                                bts->pkt_ul_ack_nack_poll_failed();
 
664
                                ul_tbf->set_state(GPRS_RLCMAC_RELEASING);
 
665
                                tbf_timer_start(ul_tbf, 3169, ul_tbf->bts->bts_data()->t3169, 0);
 
666
                                return;
 
667
                        }
 
668
                        /* reschedule UL ack */
 
669
                        ul_tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_SEND_ACK;
 
670
                }
 
671
 
 
672
        } else if (ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) {
 
673
                if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS))) {
 
674
                        LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
 
675
                             "PACKET CONTROL ACK for PACKET UPLINK "
 
676
                             "ASSIGNMENT.\n");
 
677
                                rlcmac_diag();
 
678
                                state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS);
 
679
                }
 
680
                ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE;
 
681
                n3105++;
 
682
                bts->rlc_ass_timedout();
 
683
                bts->pua_poll_timedout();
 
684
                if (n3105 == bts_data()->n3105) {
 
685
                        LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n");
 
686
                        set_state(GPRS_RLCMAC_RELEASING);
 
687
                        tbf_timer_start(this, 3195, bts_data()->t3195, 0);
 
688
                        bts->rlc_ass_failed();
 
689
                        bts->pua_poll_failed();
 
690
                        return;
 
691
                }
 
692
                /* reschedule UL assignment */
 
693
                ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
 
694
        } else if (dl_ass_state == GPRS_RLCMAC_DL_ASS_WAIT_ACK) {
 
695
                if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) {
 
696
                        LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
 
697
                                "PACKET CONTROL ACK for PACKET DOWNLINK "
 
698
                                "ASSIGNMENT.\n");
 
699
                        rlcmac_diag();
 
700
                        state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS);
 
701
                }
 
702
                dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
 
703
                n3105++;
 
704
                bts->rlc_ass_timedout();
 
705
                bts->pda_poll_timedout();
 
706
                if (n3105 == bts->bts_data()->n3105) {
 
707
                        LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n");
 
708
                        set_state(GPRS_RLCMAC_RELEASING);
 
709
                        tbf_timer_start(this, 3195, bts_data()->t3195, 0);
 
710
                        bts->rlc_ass_failed();
 
711
                        bts->pda_poll_failed();
 
712
                        return;
 
713
                }
 
714
                /* reschedule DL assignment */
 
715
                dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS;
 
716
        } else if (direction == GPRS_RLCMAC_DL_TBF) {
 
717
                gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this);
 
718
 
 
719
                if (!(dl_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) {
 
720
                        LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
 
721
                                "PACKET DOWNLINK ACK.\n");
 
722
                        dl_tbf->rlcmac_diag();
 
723
                        dl_tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK);
 
724
                }
 
725
                dl_tbf->n3105++;
 
726
                if (dl_tbf->state_is(GPRS_RLCMAC_RELEASING))
 
727
                        bts->rlc_rel_timedout();
 
728
                else {
 
729
                        bts->rlc_ack_timedout();
 
730
                        bts->pkt_dl_ack_nack_poll_timedout();
 
731
                }
 
732
                if (dl_tbf->n3105 == dl_tbf->bts->bts_data()->n3105) {
 
733
                        LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n");
 
734
                        dl_tbf->set_state(GPRS_RLCMAC_RELEASING);
 
735
                        tbf_timer_start(dl_tbf, 3195, dl_tbf->bts_data()->t3195, 0);
 
736
                        bts->pkt_dl_ack_nack_poll_failed();
 
737
                        bts->rlc_ack_failed();
 
738
                        return;
 
739
                }
 
740
                /* resend IMM.ASS on CCCH on timeout */
 
741
                if ((dl_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))
 
742
                 && !(dl_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK))) {
 
743
                        LOGP(DRLCMAC, LOGL_DEBUG, "Re-send dowlink assignment "
 
744
                                "for %s on PCH (IMSI=%s)\n",
 
745
                                tbf_name(dl_tbf),
 
746
                                imsi());
 
747
                        /* send immediate assignment */
 
748
                        dl_tbf->bts->snd_dl_ass(dl_tbf, 0, imsi());
 
749
                        dl_tbf->m_wait_confirm = 1;
 
750
                }
 
751
        } else
 
752
                LOGP(DRLCMAC, LOGL_ERROR, "- Poll Timeout, but no event!\n");
 
753
}
 
754
 
 
755
static int setup_tbf(struct gprs_rlcmac_tbf *tbf,
 
756
        GprsMs *ms, int8_t use_trx,
 
757
        uint8_t ms_class, uint8_t egprs_ms_class, uint8_t single_slot)
 
758
{
 
759
        int rc;
 
760
        struct gprs_rlcmac_bts *bts;
 
761
        if (!tbf)
 
762
                return -1;
 
763
 
 
764
        bts = tbf->bts->bts_data();
 
765
 
 
766
        if (ms->mode() == GprsCodingScheme::EGPRS)
 
767
                ms_class = egprs_ms_class;
 
768
 
 
769
        tbf->m_created_ts = time(NULL);
 
770
        tbf->set_ms_class(ms_class);
 
771
        /* select algorithm */
 
772
        rc = bts->alloc_algorithm(bts, ms, tbf, bts->alloc_algorithm_curst,
 
773
                single_slot, use_trx);
 
774
        /* if no resource */
 
775
        if (rc < 0) {
 
776
                return -1;
 
777
        }
 
778
        /* assign control ts */
 
779
        rc = tbf_assign_control_ts(tbf);
 
780
        /* if no resource */
 
781
        if (rc < 0) {
 
782
                return -1;
 
783
        }
 
784
 
 
785
        /* set timestamp */
 
786
        gettimeofday(&tbf->meas.rssi_tv, NULL);
 
787
 
 
788
        tbf->set_ms(ms);
 
789
 
 
790
        LOGP(DRLCMAC, LOGL_INFO,
 
791
                "Allocated %s: trx = %d, ul_slots = %02x, dl_slots = %02x\n",
 
792
                tbf->name(), tbf->trx->trx_no, tbf->ul_slots(), tbf->dl_slots());
 
793
 
 
794
        tbf->m_ctrs = rate_ctr_group_alloc(tbf, &tbf_ctrg_desc, 0);
 
795
        if (!tbf->m_ctrs) {
 
796
                LOGP(DRLCMAC, LOGL_ERROR, "Couldn't allocate TBF counters\n");
 
797
                return -1;
 
798
        }
 
799
 
 
800
        return 0;
 
801
}
 
802
 
 
803
gprs_rlcmac_ul_tbf::gprs_rlcmac_ul_tbf(BTS *bts_) :
 
804
        gprs_rlcmac_tbf(bts_, GPRS_RLCMAC_UL_TBF),
 
805
        m_rx_counter(0),
 
806
        m_n3103(0),
 
807
        m_contention_resolution_done(0),
 
808
        m_final_ack_sent(0),
 
809
        m_ul_gprs_ctrs(NULL),
 
810
        m_ul_egprs_ctrs(NULL)
 
811
{
 
812
        memset(&m_usf, 0, sizeof(m_usf));
 
813
}
 
814
 
 
815
static int ul_tbf_dtor(struct gprs_rlcmac_ul_tbf *tbf)
 
816
{
 
817
        tbf->~gprs_rlcmac_ul_tbf();
 
818
        return 0;
 
819
}
 
820
 
 
821
static void setup_egprs_mode(gprs_rlcmac_bts *bts, GprsMs *ms)
 
822
{
 
823
        if (GprsCodingScheme::getEgprsByNum(bts->max_mcs_ul).isEgprsGmsk() &&
 
824
                GprsCodingScheme::getEgprsByNum(bts->max_mcs_dl).isEgprsGmsk() &&
 
825
                ms->mode() != GprsCodingScheme::EGPRS)
 
826
        {
 
827
                ms->set_mode(GprsCodingScheme::EGPRS_GMSK);
 
828
        } else {
 
829
                ms->set_mode(GprsCodingScheme::EGPRS);
 
830
        }
 
831
}
 
832
 
 
833
struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts,
 
834
        GprsMs *ms, int8_t use_trx,
 
835
        uint8_t ms_class, uint8_t egprs_ms_class, uint8_t single_slot)
 
836
{
 
837
        struct gprs_rlcmac_ul_tbf *tbf;
 
838
        int rc;
 
839
 
 
840
        if (egprs_ms_class == 0 && bts->egprs_enabled) {
 
841
                LOGP(DRLCMAC, LOGL_NOTICE,
 
842
                        "Not accepting non-EGPRS phone in EGPRS-only mode\n");
 
843
                bts->bts->tbf_failed_egprs_only();
 
844
                return NULL;
 
845
        }
 
846
 
 
847
        LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n");
 
848
        LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: MS_CLASS=%d/%d\n",
 
849
                "UL", ms_class, egprs_ms_class);
 
850
 
 
851
        tbf = talloc(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
 
852
 
 
853
        if (!tbf)
 
854
                return NULL;
 
855
 
 
856
        talloc_set_destructor(tbf, ul_tbf_dtor);
 
857
        new (tbf) gprs_rlcmac_ul_tbf(bts->bts);
 
858
 
 
859
        if (!ms)
 
860
                ms = bts->bts->ms_alloc(ms_class, egprs_ms_class);
 
861
 
 
862
        if (egprs_ms_class > 0 && bts->egprs_enabled) {
 
863
                tbf->enable_egprs();
 
864
                tbf->m_window.set_sns(RLC_EGPRS_SNS);
 
865
                setup_egprs_mode(bts, ms);
 
866
                LOGP(DRLCMAC, LOGL_INFO, "Enabled EGPRS for %s, mode %s\n",
 
867
                        tbf->name(), GprsCodingScheme::modeName(ms->mode()));
 
868
        }
 
869
 
 
870
        rc = setup_tbf(tbf, ms, use_trx, ms_class, egprs_ms_class, single_slot);
 
871
 
 
872
        if (tbf->is_egprs_enabled())
 
873
                tbf->egprs_calc_ulwindow_size();
 
874
 
 
875
        /* if no resource */
 
876
        if (rc < 0) {
 
877
                talloc_free(tbf);
 
878
                return NULL;
 
879
        }
 
880
 
 
881
        tbf->m_ul_egprs_ctrs = rate_ctr_group_alloc(tbf, &tbf_ul_egprs_ctrg_desc, 0);
 
882
        tbf->m_ul_gprs_ctrs = rate_ctr_group_alloc(tbf, &tbf_ul_gprs_ctrg_desc, 0);
 
883
        if (!tbf->m_ul_egprs_ctrs || !tbf->m_ul_gprs_ctrs) {
 
884
                LOGP(DRLCMAC, LOGL_ERROR, "Couldn't allocate TBF UL counters\n");
 
885
                talloc_free(tbf);
 
886
                return NULL;
 
887
        }
 
888
 
 
889
        llist_add(&tbf->list(), &bts->bts->ul_tbfs());
 
890
        tbf->bts->tbf_ul_created();
 
891
 
 
892
        return tbf;
 
893
}
 
894
 
 
895
gprs_rlcmac_dl_tbf::BandWidth::BandWidth() :
 
896
        dl_bw_octets(0),
 
897
        dl_throughput(0),
 
898
        dl_loss_lost(0),
 
899
        dl_loss_received(0)
 
900
{
 
901
        timerclear(&dl_bw_tv);
 
902
        timerclear(&dl_loss_tv);
 
903
}
 
904
 
 
905
gprs_rlcmac_dl_tbf::gprs_rlcmac_dl_tbf(BTS *bts_) :
 
906
        gprs_rlcmac_tbf(bts_, GPRS_RLCMAC_DL_TBF),
 
907
        m_tx_counter(0),
 
908
        m_wait_confirm(0),
 
909
        m_dl_ack_requested(false),
 
910
        m_last_dl_poll_fn(0),
 
911
        m_last_dl_drained_fn(0),
 
912
        m_dl_gprs_ctrs(NULL),
 
913
        m_dl_egprs_ctrs(NULL)
 
914
{
 
915
        memset(&m_llc_timer, 0, sizeof(m_llc_timer));
 
916
}
 
917
 
 
918
static int dl_tbf_dtor(struct gprs_rlcmac_dl_tbf *tbf)
 
919
{
 
920
        tbf->~gprs_rlcmac_dl_tbf();
 
921
        return 0;
 
922
}
 
923
 
 
924
struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts,
 
925
        GprsMs *ms, int8_t use_trx,
 
926
        uint8_t ms_class, uint8_t egprs_ms_class, uint8_t single_slot)
 
927
{
 
928
        struct gprs_rlcmac_dl_tbf *tbf;
 
929
        int rc;
 
930
 
 
931
        if (egprs_ms_class == 0 && bts->egprs_enabled) {
 
932
                if (ms_class > 0) {
 
933
                        LOGP(DRLCMAC, LOGL_NOTICE,
 
934
                                "Not accepting non-EGPRS phone in EGPRS-only mode\n");
 
935
                        bts->bts->tbf_failed_egprs_only();
 
936
                        return NULL;
 
937
                }
 
938
                egprs_ms_class = 1;
 
939
        }
 
940
 
 
941
        LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n");
 
942
        LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: MS_CLASS=%d/%d\n",
 
943
                "DL", ms_class, egprs_ms_class);
 
944
 
 
945
        tbf = talloc(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
 
946
 
 
947
        if (!tbf)
 
948
                return NULL;
 
949
 
 
950
        talloc_set_destructor(tbf, dl_tbf_dtor);
 
951
        new (tbf) gprs_rlcmac_dl_tbf(bts->bts);
 
952
 
 
953
        if (!ms)
 
954
                ms = bts->bts->ms_alloc(ms_class, egprs_ms_class);
 
955
 
 
956
        if (egprs_ms_class > 0 && bts->egprs_enabled) {
 
957
                tbf->enable_egprs();
 
958
                tbf->m_window.set_sns(RLC_EGPRS_SNS);
 
959
                setup_egprs_mode(bts, ms);
 
960
                LOGP(DRLCMAC, LOGL_INFO, "Enabled EGPRS for %s, mode %s\n",
 
961
                        tbf->name(), GprsCodingScheme::modeName(ms->mode()));
 
962
        }
 
963
 
 
964
        rc = setup_tbf(tbf, ms, use_trx, ms_class, 0, single_slot);
 
965
        /* if no resource */
 
966
        if (rc < 0) {
 
967
                talloc_free(tbf);
 
968
                return NULL;
 
969
        }
 
970
 
 
971
        if (tbf->is_egprs_enabled()) {
 
972
                tbf->egprs_calc_window_size();
 
973
                tbf->m_dl_egprs_ctrs = rate_ctr_group_alloc(tbf, &tbf_dl_egprs_ctrg_desc, 0);
 
974
                if (!tbf->m_dl_egprs_ctrs) {
 
975
                        LOGP(DRLCMAC, LOGL_ERROR, "Couldn't allocate EGPRS DL counters\n");
 
976
                        talloc_free(tbf);
 
977
                        return NULL;
 
978
                }
 
979
        } else {
 
980
                tbf->m_dl_gprs_ctrs = rate_ctr_group_alloc(tbf, &tbf_dl_gprs_ctrg_desc, 0);
 
981
                if (!tbf->m_dl_gprs_ctrs) {
 
982
                        LOGP(DRLCMAC, LOGL_ERROR, "Couldn't allocate GPRS DL counters\n");
 
983
                        talloc_free(tbf);
 
984
                        return NULL;
 
985
                }
 
986
        }
 
987
 
 
988
        llist_add(&tbf->list(), &bts->bts->dl_tbfs());
 
989
        tbf->bts->tbf_dl_created();
 
990
 
 
991
        tbf->m_last_dl_poll_fn = -1;
 
992
        tbf->m_last_dl_drained_fn = -1;
 
993
 
 
994
        gettimeofday(&tbf->m_bw.dl_bw_tv, NULL);
 
995
        gettimeofday(&tbf->m_bw.dl_loss_tv, NULL);
 
996
 
 
997
        return tbf;
 
998
}
 
999
 
 
1000
static void tbf_timer_cb(void *_tbf)
 
1001
{
 
1002
        struct gprs_rlcmac_tbf *tbf = (struct gprs_rlcmac_tbf *)_tbf;
 
1003
        tbf->handle_timeout();
 
1004
}
 
1005
 
 
1006
void gprs_rlcmac_tbf::handle_timeout()
 
1007
{
 
1008
        LOGP(DRLCMAC, LOGL_DEBUG, "%s timer %u expired.\n",
 
1009
                tbf_name(this), T);
 
1010
 
 
1011
        num_T_exp++;
 
1012
 
 
1013
        switch (T) {
 
1014
        case 0: /* assignment */
 
1015
                if ((state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) {
 
1016
                        if (state_is(GPRS_RLCMAC_ASSIGN)) {
 
1017
                                LOGP(DRLCMAC, LOGL_NOTICE, "%s releasing due to "
 
1018
                                        "PACCH assignment timeout.\n", tbf_name(this));
 
1019
                                tbf_free(this);
 
1020
                                return;
 
1021
                        } else
 
1022
                                LOGP(DRLCMAC, LOGL_ERROR, "Error: %s is not "
 
1023
                                        "in assign state\n", tbf_name(this));
 
1024
                }
 
1025
                if ((state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) {
 
1026
                        gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this);
 
1027
                        dl_tbf->m_wait_confirm = 0;
 
1028
                        if (dl_tbf->state_is(GPRS_RLCMAC_ASSIGN)) {
 
1029
                                tbf_assign_control_ts(dl_tbf);
 
1030
 
 
1031
                                if (!dl_tbf->upgrade_to_multislot) {
 
1032
                                        /* change state to FLOW, so scheduler
 
1033
                                         * will start transmission */
 
1034
                                        dl_tbf->set_state(GPRS_RLCMAC_FLOW);
 
1035
                                        break;
 
1036
                                }
 
1037
 
 
1038
                                /* This tbf can be upgraded to use multiple DL
 
1039
                                 * timeslots and now that there is already one
 
1040
                                 * slot assigned send another DL assignment via
 
1041
                                 * PDCH. */
 
1042
 
 
1043
                                /* keep to flags */
 
1044
                                dl_tbf->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK;
 
1045
 
 
1046
                                dl_tbf->update();
 
1047
 
 
1048
                                dl_tbf->trigger_ass(dl_tbf);
 
1049
                        } else
 
1050
                                LOGP(DRLCMAC, LOGL_NOTICE, "%s Continue flow after "
 
1051
                                        "IMM.ASS confirm\n", tbf_name(dl_tbf));
 
1052
                }
 
1053
                break;
 
1054
        case 3169:
 
1055
        case 3191:
 
1056
        case 3195:
 
1057
                LOGP(DRLCMAC, LOGL_NOTICE, "%s T%d timeout during "
 
1058
                        "transsmission\n", tbf_name(this), T);
 
1059
                rlcmac_diag();
 
1060
                /* fall through */
 
1061
        case 3193:
 
1062
                LOGP(DRLCMAC, LOGL_DEBUG,
 
1063
                        "%s will be freed due to timeout\n", tbf_name(this));
 
1064
                /* free TBF */
 
1065
                tbf_free(this);
 
1066
                return;
 
1067
                break;
 
1068
        default:
 
1069
                LOGP(DRLCMAC, LOGL_ERROR,
 
1070
                        "%s timer expired in unknown mode: %u\n", tbf_name(this), T);
 
1071
        }
 
1072
}
 
1073
 
 
1074
int gprs_rlcmac_tbf::rlcmac_diag()
 
1075
{
 
1076
        if ((state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)))
 
1077
                LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on CCCH\n");
 
1078
        if ((state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH)))
 
1079
                LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on PACCH\n");
 
1080
        if ((state_flags & (1 << GPRS_RLCMAC_FLAG_UL_DATA)))
 
1081
                LOGP(DRLCMAC, LOGL_NOTICE, "- Uplink data was received\n");
 
1082
        else if (direction == GPRS_RLCMAC_UL_TBF)
 
1083
                LOGP(DRLCMAC, LOGL_NOTICE, "- No uplink data received yet\n");
 
1084
        if ((state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK)))
 
1085
                LOGP(DRLCMAC, LOGL_NOTICE, "- Downlink ACK was received\n");
 
1086
        else if (direction == GPRS_RLCMAC_DL_TBF)
 
1087
                LOGP(DRLCMAC, LOGL_NOTICE, "- No downlink ACK received yet\n");
 
1088
 
 
1089
        return 0;
 
1090
}
 
1091
 
 
1092
struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts)
 
1093
{
 
1094
        struct msgb *msg;
 
1095
        struct gprs_rlcmac_dl_tbf *new_dl_tbf = NULL;
 
1096
        int poll_ass_dl = 1;
 
1097
        unsigned int rrbp = 0;
 
1098
        uint32_t new_poll_fn = 0;
 
1099
        int rc;
 
1100
        bool old_tfi_is_valid = is_tfi_assigned();
 
1101
 
 
1102
        if (direction == GPRS_RLCMAC_DL_TBF && !is_control_ts(ts)) {
 
1103
                LOGP(DRLCMAC, LOGL_NOTICE, "Cannot poll for downlink "
 
1104
                        "assigment, because MS cannot reply. (TS=%d, "
 
1105
                        "first common TS=%d)\n", ts,
 
1106
                        first_common_ts);
 
1107
                poll_ass_dl = 0;
 
1108
        }
 
1109
        if (poll_ass_dl) {
 
1110
                if (poll_state == GPRS_RLCMAC_POLL_SCHED &&
 
1111
                        ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK)
 
1112
                {
 
1113
                        LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already "
 
1114
                                "scheduled for %s, so we must wait for the uplink "
 
1115
                                "assignment...\n", tbf_name(this));
 
1116
                        return NULL;
 
1117
                }
 
1118
                rc = check_polling(fn, ts, &new_poll_fn, &rrbp);
 
1119
                if (rc < 0)
 
1120
                        return NULL;
 
1121
        }
 
1122
 
 
1123
        /* on uplink TBF we get the downlink TBF to be assigned. */
 
1124
        if (direction == GPRS_RLCMAC_UL_TBF) {
 
1125
                gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(this);
 
1126
 
 
1127
                /* be sure to check first, if contention resolution is done,
 
1128
                 * otherwise we cannot send the assignment yet */
 
1129
                if (!ul_tbf->m_contention_resolution_done) {
 
1130
                        LOGP(DRLCMAC, LOGL_DEBUG, "Cannot assign DL TBF now, "
 
1131
                                "because contention resolution is not "
 
1132
                                "finished.\n");
 
1133
                        return NULL;
 
1134
                }
 
1135
        }
 
1136
 
 
1137
        if (ms())
 
1138
                new_dl_tbf = ms()->dl_tbf();
 
1139
 
 
1140
        if (!new_dl_tbf) {
 
1141
                LOGP(DRLCMACDL, LOGL_ERROR, "We have a schedule for downlink "
 
1142
                        "assignment at %s, but there is no downlink "
 
1143
                        "TBF\n", tbf_name(this));
 
1144
                dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
 
1145
                return NULL;
 
1146
        }
 
1147
 
 
1148
        if (new_dl_tbf == as_dl_tbf(this))
 
1149
                LOGP(DRLCMAC, LOGL_DEBUG,
 
1150
                        "New and old TBF are the same %s\n", name());
 
1151
 
 
1152
        if (old_tfi_is_valid && !new_dl_tbf->is_tlli_valid()) {
 
1153
                LOGP(DRLCMACDL, LOGL_ERROR,
 
1154
                        "The old TFI is not assigned and there is no "
 
1155
                        "TLLI. Old TBF %s, new TBF %s\n",
 
1156
                        name(), new_dl_tbf->name());
 
1157
                dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
 
1158
                return NULL;
 
1159
        }
 
1160
 
 
1161
        new_dl_tbf->was_releasing = was_releasing;
 
1162
        msg = msgb_alloc(23, "rlcmac_dl_ass");
 
1163
        if (!msg)
 
1164
                return NULL;
 
1165
        bitvec *ass_vec = bitvec_alloc(23, tall_pcu_ctx);
 
1166
        if (!ass_vec) {
 
1167
                msgb_free(msg);
 
1168
                return NULL;
 
1169
        }
 
1170
        bitvec_unhex(ass_vec,
 
1171
                "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
 
1172
        LOGP(DRLCMAC, LOGL_INFO, "%s  start Packet Downlink Assignment (PACCH)\n", tbf_name(new_dl_tbf));
 
1173
        RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t);
 
1174
        Encoding::write_packet_downlink_assignment(mac_control_block,
 
1175
                old_tfi_is_valid, m_tfi, (direction == GPRS_RLCMAC_DL_TBF),
 
1176
                new_dl_tbf, poll_ass_dl, rrbp,
 
1177
                bts_data()->alpha, bts_data()->gamma, -1, 0,
 
1178
                is_egprs_enabled());
 
1179
        LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++\n");
 
1180
        encode_gsm_rlcmac_downlink(ass_vec, mac_control_block);
 
1181
        LOGPC(DCSN1, LOGL_NOTICE, "\n");
 
1182
        LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- TX : Packet Downlink Assignment -------------------------\n");
 
1183
        bts->pkt_dl_assignemnt();
 
1184
        bitvec_pack(ass_vec, msgb_put(msg, 23));
 
1185
        bitvec_free(ass_vec);
 
1186
        talloc_free(mac_control_block);
 
1187
 
 
1188
        if (poll_ass_dl) {
 
1189
                set_polling(new_poll_fn, ts, GPRS_RLCMAC_POLL_DL_ASS);
 
1190
        } else {
 
1191
                dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
 
1192
                new_dl_tbf->set_state(GPRS_RLCMAC_FLOW);
 
1193
                tbf_assign_control_ts(new_dl_tbf);
 
1194
                /* stop pending assignment timer */
 
1195
                new_dl_tbf->stop_timer();
 
1196
 
 
1197
        }
 
1198
 
 
1199
        return msg;
 
1200
}
 
1201
 
 
1202
struct msgb *gprs_rlcmac_tbf::create_packet_access_reject()
 
1203
{
 
1204
        struct msgb *msg;
 
1205
 
 
1206
        msg = msgb_alloc(23, "rlcmac_ul_ass_rej");
 
1207
 
 
1208
        bitvec *packet_access_rej = bitvec_alloc(23, tall_pcu_ctx);
 
1209
 
 
1210
        bitvec_unhex(packet_access_rej,
 
1211
                "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
 
1212
 
 
1213
        Encoding::write_packet_access_reject(
 
1214
                packet_access_rej, tlli());
 
1215
 
 
1216
        bts->pkt_access_reject();
 
1217
 
 
1218
        bitvec_pack(packet_access_rej, msgb_put(msg, 23));
 
1219
 
 
1220
        bitvec_free(packet_access_rej);
 
1221
        ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE;
 
1222
 
 
1223
        /* Start Tmr only if it is UL TBF */
 
1224
        if (direction == GPRS_RLCMAC_UL_TBF)
 
1225
                tbf_timer_start(this, 0, Treject_pacch);
 
1226
 
 
1227
        return msg;
 
1228
 
 
1229
}
 
1230
 
 
1231
struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts)
 
1232
{
 
1233
        struct msgb *msg;
 
1234
        struct gprs_rlcmac_ul_tbf *new_tbf = NULL;
 
1235
        int rc;
 
1236
        unsigned int rrbp;
 
1237
        uint32_t new_poll_fn;
 
1238
 
 
1239
        if (poll_state == GPRS_RLCMAC_POLL_SCHED &&
 
1240
                ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) {
 
1241
                LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already "
 
1242
                        "scheduled for %s, so we must wait for the uplink "
 
1243
                        "assignment...\n", tbf_name(this));
 
1244
                        return NULL;
 
1245
        }
 
1246
 
 
1247
        rc = check_polling(fn, ts, &new_poll_fn, &rrbp);
 
1248
        if (rc < 0)
 
1249
                return NULL;
 
1250
 
 
1251
        if (ms())
 
1252
                new_tbf = ms()->ul_tbf();
 
1253
        if (!new_tbf) {
 
1254
                LOGP(DRLCMACUL, LOGL_ERROR, "We have a schedule for uplink "
 
1255
                        "assignment at downlink %s, but there is no uplink "
 
1256
                        "TBF\n", tbf_name(this));
 
1257
                ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE;
 
1258
                return NULL;
 
1259
        }
 
1260
 
 
1261
        msg = msgb_alloc(23, "rlcmac_ul_ass");
 
1262
        if (!msg)
 
1263
                return NULL;
 
1264
        LOGP(DRLCMAC, LOGL_INFO, "%ss start Packet Uplink Assignment (PACCH)\n", tbf_name(new_tbf));
 
1265
        bitvec *ass_vec = bitvec_alloc(23, tall_pcu_ctx);
 
1266
        if (!ass_vec) {
 
1267
                msgb_free(msg);
 
1268
                return NULL;
 
1269
        }
 
1270
        bitvec_unhex(ass_vec,
 
1271
                "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
 
1272
        Encoding::write_packet_uplink_assignment(bts_data(), ass_vec, m_tfi,
 
1273
                (direction == GPRS_RLCMAC_DL_TBF), tlli(),
 
1274
                is_tlli_valid(), new_tbf, 1, rrbp, bts_data()->alpha,
 
1275
                bts_data()->gamma, -1, is_egprs_enabled());
 
1276
        bitvec_pack(ass_vec, msgb_put(msg, 23));
 
1277
        RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t);
 
1278
        LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++\n");
 
1279
        decode_gsm_rlcmac_downlink(ass_vec, mac_control_block);
 
1280
        LOGPC(DCSN1, LOGL_NOTICE, "\n");
 
1281
        LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- TX : Packet Uplink Assignment -------------------------\n");
 
1282
        bts->pkt_ul_assignment();
 
1283
        bitvec_free(ass_vec);
 
1284
        talloc_free(mac_control_block);
 
1285
 
 
1286
        set_polling(new_poll_fn, ts, GPRS_RLCMAC_POLL_UL_ASS);
 
1287
 
 
1288
        return msg;
 
1289
}
 
1290
 
 
1291
void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_trx *trx)
 
1292
{
 
1293
        for (uint8_t ts = 0; ts < 8; ts++)
 
1294
                free_all(&trx->pdch[ts]);
 
1295
}
 
1296
 
 
1297
void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_pdch *pdch)
 
1298
{
 
1299
        for (uint8_t tfi = 0; tfi < 32; tfi++) {
 
1300
                struct gprs_rlcmac_tbf *tbf;
 
1301
 
 
1302
                tbf = pdch->ul_tbf_by_tfi(tfi);
 
1303
                if (tbf)
 
1304
                        tbf_free(tbf);
 
1305
                tbf = pdch->dl_tbf_by_tfi(tfi);
 
1306
                if (tbf)
 
1307
                        tbf_free(tbf);
 
1308
        }
 
1309
}
 
1310
 
 
1311
int gprs_rlcmac_tbf::establish_dl_tbf_on_pacch()
 
1312
{
 
1313
        struct gprs_rlcmac_dl_tbf *new_tbf = NULL;
 
1314
 
 
1315
        bts->tbf_reused();
 
1316
 
 
1317
        new_tbf = tbf_alloc_dl_tbf(bts->bts_data(), ms(),
 
1318
                this->trx->trx_no, ms_class(),
 
1319
                ms() ?  ms()->egprs_ms_class() : 0, 0);
 
1320
 
 
1321
        if (!new_tbf) {
 
1322
                LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n");
 
1323
                return -1;
 
1324
        }
 
1325
 
 
1326
        LOGP(DRLCMAC, LOGL_DEBUG, "%s Trigger downlink assignment on PACCH\n",
 
1327
                tbf_name(this));
 
1328
        new_tbf->trigger_ass(this);
 
1329
 
 
1330
        return 0;
 
1331
}
 
1332
 
 
1333
int gprs_rlcmac_tbf::set_tlli_from_ul(uint32_t new_tlli)
 
1334
{
 
1335
        struct gprs_rlcmac_tbf *dl_tbf = NULL;
 
1336
        struct gprs_rlcmac_tbf *ul_tbf = NULL;
 
1337
        GprsMs *old_ms;
 
1338
 
 
1339
        OSMO_ASSERT(direction == GPRS_RLCMAC_UL_TBF);
 
1340
 
 
1341
        old_ms = bts->ms_by_tlli(new_tlli);
 
1342
        /* Keep the old MS object for the update_ms() */
 
1343
        GprsMs::Guard guard(old_ms);
 
1344
        if (old_ms) {
 
1345
                /* Get them before calling set_ms() */
 
1346
                dl_tbf = old_ms->dl_tbf();
 
1347
                ul_tbf = old_ms->ul_tbf();
 
1348
 
 
1349
                if (!ms())
 
1350
                        set_ms(old_ms);
 
1351
        }
 
1352
 
 
1353
        if (dl_tbf && dl_tbf->ms() != ms()) {
 
1354
                LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from "
 
1355
                        "TLLI=0x%08x while %s still exists. "
 
1356
                        "Killing pending DL TBF\n", new_tlli,
 
1357
                        tbf_name(dl_tbf));
 
1358
                tbf_free(dl_tbf);
 
1359
                dl_tbf = NULL;
 
1360
        }
 
1361
        if (ul_tbf && ul_tbf->ms() != ms()) {
 
1362
                LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from "
 
1363
                        "TLLI=0x%08x while %s still exists. "
 
1364
                        "Killing pending UL TBF\n", new_tlli,
 
1365
                        tbf_name(ul_tbf));
 
1366
                tbf_free(ul_tbf);
 
1367
                ul_tbf = NULL;
 
1368
        }
 
1369
 
 
1370
        /* The TLLI has been taken from an UL message */
 
1371
        update_ms(new_tlli, GPRS_RLCMAC_UL_TBF);
 
1372
 
 
1373
#if 0 /* REMOVEME ??? */
 
1374
        if (ms()->need_dl_tbf())
 
1375
                establish_dl_tbf_on_pacch();
 
1376
#endif
 
1377
        return 1;
 
1378
}
 
1379
 
 
1380
const char *tbf_name(gprs_rlcmac_tbf *tbf)
 
1381
{
 
1382
        return tbf ? tbf->name() : "(no TBF)";
 
1383
}
 
1384
 
 
1385
const char *gprs_rlcmac_tbf::name() const
 
1386
{
 
1387
        snprintf(m_name_buf, sizeof(m_name_buf) - 1,
 
1388
                "TBF(TFI=%d TLLI=0x%08x DIR=%s STATE=%s%s)",
 
1389
                m_tfi, tlli(),
 
1390
                direction == GPRS_RLCMAC_UL_TBF ? "UL" : "DL",
 
1391
                state_name(),
 
1392
                is_egprs_enabled() ? " EGPRS" : ""
 
1393
                );
 
1394
        m_name_buf[sizeof(m_name_buf) - 1] = '\0';
 
1395
        return m_name_buf;
 
1396
}
 
1397
 
 
1398
void gprs_rlcmac_tbf::rotate_in_list()
 
1399
{
 
1400
        llist_del(&list());
 
1401
        if (direction == GPRS_RLCMAC_UL_TBF)
 
1402
                llist_add(&list(), &bts->ul_tbfs());
 
1403
        else
 
1404
                llist_add(&list(), &bts->dl_tbfs());
 
1405
}
 
1406
 
 
1407
uint8_t gprs_rlcmac_tbf::tsc() const
 
1408
{
 
1409
        return trx->pdch[first_ts].tsc;
 
1410
}
 
1411
 
 
1412
uint8_t gprs_rlcmac_tbf::dl_slots() const
 
1413
{
 
1414
        uint8_t slots = 0;
 
1415
        size_t i;
 
1416
 
 
1417
        if (direction == GPRS_RLCMAC_UL_TBF)
 
1418
                return 0;
 
1419
 
 
1420
        for (i = 0; i < ARRAY_SIZE(pdch); i += 1)
 
1421
                if (pdch[i])
 
1422
                        slots |= 1 << i;
 
1423
 
 
1424
        return slots;
 
1425
}
 
1426
 
 
1427
uint8_t gprs_rlcmac_tbf::ul_slots() const
 
1428
{
 
1429
        uint8_t slots = 0;
 
1430
        size_t i;
 
1431
 
 
1432
        if (direction == GPRS_RLCMAC_DL_TBF) {
 
1433
                if (control_ts < 8)
 
1434
                        slots |= 1 << control_ts;
 
1435
                if (first_common_ts < 8)
 
1436
                        slots |= 1 << first_common_ts;
 
1437
 
 
1438
                return slots;
 
1439
        }
 
1440
 
 
1441
        for (i = 0; i < ARRAY_SIZE(pdch); i += 1)
 
1442
                if (pdch[i])
 
1443
                        slots |= 1 << i;
 
1444
 
 
1445
        return slots;
 
1446
}
 
1447
 
 
1448
bool gprs_rlcmac_tbf::is_control_ts(uint8_t ts) const
 
1449
{
 
1450
        return ts == control_ts;
 
1451
}
 
1452
 
 
1453
struct gprs_rlcmac_ul_tbf *handle_tbf_reject(struct gprs_rlcmac_bts *bts,
 
1454
                        GprsMs *ms, uint32_t tlli, uint8_t trx_no, uint8_t ts)
 
1455
{
 
1456
        struct gprs_rlcmac_ul_tbf *ul_tbf = NULL;
 
1457
        struct gprs_rlcmac_trx *trx = &bts->trx[trx_no];
 
1458
 
 
1459
        ul_tbf = talloc(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
 
1460
        if (!ul_tbf)
 
1461
                return ul_tbf;
 
1462
 
 
1463
        talloc_set_destructor(ul_tbf, ul_tbf_dtor);
 
1464
        new (ul_tbf) gprs_rlcmac_ul_tbf(bts->bts);
 
1465
        if (!ms)
 
1466
                ms = bts->bts->ms_alloc(0, 0);
 
1467
 
 
1468
        ms->set_tlli(tlli);
 
1469
 
 
1470
        llist_add(&ul_tbf->list(), &bts->bts->ul_tbfs());
 
1471
        ul_tbf->bts->tbf_ul_created();
 
1472
        ul_tbf->set_state(GPRS_RLCMAC_ASSIGN);
 
1473
        ul_tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH);
 
1474
 
 
1475
        ul_tbf->set_ms(ms);
 
1476
        ul_tbf->update_ms(tlli, GPRS_RLCMAC_UL_TBF);
 
1477
        ul_tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ;
 
1478
        ul_tbf->control_ts = ts;
 
1479
        ul_tbf->trx = trx;
 
1480
        ul_tbf->m_ctrs = rate_ctr_group_alloc(ul_tbf, &tbf_ctrg_desc, 0);
 
1481
        ul_tbf->m_ul_egprs_ctrs = rate_ctr_group_alloc(ul_tbf,
 
1482
                                        &tbf_ul_egprs_ctrg_desc, 0);
 
1483
        ul_tbf->m_ul_gprs_ctrs = rate_ctr_group_alloc(ul_tbf,
 
1484
                                        &tbf_ul_gprs_ctrg_desc, 0);
 
1485
        if (!ul_tbf->m_ctrs || !ul_tbf->m_ul_egprs_ctrs || !ul_tbf->m_ul_gprs_ctrs) {
 
1486
                LOGP(DRLCMAC, LOGL_ERROR, "Cound not allocate TBF UL rate counters\n");
 
1487
                talloc_free(ul_tbf);
 
1488
                return NULL;
 
1489
        }
 
1490
 
 
1491
        return ul_tbf;
 
1492
}