2013-10-17 15:01:54 +00:00
|
|
|
/* bts.h
|
|
|
|
*
|
|
|
|
* Copyright (C) 2012 Ivan Klyuchnikov
|
|
|
|
* Copyright (C) 2013 by Holger Hans Peter Freyther
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
2020-12-06 00:23:51 +00:00
|
|
|
#endif
|
|
|
|
|
2013-10-17 15:01:54 +00:00
|
|
|
#include <osmocom/core/linuxlist.h>
|
2013-10-27 08:02:31 +00:00
|
|
|
#include <osmocom/core/rate_ctr.h>
|
2015-11-27 18:05:13 +00:00
|
|
|
#include <osmocom/core/stat_item.h>
|
2019-09-05 12:48:35 +00:00
|
|
|
#include <osmocom/core/tdef.h>
|
2020-12-06 00:23:51 +00:00
|
|
|
#include <osmocom/gprs/gprs_ns2.h>
|
2016-08-17 09:47:21 +00:00
|
|
|
#include <osmocom/gsm/l1sap.h>
|
2017-09-01 09:02:40 +00:00
|
|
|
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
TLLI 0x00000000 is a valid TLLI, use 0xffffffff instead
The assumption that TLLI 0x00000000 is invalid and can be used
as the initializer is wrong. Similar to TMSI, 0x00000000 is a
perfectly valid value, while 0xffffffff is reserved - use it.
According to 3GPP TS 23.003, section 2.4, a TMSI/P-TMSI with
all 32 bits equal to 1 is special and shall not be allocated by
the network. The reason is that it must be stored on the SIM,
where 'ff'O represents the erased state. According to section
2.6 of the same document, a local/foreign TLLI is derived from
P-TMSI, so the same rule applies to TLLI.
I manually checked and corrected all occurances of 'tlli' in the
code. The test expectations have been adjusted with this command:
$ find tests/ -name "*.err" | xargs sed -i "s/0x00000000/0xffffffff/g"
so there should be no behavior change. The only exception is
the 'TypesTest', where TLLI 0xffffffff is being encoded and
expected in the hexdump, so I regenerated the test output.
Change-Id: Ie89fab75ecc1d8b5e238d3ff214ea7ac830b68b5
Related: OS#4844
2020-11-08 06:27:35 +00:00
|
|
|
#include <osmocom/gsm/gsm48.h>
|
2020-03-26 14:14:01 +00:00
|
|
|
#include "mslot_class.h"
|
|
|
|
#include "gsm_rlcmac.h"
|
Split PCU global PCU object from BTS object
Currently the BTS object (and gprs_rlcmac_bts struct) are used to hold
both PCU global fields and BTS specific fields, all mangled together.
The BTS is even accessed in lots of places by means of a singleton.
This patch introduces a new struct gprs_pcu object aimed at holding all
global state, and several fields are already moved from BTS to it. The
new object can be accessed as global variable "the_pcu", reusing and
including an already exisitng "the_pcu" global variable only used for
bssgp related purposes so far.
This is only a first step towards having a complete split global pcu and
BTS, some fields are still kept in BTS and will be moved over follow-up
smaller patches in the future (since this patch is already quite big).
So far, the code still only supports one BTS, which can be accessed
using the_pcu->bts. In the future that field will be replaced with a
list, and the BTS singletons will be removed.
The cur_fn output changes in TbfTest are actually a side effect fix,
since the singleton main_bts() now points internally to the_pcu->bts,
hence the same we allocate and assign in the test. Beforehand, "the_bts"
was allocated in the stack while main_bts() still returned an unrelated
singleton BTS object instance.
Related: OS#4935
Change-Id: I88e3c6471b80245ce3798223f1a61190f14aa840
2021-01-13 17:54:38 +00:00
|
|
|
#include "gprs_pcu.h"
|
2020-12-06 00:23:51 +00:00
|
|
|
#ifdef __cplusplus
|
2013-10-17 15:01:54 +00:00
|
|
|
}
|
2020-12-06 00:23:51 +00:00
|
|
|
#endif
|
2013-10-17 18:12:37 +00:00
|
|
|
|
2020-12-06 00:23:51 +00:00
|
|
|
#ifdef __cplusplus
|
2013-10-17 18:12:37 +00:00
|
|
|
#include "poll_controller.h"
|
2013-10-19 18:47:12 +00:00
|
|
|
#include "sba.h"
|
2013-10-19 19:10:38 +00:00
|
|
|
#include "tbf.h"
|
2015-05-13 11:33:12 +00:00
|
|
|
#include "gprs_ms_storage.h"
|
2020-05-18 09:35:35 +00:00
|
|
|
#include "coding_scheme.h"
|
2018-01-26 12:31:42 +00:00
|
|
|
#include <cxx_linuxlist.h>
|
2013-10-17 15:01:54 +00:00
|
|
|
#endif
|
|
|
|
|
2019-03-06 16:09:43 +00:00
|
|
|
#include <pdch.h>
|
2013-10-17 15:01:54 +00:00
|
|
|
#include <stdint.h>
|
2020-10-26 17:39:51 +00:00
|
|
|
#include <stdbool.h>
|
2013-10-17 15:01:54 +00:00
|
|
|
|
2013-10-17 17:41:11 +00:00
|
|
|
struct BTS;
|
2015-06-18 15:16:26 +00:00
|
|
|
struct GprsMs;
|
2013-10-17 15:01:54 +00:00
|
|
|
|
|
|
|
struct gprs_rlcmac_trx {
|
|
|
|
void *fl1h;
|
|
|
|
uint16_t arfcn;
|
|
|
|
struct gprs_rlcmac_pdch pdch[8];
|
2013-10-20 08:14:03 +00:00
|
|
|
|
|
|
|
/* back pointers */
|
|
|
|
struct BTS *bts;
|
|
|
|
uint8_t trx_no;
|
2015-06-30 06:52:54 +00:00
|
|
|
|
2013-10-17 15:01:54 +00:00
|
|
|
};
|
|
|
|
|
2016-09-19 14:17:06 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
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 bts_trx_reserve_slots(struct gprs_rlcmac_trx *trx, enum gprs_rlcmac_tbf_direction dir, uint8_t slots);
|
|
|
|
void bts_trx_unreserve_slots(struct gprs_rlcmac_trx *trx, enum gprs_rlcmac_tbf_direction dir, uint8_t slots);
|
|
|
|
|
2017-11-01 18:41:37 +00:00
|
|
|
void bts_update_tbf_ta(const char *p, uint32_t fn, uint8_t trx_no, uint8_t ts, int8_t ta, bool is_rach);
|
2016-09-19 14:17:06 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-10-17 17:41:11 +00:00
|
|
|
/**
|
|
|
|
* This is the data from C. As soon as our minimal compiler is gcc 4.7
|
|
|
|
* we can start to compile pcu_vty.c with c++ and remove the split.
|
|
|
|
*/
|
2013-10-17 15:01:54 +00:00
|
|
|
struct gprs_rlcmac_bts {
|
2018-02-14 18:46:33 +00:00
|
|
|
bool active;
|
2013-10-17 15:01:54 +00:00
|
|
|
uint8_t bsic;
|
|
|
|
uint8_t fc_interval;
|
2015-05-06 08:47:30 +00:00
|
|
|
uint16_t fc_bucket_time;
|
2015-04-21 10:56:48 +00:00
|
|
|
uint32_t fc_bvc_bucket_size;
|
|
|
|
uint32_t fc_bvc_leak_rate;
|
|
|
|
uint32_t fc_ms_bucket_size;
|
|
|
|
uint32_t fc_ms_leak_rate;
|
2020-10-30 16:14:26 +00:00
|
|
|
uint8_t cs_mask; /* Allowed CS mask from BTS */
|
|
|
|
uint16_t mcs_mask; /* Allowed MCS mask from BTS */
|
2013-10-17 15:01:54 +00:00
|
|
|
uint8_t initial_cs_dl, initial_cs_ul;
|
2016-01-07 14:00:43 +00:00
|
|
|
uint8_t initial_mcs_dl, initial_mcs_ul;
|
2013-10-17 15:01:54 +00:00
|
|
|
uint16_t force_llc_lifetime; /* overrides lifetime from SGSN */
|
2015-03-20 11:02:42 +00:00
|
|
|
uint32_t llc_discard_csec;
|
2015-04-02 11:58:09 +00:00
|
|
|
uint32_t llc_idle_ack_csec;
|
llc: Use CoDel to drop packages from the LLC queue
Currently packets are only dropped if they have reached their maximum
life time. This leads to LLC queues being constantly filled under
load, increasing the latency up to the maximum life time. This kind
of bufferbloat hinders TCP's congestion avoidance algorithms. To keep
the queues short, the CoDel active queue management algorithm can be
used.
This commit changes to llc_dequeue method to apply the CoDel
algorithm to selectively drop LLC frames before they passed to the
TBF layer to be encoded in BSNs. This feature is currently disabled
by default.
The CoDel state is managed per MS since the LLC queues are also kept
in the MS objects.
Note that there is still some buffering in the TBF objects, in the
worst case (CS4) 3.5kByte + LLC-MTU octets are stored there. The
resulting additional packet delay is not (yet) taken into account for
CoDel.
Also note that configuration changes are applied to new MS objects
only.
The following VTY commands are added to the 'pcu' node:
- queue codel activates CoDel, the interval is selected by
the implementation
- queue codel interval <1-1000>
activates CoDel with a fixed interval given
in centiseconds (10ms-10s)
- no queue codel deactivates CoDel
Which interval value to use is still an open issue. For high speed
links (e.g. Ethernet), CoDel suggests 100ms. For slower links, the
expected RTT is recommended. The current implementation uses a
default value of 2000ms.
Measurements:
Note that the following measurements depend on several other factors,
most notably the interaction with the SGSN's flow control. They are
just examples to give an idea how CoDel might influence some
parameters.
The measurements have been done with a single E71, first with a
running ping only (Idle), then with an additional TCP download
of a 360k file (Busy). The CoDel interval was set to 1s.
- Idle :
ping ~400ms, avg queue delay 0ms, dropped 0
- Busy, No CoDel:
ping ~6s, avg queue delay 4-6s,
dropped 0, scheduled 948, duration 54s
- Busy, CoDel:
ping 500-1500ms, avg queue delay ~600ms,
dropped 77, scheduled 1040, duration 60s
More measurements with two MS downloading in parallel (two
independant measurements per case).
- Busy, No CoDel:
dropped 0, scheduled 1883, duration 121s
dropped 19, scheduled 2003, duration 133s
- Busy, CoDel:
dropped 22, scheduled 1926, duration 116s
dropped 22, scheduled 1955, duration 108s
Sponsored-by: On-Waves ehf
2015-07-17 14:39:09 +00:00
|
|
|
uint32_t llc_codel_interval_msec; /* 0=disabled, -1=use default interval */
|
2019-09-05 12:48:35 +00:00
|
|
|
/* Timer defintions */
|
|
|
|
struct osmo_tdef *T_defs_bts; /* timers controlled by BTS, received through PCUIF */
|
|
|
|
struct osmo_tdef *T_defs_pcu; /* timers controlled by PCU */
|
2013-10-17 15:01:54 +00:00
|
|
|
uint8_t n3101;
|
|
|
|
uint8_t n3103;
|
|
|
|
uint8_t n3105;
|
|
|
|
struct gprs_rlcmac_trx trx[8];
|
2017-09-28 13:56:05 +00:00
|
|
|
|
2013-10-17 15:01:54 +00:00
|
|
|
uint8_t force_two_phase;
|
|
|
|
uint8_t alpha, gamma;
|
2019-09-05 13:12:20 +00:00
|
|
|
bool dl_tbf_preemptive_retransmission;
|
2017-09-01 09:02:40 +00:00
|
|
|
uint8_t si13[GSM_MACBLOCK_LEN];
|
|
|
|
bool si13_is_set;
|
2016-08-16 11:02:59 +00:00
|
|
|
/* 0 to support resegmentation in DL, 1 for no reseg */
|
|
|
|
uint8_t dl_arq_type;
|
|
|
|
|
2019-11-28 16:00:44 +00:00
|
|
|
uint8_t cs_adj_enabled; /* whether cs_adj_{upper,lower}_limit are used to adjust DL CS */
|
|
|
|
uint8_t cs_adj_upper_limit; /* downgrade DL CS if error rate above its value */
|
|
|
|
uint8_t cs_adj_lower_limit; /* upgrade DL CS if error rate below its value */
|
|
|
|
/* downgrade DL CS when less than specified octets are left in tx queue. Optimization, see paper:
|
|
|
|
"Theoretical Analysis of GPRS Throughput and Delay" */
|
|
|
|
uint16_t cs_downgrade_threshold;
|
|
|
|
/* Link quality range for each UL (M)CS. Below or above, next/prev (M)CS is selected. */
|
2016-06-15 12:16:41 +00:00
|
|
|
struct {int16_t low; int16_t high; } cs_lqual_ranges[MAX_GPRS_CS];
|
2019-03-06 18:03:01 +00:00
|
|
|
struct {int16_t low; int16_t high; } mcs_lqual_ranges[MAX_EDGE_MCS];
|
2016-01-19 14:53:30 +00:00
|
|
|
uint16_t ws_base;
|
|
|
|
uint16_t ws_pdch; /* increase WS by this value per PDCH */
|
2013-10-17 17:41:11 +00:00
|
|
|
|
2015-07-16 16:33:46 +00:00
|
|
|
/* State for dynamic algorithm selection */
|
|
|
|
int multislot_disabled;
|
2013-10-19 19:10:38 +00:00
|
|
|
|
2013-10-17 17:41:11 +00:00
|
|
|
/**
|
|
|
|
* Point back to the C++ object. This is used during the transition
|
|
|
|
* period.
|
|
|
|
*/
|
|
|
|
struct BTS *bts;
|
2017-08-08 13:03:50 +00:00
|
|
|
|
2018-07-05 01:11:17 +00:00
|
|
|
/* Are we talking Gb with IP-SNS (true) or classic Gb? */
|
2020-12-06 00:23:51 +00:00
|
|
|
enum gprs_ns2_dialect ns_dialect;
|
2019-09-05 15:13:33 +00:00
|
|
|
|
|
|
|
/* Packet Application Information (3GPP TS 44.060 11.2.47, usually ETWS primary message). We don't need to store
|
|
|
|
* more than one message, because they get sent so rarely. */
|
|
|
|
struct msgb *app_info;
|
|
|
|
uint32_t app_info_pending; /* Count of MS with active TBF, to which we did not send app_info yet */
|
2020-09-16 19:52:02 +00:00
|
|
|
|
|
|
|
/* main nsei */
|
|
|
|
struct gprs_ns2_nse *nse;
|
2013-10-17 17:41:11 +00:00
|
|
|
};
|
|
|
|
|
2020-05-12 18:54:35 +00:00
|
|
|
enum {
|
|
|
|
CTR_TBF_DL_ALLOCATED,
|
|
|
|
CTR_TBF_DL_FREED,
|
|
|
|
CTR_TBF_DL_ABORTED,
|
|
|
|
CTR_TBF_UL_ALLOCATED,
|
|
|
|
CTR_TBF_UL_FREED,
|
|
|
|
CTR_TBF_UL_ABORTED,
|
|
|
|
CTR_TBF_REUSED,
|
|
|
|
CTR_TBF_ALLOC_ALGO_A,
|
|
|
|
CTR_TBF_ALLOC_ALGO_B,
|
|
|
|
CTR_RLC_SENT,
|
|
|
|
CTR_RLC_RESENT,
|
|
|
|
CTR_RLC_RESTARTED,
|
|
|
|
CTR_RLC_STALLED,
|
|
|
|
CTR_RLC_NACKED,
|
|
|
|
CTR_RLC_FINAL_BLOCK_RESENT,
|
|
|
|
CTR_RLC_ASS_TIMEDOUT,
|
|
|
|
CTR_RLC_ASS_FAILED,
|
|
|
|
CTR_RLC_ACK_TIMEDOUT,
|
|
|
|
CTR_RLC_ACK_FAILED,
|
|
|
|
CTR_RLC_REL_TIMEDOUT,
|
|
|
|
CTR_RLC_LATE_BLOCK,
|
|
|
|
CTR_RLC_SENT_DUMMY,
|
|
|
|
CTR_RLC_SENT_CONTROL,
|
|
|
|
CTR_RLC_DL_BYTES,
|
|
|
|
CTR_RLC_DL_PAYLOAD_BYTES,
|
|
|
|
CTR_RLC_UL_BYTES,
|
|
|
|
CTR_RLC_UL_PAYLOAD_BYTES,
|
|
|
|
CTR_DECODE_ERRORS,
|
|
|
|
CTR_SBA_ALLOCATED,
|
|
|
|
CTR_SBA_FREED,
|
|
|
|
CTR_SBA_TIMEDOUT,
|
|
|
|
CTR_LLC_FRAME_TIMEDOUT,
|
|
|
|
CTR_LLC_FRAME_DROPPED,
|
|
|
|
CTR_LLC_FRAME_SCHED,
|
|
|
|
CTR_LLC_DL_BYTES,
|
|
|
|
CTR_LLC_UL_BYTES,
|
|
|
|
CTR_RACH_REQUESTS,
|
|
|
|
CTR_11BIT_RACH_REQUESTS,
|
|
|
|
CTR_SPB_UL_FIRST_SEGMENT,
|
|
|
|
CTR_SPB_UL_SECOND_SEGMENT,
|
|
|
|
CTR_SPB_DL_FIRST_SEGMENT,
|
|
|
|
CTR_SPB_DL_SECOND_SEGMENT,
|
|
|
|
CTR_IMMEDIATE_ASSIGN_UL_TBF,
|
|
|
|
CTR_IMMEDIATE_ASSIGN_REJ,
|
|
|
|
CTR_IMMEDIATE_ASSIGN_DL_TBF,
|
|
|
|
CTR_CHANNEL_REQUEST_DESCRIPTION,
|
|
|
|
CTR_PKT_UL_ASSIGNMENT,
|
|
|
|
CTR_PKT_ACCESS_REJ,
|
|
|
|
CTR_PKT_DL_ASSIGNMENT,
|
|
|
|
CTR_RLC_RECV_CONTROL,
|
|
|
|
CTR_PUA_POLL_TIMEDOUT,
|
|
|
|
CTR_PUA_POLL_FAILED,
|
|
|
|
CTR_PDA_POLL_TIMEDOUT,
|
|
|
|
CTR_PDA_POLL_FAILED,
|
|
|
|
CTR_PUAN_POLL_TIMEDOUT,
|
|
|
|
CTR_PUAN_POLL_FAILED,
|
|
|
|
CTR_PDAN_POLL_TIMEDOUT,
|
|
|
|
CTR_PDAN_POLL_FAILED,
|
|
|
|
CTR_GPRS_DL_CS1,
|
|
|
|
CTR_GPRS_DL_CS2,
|
|
|
|
CTR_GPRS_DL_CS3,
|
|
|
|
CTR_GPRS_DL_CS4,
|
|
|
|
CTR_EGPRS_DL_MCS1,
|
|
|
|
CTR_EGPRS_DL_MCS2,
|
|
|
|
CTR_EGPRS_DL_MCS3,
|
|
|
|
CTR_EGPRS_DL_MCS4,
|
|
|
|
CTR_EGPRS_DL_MCS5,
|
|
|
|
CTR_EGPRS_DL_MCS6,
|
|
|
|
CTR_EGPRS_DL_MCS7,
|
|
|
|
CTR_EGPRS_DL_MCS8,
|
|
|
|
CTR_EGPRS_DL_MCS9,
|
|
|
|
CTR_GPRS_UL_CS1,
|
|
|
|
CTR_GPRS_UL_CS2,
|
|
|
|
CTR_GPRS_UL_CS3,
|
|
|
|
CTR_GPRS_UL_CS4,
|
|
|
|
CTR_EGPRS_UL_MCS1,
|
|
|
|
CTR_EGPRS_UL_MCS2,
|
|
|
|
CTR_EGPRS_UL_MCS3,
|
|
|
|
CTR_EGPRS_UL_MCS4,
|
|
|
|
CTR_EGPRS_UL_MCS5,
|
|
|
|
CTR_EGPRS_UL_MCS6,
|
|
|
|
CTR_EGPRS_UL_MCS7,
|
|
|
|
CTR_EGPRS_UL_MCS8,
|
|
|
|
CTR_EGPRS_UL_MCS9,
|
|
|
|
};
|
|
|
|
|
2020-05-12 20:45:04 +00:00
|
|
|
enum {
|
|
|
|
STAT_MS_PRESENT,
|
|
|
|
};
|
|
|
|
|
2020-05-21 12:55:46 +00:00
|
|
|
/* RACH.ind parameters (to be parsed) */
|
|
|
|
struct rach_ind_params {
|
|
|
|
enum ph_burst_type burst_type;
|
|
|
|
bool is_11bit;
|
|
|
|
uint16_t ra;
|
|
|
|
uint8_t trx_nr;
|
|
|
|
uint8_t ts_nr;
|
|
|
|
uint32_t rfn;
|
|
|
|
int16_t qta;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* [EGPRS Packet] Channel Request parameters (parsed) */
|
|
|
|
struct chan_req_params {
|
|
|
|
unsigned int egprs_mslot_class;
|
|
|
|
unsigned int priority;
|
|
|
|
bool single_block;
|
|
|
|
};
|
|
|
|
|
2013-10-17 17:41:11 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
/**
|
|
|
|
* I represent a GSM BTS. I have one or more TRX, I know the current
|
|
|
|
* GSM time and I have controllers that help with allocating resources
|
|
|
|
* on my TRXs.
|
|
|
|
*/
|
|
|
|
struct BTS {
|
|
|
|
public:
|
Split PCU global PCU object from BTS object
Currently the BTS object (and gprs_rlcmac_bts struct) are used to hold
both PCU global fields and BTS specific fields, all mangled together.
The BTS is even accessed in lots of places by means of a singleton.
This patch introduces a new struct gprs_pcu object aimed at holding all
global state, and several fields are already moved from BTS to it. The
new object can be accessed as global variable "the_pcu", reusing and
including an already exisitng "the_pcu" global variable only used for
bssgp related purposes so far.
This is only a first step towards having a complete split global pcu and
BTS, some fields are still kept in BTS and will be moved over follow-up
smaller patches in the future (since this patch is already quite big).
So far, the code still only supports one BTS, which can be accessed
using the_pcu->bts. In the future that field will be replaced with a
list, and the BTS singletons will be removed.
The cur_fn output changes in TbfTest are actually a side effect fix,
since the singleton main_bts() now points internally to the_pcu->bts,
hence the same we allocate and assign in the test. Beforehand, "the_bts"
was allocated in the stack while main_bts() still returned an unrelated
singleton BTS object instance.
Related: OS#4935
Change-Id: I88e3c6471b80245ce3798223f1a61190f14aa840
2021-01-13 17:54:38 +00:00
|
|
|
BTS(struct gprs_pcu *pcu);
|
2013-10-27 08:02:31 +00:00
|
|
|
~BTS();
|
2019-03-18 14:48:38 +00:00
|
|
|
void cleanup();
|
2013-10-17 17:41:11 +00:00
|
|
|
|
|
|
|
static BTS* main_bts();
|
|
|
|
|
|
|
|
struct gprs_rlcmac_bts *bts_data();
|
2013-10-19 18:47:12 +00:00
|
|
|
SBAController *sba();
|
2013-10-17 17:41:11 +00:00
|
|
|
|
2013-10-17 17:59:56 +00:00
|
|
|
/** TODO: change the number to unsigned */
|
|
|
|
void set_current_frame_number(int frame_number);
|
2015-08-26 11:22:28 +00:00
|
|
|
void set_current_block_frame_number(int frame_number, unsigned max_delay);
|
2013-10-17 17:59:56 +00:00
|
|
|
int current_frame_number() const;
|
|
|
|
|
2013-10-19 16:28:59 +00:00
|
|
|
/** add paging to paging queue(s) */
|
paging: pass struct osmo_mobile_identity, not encoded IE bytes
In get_paging_mi(), before this, an encoded buffer of Mobile Identity bytes is
returned. Code paths following this repeatedly decode the Mobile Identity
bytes, e.g. for logging. Also, in get_paging_mi(), since the TMSI is read in
from a different encoding than a typical Mobile Identity IE, the TMSI was
manually encoded into a typical Mobile Identity IE. This is essentially a code
dup of osmo_mobile_identity_encode(). Stop this madness.
Instead, in get_paging_mi(), return a decoded struct osmo_mobile_identity. Code
paths after this use the struct osmo_mobile_identity directly without repeated
decoding.
At the point of finally needing an encoded Mobile Identity IE (in
Encoding::write_paging_request()), do a proper osmo_mobile_identity_encode().
Since this may return errors, add an rc check for the caller of
write_paging_request(), gprs_rlcmac_paging_request().
A side effect is stricter validation of the Mobile Identity passing through the
Paging code path. Before, invalid MI might have passed through unnoticed.
Change-Id: Iad845acb0096b75dc453105c9c16b2252879b4ca
2020-08-21 14:21:23 +00:00
|
|
|
int add_paging(uint8_t chan_needed, const struct osmo_mobile_identity *mi);
|
2013-10-19 16:28:59 +00:00
|
|
|
|
2014-07-10 15:44:06 +00:00
|
|
|
gprs_rlcmac_dl_tbf *dl_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts);
|
|
|
|
gprs_rlcmac_ul_tbf *ul_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts);
|
2015-07-10 17:52:37 +00:00
|
|
|
gprs_rlcmac_dl_tbf *dl_tbf_by_tfi(uint8_t tfi, uint8_t trx, uint8_t ts);
|
|
|
|
gprs_rlcmac_ul_tbf *ul_tbf_by_tfi(uint8_t tfi, uint8_t trx, uint8_t ts);
|
2013-10-19 19:10:38 +00:00
|
|
|
|
2018-01-26 10:09:16 +00:00
|
|
|
int tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t use_trx) const;
|
2013-10-26 17:17:58 +00:00
|
|
|
|
2013-10-26 17:49:16 +00:00
|
|
|
int rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn);
|
2017-02-21 18:35:23 +00:00
|
|
|
|
bts.cpp: Fix overloading ambiguity
Fix error introduced in 1275a3f91a744e011b0dba82b09124d249c7abb5 by
using signed 32 bit integer which is enough for Frame Number in
GSM. Also, mark parameter constraints more explicitly:
- add assert for expected FN values
- don't perform computation for non-relative FN
The error was:
bts.cpp: In member function ‘uint32_t BTS::rfn_to_fn(uint32_t)’:
bts.cpp:554:25: error: call of overloaded ‘abs(uint32_t)’ is ambiguous
if (abs(rfn - m_cur_rfn) > RFN_THRESHOLD) {
^
In file included from /usr/include/c++/6/cstdlib:75:0,
from /usr/include/c++/6/stdlib.h:36,
from /usr/include/osmocom/core/linuxrbtree.h:97,
from /usr/include/osmocom/core/timer.h:35,
from ./bts.h:29,
from bts.cpp:21:
/usr/include/stdlib.h:735:12: note: candidate: int abs(int)
extern int abs (int __x) __THROW __attribute__ ((__const__)) __wur;
^~~
In file included from /usr/include/c++/6/stdlib.h:36:0,
from /usr/include/osmocom/core/linuxrbtree.h:97,
from /usr/include/osmocom/core/timer.h:35,
from ./bts.h:29,
from bts.cpp:21:
/usr/include/c++/6/cstdlib:185:3: note: candidate: __int128 std::abs(__int128)
abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; }
^~~
/usr/include/c++/6/cstdlib:180:3: note: candidate: long long int std::abs(long long int)
abs(long long __x) { return __builtin_llabs (__x); }
^~~
/usr/include/c++/6/cstdlib:172:3: note: candidate: long int std::abs(long int)
abs(long __i) { return __builtin_labs(__i); }
Change-Id: Ib6d895a97aa35414f245ea4406c6e78f1b4fb5b8
2017-03-08 11:06:42 +00:00
|
|
|
uint32_t rfn_to_fn(int32_t rfn);
|
2020-05-21 12:55:46 +00:00
|
|
|
int rcv_rach(const struct rach_ind_params *rip);
|
|
|
|
int rcv_ptcch_rach(const struct rach_ind_params *rip);
|
2013-10-26 17:49:16 +00:00
|
|
|
|
2019-12-23 11:41:34 +00:00
|
|
|
void snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup);
|
2013-10-26 18:12:59 +00:00
|
|
|
|
2020-10-30 17:35:54 +00:00
|
|
|
uint8_t max_cs_dl(void) const;
|
|
|
|
uint8_t max_cs_ul(void) const;
|
|
|
|
uint8_t max_mcs_dl(void) const;
|
|
|
|
uint8_t max_mcs_ul(void) const;
|
|
|
|
void set_max_cs_dl(uint8_t cs_dl);
|
|
|
|
void set_max_cs_ul(uint8_t cs_ul);
|
|
|
|
void set_max_mcs_dl(uint8_t mcs_dl);
|
|
|
|
void set_max_mcs_ul(uint8_t mcs_ul);
|
Implement downgrade to DL MCS1-4 when USF for GPRS_only MS
In previous status, if USF for GPRS-only MS was selected, then EGPRS
TBFs were skipped and either a GPRS TBF was selected or a Dummy Block
was sent. That means the behavior was unfair towards EGPRS TBFs, because
sometimes they were skipped in favor of GPRS ones.
This patch imporves the situation in the above mentioned USF scenario, by
first, under specific conditions, allowing selection of an EGPRS TBF and
then forcing it to transmit in EGPRS-GMSK (MCS1-4) so that the
USF-targeted MS can still decode the USF, while at the same time
providing more fairness by allowing the EGPRS TBF to transmit data.
The specific conditions mentioned above are, mainly, related to the fact
that once a DL data block has been sent, and hence a BSN was assigned to
it, it cannot be retransmitted later using another MCS, since lower
MCS1-4 wouldn't be able to contain higher MCS RLC payload.
The set of conditions could be expanded in the future by also selecting
the EGPRS TBF if retransmition is required and the block to be
retransmitted was originally transmitted as MCS1-4.
Related: OS#4544
Change-Id: I9af23e175435fe9ae7b0e4119ad52fcd4707b9ca
2020-11-16 17:49:39 +00:00
|
|
|
bool cs_dl_is_supported(CodingScheme cs);
|
2020-10-30 17:35:54 +00:00
|
|
|
|
2015-05-13 11:33:12 +00:00
|
|
|
GprsMsStorage &ms_store();
|
TLLI 0x00000000 is a valid TLLI, use 0xffffffff instead
The assumption that TLLI 0x00000000 is invalid and can be used
as the initializer is wrong. Similar to TMSI, 0x00000000 is a
perfectly valid value, while 0xffffffff is reserved - use it.
According to 3GPP TS 23.003, section 2.4, a TMSI/P-TMSI with
all 32 bits equal to 1 is special and shall not be allocated by
the network. The reason is that it must be stored on the SIM,
where 'ff'O represents the erased state. According to section
2.6 of the same document, a local/foreign TLLI is derived from
P-TMSI, so the same rule applies to TLLI.
I manually checked and corrected all occurances of 'tlli' in the
code. The test expectations have been adjusted with this command:
$ find tests/ -name "*.err" | xargs sed -i "s/0x00000000/0xffffffff/g"
so there should be no behavior change. The only exception is
the 'TypesTest', where TLLI 0xffffffff is being encoded and
expected in the hexdump, so I regenerated the test output.
Change-Id: Ie89fab75ecc1d8b5e238d3ff214ea7ac830b68b5
Related: OS#4844
2020-11-08 06:27:35 +00:00
|
|
|
GprsMs *ms_by_tlli(uint32_t tlli, uint32_t old_tlli = GSM_RESERVED_TMSI);
|
2015-08-21 16:00:54 +00:00
|
|
|
GprsMs *ms_by_imsi(const char *imsi);
|
2015-11-27 14:17:34 +00:00
|
|
|
GprsMs *ms_alloc(uint8_t ms_class, uint8_t egprs_ms_class = 0);
|
2015-05-13 11:33:12 +00:00
|
|
|
|
2017-07-21 19:56:23 +00:00
|
|
|
void send_gsmtap(enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no,
|
|
|
|
uint8_t ts_no, uint8_t channel, uint32_t fn,
|
|
|
|
const uint8_t *data, unsigned int len);
|
2020-05-19 15:23:23 +00:00
|
|
|
void send_gsmtap_meas(enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no,
|
|
|
|
uint8_t ts_no, uint8_t channel, uint32_t fn,
|
|
|
|
const uint8_t *data, unsigned int len, struct pcu_l1_meas *meas);
|
2020-06-10 17:26:15 +00:00
|
|
|
void send_gsmtap_rach(enum pcu_gsmtap_category categ, uint8_t channel,
|
|
|
|
const struct rach_ind_params *rip);
|
2017-07-21 19:56:23 +00:00
|
|
|
|
2013-10-27 08:02:31 +00:00
|
|
|
/*
|
|
|
|
* Below for C interface for the VTY
|
|
|
|
*/
|
|
|
|
struct rate_ctr_group *rate_counters() const;
|
2015-11-27 18:05:13 +00:00
|
|
|
struct osmo_stat_item_group *stat_items() const;
|
2020-05-12 18:54:35 +00:00
|
|
|
void do_rate_ctr_inc(unsigned int ctr_id);
|
2020-05-12 20:32:24 +00:00
|
|
|
void do_rate_ctr_add(unsigned int ctr_id, int inc);
|
2020-05-12 20:45:04 +00:00
|
|
|
void stat_item_add(unsigned int stat_id, int inc);
|
2013-10-27 08:02:31 +00:00
|
|
|
|
2015-12-28 18:15:40 +00:00
|
|
|
LListHead<gprs_rlcmac_tbf>& ul_tbfs();
|
|
|
|
LListHead<gprs_rlcmac_tbf>& dl_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
|
|
|
|
|
|
|
struct gprs_rlcmac_bts m_bts;
|
Split PCU global PCU object from BTS object
Currently the BTS object (and gprs_rlcmac_bts struct) are used to hold
both PCU global fields and BTS specific fields, all mangled together.
The BTS is even accessed in lots of places by means of a singleton.
This patch introduces a new struct gprs_pcu object aimed at holding all
global state, and several fields are already moved from BTS to it. The
new object can be accessed as global variable "the_pcu", reusing and
including an already exisitng "the_pcu" global variable only used for
bssgp related purposes so far.
This is only a first step towards having a complete split global pcu and
BTS, some fields are still kept in BTS and will be moved over follow-up
smaller patches in the future (since this patch is already quite big).
So far, the code still only supports one BTS, which can be accessed
using the_pcu->bts. In the future that field will be replaced with a
list, and the BTS singletons will be removed.
The cur_fn output changes in TbfTest are actually a side effect fix,
since the singleton main_bts() now points internally to the_pcu->bts,
hence the same we allocate and assign in the test. Beforehand, "the_bts"
was allocated in the stack while main_bts() still returned an unrelated
singleton BTS object instance.
Related: OS#4935
Change-Id: I88e3c6471b80245ce3798223f1a61190f14aa840
2021-01-13 17:54:38 +00:00
|
|
|
|
|
|
|
/* back pointer to PCU object */
|
|
|
|
struct gprs_pcu *pcu;
|
2013-10-17 17:41:11 +00:00
|
|
|
private:
|
Split PCU global PCU object from BTS object
Currently the BTS object (and gprs_rlcmac_bts struct) are used to hold
both PCU global fields and BTS specific fields, all mangled together.
The BTS is even accessed in lots of places by means of a singleton.
This patch introduces a new struct gprs_pcu object aimed at holding all
global state, and several fields are already moved from BTS to it. The
new object can be accessed as global variable "the_pcu", reusing and
including an already exisitng "the_pcu" global variable only used for
bssgp related purposes so far.
This is only a first step towards having a complete split global pcu and
BTS, some fields are still kept in BTS and will be moved over follow-up
smaller patches in the future (since this patch is already quite big).
So far, the code still only supports one BTS, which can be accessed
using the_pcu->bts. In the future that field will be replaced with a
list, and the BTS singletons will be removed.
The cur_fn output changes in TbfTest are actually a side effect fix,
since the singleton main_bts() now points internally to the_pcu->bts,
hence the same we allocate and assign in the test. Beforehand, "the_bts"
was allocated in the stack while main_bts() still returned an unrelated
singleton BTS object instance.
Related: OS#4935
Change-Id: I88e3c6471b80245ce3798223f1a61190f14aa840
2021-01-13 17:54:38 +00:00
|
|
|
|
2013-10-17 17:59:56 +00:00
|
|
|
int m_cur_fn;
|
2015-08-24 12:35:14 +00:00
|
|
|
int m_cur_blk_fn;
|
2020-10-30 17:35:54 +00:00
|
|
|
uint8_t m_max_cs_dl, m_max_cs_ul;
|
|
|
|
uint8_t m_max_mcs_dl, m_max_mcs_ul;
|
2013-10-17 18:12:37 +00:00
|
|
|
PollController m_pollController;
|
2013-10-19 18:47:12 +00:00
|
|
|
SBAController m_sba;
|
2013-10-27 08:02:31 +00:00
|
|
|
struct rate_ctr_group *m_ratectrs;
|
2015-11-27 18:05:13 +00:00
|
|
|
struct osmo_stat_item_group *m_statg;
|
2013-10-17 18:12:37 +00:00
|
|
|
|
2015-05-13 11:33:12 +00:00
|
|
|
GprsMsStorage m_ms_store;
|
|
|
|
|
2015-12-28 18:15:40 +00:00
|
|
|
/* list of uplink TBFs */
|
|
|
|
LListHead<gprs_rlcmac_tbf> m_ul_tbfs;
|
|
|
|
/* list of downlink TBFs */
|
|
|
|
LListHead<gprs_rlcmac_tbf> m_dl_tbfs;
|
|
|
|
|
2013-10-17 18:12:37 +00:00
|
|
|
/* disable copying to avoid slicing */
|
|
|
|
BTS(const BTS&);
|
|
|
|
BTS& operator=(const BTS&);
|
2013-10-17 15:01:54 +00:00
|
|
|
};
|
2013-10-17 17:59:56 +00:00
|
|
|
|
|
|
|
inline int BTS::current_frame_number() const
|
|
|
|
{
|
|
|
|
return m_cur_fn;
|
|
|
|
}
|
2013-10-19 18:04:57 +00:00
|
|
|
|
2013-10-19 18:47:12 +00:00
|
|
|
inline SBAController *BTS::sba()
|
|
|
|
{
|
|
|
|
return &m_sba;
|
|
|
|
}
|
2013-10-26 16:39:36 +00:00
|
|
|
|
2015-05-13 11:33:12 +00:00
|
|
|
inline GprsMsStorage &BTS::ms_store()
|
|
|
|
{
|
|
|
|
return m_ms_store;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline GprsMs *BTS::ms_by_tlli(uint32_t tlli, uint32_t old_tlli)
|
|
|
|
{
|
|
|
|
return ms_store().get_ms(tlli, old_tlli);
|
|
|
|
}
|
|
|
|
|
2015-08-21 16:00:54 +00:00
|
|
|
inline GprsMs *BTS::ms_by_imsi(const char *imsi)
|
|
|
|
{
|
|
|
|
return ms_store().get_ms(0, 0, imsi);
|
|
|
|
}
|
|
|
|
|
2015-12-28 18:15:40 +00:00
|
|
|
inline LListHead<gprs_rlcmac_tbf>& BTS::ul_tbfs()
|
|
|
|
{
|
|
|
|
return m_ul_tbfs;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline LListHead<gprs_rlcmac_tbf>& BTS::dl_tbfs()
|
|
|
|
{
|
|
|
|
return m_dl_tbfs;
|
|
|
|
}
|
|
|
|
|
2013-10-27 08:02:31 +00:00
|
|
|
inline struct rate_ctr_group *BTS::rate_counters() const
|
|
|
|
{
|
|
|
|
return m_ratectrs;
|
|
|
|
}
|
|
|
|
|
2015-11-27 18:05:13 +00:00
|
|
|
inline struct osmo_stat_item_group *BTS::stat_items() const
|
|
|
|
{
|
|
|
|
return m_statg;
|
|
|
|
}
|
|
|
|
|
2020-05-12 18:54:35 +00:00
|
|
|
inline void BTS::do_rate_ctr_inc(unsigned int ctr_id) {
|
|
|
|
rate_ctr_inc(&m_ratectrs->ctr[ctr_id]);
|
|
|
|
}
|
|
|
|
|
2020-05-12 20:32:24 +00:00
|
|
|
inline void BTS::do_rate_ctr_add(unsigned int ctr_id, int inc) {
|
|
|
|
rate_ctr_add(&m_ratectrs->ctr[ctr_id], inc);
|
|
|
|
}
|
2016-05-21 17:45:23 +00:00
|
|
|
|
2020-05-12 20:45:04 +00:00
|
|
|
inline void BTS::stat_item_add(unsigned int stat_id, int inc) {
|
|
|
|
int32_t val = osmo_stat_item_get_last(m_statg->items[stat_id]);
|
|
|
|
osmo_stat_item_set(m_statg->items[stat_id], val + inc);
|
|
|
|
}
|
2013-10-27 08:50:15 +00:00
|
|
|
|
Split PCU global PCU object from BTS object
Currently the BTS object (and gprs_rlcmac_bts struct) are used to hold
both PCU global fields and BTS specific fields, all mangled together.
The BTS is even accessed in lots of places by means of a singleton.
This patch introduces a new struct gprs_pcu object aimed at holding all
global state, and several fields are already moved from BTS to it. The
new object can be accessed as global variable "the_pcu", reusing and
including an already exisitng "the_pcu" global variable only used for
bssgp related purposes so far.
This is only a first step towards having a complete split global pcu and
BTS, some fields are still kept in BTS and will be moved over follow-up
smaller patches in the future (since this patch is already quite big).
So far, the code still only supports one BTS, which can be accessed
using the_pcu->bts. In the future that field will be replaced with a
list, and the BTS singletons will be removed.
The cur_fn output changes in TbfTest are actually a side effect fix,
since the singleton main_bts() now points internally to the_pcu->bts,
hence the same we allocate and assign in the test. Beforehand, "the_bts"
was allocated in the stack while main_bts() still returned an unrelated
singleton BTS object instance.
Related: OS#4935
Change-Id: I88e3c6471b80245ce3798223f1a61190f14aa840
2021-01-13 17:54:38 +00:00
|
|
|
struct gprs_pcu;
|
|
|
|
struct BTS* bts_alloc(struct gprs_pcu *pcu);
|
2013-10-17 17:41:11 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
2019-03-18 14:48:38 +00:00
|
|
|
void bts_cleanup();
|
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 gprs_rlcmac_bts *bts_data(struct BTS *bts);
|
2013-10-17 17:41:11 +00:00
|
|
|
struct gprs_rlcmac_bts *bts_main_data();
|
2013-10-27 08:02:31 +00:00
|
|
|
struct rate_ctr_group *bts_main_data_stats();
|
2015-11-27 18:05:13 +00:00
|
|
|
struct osmo_stat_item_group *bts_main_data_stat_items();
|
Split PCU global PCU object from BTS object
Currently the BTS object (and gprs_rlcmac_bts struct) are used to hold
both PCU global fields and BTS specific fields, all mangled together.
The BTS is even accessed in lots of places by means of a singleton.
This patch introduces a new struct gprs_pcu object aimed at holding all
global state, and several fields are already moved from BTS to it. The
new object can be accessed as global variable "the_pcu", reusing and
including an already exisitng "the_pcu" global variable only used for
bssgp related purposes so far.
This is only a first step towards having a complete split global pcu and
BTS, some fields are still kept in BTS and will be moved over follow-up
smaller patches in the future (since this patch is already quite big).
So far, the code still only supports one BTS, which can be accessed
using the_pcu->bts. In the future that field will be replaced with a
list, and the BTS singletons will be removed.
The cur_fn output changes in TbfTest are actually a side effect fix,
since the singleton main_bts() now points internally to the_pcu->bts,
hence the same we allocate and assign in the test. Beforehand, "the_bts"
was allocated in the stack while main_bts() still returned an unrelated
singleton BTS object instance.
Related: OS#4935
Change-Id: I88e3c6471b80245ce3798223f1a61190f14aa840
2021-01-13 17:54:38 +00:00
|
|
|
void bts_recalc_max_cs(struct gprs_rlcmac_bts *bts);
|
|
|
|
void bts_recalc_max_mcs(struct gprs_rlcmac_bts *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
|
|
|
struct GprsMs *bts_ms_by_imsi(struct BTS *bts, const char *imsi);
|
|
|
|
uint8_t bts_max_cs_dl(const struct BTS *bts);
|
|
|
|
uint8_t bts_max_cs_ul(const struct BTS *bts);
|
|
|
|
uint8_t bts_max_mcs_dl(const struct BTS *bts);
|
|
|
|
uint8_t bts_max_mcs_ul(const struct BTS *bts);
|
2013-10-17 17:41:11 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
2013-10-19 15:37:48 +00:00
|
|
|
|
2013-10-17 17:41:11 +00:00
|
|
|
#endif
|