2019-09-25 15:47:02 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2013 by Holger Hans Peter Freyther
|
|
|
|
* Copyright (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
|
|
|
#include "tbf.h"
|
|
|
|
|
2021-01-18 16:14:14 +00:00
|
|
|
#include <stdint.h>
|
|
|
|
|
2019-09-25 15:47:02 +00:00
|
|
|
/*
|
|
|
|
* TBF instance
|
|
|
|
*/
|
|
|
|
|
|
|
|
enum tbf_dl_prio {
|
|
|
|
DL_PRIO_NONE,
|
|
|
|
DL_PRIO_SENT_DATA, /* the data has been sent and not (yet) nacked */
|
|
|
|
DL_PRIO_LOW_AGE, /* the age has reached the first threshold */
|
|
|
|
DL_PRIO_NEW_DATA, /* the data has not been sent yet or nacked */
|
|
|
|
DL_PRIO_HIGH_AGE, /* the age has reached the second threshold */
|
|
|
|
DL_PRIO_CONTROL, /* a control block needs to be sent */
|
|
|
|
};
|
|
|
|
|
|
|
|
#define LOGPTBFDL(tbf, level, fmt, args...) LOGP(DTBFDL, level, "%s " fmt, tbf_name(tbf), ## args)
|
|
|
|
|
|
|
|
struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf {
|
2021-01-14 15:48:38 +00:00
|
|
|
gprs_rlcmac_dl_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms);
|
2020-10-23 19:00:23 +00:00
|
|
|
gprs_rlc_window *window();
|
2019-09-25 15:47:02 +00:00
|
|
|
void cleanup();
|
|
|
|
|
2020-10-28 18:58:17 +00:00
|
|
|
int append_data(uint16_t pdu_delay_csec,
|
|
|
|
const uint8_t *data, uint16_t len);
|
2019-09-25 15:47:02 +00:00
|
|
|
|
|
|
|
int rcvd_dl_ack(bool final, uint8_t ssn, uint8_t *rbb);
|
|
|
|
int rcvd_dl_ack(bool final_ack, unsigned first_bsn, struct bitvec *rbb);
|
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
|
|
|
struct msgb *create_dl_acked_block(uint32_t fn, uint8_t ts, enum mcs_kind req_mcs_kind = EGPRS);
|
2019-09-25 15:47:02 +00:00
|
|
|
void trigger_ass(struct gprs_rlcmac_tbf *old_tbf);
|
|
|
|
|
|
|
|
bool handle_ack_nack();
|
|
|
|
void request_dl_ack();
|
|
|
|
bool need_control_ts() const;
|
|
|
|
bool have_data() const;
|
|
|
|
int frames_since_last_poll(unsigned fn) const;
|
|
|
|
int frames_since_last_drain(unsigned fn) const;
|
|
|
|
bool keep_open(unsigned fn) const;
|
|
|
|
int release();
|
|
|
|
int abort();
|
|
|
|
uint16_t window_size() const;
|
|
|
|
void set_window_size();
|
|
|
|
void update_coding_scheme_counter_dl(enum CodingScheme cs);
|
|
|
|
|
|
|
|
struct msgb *llc_dequeue(bssgp_bvc_ctx *bctx);
|
|
|
|
|
|
|
|
/* Please note that all variables here will be reset when changing
|
|
|
|
* from WAIT RELEASE back to FLOW state (re-use of TBF).
|
|
|
|
* All states that need reset must be in this struct, so this is why
|
|
|
|
* variables are in both (dl and ul) structs and not outside union.
|
|
|
|
*/
|
|
|
|
int32_t m_tx_counter; /* count all transmitted blocks */
|
|
|
|
uint8_t m_wait_confirm; /* wait for CCCH IMM.ASS cnf */
|
|
|
|
bool m_dl_ack_requested;
|
|
|
|
int32_t m_last_dl_poll_fn;
|
|
|
|
int32_t m_last_dl_drained_fn;
|
|
|
|
|
|
|
|
struct BandWidth {
|
|
|
|
struct timespec dl_bw_tv; /* timestamp for dl bw calculation */
|
|
|
|
uint32_t dl_bw_octets; /* number of octets since bw_tv */
|
|
|
|
uint32_t dl_throughput; /* throughput to be displayed in stats */
|
|
|
|
|
|
|
|
struct timespec dl_loss_tv; /* timestamp for loss calculation */
|
|
|
|
uint16_t dl_loss_lost; /* sum of lost packets */
|
|
|
|
uint16_t dl_loss_received; /* sum of received packets */
|
|
|
|
|
|
|
|
BandWidth();
|
|
|
|
} m_bw;
|
|
|
|
|
|
|
|
struct rate_ctr_group *m_dl_gprs_ctrs;
|
|
|
|
struct rate_ctr_group *m_dl_egprs_ctrs;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
struct ana_result {
|
|
|
|
unsigned received_packets;
|
|
|
|
unsigned lost_packets;
|
|
|
|
unsigned received_bytes;
|
|
|
|
unsigned lost_bytes;
|
|
|
|
};
|
|
|
|
|
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
|
|
|
int take_next_bsn(uint32_t fn, int previous_bsn, enum mcs_kind req_mcs_kind,
|
|
|
|
bool *may_combine);
|
2019-09-25 15:47:02 +00:00
|
|
|
bool restart_bsn_cycle();
|
2020-05-18 09:35:35 +00:00
|
|
|
int create_new_bsn(const uint32_t fn, enum CodingScheme cs);
|
2019-09-25 15:47:02 +00:00
|
|
|
struct msgb *create_dl_acked_block(const uint32_t fn, const uint8_t ts,
|
|
|
|
int index, int index2 = -1);
|
|
|
|
int update_window(const uint8_t ssn, const uint8_t *rbb);
|
|
|
|
int update_window(unsigned first_bsn, const struct bitvec *rbb);
|
2021-07-26 10:33:39 +00:00
|
|
|
int rcvd_dl_final_ack();
|
2019-09-25 15:47:02 +00:00
|
|
|
bool dl_window_stalled() const;
|
|
|
|
void reuse_tbf();
|
|
|
|
void start_llc_timer();
|
|
|
|
int analyse_errors(char *show_rbb, uint8_t ssn, ana_result *res);
|
|
|
|
void schedule_next_frame();
|
|
|
|
|
|
|
|
enum egprs_rlc_dl_reseg_bsn_state egprs_dl_get_data
|
|
|
|
(int bsn, uint8_t **block_data);
|
|
|
|
unsigned int get_egprs_dl_spb_status(int bsn);
|
|
|
|
enum egprs_rlcmac_dl_spb get_egprs_dl_spb(int bsn);
|
|
|
|
|
|
|
|
struct osmo_timer_list m_llc_timer;
|
|
|
|
|
|
|
|
/* Please note that all variables below will be reset when changing
|
|
|
|
* from WAIT RELEASE back to FLOW state (re-use of TBF).
|
|
|
|
* All states that need reset must be in this struct, so this is why
|
|
|
|
* variables are in both (dl and ul) structs and not outside union.
|
|
|
|
*/
|
|
|
|
gprs_rlc_dl_window m_window;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline uint16_t gprs_rlcmac_dl_tbf::window_size() const
|
|
|
|
{
|
|
|
|
return m_window.ws();
|
|
|
|
}
|
|
|
|
|
2020-10-23 20:37:52 +00:00
|
|
|
struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms,
|
|
|
|
int8_t use_trx, bool single_slot);
|
|
|
|
|
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 /* ifdef __cplusplus */
|
|
|
|
struct gprs_rlcmac_dl_tbf;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
2021-01-18 16:14:14 +00:00
|
|
|
struct gprs_rlcmac_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 gprs_rlcmac_dl_tbf *as_dl_tbf(struct gprs_rlcmac_tbf *tbf);
|
2021-01-18 16:14:14 +00:00
|
|
|
/* dispatch Unitdata.DL messages */
|
|
|
|
int dl_tbf_handle(struct gprs_rlcmac_bts *bts,
|
|
|
|
const uint32_t tlli, const uint32_t old_tlli,
|
|
|
|
const char *imsi, const uint8_t ms_class,
|
|
|
|
const uint8_t egprs_ms_class, const uint16_t delay_csec,
|
|
|
|
const uint8_t *data, const uint16_t len);
|
|
|
|
|
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
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
2019-09-25 15:47:02 +00:00
|
|
|
#endif
|