Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
/* gprs_ms.c
|
|
|
|
*
|
|
|
|
* Copyright (C) 2015-2020 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include "gprs_ms.h"
|
|
|
|
#include "bts.h"
|
|
|
|
#include "tbf.h"
|
|
|
|
#include "tbf_ul.h"
|
|
|
|
#include "gprs_debug.h"
|
|
|
|
#include "gprs_codel.h"
|
|
|
|
#include "pcu_utils.h"
|
Introduce NACC support
A new nacc_fsm is introduced per MS object, with its partner priv
structure struct nacc_fsm_ctx, which exists and is available in the MS
object only during the duration of the NACC procedure.
The NACC context is created on an MS whenever a Pkt Cell Change
Notification is received on Uplink RLCMAC, which asks for neighbor
information of a given ARFCN+BSIC.
First, the target ARFCN+BSIC needs to be translated into a CGI-PS
(RAC+CI) address. That's done by asking the BSC through the Neighbour
Resolution Service available in osmo-bsc using the CTRL interface.
Once the CGI-PS of the target cell is known, PCU starts a RIM RAN-INFO
request against the SGSN (which will route the request as needed), and
wait for a response containing the SI bits from the target cell.
After the SI are received, the scheduler is instructed to eventually
poll a TBF for the MS originating the CCN, so that we can send the SI
encapsulated into multiple Packet Neighbor Cell Data messages on the
downlink.
One all the SI bits are sent, the scheduler is instructed to send a
Packet Cell Change Continue message.
Once the message above has been sent, the FSM autodestroys itself.
Caches are also introduced in this patch which allows for re-using
recently known translations ARFCN+BSIC -> CGI-PS and CGI-PS -> SI_INFO
respectively.
Change-Id: Id35f40d05f3e081f32fddbf1fa34cb338db452ca
2021-01-21 17:46:13 +00:00
|
|
|
#include "nacc_fsm.h"
|
2022-10-26 13:44:14 +00:00
|
|
|
#include "tbf_ul_ack_fsm.h"
|
2023-04-21 17:32:16 +00:00
|
|
|
#include "alloc_algo.h"
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
#include <osmocom/core/talloc.h>
|
|
|
|
#include <osmocom/core/utils.h>
|
|
|
|
#include <osmocom/core/timer.h>
|
|
|
|
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
|
|
|
#include <osmocom/gsm/gsm48.h>
|
|
|
|
#include <osmocom/core/logging.h>
|
2021-01-11 16:32:18 +00:00
|
|
|
#include <osmocom/core/stats.h>
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
#include "coding_scheme.h"
|
|
|
|
|
|
|
|
#define GPRS_CODEL_SLOW_INTERVAL_MS 4000
|
|
|
|
|
|
|
|
extern void *tall_pcu_ctx;
|
2021-01-11 16:32:18 +00:00
|
|
|
static unsigned int next_ms_ctr_group_id;
|
|
|
|
|
|
|
|
static const struct rate_ctr_desc ms_ctr_description[] = {
|
|
|
|
[MS_CTR_DL_CTRL_MSG_SCHED] = { "ms:dl_ctrl_msg_sched", "Amount of DL CTRL messages scheduled" },
|
|
|
|
};
|
|
|
|
|
2021-01-12 19:57:56 +00:00
|
|
|
static const struct rate_ctr_group_desc ms_ctrg_desc = {
|
2021-01-11 16:32:18 +00:00
|
|
|
.group_name_prefix = "pcu:ms",
|
|
|
|
.group_description = "MS Statistics",
|
|
|
|
.class_id = OSMO_STATS_CLASS_SUBSCRIBER,
|
|
|
|
.num_ctr = ARRAY_SIZE(ms_ctr_description),
|
|
|
|
.ctr_desc = ms_ctr_description,
|
|
|
|
};
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
static int64_t now_msec()
|
|
|
|
{
|
|
|
|
struct timespec ts;
|
|
|
|
osmo_clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
|
|
|
|
|
|
return (int64_t)(ts.tv_sec) * 1000 + ts.tv_nsec / 1000000;
|
|
|
|
}
|
|
|
|
|
2023-04-18 17:02:55 +00:00
|
|
|
static void ms_becomes_idle(struct GprsMs *ms);
|
2023-04-17 18:28:10 +00:00
|
|
|
|
|
|
|
static int ms_use_cb(struct osmo_use_count_entry *e, int32_t old_use_count, const char *file, int line)
|
|
|
|
{
|
|
|
|
struct GprsMs *ms = e->use_count->talloc_object;
|
|
|
|
int32_t total;
|
|
|
|
int level;
|
|
|
|
char buf[1024];
|
|
|
|
|
|
|
|
if (!e->use)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
total = osmo_use_count_total(&ms->use_count);
|
|
|
|
|
|
|
|
if (total == 0
|
|
|
|
|| (total == 1 && old_use_count == 0 && e->count == 1))
|
|
|
|
level = LOGL_INFO;
|
|
|
|
else
|
|
|
|
level = LOGL_DEBUG;
|
|
|
|
|
|
|
|
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGPSRC(DMS, level, file, line, "%s: %s %s: now used by %s\n",
|
2023-04-17 18:28:10 +00:00
|
|
|
ms_name(ms),
|
|
|
|
(e->count - old_use_count) > 0 ? "+" : "-", e->use,
|
|
|
|
(osmo_use_count_to_str_buf(buf, sizeof(buf), &ms->use_count), buf));
|
|
|
|
|
|
|
|
if (e->count < 0)
|
|
|
|
return -ERANGE;
|
|
|
|
|
2023-04-18 17:02:55 +00:00
|
|
|
if (total == 0) {
|
|
|
|
OSMO_ASSERT(ms_is_idle(ms));
|
|
|
|
ms_becomes_idle(ms);
|
|
|
|
}
|
2023-04-17 18:28:10 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-03-03 16:30:50 +00:00
|
|
|
static void ms_release_timer_cb(void *data)
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
{
|
|
|
|
struct GprsMs *ms = (struct GprsMs *) data;
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGPMS(ms, DMS, LOGL_INFO, "Release timer expired\n");
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
2023-04-18 17:02:55 +00:00
|
|
|
/* Finally free the MS after being idle for a while according to config */
|
|
|
|
talloc_free(ms);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
2022-10-26 17:44:07 +00:00
|
|
|
static void ms_llc_timer_cb(void *_ms)
|
|
|
|
{
|
|
|
|
struct GprsMs *ms = _ms;
|
|
|
|
struct gprs_rlcmac_dl_tbf *dl_tbf = ms_dl_tbf(ms);
|
|
|
|
|
|
|
|
if (!dl_tbf)
|
|
|
|
return;
|
2022-10-27 13:40:20 +00:00
|
|
|
if (tbf_state(dl_tbf_as_tbf_const(dl_tbf)) != TBF_ST_FLOW)
|
2022-10-26 17:44:07 +00:00
|
|
|
return;
|
|
|
|
|
2022-10-27 13:19:39 +00:00
|
|
|
LOGPTBFDL(dl_tbf, LOGL_DEBUG, "LLC receive timeout, requesting DL ACK\n");
|
2022-10-26 17:44:07 +00:00
|
|
|
|
2022-10-28 15:38:52 +00:00
|
|
|
dl_tbf_request_dl_ack(dl_tbf);
|
2022-10-26 17:44:07 +00:00
|
|
|
}
|
|
|
|
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
static int ms_talloc_destructor(struct GprsMs *ms);
|
2023-04-19 17:42:05 +00:00
|
|
|
struct GprsMs *ms_alloc(struct gprs_rlcmac_bts *bts, const char *use_ref)
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
{
|
|
|
|
struct GprsMs *ms = talloc_zero(tall_pcu_ctx, struct GprsMs);
|
2022-04-01 15:21:08 +00:00
|
|
|
OSMO_ASSERT(bts);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
talloc_set_destructor(ms, ms_talloc_destructor);
|
|
|
|
|
2023-04-17 16:23:56 +00:00
|
|
|
llist_add(&ms->list, &bts->ms_list);
|
2023-04-17 17:00:04 +00:00
|
|
|
bts_stat_item_inc(bts, STAT_MS_PRESENT);
|
2023-04-17 16:23:56 +00:00
|
|
|
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
ms->bts = bts;
|
2023-04-17 12:25:51 +00:00
|
|
|
ms->tlli = GSM_RESERVED_TMSI;
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
ms->new_ul_tlli = GSM_RESERVED_TMSI;
|
|
|
|
ms->new_dl_tlli = GSM_RESERVED_TMSI;
|
|
|
|
ms->ta = GSM48_TA_INVALID;
|
|
|
|
ms->current_cs_ul = UNKNOWN;
|
|
|
|
ms->current_cs_dl = UNKNOWN;
|
|
|
|
INIT_LLIST_HEAD(&ms->old_tbfs);
|
|
|
|
|
2023-04-17 18:28:10 +00:00
|
|
|
ms->use_count = (struct osmo_use_count){
|
|
|
|
.talloc_object = ms,
|
|
|
|
.use_cb = ms_use_cb,
|
|
|
|
};
|
|
|
|
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
int codel_interval = LLC_CODEL_USE_DEFAULT;
|
|
|
|
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGP(DMS, LOGL_INFO, "Creating MS object\n");
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
ms->imsi[0] = '\0';
|
2023-04-20 14:52:40 +00:00
|
|
|
osmo_timer_setup(&ms->release_timer, ms_release_timer_cb, ms);
|
2022-04-04 11:45:56 +00:00
|
|
|
llc_queue_init(&ms->llc_queue, ms);
|
2022-10-26 17:44:07 +00:00
|
|
|
memset(&ms->llc_timer, 0, sizeof(ms->llc_timer));
|
|
|
|
osmo_timer_setup(&ms->llc_timer, ms_llc_timer_cb, ms);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
ms_set_mode(ms, GPRS);
|
|
|
|
|
2022-04-01 15:21:08 +00:00
|
|
|
codel_interval = the_pcu->vty.llc_codel_interval_msec;
|
2022-04-04 11:45:56 +00:00
|
|
|
if (codel_interval == LLC_CODEL_USE_DEFAULT)
|
|
|
|
codel_interval = GPRS_CODEL_SLOW_INTERVAL_MS;
|
|
|
|
llc_queue_set_codel_interval(&ms->llc_queue, codel_interval);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
ms->last_cs_not_low = now_msec();
|
|
|
|
ms->app_info_pending = false;
|
2021-01-11 16:32:18 +00:00
|
|
|
|
|
|
|
ms->ctrs = rate_ctr_group_alloc(ms, &ms_ctrg_desc, next_ms_ctr_group_id++);
|
|
|
|
if (!ms->ctrs)
|
|
|
|
goto free_ret;
|
|
|
|
|
2023-04-19 17:42:05 +00:00
|
|
|
if (use_ref)
|
|
|
|
ms_ref(ms, use_ref);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
return ms;
|
2021-01-11 16:32:18 +00:00
|
|
|
free_ret:
|
|
|
|
talloc_free(ms);
|
|
|
|
return NULL;
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int ms_talloc_destructor(struct GprsMs *ms)
|
|
|
|
{
|
|
|
|
struct llist_item *pos, *tmp;
|
|
|
|
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGPMS(ms, DMS, LOGL_INFO, "Destroying MS object\n");
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
2023-04-17 17:00:04 +00:00
|
|
|
bts_stat_item_dec(ms->bts, STAT_MS_PRESENT);
|
2023-04-17 16:23:56 +00:00
|
|
|
llist_del(&ms->list);
|
|
|
|
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
ms_set_reserved_slots(ms, NULL, 0, 0);
|
|
|
|
|
2023-04-20 14:52:40 +00:00
|
|
|
osmo_timer_del(&ms->release_timer);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
if (ms->ul_tbf) {
|
Make sure GprsMs free() also frees its tbfs
This fixes TBF objects leaking and ending up alive when the MS object is
explicitly freed through talloc_free (and sporadically
crashing TbfTest once a timeout for them occur).
This mostly affects unit tests, where most of the explicit free()
happens.
In osmo-pcu, in general, the GprsMs object only gets _free() called when
its resource count reaches 0, aka no more TBFs are attached to it. Hence
in general GprsMs object is freed() only when no TBFs (to be leaked) are
present.
However, in the unit tests it's usual that we want to wipe the entire
context by eg. feeing the PCU, the BTS or MS object, which should also
free the related TBFs.
When running osmo-pcu this may only be an issue when the MS object is
freed explicitly, which could happen for instance when a BTS is torn down,
ie. PCUIF going down, moment at which all GprsMs of that BTS are freed.
But in there actually it iterates over PDCHs to free all TBFs, so it's
fine.
If we iterated over MS, this could have ended up in a crash, like
it happened in TbfTest sporadically, but it's not a bit problem if we
crash + restart at that time since anyway the BTS is gone ore just
getting up around that time.
Related: OS#6359
Change-Id: Ibbdec94acb8132be20508d3178d88da44bfaf91d
2024-03-25 19:13:47 +00:00
|
|
|
tbf_free(ul_tbf_as_tbf(ms->ul_tbf));
|
|
|
|
OSMO_ASSERT(ms->ul_tbf == NULL);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ms->dl_tbf) {
|
Make sure GprsMs free() also frees its tbfs
This fixes TBF objects leaking and ending up alive when the MS object is
explicitly freed through talloc_free (and sporadically
crashing TbfTest once a timeout for them occur).
This mostly affects unit tests, where most of the explicit free()
happens.
In osmo-pcu, in general, the GprsMs object only gets _free() called when
its resource count reaches 0, aka no more TBFs are attached to it. Hence
in general GprsMs object is freed() only when no TBFs (to be leaked) are
present.
However, in the unit tests it's usual that we want to wipe the entire
context by eg. feeing the PCU, the BTS or MS object, which should also
free the related TBFs.
When running osmo-pcu this may only be an issue when the MS object is
freed explicitly, which could happen for instance when a BTS is torn down,
ie. PCUIF going down, moment at which all GprsMs of that BTS are freed.
But in there actually it iterates over PDCHs to free all TBFs, so it's
fine.
If we iterated over MS, this could have ended up in a crash, like
it happened in TbfTest sporadically, but it's not a bit problem if we
crash + restart at that time since anyway the BTS is gone ore just
getting up around that time.
Related: OS#6359
Change-Id: Ibbdec94acb8132be20508d3178d88da44bfaf91d
2024-03-25 19:13:47 +00:00
|
|
|
tbf_free(dl_tbf_as_tbf(ms->dl_tbf));
|
|
|
|
OSMO_ASSERT(ms->dl_tbf == NULL);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
llist_for_each_entry_safe(pos, tmp, &ms->old_tbfs, list) {
|
|
|
|
struct gprs_rlcmac_tbf *tbf = (struct gprs_rlcmac_tbf *)pos->entry;
|
Make sure GprsMs free() also frees its tbfs
This fixes TBF objects leaking and ending up alive when the MS object is
explicitly freed through talloc_free (and sporadically
crashing TbfTest once a timeout for them occur).
This mostly affects unit tests, where most of the explicit free()
happens.
In osmo-pcu, in general, the GprsMs object only gets _free() called when
its resource count reaches 0, aka no more TBFs are attached to it. Hence
in general GprsMs object is freed() only when no TBFs (to be leaked) are
present.
However, in the unit tests it's usual that we want to wipe the entire
context by eg. feeing the PCU, the BTS or MS object, which should also
free the related TBFs.
When running osmo-pcu this may only be an issue when the MS object is
freed explicitly, which could happen for instance when a BTS is torn down,
ie. PCUIF going down, moment at which all GprsMs of that BTS are freed.
But in there actually it iterates over PDCHs to free all TBFs, so it's
fine.
If we iterated over MS, this could have ended up in a crash, like
it happened in TbfTest sporadically, but it's not a bit problem if we
crash + restart at that time since anyway the BTS is gone ore just
getting up around that time.
Related: OS#6359
Change-Id: Ibbdec94acb8132be20508d3178d88da44bfaf91d
2024-03-25 19:13:47 +00:00
|
|
|
tbf_free(tbf);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
llc_queue_clear(&ms->llc_queue, ms->bts);
|
2022-10-26 17:44:07 +00:00
|
|
|
osmo_timer_del(&ms->llc_timer);
|
2021-01-11 16:32:18 +00:00
|
|
|
|
|
|
|
if (ms->ctrs)
|
|
|
|
rate_ctr_group_free(ms->ctrs);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-04-18 17:02:55 +00:00
|
|
|
/* MS has no attached TBFs anymore. */
|
|
|
|
static void ms_becomes_idle(struct GprsMs *ms)
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
{
|
2023-04-20 14:42:54 +00:00
|
|
|
unsigned long delay_rel_sec = osmo_tdef_get(ms->bts->pcu->T_defs, -2030, OSMO_TDEF_S, -1);
|
|
|
|
|
2023-04-20 15:18:34 +00:00
|
|
|
osmo_gettimeofday(&ms->tv_idle_start, NULL);
|
|
|
|
|
2023-04-18 17:02:55 +00:00
|
|
|
ms_set_reserved_slots(ms, NULL, 0, 0);
|
|
|
|
ms->first_common_ts = NULL;
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
2023-04-17 18:43:26 +00:00
|
|
|
/* Immediate free():
|
|
|
|
* Skip delaying free() through release timer if delay is configured to be 0.
|
|
|
|
* This is useful for synced freed during unit tests.
|
|
|
|
*/
|
2023-04-20 14:42:54 +00:00
|
|
|
if (delay_rel_sec == 0) {
|
2023-04-18 17:02:55 +00:00
|
|
|
talloc_free(ms);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
return;
|
2023-04-18 17:02:55 +00:00
|
|
|
}
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
2023-04-17 18:43:26 +00:00
|
|
|
/* Immediate free():
|
|
|
|
* Skip delaying free() through release timer if TMSI is not
|
|
|
|
* known, since those cannot really be reused.
|
|
|
|
*/
|
2023-04-18 17:02:55 +00:00
|
|
|
if (ms_tlli(ms) == GSM_RESERVED_TMSI) {
|
|
|
|
talloc_free(ms);
|
2023-04-17 18:43:26 +00:00
|
|
|
return;
|
2023-04-17 18:28:10 +00:00
|
|
|
}
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
2023-04-20 14:42:54 +00:00
|
|
|
LOGPMS(ms, DMS, LOGL_INFO, "Schedule MS release in %lu secs\n", delay_rel_sec);
|
2023-04-20 14:52:40 +00:00
|
|
|
osmo_timer_schedule(&ms->release_timer, delay_rel_sec, 0);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
2023-04-18 17:02:55 +00:00
|
|
|
static void ms_becomes_active(struct GprsMs *ms)
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
{
|
2023-04-20 14:52:40 +00:00
|
|
|
if (!osmo_timer_pending(&ms->release_timer))
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
return;
|
|
|
|
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGPMS(ms, DMS, LOGL_DEBUG, "Cancel scheduled MS release\n");
|
2021-03-03 16:30:50 +00:00
|
|
|
|
2023-04-20 15:18:34 +00:00
|
|
|
timerclear(&ms->tv_idle_start);
|
2023-04-20 14:52:40 +00:00
|
|
|
osmo_timer_del(&ms->release_timer);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ms_set_mode(struct GprsMs *ms, enum mcs_kind mode)
|
|
|
|
{
|
|
|
|
ms->mode = mode;
|
|
|
|
|
|
|
|
switch (ms->mode) {
|
|
|
|
case GPRS:
|
|
|
|
if (!mcs_is_gprs(ms->current_cs_ul)) {
|
|
|
|
ms->current_cs_ul = mcs_get_gprs_by_num(
|
2021-01-14 15:48:38 +00:00
|
|
|
ms->bts->initial_cs_ul);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
if (!mcs_is_valid(ms->current_cs_ul))
|
|
|
|
ms->current_cs_ul = CS1;
|
|
|
|
}
|
|
|
|
if (!mcs_is_gprs(ms->current_cs_dl)) {
|
|
|
|
ms->current_cs_dl = mcs_get_gprs_by_num(
|
2021-01-14 15:48:38 +00:00
|
|
|
ms->bts->initial_cs_dl);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
if (!mcs_is_valid(ms->current_cs_dl))
|
|
|
|
ms->current_cs_dl = CS1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EGPRS_GMSK:
|
2021-01-25 14:08:35 +00:00
|
|
|
if (!mcs_is_edge_gmsk(ms->current_cs_ul)) {
|
|
|
|
ms->current_cs_ul = mcs_get_egprs_by_num(
|
|
|
|
ms->bts->initial_mcs_ul);
|
|
|
|
if (!mcs_is_valid(ms->current_cs_ul))
|
|
|
|
ms->current_cs_ul = MCS1;
|
|
|
|
}
|
|
|
|
if (!mcs_is_edge_gmsk(ms->current_cs_dl)) {
|
|
|
|
ms->current_cs_dl = mcs_get_egprs_by_num(
|
|
|
|
ms->bts->initial_mcs_dl);
|
|
|
|
if (!mcs_is_valid(ms->current_cs_dl))
|
|
|
|
ms->current_cs_dl = MCS1;
|
|
|
|
}
|
|
|
|
break;
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
case EGPRS:
|
|
|
|
if (!mcs_is_edge(ms->current_cs_ul)) {
|
|
|
|
ms->current_cs_ul = mcs_get_egprs_by_num(
|
2021-01-14 15:48:38 +00:00
|
|
|
ms->bts->initial_mcs_ul);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
if (!mcs_is_valid(ms->current_cs_ul))
|
|
|
|
ms->current_cs_ul = MCS1;
|
|
|
|
}
|
|
|
|
if (!mcs_is_edge(ms->current_cs_dl)) {
|
|
|
|
ms->current_cs_dl = mcs_get_egprs_by_num(
|
2021-01-14 15:48:38 +00:00
|
|
|
ms->bts->initial_mcs_dl);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
if (!mcs_is_valid(ms->current_cs_dl))
|
|
|
|
ms->current_cs_dl = MCS1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-18 15:31:02 +00:00
|
|
|
/* If a TBF is attached to an MS, it is either in ms->{dl,ul}_tbf or in ms->old_tbfs list */
|
|
|
|
static bool ms_tbf_is_attached(const struct GprsMs *ms, const struct gprs_rlcmac_tbf *tbf)
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
{
|
2023-04-18 15:31:02 +00:00
|
|
|
const struct llist_item *pos;
|
|
|
|
OSMO_ASSERT(ms);
|
|
|
|
OSMO_ASSERT(tbf);
|
|
|
|
OSMO_ASSERT(tbf_ms(tbf) == ms);
|
|
|
|
|
|
|
|
if (tbf == ul_tbf_as_tbf_const(ms->ul_tbf))
|
|
|
|
return true;
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
2023-04-18 15:31:02 +00:00
|
|
|
if (tbf == dl_tbf_as_tbf_const(ms->dl_tbf))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
llist_for_each_entry(pos, &ms->old_tbfs, list) {
|
|
|
|
const struct gprs_rlcmac_tbf *tmp_tbf = (struct gprs_rlcmac_tbf *)pos->entry;
|
|
|
|
if (tmp_tbf == tbf)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ms_attach_ul_tbf(struct GprsMs *ms, struct gprs_rlcmac_ul_tbf *tbf)
|
|
|
|
{
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGPMS(ms, DMS, LOGL_INFO, "Attaching UL TBF: %s\n", tbf_name((struct gprs_rlcmac_tbf *)tbf));
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
if (ms->ul_tbf)
|
2022-10-27 13:40:20 +00:00
|
|
|
llist_add_tail(tbf_ms_list(ul_tbf_as_tbf(ms->ul_tbf)), &ms->old_tbfs);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
ms->ul_tbf = tbf;
|
|
|
|
|
2023-04-18 17:02:55 +00:00
|
|
|
ms_ref(ms, MS_USE_TBF);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ms_attach_dl_tbf(struct GprsMs *ms, struct gprs_rlcmac_dl_tbf *tbf)
|
|
|
|
{
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGPMS(ms, DMS, LOGL_INFO, "Attaching DL TBF: %s\n", tbf_name((struct gprs_rlcmac_tbf *)tbf));
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
if (ms->dl_tbf)
|
2022-10-27 13:40:20 +00:00
|
|
|
llist_add_tail(tbf_ms_list(dl_tbf_as_tbf(ms->dl_tbf)), &ms->old_tbfs);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
ms->dl_tbf = tbf;
|
|
|
|
|
2023-04-18 17:02:55 +00:00
|
|
|
ms_ref(ms, MS_USE_TBF);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ms_attach_tbf(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf)
|
|
|
|
{
|
2023-04-18 14:33:34 +00:00
|
|
|
OSMO_ASSERT(ms);
|
|
|
|
OSMO_ASSERT(tbf);
|
2023-04-18 15:31:02 +00:00
|
|
|
OSMO_ASSERT(!ms_tbf_is_attached(ms, tbf));
|
2023-04-18 14:33:34 +00:00
|
|
|
|
2021-08-23 14:58:04 +00:00
|
|
|
if (tbf_direction(tbf) == GPRS_RLCMAC_DL_TBF)
|
2022-10-27 13:25:55 +00:00
|
|
|
ms_attach_dl_tbf(ms, tbf_as_dl_tbf(tbf));
|
2021-08-23 14:58:04 +00:00
|
|
|
else
|
2022-10-27 13:25:55 +00:00
|
|
|
ms_attach_ul_tbf(ms, tbf_as_ul_tbf(tbf));
|
2023-04-18 17:02:55 +00:00
|
|
|
|
|
|
|
ms_becomes_active(ms);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ms_detach_tbf(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf)
|
|
|
|
{
|
2023-04-18 15:31:02 +00:00
|
|
|
OSMO_ASSERT(tbf_ms(tbf) == ms);
|
|
|
|
|
|
|
|
/* In general this should not happen, but it can happen if during TBF
|
|
|
|
* allocation something fails before tbf->setup() called ms_attach_tbf(). */
|
|
|
|
if (!ms_tbf_is_attached(ms, tbf))
|
|
|
|
return;
|
|
|
|
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGPMS(ms, DMS, LOGL_INFO, "Detaching TBF: %s\n",
|
2023-04-18 15:50:34 +00:00
|
|
|
tbf_name(tbf));
|
|
|
|
|
2023-04-18 15:31:02 +00:00
|
|
|
if (tbf == ul_tbf_as_tbf(ms->ul_tbf)) {
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
ms->ul_tbf = NULL;
|
2023-04-18 15:31:02 +00:00
|
|
|
} else if (tbf == dl_tbf_as_tbf(ms->dl_tbf)) {
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
ms->dl_tbf = NULL;
|
|
|
|
} else {
|
2023-04-18 15:31:02 +00:00
|
|
|
/* We know from ms_tbf_is_attached()==true check above that tbf
|
|
|
|
* is in ms->old_tbfs, no need to look it up again. */
|
|
|
|
llist_del(tbf_ms_list(tbf));
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
2023-04-18 17:02:55 +00:00
|
|
|
ms_unref(ms, MS_USE_TBF);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
2023-04-18 17:02:55 +00:00
|
|
|
/* Cleans up old MS being merged into a new one. Should be called with a
|
2023-04-28 12:46:32 +00:00
|
|
|
* ms_ref() taken to avoid use-after-free.
|
|
|
|
*/
|
2023-04-28 12:29:40 +00:00
|
|
|
static void ms_reset(struct GprsMs *ms)
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
{
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGPMS(ms, DMS, LOGL_INFO, "Clearing MS object\n");
|
2023-04-18 17:02:55 +00:00
|
|
|
struct llist_item *pos;
|
|
|
|
struct gprs_rlcmac_tbf *tbf;
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
2023-04-18 17:02:55 +00:00
|
|
|
tbf = ul_tbf_as_tbf(ms_ul_tbf(ms));
|
|
|
|
if (tbf && !tbf_timers_pending(tbf, T_MAX))
|
|
|
|
tbf_free(tbf);
|
|
|
|
tbf = dl_tbf_as_tbf(ms_dl_tbf(ms));
|
|
|
|
if (tbf && !tbf_timers_pending(tbf, T_MAX))
|
|
|
|
tbf_free(tbf);
|
|
|
|
|
2023-04-28 12:45:39 +00:00
|
|
|
while ((pos = llist_first_entry_or_null(&ms->old_tbfs, struct llist_item, list))) {
|
2023-04-18 17:02:55 +00:00
|
|
|
tbf = (struct gprs_rlcmac_tbf *)pos->entry;
|
|
|
|
if (!tbf_timers_pending(tbf, T_MAX))
|
|
|
|
tbf_free(tbf);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Flag it with invalid data so that it cannot be looked up anymore and
|
2023-04-20 14:42:54 +00:00
|
|
|
* shows up specially if listed in VTY. Furthermore, it will also trigger
|
|
|
|
* immediate free() when it becomes idle: */
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
ms->tlli = GSM_RESERVED_TMSI;
|
|
|
|
ms->new_dl_tlli = ms->tlli;
|
|
|
|
ms->new_ul_tlli = ms->tlli;
|
|
|
|
ms->imsi[0] = '\0';
|
|
|
|
}
|
|
|
|
|
2022-10-21 16:49:48 +00:00
|
|
|
/* This function should be called on the MS object of a TBF each time an RLCMAC
|
|
|
|
* block is received for it with TLLI information.
|
|
|
|
* Besides updating the TLLI field on the MS object, it also seeks for other MS
|
|
|
|
* objects in the store and merges them into the current MS object. The MS
|
|
|
|
* duplication happened because we don't learn the TLLI of the created TBF until
|
|
|
|
* a later point. */
|
|
|
|
void ms_update_announced_tlli(struct GprsMs *ms, uint32_t tlli)
|
|
|
|
{
|
|
|
|
struct GprsMs *old_ms = NULL;
|
|
|
|
|
|
|
|
if (tlli == GSM_RESERVED_TMSI)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* When the TLLI does not match the ms, check if there is another
|
|
|
|
* MS object that belongs to that TLLI and if yes make sure one of them
|
|
|
|
* gets deleted. */
|
|
|
|
if (!ms_check_tlli(ms, tlli))
|
2023-04-17 14:33:35 +00:00
|
|
|
old_ms = bts_get_ms_by_tlli(ms->bts, tlli, GSM_RESERVED_TMSI);
|
2022-10-21 16:49:48 +00:00
|
|
|
|
|
|
|
ms_set_tlli(ms, tlli);
|
|
|
|
|
|
|
|
if (old_ms)
|
|
|
|
ms_merge_and_clear_ms(ms, old_ms);
|
|
|
|
/* old_ms may no longer be available here */
|
|
|
|
}
|
|
|
|
|
2022-10-31 11:55:03 +00:00
|
|
|
/* Merge 'old_ms' object into 'ms' object.
|
|
|
|
* 'old_ms' may be freed during the call to this function, don't use the pointer to it afterwards */
|
|
|
|
void ms_merge_and_clear_ms(struct GprsMs *ms, struct GprsMs *old_ms)
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
{
|
2022-10-31 11:55:03 +00:00
|
|
|
char old_ms_name[128];
|
2023-06-27 16:02:33 +00:00
|
|
|
struct gprs_rlcmac_dl_tbf *dl_tbf;
|
|
|
|
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
OSMO_ASSERT(old_ms != ms);
|
2023-04-17 18:28:10 +00:00
|
|
|
ms_ref(old_ms, __func__);
|
2022-10-31 11:55:03 +00:00
|
|
|
|
|
|
|
ms_name_buf(old_ms, old_ms_name, sizeof(old_ms_name));
|
|
|
|
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGPMS(ms, DMS, LOGL_INFO, "Merge MS: %s\n", old_ms_name);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
if (strlen(ms_imsi(ms)) == 0 && strlen(ms_imsi(old_ms)) != 0)
|
|
|
|
osmo_strlcpy(ms->imsi, ms_imsi(old_ms), sizeof(ms->imsi));
|
|
|
|
|
|
|
|
if (!ms_ms_class(ms) && ms_ms_class(old_ms))
|
|
|
|
ms_set_ms_class(ms, ms_ms_class(old_ms));
|
|
|
|
|
|
|
|
if (!ms_egprs_ms_class(ms) && ms_egprs_ms_class(old_ms))
|
|
|
|
ms_set_egprs_ms_class(ms, ms_egprs_ms_class(old_ms));
|
|
|
|
|
2023-06-27 16:02:33 +00:00
|
|
|
|
|
|
|
if ((dl_tbf = ms_dl_tbf(old_ms))) {
|
|
|
|
/* Move the last partially/totally unacked LLC PDU back to the LLC queue: */
|
|
|
|
dl_tbf_copy_unacked_pdus_to_llc_queue(dl_tbf);
|
|
|
|
}
|
|
|
|
/* Now merge the old_ms queue into the new one: */
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
llc_queue_move_and_merge(&ms->llc_queue, &old_ms->llc_queue);
|
|
|
|
|
|
|
|
/* Clean up the old MS object */
|
2022-10-31 11:55:03 +00:00
|
|
|
ms_reset(old_ms);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
2023-04-17 18:28:10 +00:00
|
|
|
ms_unref(old_ms, __func__);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
2022-11-03 12:35:19 +00:00
|
|
|
/* Apply changes to the TLLI directly, used interally by functions below: */
|
|
|
|
static void ms_apply_tlli_change(struct GprsMs *ms, uint32_t tlli)
|
|
|
|
{
|
|
|
|
ms->tlli = tlli;
|
|
|
|
ms->new_dl_tlli = GSM_RESERVED_TMSI;
|
|
|
|
ms->new_ul_tlli = GSM_RESERVED_TMSI;
|
|
|
|
|
|
|
|
/* Update TBF FSM names: */
|
|
|
|
if (ms->ul_tbf)
|
|
|
|
tbf_update_state_fsm_name(ul_tbf_as_tbf(ms->ul_tbf));
|
|
|
|
if (ms->dl_tbf)
|
|
|
|
tbf_update_state_fsm_name(dl_tbf_as_tbf(ms->dl_tbf));
|
|
|
|
}
|
|
|
|
|
2022-10-21 12:10:41 +00:00
|
|
|
/* Set/update the MS object TLLI based on knowledge gained from the MS side (Uplink direction) */
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
void ms_set_tlli(struct GprsMs *ms, uint32_t tlli)
|
|
|
|
{
|
|
|
|
if (tlli == ms->tlli || tlli == ms->new_ul_tlli)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (tlli != ms->new_dl_tlli) {
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGP(DMS, LOGL_INFO,
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
"Modifying MS object, UL TLLI: 0x%08x -> 0x%08x, "
|
|
|
|
"not yet confirmed\n",
|
|
|
|
ms_tlli(ms), tlli);
|
|
|
|
ms->new_ul_tlli = tlli;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGP(DMS, LOGL_INFO,
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
"Modifying MS object, TLLI: 0x%08x -> 0x%08x, "
|
|
|
|
"already confirmed partly\n",
|
|
|
|
ms->tlli, tlli);
|
|
|
|
|
2022-11-03 12:35:19 +00:00
|
|
|
ms_apply_tlli_change(ms, tlli);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
2022-10-21 12:10:41 +00:00
|
|
|
/* Set/update the MS object TLLI based on knowledge gained from the SGSN side (Downlink direction) */
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
bool ms_confirm_tlli(struct GprsMs *ms, uint32_t tlli)
|
|
|
|
{
|
|
|
|
if (tlli == ms->tlli || tlli == ms->new_dl_tlli)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (tlli != ms->new_ul_tlli) {
|
|
|
|
/* The MS has not sent a message with the new TLLI, which may
|
|
|
|
* happen according to the spec [TODO: add reference]. */
|
|
|
|
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGP(DMS, LOGL_INFO,
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
"The MS object cannot fully confirm an unexpected TLLI: 0x%08x, "
|
|
|
|
"partly confirmed\n", tlli);
|
|
|
|
/* Use the network's idea of TLLI as candidate, this does not
|
|
|
|
* change the result value of tlli() */
|
|
|
|
ms->new_dl_tlli = tlli;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGP(DMS, LOGL_INFO,
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
"Modifying MS object, TLLI: 0x%08x confirmed\n", tlli);
|
|
|
|
|
2022-11-03 12:35:19 +00:00
|
|
|
ms_apply_tlli_change(ms, tlli);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ms_set_imsi(struct GprsMs *ms, const char *imsi)
|
|
|
|
{
|
|
|
|
if (!imsi) {
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGP(DMS, LOGL_ERROR, "Expected IMSI!\n");
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (imsi[0] && strlen(imsi) < 3) {
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGP(DMS, LOGL_ERROR, "No valid IMSI '%s'!\n",
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
imsi);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(imsi, ms->imsi) == 0)
|
|
|
|
return;
|
|
|
|
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGP(DMS, LOGL_INFO,
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
"Modifying MS object, TLLI = 0x%08x, IMSI '%s' -> '%s'\n",
|
|
|
|
ms_tlli(ms), ms->imsi, imsi);
|
|
|
|
|
2023-04-17 16:16:48 +00:00
|
|
|
struct GprsMs *old_ms = bts_get_ms_by_imsi(ms->bts, imsi);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
/* Check if we are going to store a different MS object with already
|
|
|
|
existing IMSI. This is probably a bug in code calling this function,
|
|
|
|
since it should take care of this explicitly */
|
|
|
|
if (old_ms) {
|
|
|
|
/* We cannot find ms->ms by IMSI since we know that it has a
|
|
|
|
* different IMSI */
|
|
|
|
OSMO_ASSERT(old_ms != ms);
|
|
|
|
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGPMS(ms, DMS, LOGL_NOTICE,
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
"IMSI '%s' was already assigned to another "
|
|
|
|
"MS object: TLLI = 0x%08x, that IMSI will be removed\n",
|
|
|
|
imsi, ms_tlli(old_ms));
|
|
|
|
|
|
|
|
ms_merge_and_clear_ms(ms, old_ms);
|
2022-10-31 11:58:46 +00:00
|
|
|
/* old_ms may no longer be available here */
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
2022-11-03 12:35:19 +00:00
|
|
|
/* Store the new IMSI: */
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
osmo_strlcpy(ms->imsi, imsi, sizeof(ms->imsi));
|
2022-11-03 12:35:19 +00:00
|
|
|
|
|
|
|
/* Update TBF FSM names: */
|
|
|
|
if (ms->ul_tbf)
|
|
|
|
tbf_update_state_fsm_name(ul_tbf_as_tbf(ms->ul_tbf));
|
|
|
|
if (ms->dl_tbf)
|
|
|
|
tbf_update_state_fsm_name(dl_tbf_as_tbf(ms->dl_tbf));
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ms_set_ta(struct GprsMs *ms, uint8_t ta_)
|
|
|
|
{
|
|
|
|
if (ta_ == ms->ta)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (gsm48_ta_is_valid(ta_)) {
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGP(DMS, LOGL_INFO,
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
"Modifying MS object, TLLI = 0x%08x, TA %d -> %d\n",
|
|
|
|
ms_tlli(ms), ms->ta, ta_);
|
|
|
|
ms->ta = ta_;
|
|
|
|
} else
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGP(DMS, LOGL_NOTICE,
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
"MS object, TLLI = 0x%08x, invalid TA %d rejected (old "
|
|
|
|
"value %d kept)\n", ms_tlli(ms), ta_, ms->ta);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ms_set_ms_class(struct GprsMs *ms, uint8_t ms_class_)
|
|
|
|
{
|
|
|
|
if (ms_class_ == ms->ms_class)
|
|
|
|
return;
|
|
|
|
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGP(DMS, LOGL_INFO,
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
"Modifying MS object, TLLI = 0x%08x, MS class %d -> %d\n",
|
|
|
|
ms_tlli(ms), ms->ms_class, ms_class_);
|
|
|
|
|
|
|
|
ms->ms_class = ms_class_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ms_set_egprs_ms_class(struct GprsMs *ms, uint8_t ms_class_)
|
|
|
|
{
|
|
|
|
if (ms_class_ == ms->egprs_ms_class)
|
|
|
|
return;
|
|
|
|
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGP(DMS, LOGL_INFO,
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
"Modifying MS object, TLLI = 0x%08x, EGPRS MS class %d -> %d\n",
|
|
|
|
ms_tlli(ms), ms->egprs_ms_class, ms_class_);
|
|
|
|
|
|
|
|
ms->egprs_ms_class = ms_class_;
|
|
|
|
|
|
|
|
if (!bts_max_mcs_ul(ms->bts) || !bts_max_mcs_dl(ms->bts)) {
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGPMS(ms, DMS, LOGL_DEBUG,
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
"Avoid enabling EGPRS because use of MCS is disabled: ul=%u dl=%u\n",
|
|
|
|
bts_max_mcs_ul(ms->bts), bts_max_mcs_dl(ms->bts));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mcs_is_edge_gmsk(mcs_get_egprs_by_num(bts_max_mcs_ul(ms->bts))) &&
|
|
|
|
mcs_is_edge_gmsk(mcs_get_egprs_by_num(bts_max_mcs_dl(ms->bts))) &&
|
|
|
|
ms_mode(ms) != EGPRS)
|
|
|
|
{
|
|
|
|
ms_set_mode(ms, EGPRS_GMSK);
|
|
|
|
} else {
|
|
|
|
ms_set_mode(ms, EGPRS);
|
|
|
|
}
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGPMS(ms, DMS, LOGL_INFO, "Enabled EGPRS, mode %s\n", mode_name(ms_mode(ms)));
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ms_update_error_rate(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf, int error_rate)
|
|
|
|
{
|
|
|
|
int64_t now;
|
|
|
|
enum CodingScheme max_cs_dl = ms_max_cs_dl(ms);
|
|
|
|
OSMO_ASSERT(max_cs_dl);
|
|
|
|
|
|
|
|
if (error_rate < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
now = now_msec();
|
|
|
|
|
|
|
|
/* TODO: Check for TBF direction */
|
|
|
|
/* TODO: Support different CS values for UL and DL */
|
|
|
|
|
|
|
|
ms->nack_rate_dl = error_rate;
|
|
|
|
|
2021-01-14 12:17:01 +00:00
|
|
|
if (error_rate > the_pcu->vty.cs_adj_upper_limit) {
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
if (mcs_chan_code(ms->current_cs_dl) > 0) {
|
|
|
|
mcs_dec_kind(&ms->current_cs_dl, ms_mode(ms));
|
|
|
|
LOGP(DRLCMACDL, LOGL_INFO,
|
|
|
|
"MS (IMSI %s): High error rate %d%%, "
|
|
|
|
"reducing CS level to %s\n",
|
|
|
|
ms_imsi(ms), error_rate, mcs_name(ms->current_cs_dl));
|
|
|
|
ms->last_cs_not_low = now;
|
|
|
|
}
|
2021-01-14 12:17:01 +00:00
|
|
|
} else if (error_rate < the_pcu->vty.cs_adj_lower_limit) {
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
if (ms->current_cs_dl < max_cs_dl) {
|
|
|
|
if (now - ms->last_cs_not_low > 1000) {
|
|
|
|
mcs_inc_kind(&ms->current_cs_dl, ms_mode(ms));
|
|
|
|
|
|
|
|
LOGP(DRLCMACDL, LOGL_INFO,
|
|
|
|
"MS (IMSI %s): Low error rate %d%%, "
|
|
|
|
"increasing DL CS level to %s\n",
|
|
|
|
ms_imsi(ms), error_rate,
|
|
|
|
mcs_name(ms->current_cs_dl));
|
|
|
|
ms->last_cs_not_low = now;
|
|
|
|
} else {
|
|
|
|
LOGP(DRLCMACDL, LOGL_DEBUG,
|
|
|
|
"MS (IMSI %s): Low error rate %d%%, "
|
|
|
|
"ignored (within blocking period)\n",
|
|
|
|
ms_imsi(ms), error_rate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
LOGP(DRLCMACDL, LOGL_DEBUG,
|
|
|
|
"MS (IMSI %s): Medium error rate %d%%, ignored\n",
|
|
|
|
ms_imsi(ms), error_rate);
|
|
|
|
ms->last_cs_not_low = now;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
enum CodingScheme ms_max_cs_ul(const struct GprsMs *ms)
|
|
|
|
{
|
2021-01-25 14:10:33 +00:00
|
|
|
enum CodingScheme cs;
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
OSMO_ASSERT(ms->bts != NULL);
|
|
|
|
|
|
|
|
if (mcs_is_gprs(ms->current_cs_ul)) {
|
|
|
|
if (!bts_max_cs_ul(ms->bts)) {
|
|
|
|
return CS4;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mcs_get_gprs_by_num(bts_max_cs_ul(ms->bts));
|
|
|
|
}
|
|
|
|
|
2021-01-25 14:10:33 +00:00
|
|
|
cs = mcs_get_egprs_by_num(bts_max_mcs_ul(ms->bts));
|
|
|
|
if (ms_mode(ms) == EGPRS_GMSK && cs > MCS4)
|
|
|
|
cs = MCS4;
|
|
|
|
return cs;
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ms_set_current_cs_dl(struct GprsMs *ms, enum CodingScheme scheme)
|
|
|
|
{
|
|
|
|
ms->current_cs_dl = scheme;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum CodingScheme ms_max_cs_dl(const struct GprsMs *ms)
|
|
|
|
{
|
2021-01-25 14:10:33 +00:00
|
|
|
enum CodingScheme cs;
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
OSMO_ASSERT(ms->bts != NULL);
|
|
|
|
|
|
|
|
if (mcs_is_gprs(ms->current_cs_dl)) {
|
|
|
|
if (!bts_max_cs_dl(ms->bts)) {
|
|
|
|
return CS4;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mcs_get_gprs_by_num(bts_max_cs_dl(ms->bts));
|
|
|
|
}
|
|
|
|
|
2021-01-25 14:10:33 +00:00
|
|
|
cs = mcs_get_egprs_by_num(bts_max_mcs_dl(ms->bts));
|
|
|
|
if (ms_mode(ms) == EGPRS_GMSK && cs > MCS4)
|
|
|
|
cs = MCS4;
|
|
|
|
return cs;
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ms_update_cs_ul(struct GprsMs *ms, const struct pcu_l1_meas *meas)
|
|
|
|
{
|
|
|
|
enum CodingScheme max_cs_ul = ms_max_cs_ul(ms);
|
|
|
|
|
|
|
|
int old_link_qual;
|
|
|
|
int low;
|
|
|
|
int high;
|
|
|
|
enum CodingScheme new_cs_ul = ms->current_cs_ul;
|
|
|
|
uint8_t current_cs = mcs_chan_code(ms->current_cs_ul);
|
|
|
|
|
|
|
|
if (!max_cs_ul) {
|
|
|
|
LOGP(DRLCMACMEAS, LOGL_ERROR,
|
|
|
|
"max_cs_ul cannot be derived (current UL CS: %s)\n",
|
|
|
|
mcs_name(ms->current_cs_ul));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ms->current_cs_ul) {
|
|
|
|
LOGP(DRLCMACMEAS, LOGL_ERROR,
|
|
|
|
"Unable to update UL (M)CS because it's not set: %s\n",
|
|
|
|
mcs_name(ms->current_cs_ul));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!meas->have_link_qual) {
|
|
|
|
LOGP(DRLCMACMEAS, LOGL_ERROR,
|
|
|
|
"Unable to update UL (M)CS %s because we don't have link quality measurements.\n",
|
|
|
|
mcs_name(ms->current_cs_ul));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mcs_is_gprs(ms->current_cs_ul)) {
|
|
|
|
if (current_cs >= MAX_GPRS_CS)
|
|
|
|
current_cs = MAX_GPRS_CS - 1;
|
2021-01-14 12:30:04 +00:00
|
|
|
low = the_pcu->vty.cs_lqual_ranges[current_cs].low;
|
|
|
|
high = the_pcu->vty.cs_lqual_ranges[current_cs].high;
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
} else if (mcs_is_edge(ms->current_cs_ul)) {
|
|
|
|
if (current_cs >= MAX_EDGE_MCS)
|
|
|
|
current_cs = MAX_EDGE_MCS - 1;
|
2021-01-14 12:30:04 +00:00
|
|
|
low = the_pcu->vty.mcs_lqual_ranges[current_cs].low;
|
|
|
|
high = the_pcu->vty.mcs_lqual_ranges[current_cs].high;
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
} else {
|
|
|
|
LOGP(DRLCMACMEAS, LOGL_ERROR,
|
|
|
|
"Unable to update UL (M)CS because it's neither GPRS nor EDGE: %s\n",
|
|
|
|
mcs_name(ms->current_cs_ul));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* To avoid rapid changes of the coding scheme, we also take
|
|
|
|
* the old link quality value into account (if present). */
|
|
|
|
if (ms->l1_meas.have_link_qual)
|
|
|
|
old_link_qual = ms->l1_meas.link_qual;
|
|
|
|
else
|
|
|
|
old_link_qual = meas->link_qual;
|
|
|
|
|
|
|
|
if (meas->link_qual < low && old_link_qual < low)
|
|
|
|
mcs_dec_kind(&new_cs_ul, ms_mode(ms));
|
|
|
|
else if (meas->link_qual > high && old_link_qual > high &&
|
|
|
|
ms->current_cs_ul < max_cs_ul)
|
|
|
|
mcs_inc_kind(&new_cs_ul, ms_mode(ms));
|
|
|
|
|
|
|
|
if (ms->current_cs_ul != new_cs_ul) {
|
|
|
|
LOGPMS(ms, DRLCMACMEAS, LOGL_INFO,
|
|
|
|
"Link quality %ddB (old %ddB) left window [%d, %d], "
|
|
|
|
"modifying uplink CS level: %s -> %s\n",
|
|
|
|
meas->link_qual, old_link_qual,
|
|
|
|
low, high,
|
|
|
|
mcs_name(ms->current_cs_ul), mcs_name(new_cs_ul));
|
|
|
|
|
|
|
|
ms->current_cs_ul = new_cs_ul;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ms_update_l1_meas(struct GprsMs *ms, const struct pcu_l1_meas *meas)
|
|
|
|
{
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
ms_update_cs_ul(ms, meas);
|
|
|
|
|
|
|
|
if (meas->have_rssi)
|
|
|
|
pcu_l1_meas_set_rssi(&ms->l1_meas, meas->rssi);
|
|
|
|
if (meas->have_bto)
|
|
|
|
pcu_l1_meas_set_bto(&ms->l1_meas, meas->bto);
|
|
|
|
if (meas->have_ber)
|
|
|
|
pcu_l1_meas_set_ber(&ms->l1_meas, meas->ber);
|
|
|
|
if (meas->have_link_qual)
|
|
|
|
pcu_l1_meas_set_link_qual(&ms->l1_meas, meas->link_qual);
|
|
|
|
|
|
|
|
if (meas->have_ms_rx_qual)
|
|
|
|
pcu_l1_meas_set_ms_rx_qual(&ms->l1_meas, meas->ms_rx_qual);
|
|
|
|
if (meas->have_ms_c_value)
|
|
|
|
pcu_l1_meas_set_ms_c_value(&ms->l1_meas, meas->ms_c_value);
|
|
|
|
if (meas->have_ms_sign_var)
|
|
|
|
pcu_l1_meas_set_ms_sign_var(&ms->l1_meas, meas->ms_sign_var);
|
|
|
|
|
|
|
|
if (meas->have_ms_i_level) {
|
|
|
|
for (i = 0; i < ARRAY_SIZE(meas->ts); ++i) {
|
|
|
|
if (meas->ts[i].have_ms_i_level)
|
|
|
|
pcu_l1_meas_set_ms_i_level(&ms->l1_meas, i, meas->ts[i].ms_i_level);
|
|
|
|
else
|
|
|
|
ms->l1_meas.ts[i].have_ms_i_level = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-25 11:05:32 +00:00
|
|
|
/* req_mcs_kind acts as a set filter, where EGPRS means any and GPRS is the most restrictive */
|
|
|
|
enum CodingScheme ms_current_cs_dl(const struct GprsMs *ms, enum mcs_kind req_mcs_kind)
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
{
|
2021-01-25 11:05:32 +00:00
|
|
|
enum CodingScheme orig_cs = ms->current_cs_dl;
|
|
|
|
struct gprs_rlcmac_bts *bts = ms->bts;
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
size_t unencoded_octets;
|
2021-01-25 11:05:32 +00:00
|
|
|
enum CodingScheme cs;
|
|
|
|
|
|
|
|
/* It could be that a TBF requests a GPRS CS despite the MS currently
|
|
|
|
being upgraded to EGPRS (hence reporting MCS). That could happen
|
|
|
|
because the TBF was created early in the process where we didn't have
|
|
|
|
yet enough information about the MS, and only AFTER it was created we
|
|
|
|
upgraded the MS to be EGPRS capable.
|
|
|
|
As a result, when the MS is queried for the target CS here, we could be
|
|
|
|
returning an MCS despite the current TBF being established as GPRS,
|
|
|
|
but we rather stick to the TBF type we assigned to the MS rather than
|
|
|
|
magically sending EGPRS data blocks to a GPRS TBF.
|
|
|
|
It could also be that the caller requests specific MCS kind
|
|
|
|
explicitly too due to scheduling restrictions (GPRS+EGPRS multiplexing). */
|
|
|
|
if (req_mcs_kind == EGPRS_GMSK && mcs_is_edge(orig_cs) && orig_cs > MCS4) {
|
|
|
|
cs = bts_cs_dl_is_supported(bts, MCS4) ? MCS4 :
|
|
|
|
bts_cs_dl_is_supported(bts, MCS3) ? MCS3 :
|
|
|
|
bts_cs_dl_is_supported(bts, MCS2) ? MCS2 :
|
|
|
|
MCS1;
|
|
|
|
} else if (req_mcs_kind == GPRS && mcs_is_edge(orig_cs)) { /* GPRS */
|
|
|
|
int i;
|
|
|
|
cs = orig_cs > MCS4 ? MCS4 : orig_cs;
|
|
|
|
cs -= (MCS1 - CS1); /* MCSx -> CSx */
|
|
|
|
/* Find suitable CS starting from equivalent MCS which is supported by BTS: */
|
|
|
|
for (i = mcs_chan_code(cs); !bts_cs_dl_is_supported(bts, CS1 + i); i--);
|
|
|
|
OSMO_ASSERT(i >= 0 && i <= 3); /* CS1 is always supported */
|
|
|
|
cs = CS1 + i;
|
|
|
|
} else {
|
|
|
|
cs = orig_cs;
|
|
|
|
}
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
2021-01-25 11:05:32 +00:00
|
|
|
if (orig_cs != cs)
|
2023-04-19 18:38:40 +00:00
|
|
|
LOGPMS(ms, DMS, LOGL_INFO, "MS (mode=%s) suggests transmitting "
|
2021-01-25 11:05:32 +00:00
|
|
|
"DL %s, downgrade to %s in order to match TBF & scheduler requirements\n",
|
|
|
|
mode_name(ms_mode(ms)), mcs_name(orig_cs), mcs_name(cs));
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
unencoded_octets = llc_queue_octets(&ms->llc_queue);
|
|
|
|
|
|
|
|
/* If the DL TBF is active, add number of unencoded chunk octets */
|
|
|
|
if (ms->dl_tbf)
|
2022-10-27 13:40:20 +00:00
|
|
|
unencoded_octets += llc_chunk_size(tbf_llc(dl_tbf_as_tbf(ms->dl_tbf)));
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
/* There are many unencoded octets, don't reduce */
|
2021-01-14 12:20:55 +00:00
|
|
|
if (unencoded_octets >= the_pcu->vty.cs_downgrade_threshold)
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
return cs;
|
|
|
|
|
|
|
|
/* RF conditions are good, don't reduce */
|
2021-01-14 12:17:01 +00:00
|
|
|
if (ms->nack_rate_dl < the_pcu->vty.cs_adj_lower_limit)
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
return cs;
|
|
|
|
|
|
|
|
/* The throughput would probably be better if the CS level was reduced */
|
|
|
|
mcs_dec_kind(&cs, ms_mode(ms));
|
|
|
|
|
|
|
|
/* CS-2 doesn't gain throughput with small packets, further reduce to CS-1 */
|
|
|
|
if (cs == CS2)
|
|
|
|
mcs_dec_kind(&cs, ms_mode(ms));
|
|
|
|
|
|
|
|
return cs;
|
|
|
|
}
|
|
|
|
|
2022-12-13 17:29:25 +00:00
|
|
|
struct gprs_rlcmac_pdch *ms_first_common_ts(const struct GprsMs *ms)
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
{
|
2022-12-12 18:22:44 +00:00
|
|
|
return ms->first_common_ts;
|
|
|
|
}
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
2022-12-13 17:29:25 +00:00
|
|
|
void ms_set_first_common_ts(struct GprsMs *ms, struct gprs_rlcmac_pdch *pdch)
|
2022-12-12 18:22:44 +00:00
|
|
|
{
|
2022-12-13 17:29:25 +00:00
|
|
|
OSMO_ASSERT(pdch);
|
|
|
|
ms->first_common_ts = pdch;
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t ms_dl_slots(const struct GprsMs *ms)
|
|
|
|
{
|
|
|
|
uint8_t slots = 0;
|
|
|
|
|
|
|
|
if (ms->dl_tbf)
|
2022-10-27 13:40:20 +00:00
|
|
|
slots |= tbf_dl_slots(dl_tbf_as_tbf(ms->dl_tbf));
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
if (ms->ul_tbf)
|
2022-10-27 13:40:20 +00:00
|
|
|
slots |= tbf_dl_slots(ul_tbf_as_tbf(ms->ul_tbf));
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
return slots;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t ms_ul_slots(const struct GprsMs *ms)
|
|
|
|
{
|
|
|
|
uint8_t slots = 0;
|
|
|
|
|
|
|
|
if (ms->dl_tbf)
|
2022-10-27 13:40:20 +00:00
|
|
|
slots |= tbf_ul_slots(dl_tbf_as_tbf(ms->dl_tbf));
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
if (ms->ul_tbf)
|
2022-10-27 13:40:20 +00:00
|
|
|
slots |= tbf_ul_slots(ul_tbf_as_tbf(ms->ul_tbf));
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
return slots;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t ms_current_pacch_slots(const struct GprsMs *ms)
|
|
|
|
{
|
|
|
|
uint8_t slots = 0;
|
|
|
|
|
2022-10-27 13:40:20 +00:00
|
|
|
bool is_dl_active = ms->dl_tbf && tbf_is_tfi_assigned(dl_tbf_as_tbf(ms->dl_tbf));
|
|
|
|
bool is_ul_active = ms->ul_tbf && tbf_is_tfi_assigned(ul_tbf_as_tbf(ms->ul_tbf));
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
if (!is_dl_active && !is_ul_active)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* see TS 44.060, 8.1.1.2.2 */
|
|
|
|
if (is_dl_active && !is_ul_active)
|
2022-10-27 13:40:20 +00:00
|
|
|
slots = tbf_dl_slots(dl_tbf_as_tbf(ms->dl_tbf));
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
else if (!is_dl_active && is_ul_active)
|
2022-10-27 13:40:20 +00:00
|
|
|
slots = tbf_ul_slots(ul_tbf_as_tbf(ms->ul_tbf));
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
else
|
2022-10-27 13:40:20 +00:00
|
|
|
slots = tbf_ul_slots(ul_tbf_as_tbf(ms->ul_tbf)) &
|
|
|
|
tbf_dl_slots(dl_tbf_as_tbf(ms->dl_tbf));
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
|
|
|
|
/* Assume a multislot class 1 device */
|
|
|
|
/* TODO: For class 2 devices, this could be removed */
|
|
|
|
slots = pcu_lsb(slots);
|
|
|
|
|
|
|
|
return slots;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ms_set_reserved_slots(struct GprsMs *ms, struct gprs_rlcmac_trx *trx,
|
|
|
|
uint8_t ul_slots, uint8_t dl_slots)
|
|
|
|
{
|
|
|
|
if (ms->current_trx) {
|
|
|
|
bts_trx_unreserve_slots(ms->current_trx, GPRS_RLCMAC_DL_TBF,
|
|
|
|
ms->reserved_dl_slots);
|
|
|
|
bts_trx_unreserve_slots(ms->current_trx, GPRS_RLCMAC_UL_TBF,
|
|
|
|
ms->reserved_ul_slots);
|
|
|
|
ms->reserved_dl_slots = 0;
|
|
|
|
ms->reserved_ul_slots = 0;
|
|
|
|
}
|
|
|
|
ms->current_trx = trx;
|
|
|
|
if (trx) {
|
|
|
|
ms->reserved_dl_slots = dl_slots;
|
|
|
|
ms->reserved_ul_slots = ul_slots;
|
|
|
|
bts_trx_reserve_slots(ms->current_trx, GPRS_RLCMAC_DL_TBF,
|
|
|
|
ms->reserved_dl_slots);
|
|
|
|
bts_trx_reserve_slots(ms->current_trx, GPRS_RLCMAC_UL_TBF,
|
|
|
|
ms->reserved_ul_slots);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct gprs_rlcmac_tbf *ms_tbf(const struct GprsMs *ms, enum gprs_rlcmac_tbf_direction dir)
|
|
|
|
{
|
|
|
|
switch (dir) {
|
2022-10-27 13:40:20 +00:00
|
|
|
case GPRS_RLCMAC_DL_TBF: return dl_tbf_as_tbf(ms->dl_tbf);
|
|
|
|
case GPRS_RLCMAC_UL_TBF: return ul_tbf_as_tbf(ms->ul_tbf);
|
Convert GprsMS and helpers classes to C
As we integrate osmo-pcu more and more with libosmocore features, it
becomes really hard to use them since libosmocore relies heavily on C
specific compilation features, which are not available in old C++
compilers (such as designated initializers for complex types in FSMs).
GprsMs is right now a quite simple object since initial design of
osmo-pcu made it optional and most of the logic was placed and stored
duplicated in TBF objects. However, that's changing as we introduce more
features, with the GprsMS class getting more weight. Hence, let's move
it now to be a C struct in order to be able to easily use libosmocore
features there, such as FSMs.
Some helper classes which GprsMs uses are also mostly move to C since
they are mostly structs with methods, so there's no point in having
duplicated APIs for C++ and C for such simple cases.
For some more complex classes, like (ul_,dl_)tbf, C API bindings are
added where needed so that GprsMs can use functionalitites from that
class. Most of those APIs can be kept afterwards and drop the C++ ones
since they provide no benefit in general.
Change-Id: I0b50e3367aaad9dcada76da97b438e452c8b230c
2020-12-16 14:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
Introduce NACC support
A new nacc_fsm is introduced per MS object, with its partner priv
structure struct nacc_fsm_ctx, which exists and is available in the MS
object only during the duration of the NACC procedure.
The NACC context is created on an MS whenever a Pkt Cell Change
Notification is received on Uplink RLCMAC, which asks for neighbor
information of a given ARFCN+BSIC.
First, the target ARFCN+BSIC needs to be translated into a CGI-PS
(RAC+CI) address. That's done by asking the BSC through the Neighbour
Resolution Service available in osmo-bsc using the CTRL interface.
Once the CGI-PS of the target cell is known, PCU starts a RIM RAN-INFO
request against the SGSN (which will route the request as needed), and
wait for a response containing the SI bits from the target cell.
After the SI are received, the scheduler is instructed to eventually
poll a TBF for the MS originating the CCN, so that we can send the SI
encapsulated into multiple Packet Neighbor Cell Data messages on the
downlink.
One all the SI bits are sent, the scheduler is instructed to send a
Packet Cell Change Continue message.
Once the message above has been sent, the FSM autodestroys itself.
Caches are also introduced in this patch which allows for re-using
recently known translations ARFCN+BSIC -> CGI-PS and CGI-PS -> SI_INFO
respectively.
Change-Id: Id35f40d05f3e081f32fddbf1fa34cb338db452ca
2021-01-21 17:46:13 +00:00
|
|
|
|
2022-10-21 13:00:08 +00:00
|
|
|
const char *ms_name(const struct GprsMs *ms)
|
|
|
|
{
|
|
|
|
static char _ms_name_buf[128];
|
|
|
|
return ms_name_buf(ms, _ms_name_buf, sizeof(_ms_name_buf));
|
|
|
|
}
|
|
|
|
|
|
|
|
char *ms_name_buf(const struct GprsMs *ms, char *buf, unsigned int buf_size)
|
|
|
|
{
|
2022-11-03 13:16:17 +00:00
|
|
|
struct osmo_strbuf sb = { .buf = buf, .len = buf_size };
|
|
|
|
uint32_t tlli = ms_tlli(ms);
|
|
|
|
|
|
|
|
OSMO_STRBUF_PRINTF(sb, "MS(");
|
|
|
|
if (ms_imsi_is_valid(ms))
|
|
|
|
OSMO_STRBUF_PRINTF(sb, "IMSI-%s:", ms_imsi(ms));
|
|
|
|
if (tlli != GSM_RESERVED_TMSI)
|
|
|
|
OSMO_STRBUF_PRINTF(sb, "TLLI-0x%08x:", tlli);
|
|
|
|
OSMO_STRBUF_PRINTF(sb, "TA-%" PRIu8 ":MSCLS-%" PRIu8 "-%" PRIu8,
|
|
|
|
ms_ta(ms), ms_ms_class(ms), ms_egprs_ms_class(ms));
|
|
|
|
if (ms->ul_tbf)
|
|
|
|
OSMO_STRBUF_PRINTF(sb, ":UL");
|
|
|
|
if (ms->dl_tbf)
|
|
|
|
OSMO_STRBUF_PRINTF(sb, ":DL");
|
|
|
|
|
|
|
|
OSMO_STRBUF_PRINTF(sb, ")");
|
2022-10-21 13:00:08 +00:00
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
Introduce NACC support
A new nacc_fsm is introduced per MS object, with its partner priv
structure struct nacc_fsm_ctx, which exists and is available in the MS
object only during the duration of the NACC procedure.
The NACC context is created on an MS whenever a Pkt Cell Change
Notification is received on Uplink RLCMAC, which asks for neighbor
information of a given ARFCN+BSIC.
First, the target ARFCN+BSIC needs to be translated into a CGI-PS
(RAC+CI) address. That's done by asking the BSC through the Neighbour
Resolution Service available in osmo-bsc using the CTRL interface.
Once the CGI-PS of the target cell is known, PCU starts a RIM RAN-INFO
request against the SGSN (which will route the request as needed), and
wait for a response containing the SI bits from the target cell.
After the SI are received, the scheduler is instructed to eventually
poll a TBF for the MS originating the CCN, so that we can send the SI
encapsulated into multiple Packet Neighbor Cell Data messages on the
downlink.
One all the SI bits are sent, the scheduler is instructed to send a
Packet Cell Change Continue message.
Once the message above has been sent, the FSM autodestroys itself.
Caches are also introduced in this patch which allows for re-using
recently known translations ARFCN+BSIC -> CGI-PS and CGI-PS -> SI_INFO
respectively.
Change-Id: Id35f40d05f3e081f32fddbf1fa34cb338db452ca
2021-01-21 17:46:13 +00:00
|
|
|
int ms_nacc_start(struct GprsMs *ms, Packet_Cell_Change_Notification_t *notif)
|
|
|
|
{
|
|
|
|
if (!ms->nacc)
|
|
|
|
ms->nacc = nacc_fsm_alloc(ms);
|
|
|
|
if (!ms->nacc)
|
|
|
|
return -EINVAL;
|
|
|
|
return osmo_fsm_inst_dispatch(ms->nacc->fi, NACC_EV_RX_CELL_CHG_NOTIFICATION, notif);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ms_nacc_rts(const struct GprsMs *ms)
|
|
|
|
{
|
|
|
|
if (!ms->nacc)
|
|
|
|
return false;
|
|
|
|
if (ms->nacc->fi->state == NACC_ST_TX_NEIGHBOUR_DATA ||
|
|
|
|
ms->nacc->fi->state == NACC_ST_TX_CELL_CHG_CONTINUE)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-12-12 17:02:25 +00:00
|
|
|
struct msgb *ms_nacc_create_rlcmac_msg(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf,
|
|
|
|
const struct gprs_rlcmac_pdch *pdch, uint32_t fn)
|
Introduce NACC support
A new nacc_fsm is introduced per MS object, with its partner priv
structure struct nacc_fsm_ctx, which exists and is available in the MS
object only during the duration of the NACC procedure.
The NACC context is created on an MS whenever a Pkt Cell Change
Notification is received on Uplink RLCMAC, which asks for neighbor
information of a given ARFCN+BSIC.
First, the target ARFCN+BSIC needs to be translated into a CGI-PS
(RAC+CI) address. That's done by asking the BSC through the Neighbour
Resolution Service available in osmo-bsc using the CTRL interface.
Once the CGI-PS of the target cell is known, PCU starts a RIM RAN-INFO
request against the SGSN (which will route the request as needed), and
wait for a response containing the SI bits from the target cell.
After the SI are received, the scheduler is instructed to eventually
poll a TBF for the MS originating the CCN, so that we can send the SI
encapsulated into multiple Packet Neighbor Cell Data messages on the
downlink.
One all the SI bits are sent, the scheduler is instructed to send a
Packet Cell Change Continue message.
Once the message above has been sent, the FSM autodestroys itself.
Caches are also introduced in this patch which allows for re-using
recently known translations ARFCN+BSIC -> CGI-PS and CGI-PS -> SI_INFO
respectively.
Change-Id: Id35f40d05f3e081f32fddbf1fa34cb338db452ca
2021-01-21 17:46:13 +00:00
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
struct nacc_ev_create_rlcmac_msg_ctx data_ctx;
|
|
|
|
|
2021-02-01 13:52:48 +00:00
|
|
|
data_ctx = (struct nacc_ev_create_rlcmac_msg_ctx) {
|
|
|
|
.tbf = tbf,
|
2022-12-12 17:02:25 +00:00
|
|
|
.pdch = pdch,
|
2021-02-01 13:52:48 +00:00
|
|
|
.fn = fn,
|
|
|
|
.msg = NULL,
|
|
|
|
};
|
Introduce NACC support
A new nacc_fsm is introduced per MS object, with its partner priv
structure struct nacc_fsm_ctx, which exists and is available in the MS
object only during the duration of the NACC procedure.
The NACC context is created on an MS whenever a Pkt Cell Change
Notification is received on Uplink RLCMAC, which asks for neighbor
information of a given ARFCN+BSIC.
First, the target ARFCN+BSIC needs to be translated into a CGI-PS
(RAC+CI) address. That's done by asking the BSC through the Neighbour
Resolution Service available in osmo-bsc using the CTRL interface.
Once the CGI-PS of the target cell is known, PCU starts a RIM RAN-INFO
request against the SGSN (which will route the request as needed), and
wait for a response containing the SI bits from the target cell.
After the SI are received, the scheduler is instructed to eventually
poll a TBF for the MS originating the CCN, so that we can send the SI
encapsulated into multiple Packet Neighbor Cell Data messages on the
downlink.
One all the SI bits are sent, the scheduler is instructed to send a
Packet Cell Change Continue message.
Once the message above has been sent, the FSM autodestroys itself.
Caches are also introduced in this patch which allows for re-using
recently known translations ARFCN+BSIC -> CGI-PS and CGI-PS -> SI_INFO
respectively.
Change-Id: Id35f40d05f3e081f32fddbf1fa34cb338db452ca
2021-01-21 17:46:13 +00:00
|
|
|
|
|
|
|
rc = osmo_fsm_inst_dispatch(ms->nacc->fi, NACC_EV_CREATE_RLCMAC_MSG, &data_ctx);
|
|
|
|
if (rc != 0 || !data_ctx.msg)
|
|
|
|
return NULL;
|
|
|
|
return data_ctx.msg;
|
|
|
|
}
|
2022-10-26 17:44:07 +00:00
|
|
|
|
|
|
|
static void ms_start_llc_timer(struct GprsMs *ms)
|
|
|
|
{
|
|
|
|
if (the_pcu->vty.llc_idle_ack_csec > 0) {
|
|
|
|
struct timespec tv;
|
|
|
|
csecs_to_timespec(the_pcu->vty.llc_idle_ack_csec, &tv);
|
|
|
|
osmo_timer_schedule(&ms->llc_timer, tv.tv_sec, tv.tv_nsec / 1000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-26 13:44:14 +00:00
|
|
|
/* Can we get to send a DL TBF ass to the MS? */
|
|
|
|
static bool ms_is_reachable_for_dl_ass(const struct GprsMs *ms)
|
|
|
|
{
|
2023-07-05 12:15:56 +00:00
|
|
|
const struct gprs_rlcmac_dl_tbf *dl_tbf = ms_dl_tbf(ms);
|
2023-07-05 12:18:24 +00:00
|
|
|
const struct gprs_rlcmac_ul_tbf *ul_tbf = ms_ul_tbf(ms);
|
2022-10-26 13:44:14 +00:00
|
|
|
|
2023-07-05 12:15:56 +00:00
|
|
|
/* This function assumes it is called when no DL TBF is present, or
|
|
|
|
* alternatively if it's not really in use by the MS (TBF_ST_WAIT_REUSE_TFI) */
|
|
|
|
OSMO_ASSERT(!dl_tbf ||
|
|
|
|
tbf_state(dl_tbf_as_tbf_const(dl_tbf)) == TBF_ST_WAIT_REUSE_TFI);
|
2022-10-26 13:44:14 +00:00
|
|
|
|
|
|
|
/* 3GPP TS 44.060 sec 7.1.3.1 Initiation of the Packet resource request procedure:
|
|
|
|
* "Furthermore, the mobile station shall not respond to PACKET DOWNLINK ASSIGNMENT
|
|
|
|
* or MULTIPLE TBF DOWNLINK ASSIGNMENT messages before contention resolution is
|
|
|
|
* completed on the mobile station side." */
|
|
|
|
/* The possible uplink TBF is used to trigger downlink assignment:
|
|
|
|
* - If there is no uplink TBF the MS is potentially in packet idle mode
|
|
|
|
* and hence assignment will be done over CCCH (PCH)
|
|
|
|
* - If there's an uplink TBF but it is finished (waiting for last PKT
|
|
|
|
* CTRL ACK after sending last Pkt UL ACK/NACK with FINAL_ACK=1, then we
|
|
|
|
* have no ways to contact the MS right now. Assignment will be delayed
|
|
|
|
* until PKT CTRL ACK is received and the TBF is released at the MS side
|
|
|
|
* (then assignment goes through PCH).
|
|
|
|
*/
|
|
|
|
if (!ul_tbf)
|
|
|
|
return true;
|
|
|
|
if (ul_tbf_contention_resolution_done(ul_tbf) &&
|
2023-06-26 11:52:08 +00:00
|
|
|
!tbf_ul_ack_waiting_cnf_final_ack(ul_tbf) &&
|
2023-07-05 12:18:24 +00:00
|
|
|
tbf_state(ul_tbf_as_tbf_const(ul_tbf)) != TBF_ST_RELEASING)
|
2022-10-26 13:44:14 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-10-28 17:50:09 +00:00
|
|
|
/* Alloc a UL TBF to be assigned over PACCH. Called when an MS requests to
|
|
|
|
* create a new UL TBF during the end of life of a previous UL TBF (or an SBA).
|
|
|
|
* In summary, this TBF is allocated as a consequence of receiving a "Pkt
|
|
|
|
* Resource Req" or "Pkt Ctrl Ack" from the MS.
|
|
|
|
* See TS 44.060 9.3.2.4.2 "Non-extended uplink TBF mode".
|
|
|
|
*/
|
|
|
|
struct gprs_rlcmac_ul_tbf *ms_new_ul_tbf_assigned_pacch(struct GprsMs *ms, int8_t use_trx)
|
|
|
|
{
|
|
|
|
struct gprs_rlcmac_ul_tbf *ul_tbf;
|
2023-04-21 17:32:16 +00:00
|
|
|
const struct alloc_resources_req req = {
|
|
|
|
.bts = ms->bts,
|
|
|
|
.ms = ms,
|
|
|
|
.direction = GPRS_RLCMAC_UL_TBF,
|
|
|
|
.single = false,
|
|
|
|
.use_trx = use_trx,
|
|
|
|
};
|
|
|
|
struct alloc_resources_res res = {};
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = the_pcu->alloc_algorithm(&req, &res);
|
|
|
|
if (rc < 0) {
|
|
|
|
LOGPMS(ms, DTBF, LOGL_NOTICE,
|
|
|
|
"Timeslot Allocation failed: trx = %d, single_slot = %d\n",
|
|
|
|
req.use_trx, req.single);
|
|
|
|
bts_do_rate_ctr_inc(ms->bts, CTR_TBF_ALLOC_FAIL);
|
|
|
|
return NULL;
|
|
|
|
}
|
2022-10-28 17:50:09 +00:00
|
|
|
|
2023-04-21 17:32:16 +00:00
|
|
|
ul_tbf = ul_tbf_alloc(ms->bts, ms);
|
2022-10-28 17:50:09 +00:00
|
|
|
if (!ul_tbf) {
|
2023-04-21 17:32:16 +00:00
|
|
|
LOGPMS(ms, DTBF, LOGL_NOTICE, "ul_tbf_alloc() failed\n");
|
2022-10-28 17:50:09 +00:00
|
|
|
/* Caller will most probably send a Imm Ass Reject after return */
|
|
|
|
return NULL;
|
|
|
|
}
|
2023-04-21 17:32:16 +00:00
|
|
|
|
|
|
|
/* Update MS, really allocate the resources */
|
|
|
|
if (res.reserved_ul_slots != ms_reserved_ul_slots(ms) ||
|
|
|
|
res.reserved_dl_slots != ms_reserved_dl_slots(ms)) {
|
|
|
|
/* The reserved slots have changed, update the MS */
|
|
|
|
ms_set_reserved_slots(ms, res.trx, res.reserved_ul_slots, res.reserved_dl_slots);
|
|
|
|
}
|
|
|
|
ms_set_first_common_ts(ms, res.first_common_ts);
|
|
|
|
|
|
|
|
/* Apply allocated resources to TBF: */
|
|
|
|
ul_tbf_apply_allocated_resources(ul_tbf, &res);
|
|
|
|
|
|
|
|
ms_attach_tbf(ms, ul_tbf_as_tbf(ul_tbf));
|
|
|
|
|
2022-10-28 17:50:09 +00:00
|
|
|
osmo_fsm_inst_dispatch(tbf_state_fi(ul_tbf_as_tbf(ul_tbf)), TBF_EV_ASSIGN_ADD_PACCH, NULL);
|
|
|
|
/* Contention resolution is considered to be done since TLLI is known in MS */
|
|
|
|
return ul_tbf;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Alloc a UL TBF to be assigned over AGCH. Used by request of a "One phase
|
|
|
|
* packet access", where MS requested only 1 PDCH TS (TS 44.018 Table 9.1.8.1). */
|
|
|
|
struct gprs_rlcmac_ul_tbf *ms_new_ul_tbf_assigned_agch(struct GprsMs *ms)
|
|
|
|
{
|
|
|
|
struct gprs_rlcmac_ul_tbf *ul_tbf;
|
2023-04-21 17:32:16 +00:00
|
|
|
const struct alloc_resources_req req = {
|
|
|
|
.bts = ms->bts,
|
|
|
|
.ms = ms,
|
|
|
|
.direction = GPRS_RLCMAC_UL_TBF,
|
|
|
|
.single = true,
|
|
|
|
.use_trx = -1,
|
|
|
|
};
|
|
|
|
struct alloc_resources_res res = {};
|
|
|
|
int rc;
|
2022-10-28 17:50:09 +00:00
|
|
|
|
2023-04-21 17:32:16 +00:00
|
|
|
rc = the_pcu->alloc_algorithm(&req, &res);
|
|
|
|
if (rc < 0) {
|
|
|
|
LOGPMS(ms, DTBF, LOGL_NOTICE,
|
|
|
|
"Timeslot Allocation failed: trx = %d, single_slot = %d\n",
|
|
|
|
req.use_trx, req.single);
|
|
|
|
bts_do_rate_ctr_inc(ms->bts, CTR_TBF_ALLOC_FAIL);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ul_tbf = ul_tbf_alloc(ms->bts, ms);
|
2022-10-28 17:50:09 +00:00
|
|
|
if (!ul_tbf) {
|
2023-04-21 17:32:16 +00:00
|
|
|
LOGPMS(ms, DTBF, LOGL_NOTICE, "ul_tbf_alloc() failed\n");
|
2022-10-28 17:50:09 +00:00
|
|
|
/* Caller will most probably send a Imm Ass Reject after return */
|
|
|
|
return NULL;
|
|
|
|
}
|
2023-04-21 17:32:16 +00:00
|
|
|
|
|
|
|
/* Update MS, really allocate the resources */
|
|
|
|
if (res.reserved_ul_slots != ms_reserved_ul_slots(ms) ||
|
|
|
|
res.reserved_dl_slots != ms_reserved_dl_slots(ms)) {
|
|
|
|
/* The reserved slots have changed, update the MS */
|
|
|
|
ms_set_reserved_slots(ms, res.trx, res.reserved_ul_slots, res.reserved_dl_slots);
|
|
|
|
}
|
|
|
|
ms_set_first_common_ts(ms, res.first_common_ts);
|
|
|
|
|
|
|
|
/* Apply allocated resources to TBF: */
|
|
|
|
ul_tbf_apply_allocated_resources(ul_tbf, &res);
|
|
|
|
|
|
|
|
ms_attach_tbf(ms, ul_tbf_as_tbf(ul_tbf));
|
|
|
|
|
2022-10-28 17:50:09 +00:00
|
|
|
osmo_fsm_inst_dispatch(tbf_state_fi(ul_tbf_as_tbf(ul_tbf)), TBF_EV_ASSIGN_ADD_CCCH, NULL);
|
|
|
|
return ul_tbf;
|
|
|
|
}
|
|
|
|
|
2022-12-13 16:35:04 +00:00
|
|
|
/* Create a temporary dummy TBF to Tx a ImmAssReject if allocating a new one during
|
|
|
|
* packet resource Request failed. This is similar as ul_tbf_alloc() but without
|
2023-04-21 17:32:16 +00:00
|
|
|
* calling alloc_algo (in charge of TFI/USF allocation), and reusing resources
|
2022-12-13 16:35:04 +00:00
|
|
|
* from Packet Resource Request we received. See TS 44.060 sec 7.1.3.2.1 */
|
|
|
|
struct gprs_rlcmac_ul_tbf *ms_new_ul_tbf_rejected_pacch(struct GprsMs *ms, struct gprs_rlcmac_pdch *pdch)
|
|
|
|
{
|
|
|
|
struct gprs_rlcmac_ul_tbf *ul_tbf;
|
2023-04-21 17:32:16 +00:00
|
|
|
struct alloc_resources_res fake_res = {
|
|
|
|
.trx = pdch->trx,
|
|
|
|
.first_common_ts = pdch,
|
|
|
|
.reserved_ul_slots = 0,
|
|
|
|
.reserved_dl_slots = 0,
|
|
|
|
.ass_slots_mask = 0,
|
|
|
|
.upgrade_to_multislot = false,
|
|
|
|
.tfi = TBF_TFI_UNSET,
|
|
|
|
.usf = {0},
|
|
|
|
};
|
|
|
|
ul_tbf = ul_tbf_alloc(ms->bts, ms);
|
2022-12-13 16:35:04 +00:00
|
|
|
if (!ul_tbf)
|
|
|
|
return NULL;
|
2023-04-21 17:32:16 +00:00
|
|
|
|
|
|
|
/* The only one TS is the common, control TS */
|
|
|
|
ms_set_first_common_ts(ms, pdch);
|
|
|
|
|
|
|
|
/* Apply fake resources to TBF, to attach it to the proper TRX/PDCH: */
|
|
|
|
ul_tbf_apply_allocated_resources(ul_tbf, &fake_res);
|
|
|
|
|
|
|
|
ms_attach_tbf(ms, ul_tbf_as_tbf(ul_tbf));
|
|
|
|
|
2022-12-13 16:35:04 +00:00
|
|
|
osmo_fsm_inst_dispatch(tbf_state_fi(ul_tbf_as_tbf(ul_tbf)), TBF_EV_ASSIGN_ADD_PACCH, NULL);
|
|
|
|
osmo_fsm_inst_dispatch(tbf_ul_ass_fi(ul_tbf_as_tbf(ul_tbf)), TBF_UL_ASS_EV_SCHED_ASS_REJ, NULL);
|
|
|
|
|
|
|
|
return ul_tbf;
|
|
|
|
}
|
|
|
|
|
2022-10-28 16:01:31 +00:00
|
|
|
/* A new DL-TBF is allocated and assigned through PACCH using "tbf".
|
|
|
|
* "tbf" may be either a UL-TBF or a DL-TBF.
|
|
|
|
* Note: This should be called only when MS is reachable, see ms_is_reachable_for_dl_ass().
|
|
|
|
*/
|
|
|
|
int ms_new_dl_tbf_assigned_on_pacch(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf)
|
2022-10-26 13:44:14 +00:00
|
|
|
{
|
2022-10-28 16:01:31 +00:00
|
|
|
OSMO_ASSERT(tbf);
|
2022-10-26 13:44:14 +00:00
|
|
|
struct gprs_rlcmac_dl_tbf *dl_tbf;
|
2023-04-21 17:32:16 +00:00
|
|
|
const struct alloc_resources_req req = {
|
|
|
|
.bts = ms->bts,
|
|
|
|
.ms = ms,
|
|
|
|
.direction = GPRS_RLCMAC_DL_TBF,
|
|
|
|
.single = false,
|
|
|
|
.use_trx = tbf_get_trx(tbf)->trx_no,
|
|
|
|
};
|
|
|
|
struct alloc_resources_res res = {};
|
|
|
|
int rc;
|
2022-10-26 13:44:14 +00:00
|
|
|
|
2023-04-21 17:32:16 +00:00
|
|
|
rc = the_pcu->alloc_algorithm(&req, &res);
|
|
|
|
if (rc < 0) {
|
|
|
|
LOGPMS(ms, DTBF, LOGL_NOTICE,
|
|
|
|
"Timeslot Allocation failed: trx = %d, single_slot = %d\n",
|
|
|
|
req.use_trx, req.single);
|
|
|
|
bts_do_rate_ctr_inc(ms->bts, CTR_TBF_ALLOC_FAIL);
|
2022-10-28 16:01:31 +00:00
|
|
|
return -EBUSY;
|
2022-10-26 13:44:14 +00:00
|
|
|
}
|
|
|
|
|
2023-04-21 17:32:16 +00:00
|
|
|
dl_tbf = dl_tbf_alloc(ms->bts, ms);
|
|
|
|
if (!dl_tbf) {
|
|
|
|
LOGPMS(ms, DTBF, LOGL_NOTICE, "dl_tbf_alloc() failed\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update MS, really allocate the resources */
|
|
|
|
if (res.reserved_ul_slots != ms_reserved_ul_slots(ms) ||
|
|
|
|
res.reserved_dl_slots != ms_reserved_dl_slots(ms)) {
|
|
|
|
/* The reserved slots have changed, update the MS */
|
|
|
|
ms_set_reserved_slots(ms, res.trx, res.reserved_ul_slots, res.reserved_dl_slots);
|
|
|
|
}
|
|
|
|
ms_set_first_common_ts(ms, res.first_common_ts);
|
|
|
|
|
|
|
|
/* Apply allocated resources to TBF: */
|
|
|
|
dl_tbf_apply_allocated_resources(dl_tbf, &res);
|
|
|
|
|
|
|
|
ms_attach_tbf(ms, dl_tbf_as_tbf(dl_tbf));
|
|
|
|
|
2022-10-28 16:01:31 +00:00
|
|
|
LOGPTBFDL(dl_tbf, LOGL_DEBUG, "[DOWNLINK] START (PACCH)\n");
|
|
|
|
dl_tbf_trigger_ass_on_pacch(dl_tbf, tbf);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* A new DL-TBF is allocated and assigned through PCH.
|
|
|
|
* Note: This should be called only when MS is reachable, see ms_is_reachable_for_dl_ass().
|
|
|
|
*/
|
|
|
|
int ms_new_dl_tbf_assigned_on_pch(struct GprsMs *ms)
|
|
|
|
{
|
|
|
|
struct gprs_rlcmac_dl_tbf *dl_tbf;
|
2023-04-21 17:32:16 +00:00
|
|
|
const struct alloc_resources_req req = {
|
|
|
|
.bts = ms->bts,
|
|
|
|
.ms = ms,
|
|
|
|
.direction = GPRS_RLCMAC_DL_TBF,
|
|
|
|
.single = true,
|
|
|
|
.use_trx = -1,
|
|
|
|
};
|
|
|
|
struct alloc_resources_res res = {};
|
|
|
|
int rc;
|
2022-10-28 16:01:31 +00:00
|
|
|
|
2023-04-21 17:32:16 +00:00
|
|
|
rc = the_pcu->alloc_algorithm(&req, &res);
|
|
|
|
if (rc < 0) {
|
|
|
|
LOGPMS(ms, DTBF, LOGL_NOTICE,
|
|
|
|
"Timeslot Allocation failed: trx = %d, single_slot = %d\n",
|
|
|
|
req.use_trx, req.single);
|
|
|
|
bts_do_rate_ctr_inc(ms->bts, CTR_TBF_ALLOC_FAIL);
|
2022-10-26 13:44:14 +00:00
|
|
|
return -EBUSY;
|
|
|
|
}
|
|
|
|
|
2023-04-21 17:32:16 +00:00
|
|
|
dl_tbf = dl_tbf_alloc(ms->bts, ms);
|
|
|
|
if (!dl_tbf) {
|
|
|
|
LOGPMS(ms, DTBF, LOGL_NOTICE, "dl_tbf_alloc() failed\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update MS, really allocate the resources */
|
|
|
|
if (res.reserved_ul_slots != ms_reserved_ul_slots(ms) ||
|
|
|
|
res.reserved_dl_slots != ms_reserved_dl_slots(ms)) {
|
|
|
|
/* The reserved slots have changed, update the MS */
|
|
|
|
ms_set_reserved_slots(ms, res.trx, res.reserved_ul_slots, res.reserved_dl_slots);
|
|
|
|
}
|
|
|
|
ms_set_first_common_ts(ms, res.first_common_ts);
|
|
|
|
|
|
|
|
/* Apply allocated resources to TBF: */
|
|
|
|
dl_tbf_apply_allocated_resources(dl_tbf, &res);
|
|
|
|
|
|
|
|
ms_attach_tbf(ms, dl_tbf_as_tbf(dl_tbf));
|
|
|
|
|
2022-10-28 16:01:31 +00:00
|
|
|
LOGPTBFDL(dl_tbf, LOGL_DEBUG, "[DOWNLINK] START (PCH)\n");
|
|
|
|
dl_tbf_trigger_ass_on_pch(dl_tbf);
|
2022-10-26 13:44:14 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-10-26 17:44:07 +00:00
|
|
|
int ms_append_llc_dl_data(struct GprsMs *ms, uint16_t pdu_delay_csec, const uint8_t *data, uint16_t len)
|
|
|
|
{
|
|
|
|
struct timespec expire_time;
|
|
|
|
struct gprs_rlcmac_dl_tbf *dl_tbf;
|
2022-10-26 13:44:14 +00:00
|
|
|
int rc = 0;
|
2022-10-26 17:44:07 +00:00
|
|
|
|
|
|
|
LOGPMS(ms, DTBFDL, LOGL_DEBUG, "appending %u bytes to DL LLC queue\n", len);
|
|
|
|
|
|
|
|
struct msgb *llc_msg = msgb_alloc(len, "llc_pdu_queue");
|
|
|
|
if (!llc_msg)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
llc_queue_calc_pdu_lifetime(ms->bts, pdu_delay_csec, &expire_time);
|
|
|
|
memcpy(msgb_put(llc_msg, len), data, len);
|
|
|
|
llc_queue_enqueue(ms_llc_queue(ms), llc_msg, &expire_time);
|
|
|
|
ms_start_llc_timer(ms);
|
|
|
|
|
|
|
|
dl_tbf = ms_dl_tbf(ms);
|
2022-10-26 13:44:14 +00:00
|
|
|
if (dl_tbf) {
|
2023-06-19 16:38:33 +00:00
|
|
|
switch (tbf_state(dl_tbf_as_tbf_const(dl_tbf))) {
|
|
|
|
case TBF_ST_WAIT_RELEASE:
|
|
|
|
LOGPTBFDL(dl_tbf, LOGL_DEBUG, "in WAIT RELEASE state (T3192), so reuse TBF\n");
|
2022-10-28 16:01:31 +00:00
|
|
|
rc = ms_new_dl_tbf_assigned_on_pacch(ms, dl_tbf_as_tbf(dl_tbf));
|
2023-06-19 16:38:33 +00:00
|
|
|
return rc;
|
|
|
|
case TBF_ST_WAIT_REUSE_TFI:
|
|
|
|
/* According to DL TBF state it should be back to CCCH, let's check UL TBF to have more information. */
|
|
|
|
break;
|
|
|
|
case TBF_ST_RELEASING:
|
|
|
|
/* Something went wrong (T3195), delay for later. */
|
|
|
|
default:
|
|
|
|
/* DL TBF in working status (do nothing)*/
|
|
|
|
return 0;
|
2022-10-26 13:44:14 +00:00
|
|
|
}
|
2023-06-19 16:38:33 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if we can create a DL TBF to start sending the enqueued
|
|
|
|
* data. Otherwise it will be triggered later when it is reachable
|
|
|
|
* again. */
|
|
|
|
if (ms_is_reachable_for_dl_ass(ms)) {
|
|
|
|
if (ms_ul_tbf(ms))
|
|
|
|
rc = ms_new_dl_tbf_assigned_on_pacch(ms, ul_tbf_as_tbf(ms_ul_tbf(ms)));
|
|
|
|
else
|
|
|
|
rc = ms_new_dl_tbf_assigned_on_pch(ms);
|
2022-10-26 17:44:07 +00:00
|
|
|
}
|
2022-10-26 13:44:14 +00:00
|
|
|
return rc;
|
2022-10-26 17:44:07 +00:00
|
|
|
}
|