diff options
Diffstat (limited to 'src/tbf_dl.h')
-rw-r--r-- | src/tbf_dl.h | 76 |
1 files changed, 54 insertions, 22 deletions
diff --git a/src/tbf_dl.h b/src/tbf_dl.h index d20ad75f..59a03565 100644 --- a/src/tbf_dl.h +++ b/src/tbf_dl.h @@ -11,10 +11,6 @@ * 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 @@ -22,9 +18,18 @@ #ifdef __cplusplus #include "tbf.h" +#include "rlc_window_dl.h" #include <stdint.h> +#ifdef __cplusplus +extern "C" { +#endif +#include <tbf_fsm.h> +#ifdef __cplusplus +} +#endif + /* * TBF instance */ @@ -38,17 +43,20 @@ enum tbf_dl_prio { DL_PRIO_CONTROL, /* a control block needs to be sent */ }; +struct gprs_dl_llc_llist_item { + struct llist_head list; /* this item added in dl_tbf->tx_llc_until_first_dl_ack_rcvd */ + struct gprs_llc llc; +}; + struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf { gprs_rlcmac_dl_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms); ~gprs_rlcmac_dl_tbf(); gprs_rlc_window *window(); - - int append_data(uint16_t pdu_delay_csec, - const uint8_t *data, uint16_t len); + void apply_allocated_resources(const struct alloc_resources_res *res); int rcvd_dl_ack(bool final_ack, unsigned first_bsn, struct bitvec *rbb); - struct msgb *create_dl_acked_block(uint32_t fn, uint8_t ts, enum mcs_kind req_mcs_kind = EGPRS); - void trigger_ass(struct gprs_rlcmac_tbf *old_tbf); + struct msgb *create_dl_acked_block(uint32_t fn, const gprs_rlcmac_pdch *pdch, + enum mcs_kind req_mcs_kind = EGPRS); void request_dl_ack(); bool need_poll_for_dl_ack_nack() const; @@ -61,8 +69,6 @@ struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf { 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 @@ -71,7 +77,17 @@ struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf { int32_t m_tx_counter; /* count all transmitted blocks */ bool m_dl_ack_requested; int32_t m_last_dl_poll_fn; + /* Whether we failed to receive ("poll timeout") last PKT CTRL ACK from + * MS polled during DL ACK/NACK with RRBP set in "m_last_dl_poll_fn": */ + bool m_last_dl_poll_ack_lost; int32_t m_last_dl_drained_fn; + /* Whether we receive at least one PKT DL ACK/NACK from MS since this DL TBF was assigned: */ + bool m_first_dl_ack_rcvd; + + /* Keep transmitted LLC PDUs until first ACK to avoid losing them if MS is not there. + * list of gprs_dl_llc_llist_item, stored in inverse order of transmission (last transmitted + * is first in the list ) */ + struct llist_head tx_llc_until_first_dl_ack_rcvd; struct BandWidth { struct timespec dl_bw_tv; /* timestamp for dl bw calculation */ @@ -88,6 +104,8 @@ struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf { struct rate_ctr_group *m_dl_gprs_ctrs; struct rate_ctr_group *m_dl_egprs_ctrs; + struct tbf_dl_fsm_ctx state_fsm; + protected: struct ana_result { unsigned received_packets; @@ -100,13 +118,12 @@ protected: bool *may_combine); bool restart_bsn_cycle(); int create_new_bsn(const uint32_t fn, enum CodingScheme cs); - struct msgb *create_dl_acked_block(const uint32_t fn, const uint8_t ts, - int index, int index2 = -1); + struct msgb *create_dl_acked_block(const uint32_t fn, const struct gprs_rlcmac_pdch *pdch, + int index, int index2 = -1); int update_window(unsigned first_bsn, const struct bitvec *rbb); int rcvd_dl_final_ack(); 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(); @@ -115,8 +132,6 @@ protected: 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 @@ -130,9 +145,6 @@ inline uint16_t gprs_rlcmac_dl_tbf::window_size() const return m_window.ws(); } -struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms, - int8_t use_trx, bool single_slot); - #else /* ifdef __cplusplus */ struct gprs_rlcmac_dl_tbf; #endif @@ -142,7 +154,10 @@ extern "C" { #endif struct gprs_rlcmac_bts; -struct gprs_rlcmac_dl_tbf *as_dl_tbf(struct gprs_rlcmac_tbf *tbf); +struct gprs_rlcmac_dl_tbf *dl_tbf_alloc(struct gprs_rlcmac_bts *bts, struct GprsMs *ms); + +struct gprs_rlcmac_dl_tbf *tbf_as_dl_tbf(struct gprs_rlcmac_tbf *tbf); +const struct gprs_rlcmac_dl_tbf *tbf_as_dl_tbf_const(const struct gprs_rlcmac_tbf *tbf); /* dispatch Unitdata.DL messages */ int dl_tbf_handle(struct gprs_rlcmac_bts *bts, const uint32_t tlli, const uint32_t old_tlli, @@ -150,9 +165,26 @@ int dl_tbf_handle(struct gprs_rlcmac_bts *bts, const uint8_t egprs_ms_class, const uint16_t delay_csec, const uint8_t *data, const uint16_t len); -void tbf_dl_trigger_ass(struct gprs_rlcmac_dl_tbf *tbf, struct gprs_rlcmac_tbf *old_tbf); +void dl_tbf_apply_allocated_resources(struct gprs_rlcmac_dl_tbf *dl_tbf, const struct alloc_resources_res *res); +void dl_tbf_trigger_ass_on_pacch(struct gprs_rlcmac_dl_tbf *tbf, struct gprs_rlcmac_tbf *old_tbf); +void dl_tbf_trigger_ass_on_pch(struct gprs_rlcmac_dl_tbf *tbf); +void dl_tbf_request_dl_ack(struct gprs_rlcmac_dl_tbf *tbf); +bool dl_tbf_first_dl_ack_rcvd(const struct gprs_rlcmac_dl_tbf *tbf); +int dl_tbf_upgrade_to_multislot(struct gprs_rlcmac_dl_tbf *tbf); + +void dl_tbf_copy_unacked_pdus_to_llc_queue(struct gprs_rlcmac_dl_tbf *tbf); + +static inline struct gprs_rlcmac_tbf *dl_tbf_as_tbf(struct gprs_rlcmac_dl_tbf *dl_tbf) +{ + return (struct gprs_rlcmac_tbf *)dl_tbf; +} + +static inline const struct gprs_rlcmac_tbf *dl_tbf_as_tbf_const(const struct gprs_rlcmac_dl_tbf *dl_tbf) +{ + return (const struct gprs_rlcmac_tbf *)dl_tbf; +} -#define LOGPTBFDL(tbf, level, fmt, args...) LOGP(DTBFDL, level, "%s " fmt, tbf_name(tbf), ## args) +#define LOGPTBFDL(dl_tbf, level, fmt, args...) LOGP(DTBFDL, level, "%s " fmt, tbf_name(dl_tbf_as_tbf_const(dl_tbf)), ## args) #ifdef __cplusplus } #endif |