From: Holger Hans Peter Freyther holger@moiji-mobile.com
This is the begin of a long march of turning tbf into a C++ class and properly hiding the secrets inside this implementation instead of having it spread across various different files. --- src/gprs_rlcmac.cpp | 1 + src/gprs_rlcmac.h | 97 -------------------------------------------- src/gprs_rlcmac_meas.cpp | 1 + src/gprs_rlcmac_sched.cpp | 1 + src/pcu_l1_if.cpp | 1 + src/tbf.h | 100 +++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 103 insertions(+), 98 deletions(-)
diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index 6546f8a..3dab44f 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -22,6 +22,7 @@ #include <gprs_bssgp_pcu.h> #include <pcu_l1_if.h> #include <gprs_rlcmac.h> +#include <tbf.h>
/* 3GPP TS 05.02 Annex B.1 */
diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index 8de7417..6fdf600 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -155,103 +155,6 @@ enum gprs_rlcmac_tbf_direction { #define GPRS_RLCMAC_FLAG_TO_DL_ASS 7 #define GPRS_RLCMAC_FLAG_TO_MASK 0xf0 /* timeout bits */
-struct gprs_rlcmac_tbf { - struct llist_head list; - enum gprs_rlcmac_tbf_state state; - uint32_t state_flags; - enum gprs_rlcmac_tbf_direction direction; - uint8_t tfi; - uint32_t tlli; - uint8_t tlli_valid; - uint8_t trx; - uint16_t arfcn; - uint8_t tsc; - uint8_t first_ts; /* first TS used by TBF */ - uint8_t first_common_ts; /* first TS that the phone can send and - reveive simultaniously */ - uint8_t control_ts; /* timeslot control messages and polling */ - uint8_t ms_class; - struct gprs_rlcmac_pdch *pdch[8]; /* list of PDCHs allocated to TBF */ - uint16_t ta; - uint8_t llc_frame[LLC_MAX_LEN]; /* current DL or UL frame */ - uint16_t llc_index; /* current write/read position of frame */ - uint16_t llc_length; /* len of current DL LLC_frame, 0 == no frame */ - struct llist_head llc_queue; /* queued LLC DL data */ - - enum gprs_rlcmac_tbf_dl_ass_state dl_ass_state; - enum gprs_rlcmac_tbf_ul_ass_state ul_ass_state; - enum gprs_rlcmac_tbf_ul_ack_state ul_ack_state; - - enum gprs_rlcmac_tbf_poll_state poll_state; - uint32_t poll_fn; /* frame number to poll */ - - uint16_t ws; /* window size */ - uint16_t sns; /* sequence number space */ - - /* 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. - */ - union { - struct { - uint16_t bsn; /* block sequence number */ - uint16_t v_s; /* send state */ - uint16_t v_a; /* ack state */ - char v_b[RLC_MAX_SNS/2]; /* acknowledge state array */ - int32_t tx_counter; /* count all transmitted blocks */ - char imsi[16]; /* store IMSI for PCH retransmission */ - uint8_t wait_confirm; /* wait for CCCH IMM.ASS cnf */ - } dl; - struct { - uint16_t bsn; /* block sequence number */ - uint16_t v_r; /* receive state */ - uint16_t v_q; /* receive window state */ - char v_n[RLC_MAX_SNS/2]; /* receive state array */ - int32_t rx_counter; /* count all received blocks */ - uint8_t n3103; /* N3103 counter */ - uint8_t usf[8]; /* list USFs per PDCH (timeslot) */ - uint8_t contention_resolution_done; /* set after done */ - uint8_t final_ack_sent; /* set if we sent final ack */ - } ul; - } dir; - uint8_t rlc_block[RLC_MAX_SNS/2][RLC_MAX_LEN]; /* block history */ - uint8_t rlc_block_len[RLC_MAX_SNS/2]; /* block len of history */ - - uint8_t n3105; /* N3105 counter */ - - struct osmo_timer_list timer; - unsigned int T; /* Txxxx number */ - unsigned int num_T_exp; /* number of consecutive T expirations */ - - struct osmo_gsm_timer_list gsm_timer; - unsigned int fT; /* fTxxxx number */ - unsigned int num_fT_exp; /* number of consecutive fT expirations */ - - struct { - char imsi[16]; - - struct timeval dl_bw_tv; /* timestamp for dl bw calculation */ - uint32_t dl_bw_octets; /* number of octets since bw_tv */ - - struct timeval rssi_tv; /* timestamp for rssi calculation */ - int32_t rssi_sum; /* sum of rssi values */ - int rssi_num; /* number of rssi values added since rssi_tv */ - - struct timeval 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 */ - - } meas; - - uint8_t cs; /* current coding scheme */ - -#ifdef DEBUG_DIAGRAM - int diag; /* number where TBF is presented in diagram */ - int diag_new; /* used to format output of new TBF */ -#endif -}; - extern struct llist_head gprs_rlcmac_ul_tbfs; /* list of uplink TBFs */ extern struct llist_head gprs_rlcmac_dl_tbfs; /* list of downlink TBFs */ extern struct llist_head gprs_rlcmac_sbas; /* list of single block allocs */ diff --git a/src/gprs_rlcmac_meas.cpp b/src/gprs_rlcmac_meas.cpp index 75da835..3229795 100644 --- a/src/gprs_rlcmac_meas.cpp +++ b/src/gprs_rlcmac_meas.cpp @@ -20,6 +20,7 @@ #include <gprs_rlcmac.h> #include <gprs_debug.h> #include <pcu_l1_if.h> +#include <tbf.h>
#include <string.h> #include <errno.h> diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index 6290c5d..f3edaac 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -20,6 +20,7 @@ #include <gprs_bssgp_pcu.h> #include <gprs_rlcmac.h> #include <pcu_l1_if.h> +#include <tbf.h>
uint32_t sched_poll(uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr, struct gprs_rlcmac_tbf **poll_tbf, diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index 218dc23..47bf740 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -37,6 +37,7 @@ extern "C" { #include <gprs_debug.h> #include <gprs_bssgp_pcu.h> #include <pcuif_proto.h> +#include <tbf.h>
// FIXME: move this, when changed from c++ to c. extern "C" { diff --git a/src/tbf.h b/src/tbf.h index 330eac1..a6dfced 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -18,9 +18,107 @@
#pragma once
+#include "gprs_rlcmac.h" + #include <stdint.h>
-struct gprs_rlcmac_bts; +struct gprs_rlcmac_tbf { + struct llist_head list; + enum gprs_rlcmac_tbf_state state; + uint32_t state_flags; + enum gprs_rlcmac_tbf_direction direction; + uint8_t tfi; + uint32_t tlli; + uint8_t tlli_valid; + uint8_t trx; + uint16_t arfcn; + uint8_t tsc; + uint8_t first_ts; /* first TS used by TBF */ + uint8_t first_common_ts; /* first TS that the phone can send and + reveive simultaniously */ + uint8_t control_ts; /* timeslot control messages and polling */ + uint8_t ms_class; + struct gprs_rlcmac_pdch *pdch[8]; /* list of PDCHs allocated to TBF */ + uint16_t ta; + uint8_t llc_frame[LLC_MAX_LEN]; /* current DL or UL frame */ + uint16_t llc_index; /* current write/read position of frame */ + uint16_t llc_length; /* len of current DL LLC_frame, 0 == no frame */ + struct llist_head llc_queue; /* queued LLC DL data */ + + enum gprs_rlcmac_tbf_dl_ass_state dl_ass_state; + enum gprs_rlcmac_tbf_ul_ass_state ul_ass_state; + enum gprs_rlcmac_tbf_ul_ack_state ul_ack_state; + + enum gprs_rlcmac_tbf_poll_state poll_state; + uint32_t poll_fn; /* frame number to poll */ + + uint16_t ws; /* window size */ + uint16_t sns; /* sequence number space */ + + /* 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. + */ + union { + struct { + uint16_t bsn; /* block sequence number */ + uint16_t v_s; /* send state */ + uint16_t v_a; /* ack state */ + char v_b[RLC_MAX_SNS/2]; /* acknowledge state array */ + int32_t tx_counter; /* count all transmitted blocks */ + char imsi[16]; /* store IMSI for PCH retransmission */ + uint8_t wait_confirm; /* wait for CCCH IMM.ASS cnf */ + } dl; + struct { + uint16_t bsn; /* block sequence number */ + uint16_t v_r; /* receive state */ + uint16_t v_q; /* receive window state */ + char v_n[RLC_MAX_SNS/2]; /* receive state array */ + int32_t rx_counter; /* count all received blocks */ + uint8_t n3103; /* N3103 counter */ + uint8_t usf[8]; /* list USFs per PDCH (timeslot) */ + uint8_t contention_resolution_done; /* set after done */ + uint8_t final_ack_sent; /* set if we sent final ack */ + } ul; + } dir; + uint8_t rlc_block[RLC_MAX_SNS/2][RLC_MAX_LEN]; /* block history */ + uint8_t rlc_block_len[RLC_MAX_SNS/2]; /* block len of history */ + + uint8_t n3105; /* N3105 counter */ + + struct osmo_timer_list timer; + unsigned int T; /* Txxxx number */ + unsigned int num_T_exp; /* number of consecutive T expirations */ + + struct osmo_gsm_timer_list gsm_timer; + unsigned int fT; /* fTxxxx number */ + unsigned int num_fT_exp; /* number of consecutive fT expirations */ + + struct { + char imsi[16]; + + struct timeval dl_bw_tv; /* timestamp for dl bw calculation */ + uint32_t dl_bw_octets; /* number of octets since bw_tv */ + + struct timeval rssi_tv; /* timestamp for rssi calculation */ + int32_t rssi_sum; /* sum of rssi values */ + int rssi_num; /* number of rssi values added since rssi_tv */ + + struct timeval 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 */ + + } meas; + + uint8_t cs; /* current coding scheme */ + +#ifdef DEBUG_DIAGRAM + int diag; /* number where TBF is presented in diagram */ + int diag_new; /* used to format output of new TBF */ +#endif +}; +
/* dispatch Unitdata.DL messages */ int tbf_handle(struct gprs_rlcmac_bts *bts,
From: Holger Hans Peter Freyther holger@moiji-mobile.com
--- src/gprs_rlcmac.h | 94 ---------------------------------------------------- src/sysmo_sock.cpp | 1 + src/tbf.h | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 94 deletions(-)
diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index 6fdf600..a40ebd6 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -97,69 +97,6 @@ extern struct gprs_rlcmac_bts *gprs_rlcmac_bts;
#ifdef __cplusplus /* - * TBF instance - */ - -#define LLC_MAX_LEN 1543 -#define RLC_MAX_SNS 128 /* GPRS, must be power of 2 */ -#define RLC_MAX_WS 64 /* max window size */ -#define RLC_MAX_LEN 54 /* CS-4 including spare bits */ - -#define Tassign_agch 0,200000 /* waiting after IMM.ASS confirm */ -#define Tassign_pacch 2,0 /* timeout for pacch assigment */ - -enum gprs_rlcmac_tbf_state { - GPRS_RLCMAC_NULL = 0, /* new created TBF */ - GPRS_RLCMAC_ASSIGN, /* wait for downlink assignment */ - GPRS_RLCMAC_FLOW, /* RLC/MAC flow, resource needed */ - GPRS_RLCMAC_FINISHED, /* flow finished, wait for release */ - GPRS_RLCMAC_WAIT_RELEASE,/* wait for release or restart of DL TBF */ - GPRS_RLCMAC_RELEASING, /* releasing, wait to free TBI/USF */ -}; - -enum gprs_rlcmac_tbf_poll_state { - GPRS_RLCMAC_POLL_NONE = 0, - GPRS_RLCMAC_POLL_SCHED, /* a polling was scheduled */ -}; - -enum gprs_rlcmac_tbf_dl_ass_state { - GPRS_RLCMAC_DL_ASS_NONE = 0, - GPRS_RLCMAC_DL_ASS_SEND_ASS, /* send downlink assignment on next RTS */ - GPRS_RLCMAC_DL_ASS_WAIT_ACK, /* wait for PACKET CONTROL ACK */ -}; - -enum gprs_rlcmac_tbf_ul_ass_state { - GPRS_RLCMAC_UL_ASS_NONE = 0, - GPRS_RLCMAC_UL_ASS_SEND_ASS, /* send uplink assignment on next RTS */ - GPRS_RLCMAC_UL_ASS_WAIT_ACK, /* wait for PACKET CONTROL ACK */ -}; - -enum gprs_rlcmac_tbf_ul_ack_state { - GPRS_RLCMAC_UL_ACK_NONE = 0, - GPRS_RLCMAC_UL_ACK_SEND_ACK, /* send acknowledge on next RTS */ - GPRS_RLCMAC_UL_ACK_WAIT_ACK, /* wait for PACKET CONTROL ACK */ -}; - -enum gprs_rlcmac_tbf_direction { - GPRS_RLCMAC_DL_TBF, - GPRS_RLCMAC_UL_TBF -}; - -#define GPRS_RLCMAC_FLAG_CCCH 0 /* assignment on CCCH */ -#define GPRS_RLCMAC_FLAG_PACCH 1 /* assignment on PACCH */ -#define GPRS_RLCMAC_FLAG_UL_DATA 2 /* uplink data received */ -#define GPRS_RLCMAC_FLAG_DL_ACK 3 /* downlink acknowledge received */ -#define GPRS_RLCMAC_FLAG_TO_UL_ACK 4 -#define GPRS_RLCMAC_FLAG_TO_DL_ACK 5 -#define GPRS_RLCMAC_FLAG_TO_UL_ASS 6 -#define GPRS_RLCMAC_FLAG_TO_DL_ASS 7 -#define GPRS_RLCMAC_FLAG_TO_MASK 0xf0 /* timeout bits */ - -extern struct llist_head gprs_rlcmac_ul_tbfs; /* list of uplink TBFs */ -extern struct llist_head gprs_rlcmac_dl_tbfs; /* list of downlink TBFs */ -extern struct llist_head gprs_rlcmac_sbas; /* list of single block allocs */ - -/* * paging entry */ struct gprs_rlcmac_paging { @@ -213,37 +150,6 @@ int sba_alloc(uint8_t *_trx, uint8_t *_ts, uint32_t *_fn, uint8_t ta);
struct gprs_rlcmac_sba *sba_find(uint8_t trx, uint8_t ts, uint32_t fn);
-int tfi_find_free(struct gprs_rlcmac_bts *bts, enum gprs_rlcmac_tbf_direction dir, - uint8_t *_trx, int8_t use_trx); - -struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts, - struct gprs_rlcmac_tbf *old_tbf, - enum gprs_rlcmac_tbf_direction dir, uint8_t tfi, uint8_t trx, - uint8_t ms_class, uint8_t single_slot); - -struct gprs_rlcmac_tbf *tbf_by_tfi(struct gprs_rlcmac_bts *bts, - uint8_t tfi, uint8_t trx, - enum gprs_rlcmac_tbf_direction dir); - -struct gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli, - enum gprs_rlcmac_tbf_direction dir); - -struct gprs_rlcmac_tbf *tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts); - -void tbf_free(struct gprs_rlcmac_tbf *tbf); - -int tbf_update(struct gprs_rlcmac_tbf *tbf); - -int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf); - -void tbf_new_state(struct gprs_rlcmac_tbf *tbf, - enum gprs_rlcmac_tbf_state state); - -void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T, - unsigned int seconds, unsigned int microseconds); - -void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf); - /* TS 44.060 Section 10.4.7 Table 10.4.7.1: Payload Type field */ enum gprs_rlcmac_block_type { GPRS_RLCMAC_DATA_BLOCK = 0x0, diff --git a/src/sysmo_sock.cpp b/src/sysmo_sock.cpp index e116e5a..d075df0 100644 --- a/src/sysmo_sock.cpp +++ b/src/sysmo_sock.cpp @@ -36,6 +36,7 @@ extern "C" { #include <gprs_debug.h> #include <gprs_bssgp_pcu.h> #include <pcuif_proto.h> +#include <tbf.h>
extern void *tall_pcu_ctx;
diff --git a/src/tbf.h b/src/tbf.h index a6dfced..cf2481d 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -22,6 +22,70 @@
#include <stdint.h>
+/* + * TBF instance + */ + +#define LLC_MAX_LEN 1543 +#define RLC_MAX_SNS 128 /* GPRS, must be power of 2 */ +#define RLC_MAX_WS 64 /* max window size */ +#define RLC_MAX_LEN 54 /* CS-4 including spare bits */ + +#define Tassign_agch 0,200000 /* waiting after IMM.ASS confirm */ +#define Tassign_pacch 2,0 /* timeout for pacch assigment */ + +enum gprs_rlcmac_tbf_state { + GPRS_RLCMAC_NULL = 0, /* new created TBF */ + GPRS_RLCMAC_ASSIGN, /* wait for downlink assignment */ + GPRS_RLCMAC_FLOW, /* RLC/MAC flow, resource needed */ + GPRS_RLCMAC_FINISHED, /* flow finished, wait for release */ + GPRS_RLCMAC_WAIT_RELEASE,/* wait for release or restart of DL TBF */ + GPRS_RLCMAC_RELEASING, /* releasing, wait to free TBI/USF */ +}; + +enum gprs_rlcmac_tbf_poll_state { + GPRS_RLCMAC_POLL_NONE = 0, + GPRS_RLCMAC_POLL_SCHED, /* a polling was scheduled */ +}; + +enum gprs_rlcmac_tbf_dl_ass_state { + GPRS_RLCMAC_DL_ASS_NONE = 0, + GPRS_RLCMAC_DL_ASS_SEND_ASS, /* send downlink assignment on next RTS */ + GPRS_RLCMAC_DL_ASS_WAIT_ACK, /* wait for PACKET CONTROL ACK */ +}; + +enum gprs_rlcmac_tbf_ul_ass_state { + GPRS_RLCMAC_UL_ASS_NONE = 0, + GPRS_RLCMAC_UL_ASS_SEND_ASS, /* send uplink assignment on next RTS */ + GPRS_RLCMAC_UL_ASS_WAIT_ACK, /* wait for PACKET CONTROL ACK */ +}; + +enum gprs_rlcmac_tbf_ul_ack_state { + GPRS_RLCMAC_UL_ACK_NONE = 0, + GPRS_RLCMAC_UL_ACK_SEND_ACK, /* send acknowledge on next RTS */ + GPRS_RLCMAC_UL_ACK_WAIT_ACK, /* wait for PACKET CONTROL ACK */ +}; + +enum gprs_rlcmac_tbf_direction { + GPRS_RLCMAC_DL_TBF, + GPRS_RLCMAC_UL_TBF +}; + +#define GPRS_RLCMAC_FLAG_CCCH 0 /* assignment on CCCH */ +#define GPRS_RLCMAC_FLAG_PACCH 1 /* assignment on PACCH */ +#define GPRS_RLCMAC_FLAG_UL_DATA 2 /* uplink data received */ +#define GPRS_RLCMAC_FLAG_DL_ACK 3 /* downlink acknowledge received */ +#define GPRS_RLCMAC_FLAG_TO_UL_ACK 4 +#define GPRS_RLCMAC_FLAG_TO_DL_ACK 5 +#define GPRS_RLCMAC_FLAG_TO_UL_ASS 6 +#define GPRS_RLCMAC_FLAG_TO_DL_ASS 7 +#define GPRS_RLCMAC_FLAG_TO_MASK 0xf0 /* timeout bits */ + +extern struct llist_head gprs_rlcmac_ul_tbfs; /* list of uplink TBFs */ +extern struct llist_head gprs_rlcmac_dl_tbfs; /* list of downlink TBFs */ +extern struct llist_head gprs_rlcmac_sbas; /* list of single block allocs */ + + struct gprs_rlcmac_tbf { struct llist_head list; enum gprs_rlcmac_tbf_state state; @@ -128,3 +192,35 @@ int tbf_handle(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts, int8_t use_trx, uint8_t ms_class, uint32_t tlli, uint8_t ta, struct gprs_rlcmac_tbf *dl_tbf); + +int tfi_find_free(struct gprs_rlcmac_bts *bts, enum gprs_rlcmac_tbf_direction dir, + uint8_t *_trx, int8_t use_trx); + +struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts, + struct gprs_rlcmac_tbf *old_tbf, + enum gprs_rlcmac_tbf_direction dir, uint8_t tfi, uint8_t trx, + uint8_t ms_class, uint8_t single_slot); + +struct gprs_rlcmac_tbf *tbf_by_tfi(struct gprs_rlcmac_bts *bts, + uint8_t tfi, uint8_t trx, + enum gprs_rlcmac_tbf_direction dir); + +struct gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli, + enum gprs_rlcmac_tbf_direction dir); + +struct gprs_rlcmac_tbf *tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts); + +void tbf_free(struct gprs_rlcmac_tbf *tbf); + +int tbf_update(struct gprs_rlcmac_tbf *tbf); + +int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf); + +void tbf_new_state(struct gprs_rlcmac_tbf *tbf, + enum gprs_rlcmac_tbf_state state); + +void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T, + unsigned int seconds, unsigned int microseconds); + +void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf); +
From: Holger Hans Peter Freyther holger@moiji-mobile.com
Move the code out of the sysmocom_socket (as this is only required to talk to our hardware) and into the TBF class that actually knows what a TBF is. --- src/sysmo_sock.cpp | 12 ++---------- src/tbf.cpp | 14 ++++++++++++++ src/tbf.h | 4 ++++ 3 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/src/sysmo_sock.cpp b/src/sysmo_sock.cpp index d075df0..591c105 100644 --- a/src/sysmo_sock.cpp +++ b/src/sysmo_sock.cpp @@ -82,8 +82,7 @@ static void pcu_sock_close(struct pcu_sock_state *state, int lost) { struct osmo_fd *bfd = &state->conn_bfd; struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts; - struct gprs_rlcmac_tbf *tbf; - uint8_t trx, ts, tfi; + uint8_t trx, ts;
LOGP(DL1IF, LOGL_NOTICE, "PCU socket has %s connection\n", (lost) ? "LOST" : "closed"); @@ -108,14 +107,7 @@ static void pcu_sock_close(struct pcu_sock_state *state, int lost) #endif for (ts = 0; ts < 8; ts++) bts->trx[trx].pdch[ts].enable = 0; - for (tfi = 0; tfi < 32; tfi++) { - tbf = bts->trx[trx].ul_tbf[tfi]; - if (tbf) - tbf_free(tbf); - tbf = bts->trx[trx].dl_tbf[tfi]; - if (tbf) - tbf_free(tbf); - } + gprs_rlcmac_tbf::free_all(&bts->trx[trx]); }
gprs_bssgp_destroy_or_exit(); diff --git a/src/tbf.cpp b/src/tbf.cpp index 79f1ea8..8aff463 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -237,3 +237,17 @@ struct gprs_rlcmac_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts,
return tbf; } + +void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_trx *trx) +{ + for (uint8_t tfi = 0; tfi < 32; tfi++) { + struct gprs_rlcmac_tbf *tbf; + + tbf = trx->ul_tbf[tfi]; + if (tbf) + tbf_free(tbf); + tbf = trx->dl_tbf[tfi]; + if (tbf) + tbf_free(tbf); + } +} diff --git a/src/tbf.h b/src/tbf.h index cf2481d..b73d0b8 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -87,6 +87,10 @@ extern struct llist_head gprs_rlcmac_sbas; /* list of single block allocs */
struct gprs_rlcmac_tbf { + + static void free_all(struct gprs_rlcmac_trx *trx); + + struct llist_head list; enum gprs_rlcmac_tbf_state state; uint32_t state_flags;
From: Holger Hans Peter Freyther holger@moiji-mobile.com
--- src/pcu_l1_if.cpp | 12 ++---------- src/tbf.cpp | 14 ++++++++++++++ src/tbf.h | 1 + 3 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index 47bf740..a31974f 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -306,20 +306,12 @@ static int pcu_rx_rach_ind(struct gsm_pcu_if_rach_ind *rach_ind)
int flush_pdch(struct gprs_rlcmac_pdch *pdch, uint8_t trx, uint8_t ts) { - uint8_t tfi; - struct gprs_rlcmac_tbf *tbf; struct gprs_rlcmac_paging *pag; struct gprs_rlcmac_sba *sba, *sba2;
/* kick all TBF on slot */ - for (tfi = 0; tfi < 32; tfi++) { - tbf = pdch->ul_tbf[tfi]; - if (tbf) - tbf_free(tbf); - tbf = pdch->dl_tbf[tfi]; - if (tbf) - tbf_free(tbf); - } + gprs_rlcmac_tbf::free_all(pdch); + /* flush all pending paging messages */ while ((pag = gprs_rlcmac_dequeue_paging(pdch))) talloc_free(pag); diff --git a/src/tbf.cpp b/src/tbf.cpp index 8aff463..4bb42a7 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -251,3 +251,17 @@ void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_trx *trx) tbf_free(tbf); } } + +void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_pdch *pdch) +{ + for (uint8_t tfi = 0; tfi < 32; tfi++) { + struct gprs_rlcmac_tbf *tbf; + + tbf = pdch->ul_tbf[tfi]; + if (tbf) + tbf_free(tbf); + tbf = pdch->dl_tbf[tfi]; + if (tbf) + tbf_free(tbf); + } +} diff --git a/src/tbf.h b/src/tbf.h index b73d0b8..74df237 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -89,6 +89,7 @@ extern struct llist_head gprs_rlcmac_sbas; /* list of single block allocs */ struct gprs_rlcmac_tbf {
static void free_all(struct gprs_rlcmac_trx *trx); + static void free_all(struct gprs_rlcmac_pdch *pdch);
struct llist_head list;
From: Holger Hans Peter Freyther holger@moiji-mobile.com
--- src/gprs_rlcmac.cpp | 153 ---------------------------------------------------- src/tbf.cpp | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+), 153 deletions(-)
diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index 3dab44f..d33dc8c 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -888,159 +888,6 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, return 0; }
-static void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf) -{ - struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts; - struct gprs_rlcmac_pdch *pdch; - int ts; - - if (tbf->direction == GPRS_RLCMAC_UL_TBF) { - bts->trx[tbf->trx].ul_tbf[tbf->tfi] = NULL; - for (ts = 0; ts < 8; ts++) { - pdch = tbf->pdch[ts]; - if (pdch) - pdch->ul_tbf[tbf->tfi] = NULL; - tbf->pdch[ts] = NULL; - } - } else { - bts->trx[tbf->trx].dl_tbf[tbf->tfi] = NULL; - for (ts = 0; ts < 8; ts++) { - pdch = tbf->pdch[ts]; - if (pdch) - pdch->dl_tbf[tbf->tfi] = NULL; - tbf->pdch[ts] = NULL; - } - } -} - -void tbf_free(struct gprs_rlcmac_tbf *tbf) -{ - struct msgb *msg; - - /* Give final measurement report */ - gprs_rlcmac_rssi_rep(tbf); - gprs_rlcmac_lost_rep(tbf); - - debug_diagram(tbf->diag, "+---------------+"); - debug_diagram(tbf->diag, "| THE END |"); - debug_diagram(tbf->diag, "+---------------+"); - LOGP(DRLCMAC, LOGL_INFO, "Free %s TBF=%d with TLLI=0x%08x.\n", - (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, - tbf->tlli); - if (tbf->ul_ass_state != GPRS_RLCMAC_UL_ASS_NONE) - LOGP(DRLCMAC, LOGL_ERROR, "Software error: Pending uplink " - "assignment. This may not happen, because the " - "assignment message never gets transmitted. Please " - "be shure not to free in this state. PLEASE FIX!\n"); - if (tbf->dl_ass_state != GPRS_RLCMAC_DL_ASS_NONE) - LOGP(DRLCMAC, LOGL_ERROR, "Software error: Pending downlink " - "assignment. This may not happen, because the " - "assignment message never gets transmitted. Please " - "be shure not to free in this state. PLEASE FIX!\n"); - tbf_timer_stop(tbf); - while ((msg = msgb_dequeue(&tbf->llc_queue))) - msgb_free(msg); - tbf_unlink_pdch(tbf); - llist_del(&tbf->list); - LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF ends here **********\n"); - talloc_free(tbf); -} - -int tbf_update(struct gprs_rlcmac_tbf *tbf) -{ - struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts; - struct gprs_rlcmac_tbf *ul_tbf = NULL; - int rc; - - LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF update **********\n"); - - if (tbf->direction != GPRS_RLCMAC_DL_TBF) - return -EINVAL; - - if (!tbf->ms_class) { - LOGP(DRLCMAC, LOGL_DEBUG, "- Cannot update, no class\n"); - return -EINVAL; - } - - ul_tbf = tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_UL_TBF); - - tbf_unlink_pdch(tbf); - rc = bts->alloc_algorithm(bts, ul_tbf, tbf, bts->alloc_algorithm_curst, 0); - /* if no ressource */ - if (rc < 0) { - LOGP(DRLCMAC, LOGL_ERROR, "No ressource after update???\n"); - return -rc; - } - - return 0; -} - -int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf) -{ - if (tbf->control_ts == 0xff) - LOGP(DRLCMAC, LOGL_INFO, "- Setting Control TS %d\n", - tbf->first_common_ts); - else if (tbf->control_ts != tbf->first_common_ts) - LOGP(DRLCMAC, LOGL_INFO, "- Changing Control TS %d\n", - tbf->first_common_ts); - tbf->control_ts = tbf->first_common_ts; - - return 0; -} - - -const char *tbf_state_name[] = { - "NULL", - "ASSIGN", - "FLOW", - "FINISHED", - "WAIT RELEASE", - "RELEASING", -}; - -void tbf_new_state(struct gprs_rlcmac_tbf *tbf, - enum gprs_rlcmac_tbf_state state) -{ - debug_diagram(tbf->diag, "->%s", tbf_state_name[state]); - LOGP(DRLCMAC, LOGL_DEBUG, "%s TBF=%d changes state from %s to %s\n", - (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, - tbf_state_name[tbf->state], tbf_state_name[state]); - tbf->state = state; -} - -void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T, - unsigned int seconds, unsigned int microseconds) -{ - if (!osmo_timer_pending(&tbf->timer)) - LOGP(DRLCMAC, LOGL_DEBUG, "Starting %s TBF=%d timer %u.\n", - (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", - tbf->tfi, T); - else - LOGP(DRLCMAC, LOGL_DEBUG, "Restarting %s TBF=%d timer %u " - "while old timer %u pending \n", - (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", - tbf->tfi, T, tbf->T); - - tbf->T = T; - tbf->num_T_exp = 0; - - /* Tunning timers can be safely re-scheduled. */ - tbf->timer.data = tbf; - tbf->timer.cb = &tbf_timer_cb; - - osmo_timer_schedule(&tbf->timer, seconds, microseconds); -} - -void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf) -{ - if (osmo_timer_pending(&tbf->timer)) { - LOGP(DRLCMAC, LOGL_DEBUG, "Stopping %s TBF=%d timer %u.\n", - (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", - tbf->tfi, tbf->T); - osmo_timer_del(&tbf->timer); - } -} - /* starting time for assigning single slot * This offset must be a multiple of 13. */ #define AGCH_START_OFFSET 52 diff --git a/src/tbf.cpp b/src/tbf.cpp index 4bb42a7..b93d0f1 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -25,6 +25,7 @@
extern "C" { #include <osmocom/core/msgb.h> +#include <osmocom/core/talloc.h> }
#include <errno.h> @@ -238,6 +239,158 @@ struct gprs_rlcmac_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts, return tbf; }
+static void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf) +{ + struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts; + struct gprs_rlcmac_pdch *pdch; + int ts; + + if (tbf->direction == GPRS_RLCMAC_UL_TBF) { + bts->trx[tbf->trx].ul_tbf[tbf->tfi] = NULL; + for (ts = 0; ts < 8; ts++) { + pdch = tbf->pdch[ts]; + if (pdch) + pdch->ul_tbf[tbf->tfi] = NULL; + tbf->pdch[ts] = NULL; + } + } else { + bts->trx[tbf->trx].dl_tbf[tbf->tfi] = NULL; + for (ts = 0; ts < 8; ts++) { + pdch = tbf->pdch[ts]; + if (pdch) + pdch->dl_tbf[tbf->tfi] = NULL; + tbf->pdch[ts] = NULL; + } + } +} + +void tbf_free(struct gprs_rlcmac_tbf *tbf) +{ + struct msgb *msg; + + /* Give final measurement report */ + gprs_rlcmac_rssi_rep(tbf); + gprs_rlcmac_lost_rep(tbf); + + debug_diagram(tbf->diag, "+---------------+"); + debug_diagram(tbf->diag, "| THE END |"); + debug_diagram(tbf->diag, "+---------------+"); + LOGP(DRLCMAC, LOGL_INFO, "Free %s TBF=%d with TLLI=0x%08x.\n", + (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, + tbf->tlli); + if (tbf->ul_ass_state != GPRS_RLCMAC_UL_ASS_NONE) + LOGP(DRLCMAC, LOGL_ERROR, "Software error: Pending uplink " + "assignment. This may not happen, because the " + "assignment message never gets transmitted. Please " + "be shure not to free in this state. PLEASE FIX!\n"); + if (tbf->dl_ass_state != GPRS_RLCMAC_DL_ASS_NONE) + LOGP(DRLCMAC, LOGL_ERROR, "Software error: Pending downlink " + "assignment. This may not happen, because the " + "assignment message never gets transmitted. Please " + "be shure not to free in this state. PLEASE FIX!\n"); + tbf_timer_stop(tbf); + while ((msg = msgb_dequeue(&tbf->llc_queue))) + msgb_free(msg); + tbf_unlink_pdch(tbf); + llist_del(&tbf->list); + LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF ends here **********\n"); + talloc_free(tbf); +} + +int tbf_update(struct gprs_rlcmac_tbf *tbf) +{ + struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts; + struct gprs_rlcmac_tbf *ul_tbf = NULL; + int rc; + + LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF update **********\n"); + + if (tbf->direction != GPRS_RLCMAC_DL_TBF) + return -EINVAL; + + if (!tbf->ms_class) { + LOGP(DRLCMAC, LOGL_DEBUG, "- Cannot update, no class\n"); + return -EINVAL; + } + + ul_tbf = tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_UL_TBF); + + tbf_unlink_pdch(tbf); + rc = bts->alloc_algorithm(bts, ul_tbf, tbf, bts->alloc_algorithm_curst, 0); + /* if no ressource */ + if (rc < 0) { + LOGP(DRLCMAC, LOGL_ERROR, "No ressource after update???\n"); + return -rc; + } + + return 0; +} + +int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf) +{ + if (tbf->control_ts == 0xff) + LOGP(DRLCMAC, LOGL_INFO, "- Setting Control TS %d\n", + tbf->first_common_ts); + else if (tbf->control_ts != tbf->first_common_ts) + LOGP(DRLCMAC, LOGL_INFO, "- Changing Control TS %d\n", + tbf->first_common_ts); + tbf->control_ts = tbf->first_common_ts; + + return 0; +} + +static const char *tbf_state_name[] = { + "NULL", + "ASSIGN", + "FLOW", + "FINISHED", + "WAIT RELEASE", + "RELEASING", +}; + +void tbf_new_state(struct gprs_rlcmac_tbf *tbf, + enum gprs_rlcmac_tbf_state state) +{ + debug_diagram(tbf->diag, "->%s", tbf_state_name[state]); + LOGP(DRLCMAC, LOGL_DEBUG, "%s TBF=%d changes state from %s to %s\n", + (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, + tbf_state_name[tbf->state], tbf_state_name[state]); + tbf->state = state; +} + +void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T, + unsigned int seconds, unsigned int microseconds) +{ + if (!osmo_timer_pending(&tbf->timer)) + LOGP(DRLCMAC, LOGL_DEBUG, "Starting %s TBF=%d timer %u.\n", + (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", + tbf->tfi, T); + else + LOGP(DRLCMAC, LOGL_DEBUG, "Restarting %s TBF=%d timer %u " + "while old timer %u pending \n", + (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", + tbf->tfi, T, tbf->T); + + tbf->T = T; + tbf->num_T_exp = 0; + + /* Tunning timers can be safely re-scheduled. */ + tbf->timer.data = tbf; + tbf->timer.cb = &tbf_timer_cb; + + osmo_timer_schedule(&tbf->timer, seconds, microseconds); +} + +void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf) +{ + if (osmo_timer_pending(&tbf->timer)) { + LOGP(DRLCMAC, LOGL_DEBUG, "Stopping %s TBF=%d timer %u.\n", + (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", + tbf->tfi, tbf->T); + osmo_timer_del(&tbf->timer); + } +} + void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_trx *trx) { for (uint8_t tfi = 0; tfi < 32; tfi++) {
From: Holger Hans Peter Freyther holger@moiji-mobile.com
--- src/gprs_rlcmac.cpp | 48 ------------------------------------------------ 1 file changed, 48 deletions(-)
diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index d33dc8c..8841445 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -950,54 +950,6 @@ struct gprs_rlcmac_sba *sba_find(uint8_t trx, uint8_t ts, uint32_t fn) return NULL; }
-#if 0 -static void tbf_gsm_timer_cb(void *_tbf) -{ - struct gprs_rlcmac_tbf *tbf = (struct gprs_rlcmac_tbf *)_tbf; - - tbf->num_fT_exp++; - - switch (tbf->fT) { - case 0: -hier alles berdenken - // This is timer for delay RLC/MAC data sending after Downlink Immediate Assignment on CCCH. - gprs_rlcmac_segment_llc_pdu(tbf); - LOGP(DRLCMAC, LOGL_NOTICE, "TBF: [DOWNLINK] END TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli); - tbf_free(tbf); - break; - default: - LOGP(DRLCMAC, LOGL_NOTICE, "Timer expired in unknown mode: %u \n", tbf->fT); - } -} - -static void tbf_gsm_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int fT, - int frames) -{ - if (osmo_gsm_timer_pending(&tbf->gsm_timer)) - LOGP(DRLCMAC, LOGL_NOTICE, "Starting TBF timer %u while old timer %u pending \n", fT, tbf->fT); - tbf->fT = fT; - tbf->num_fT_exp = 0; - - /* FIXME: we should do this only once ? */ - tbf->gsm_timer.data = tbf; - tbf->gsm_timer.cb = &tbf_gsm_timer_cb; - - osmo_gsm_timer_schedule(&tbf->gsm_timer, frames); -} - -eine stop-funktion, auch im tbf_free aufrufen - -#endif - -#if 0 -void gprs_rlcmac_enqueue_block(bitvec *block, int len) -{ - struct msgb *msg = msgb_alloc(len, "rlcmac_dl"); - bitvec_pack(block, msgb_put(msg, len)); - msgb_enqueue(&block_queue, msg); -} -#endif - /* received RLC/MAC block from L1 */ int gprs_rlcmac_rcv_block(uint8_t trx, uint8_t ts, uint8_t *data, uint8_t len, uint32_t fn, int8_t rssi)
From: Holger Hans Peter Freyther holger@moiji-mobile.com
Introduce the first instance method for printing out diagonistic about itself and create a jump function for it. --- src/gprs_rlcmac.cpp | 150 ------------------------------- src/gprs_rlcmac.h | 2 - src/gprs_rlcmac_data.cpp | 72 +-------------- src/tbf.cpp | 227 +++++++++++++++++++++++++++++++++++++++++++++++ src/tbf.h | 3 + 5 files changed, 231 insertions(+), 223 deletions(-)
diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index 8841445..9b4e643 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -253,156 +253,6 @@ static inline int8_t find_free_usf(struct gprs_rlcmac_pdch *pdch, uint8_t ts) return -1; }
-/* lookup TBF Entity (by TFI) */ -struct gprs_rlcmac_tbf *tbf_by_tfi(struct gprs_rlcmac_bts *bts, - uint8_t tfi, uint8_t trx, enum gprs_rlcmac_tbf_direction dir) -{ - struct gprs_rlcmac_tbf *tbf; - - if (tfi >= 32 || trx >= 8) - return NULL; - - if (dir == GPRS_RLCMAC_UL_TBF) - tbf = bts->trx[trx].ul_tbf[tfi]; - else - tbf = bts->trx[trx].dl_tbf[tfi]; - if (!tbf) - return NULL; - - if (tbf->state != GPRS_RLCMAC_RELEASING) - return tbf; - - return NULL; -} - -/* search for active downlink or uplink tbf */ -struct gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli, - enum gprs_rlcmac_tbf_direction dir) -{ - struct gprs_rlcmac_tbf *tbf; - if (dir == GPRS_RLCMAC_UL_TBF) { - llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { - if (tbf->state != GPRS_RLCMAC_RELEASING - && tbf->tlli == tlli && tbf->tlli_valid) - return tbf; - } - } else { - llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { - if (tbf->state != GPRS_RLCMAC_RELEASING - && tbf->tlli == tlli) - return tbf; - } - } - return NULL; -} - -struct gprs_rlcmac_tbf *tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) -{ - struct gprs_rlcmac_tbf *tbf; - - /* only one TBF can poll on specific TS/FN, because scheduler can only - * schedule one downlink control block (with polling) at a FN per TS */ - llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { - if (tbf->state != GPRS_RLCMAC_RELEASING - && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED - && tbf->poll_fn == fn && tbf->trx == trx - && tbf->control_ts == ts) - return tbf; - } - llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { - if (tbf->state != GPRS_RLCMAC_RELEASING - && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED - && tbf->poll_fn == fn && tbf->trx == trx - && tbf->control_ts == ts) - return tbf; - } - return NULL; -} - -struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts, - struct gprs_rlcmac_tbf *old_tbf, enum gprs_rlcmac_tbf_direction dir, - uint8_t tfi, uint8_t trx, - uint8_t ms_class, uint8_t single_slot) -{ - struct gprs_rlcmac_tbf *tbf; - int rc; - -#ifdef DEBUG_DIAGRAM - /* hunt for first free number in diagram */ - int diagram_num; - for (diagram_num = 0; ; diagram_num++) { - llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { - if (tbf->diag == diagram_num) - goto next_diagram; - } - llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { - if (tbf->diag == diagram_num) - goto next_diagram; - } - break; -next_diagram: - continue; - } -#endif - - LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n"); - LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: TFI=%d TRX=%d " - "MS_CLASS=%d\n", (dir == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", - tfi, trx, ms_class); - - if (trx >= 8 || tfi >= 32) - return NULL; - - tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_tbf); - if (!tbf) - return NULL; - -#ifdef DEBUG_DIAGRAM - tbf->diag = diagram_num; -#endif - tbf->direction = dir; - tbf->tfi = tfi; - tbf->trx = trx; - tbf->arfcn = bts->trx[trx].arfcn; - tbf->ms_class = ms_class; - tbf->ws = 64; - tbf->sns = 128; - /* select algorithm */ - rc = bts->alloc_algorithm(bts, old_tbf, tbf, bts->alloc_algorithm_curst, - single_slot); - /* if no ressource */ - if (rc < 0) { - talloc_free(tbf); - return NULL; - } - /* assign control ts */ - tbf->control_ts = 0xff; - rc = tbf_assign_control_ts(tbf); - /* if no ressource */ - if (rc < 0) { - talloc_free(tbf); - return NULL; - } - - /* set timestamp */ - gettimeofday(&tbf->meas.dl_bw_tv, NULL); - gettimeofday(&tbf->meas.rssi_tv, NULL); - gettimeofday(&tbf->meas.dl_loss_tv, NULL); - - INIT_LLIST_HEAD(&tbf->llc_queue); - if (dir == GPRS_RLCMAC_UL_TBF) - llist_add(&tbf->list, &gprs_rlcmac_ul_tbfs); - else - llist_add(&tbf->list, &gprs_rlcmac_dl_tbfs); - - debug_diagram(tbf->diag, "+-----------------+"); - debug_diagram(tbf->diag, "|NEW %s TBF TFI=%2d|", - (dir == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tfi); - debug_diagram(tbf->diag, "+-----------------+"); - - return tbf; -} - /* Slot Allocation: Algorithm A * * Assign single slot for uplink and downlink diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index a40ebd6..8863af4 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -183,8 +183,6 @@ void write_packet_uplink_ack(RlcMacDownlink_t * block, struct gprs_rlcmac_tbf *t
int gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf);
-void tbf_timer_cb(void *_tbf); - int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_tbf *tbf);
int gprs_rlcmac_sba_timeout(struct gprs_rlcmac_sba *sba); diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp index bc55c57..b5ea7c9 100644 --- a/src/gprs_rlcmac_data.cpp +++ b/src/gprs_rlcmac_data.cpp @@ -79,20 +79,7 @@ static void gprs_rlcmac_downlink_assignment(gprs_rlcmac_tbf *tbf, uint8_t poll,
static int gprs_rlcmac_diag(struct gprs_rlcmac_tbf *tbf) { - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) - LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on CCCH\n"); - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) - LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on PACCH\n"); - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_UL_DATA))) - LOGP(DRLCMAC, LOGL_NOTICE, "- Uplink data was received\n"); - else if (tbf->direction == GPRS_RLCMAC_UL_TBF) - LOGP(DRLCMAC, LOGL_NOTICE, "- No uplink data received yet\n"); - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK))) - LOGP(DRLCMAC, LOGL_NOTICE, "- Downlink ACK was received\n"); - else if (tbf->direction == GPRS_RLCMAC_DL_TBF) - LOGP(DRLCMAC, LOGL_NOTICE, "- No downlink ACK received yet\n"); - - return 0; + return tbf->rlcmac_diag(); }
int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_tbf *tbf) @@ -487,63 +474,6 @@ int gprs_rlcmac_rcv_control_block(bitvec *rlc_block, uint8_t trx, uint8_t ts, char debug_imsi[16]; #endif
-void tbf_timer_cb(void *_tbf) -{ - struct gprs_rlcmac_tbf *tbf = (struct gprs_rlcmac_tbf *)_tbf; - - LOGP(DRLCMAC, LOGL_DEBUG, "%s TBF=%d timer %u expired.\n", - (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, - tbf->T); - - tbf->num_T_exp++; - - switch (tbf->T) { -#ifdef DEBUG_DL_ASS_IDLE - case 1234: - gprs_rlcmac_trigger_downlink_assignment(tbf, NULL, debug_imsi); - break; -#endif - case 0: /* assignment */ - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) { - if (tbf->state == GPRS_RLCMAC_ASSIGN) { - LOGP(DRLCMAC, LOGL_NOTICE, "Releasing due to " - "PACCH assignment timeout.\n"); - tbf_free(tbf); - } else - LOGP(DRLCMAC, LOGL_ERROR, "Error: TBF is not " - "in assign state\n"); - } - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) { - /* change state to FLOW, so scheduler will start transmission */ - tbf->dir.dl.wait_confirm = 0; - if (tbf->state == GPRS_RLCMAC_ASSIGN) { - tbf_new_state(tbf, GPRS_RLCMAC_FLOW); - tbf_assign_control_ts(tbf); - } else - LOGP(DRLCMAC, LOGL_NOTICE, "Continue flow after " - "IMM.ASS confirm\n"); - } - break; - case 3169: - case 3191: - case 3195: - LOGP(DRLCMAC, LOGL_NOTICE, "TBF T%d timeout during " - "transsmission\n", tbf->T); - gprs_rlcmac_diag(tbf); - /* fall through */ - case 3193: - if (tbf->T == 3193) - debug_diagram(tbf->diag, "T3193 timeout"); - LOGP(DRLCMAC, LOGL_DEBUG, "TBF will be freed due to timeout\n"); - /* free TBF */ - tbf_free(tbf); - break; - default: - LOGP(DRLCMAC, LOGL_ERROR, "Timer expired in unknown mode: %u\n", - tbf->T); - } -} - /* * UL data block flow */ diff --git a/src/tbf.cpp b/src/tbf.cpp index b93d0f1..918520c 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -31,6 +31,8 @@ extern "C" { #include <errno.h> #include <string.h>
+extern void *tall_pcu_ctx; + static inline void tbf_update_ms_class(struct gprs_rlcmac_tbf *tbf, const uint8_t ms_class) { @@ -391,6 +393,231 @@ void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf) } }
+/* lookup TBF Entity (by TFI) */ +struct gprs_rlcmac_tbf *tbf_by_tfi(struct gprs_rlcmac_bts *bts, + uint8_t tfi, uint8_t trx, enum gprs_rlcmac_tbf_direction dir) +{ + struct gprs_rlcmac_tbf *tbf; + + if (tfi >= 32 || trx >= 8) + return NULL; + + if (dir == GPRS_RLCMAC_UL_TBF) + tbf = bts->trx[trx].ul_tbf[tfi]; + else + tbf = bts->trx[trx].dl_tbf[tfi]; + if (!tbf) + return NULL; + + if (tbf->state != GPRS_RLCMAC_RELEASING) + return tbf; + + return NULL; +} + +/* search for active downlink or uplink tbf */ +struct gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli, + enum gprs_rlcmac_tbf_direction dir) +{ + struct gprs_rlcmac_tbf *tbf; + if (dir == GPRS_RLCMAC_UL_TBF) { + llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { + if (tbf->state != GPRS_RLCMAC_RELEASING + && tbf->tlli == tlli && tbf->tlli_valid) + return tbf; + } + } else { + llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { + if (tbf->state != GPRS_RLCMAC_RELEASING + && tbf->tlli == tlli) + return tbf; + } + } + return NULL; +} + +struct gprs_rlcmac_tbf *tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) +{ + struct gprs_rlcmac_tbf *tbf; + + /* only one TBF can poll on specific TS/FN, because scheduler can only + * schedule one downlink control block (with polling) at a FN per TS */ + llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { + if (tbf->state != GPRS_RLCMAC_RELEASING + && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED + && tbf->poll_fn == fn && tbf->trx == trx + && tbf->control_ts == ts) + return tbf; + } + llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { + if (tbf->state != GPRS_RLCMAC_RELEASING + && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED + && tbf->poll_fn == fn && tbf->trx == trx + && tbf->control_ts == ts) + return tbf; + } + return NULL; +} + +struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts, + struct gprs_rlcmac_tbf *old_tbf, enum gprs_rlcmac_tbf_direction dir, + uint8_t tfi, uint8_t trx, + uint8_t ms_class, uint8_t single_slot) +{ + struct gprs_rlcmac_tbf *tbf; + int rc; + +#ifdef DEBUG_DIAGRAM + /* hunt for first free number in diagram */ + int diagram_num; + for (diagram_num = 0; ; diagram_num++) { + llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { + if (tbf->diag == diagram_num) + goto next_diagram; + } + llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { + if (tbf->diag == diagram_num) + goto next_diagram; + } + break; +next_diagram: + continue; + } +#endif + + LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n"); + LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: TFI=%d TRX=%d " + "MS_CLASS=%d\n", (dir == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", + tfi, trx, ms_class); + + if (trx >= 8 || tfi >= 32) + return NULL; + + tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_tbf); + if (!tbf) + return NULL; + +#ifdef DEBUG_DIAGRAM + tbf->diag = diagram_num; +#endif + tbf->direction = dir; + tbf->tfi = tfi; + tbf->trx = trx; + tbf->arfcn = bts->trx[trx].arfcn; + tbf->ms_class = ms_class; + tbf->ws = 64; + tbf->sns = 128; + /* select algorithm */ + rc = bts->alloc_algorithm(bts, old_tbf, tbf, bts->alloc_algorithm_curst, + single_slot); + /* if no ressource */ + if (rc < 0) { + talloc_free(tbf); + return NULL; + } + /* assign control ts */ + tbf->control_ts = 0xff; + rc = tbf_assign_control_ts(tbf); + /* if no ressource */ + if (rc < 0) { + talloc_free(tbf); + return NULL; + } + + /* set timestamp */ + gettimeofday(&tbf->meas.dl_bw_tv, NULL); + gettimeofday(&tbf->meas.rssi_tv, NULL); + gettimeofday(&tbf->meas.dl_loss_tv, NULL); + + INIT_LLIST_HEAD(&tbf->llc_queue); + if (dir == GPRS_RLCMAC_UL_TBF) + llist_add(&tbf->list, &gprs_rlcmac_ul_tbfs); + else + llist_add(&tbf->list, &gprs_rlcmac_dl_tbfs); + + debug_diagram(tbf->diag, "+-----------------+"); + debug_diagram(tbf->diag, "|NEW %s TBF TFI=%2d|", + (dir == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tfi); + debug_diagram(tbf->diag, "+-----------------+"); + + return tbf; +} + +void tbf_timer_cb(void *_tbf) +{ + struct gprs_rlcmac_tbf *tbf = (struct gprs_rlcmac_tbf *)_tbf; + + LOGP(DRLCMAC, LOGL_DEBUG, "%s TBF=%d timer %u expired.\n", + (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, + tbf->T); + + tbf->num_T_exp++; + + switch (tbf->T) { +#ifdef DEBUG_DL_ASS_IDLE + case 1234: + gprs_rlcmac_trigger_downlink_assignment(tbf, NULL, debug_imsi); + break; +#endif + case 0: /* assignment */ + if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) { + if (tbf->state == GPRS_RLCMAC_ASSIGN) { + LOGP(DRLCMAC, LOGL_NOTICE, "Releasing due to " + "PACCH assignment timeout.\n"); + tbf_free(tbf); + } else + LOGP(DRLCMAC, LOGL_ERROR, "Error: TBF is not " + "in assign state\n"); + } + if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) { + /* change state to FLOW, so scheduler will start transmission */ + tbf->dir.dl.wait_confirm = 0; + if (tbf->state == GPRS_RLCMAC_ASSIGN) { + tbf_new_state(tbf, GPRS_RLCMAC_FLOW); + tbf_assign_control_ts(tbf); + } else + LOGP(DRLCMAC, LOGL_NOTICE, "Continue flow after " + "IMM.ASS confirm\n"); + } + break; + case 3169: + case 3191: + case 3195: + LOGP(DRLCMAC, LOGL_NOTICE, "TBF T%d timeout during " + "transsmission\n", tbf->T); + tbf->rlcmac_diag(); + /* fall through */ + case 3193: + if (tbf->T == 3193) + debug_diagram(tbf->diag, "T3193 timeout"); + LOGP(DRLCMAC, LOGL_DEBUG, "TBF will be freed due to timeout\n"); + /* free TBF */ + tbf_free(tbf); + break; + default: + LOGP(DRLCMAC, LOGL_ERROR, "Timer expired in unknown mode: %u\n", + tbf->T); + } +} + +int gprs_rlcmac_tbf::rlcmac_diag() +{ + if ((state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) + LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on CCCH\n"); + if ((state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) + LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on PACCH\n"); + if ((state_flags & (1 << GPRS_RLCMAC_FLAG_UL_DATA))) + LOGP(DRLCMAC, LOGL_NOTICE, "- Uplink data was received\n"); + else if (direction == GPRS_RLCMAC_UL_TBF) + LOGP(DRLCMAC, LOGL_NOTICE, "- No uplink data received yet\n"); + if ((state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK))) + LOGP(DRLCMAC, LOGL_NOTICE, "- Downlink ACK was received\n"); + else if (direction == GPRS_RLCMAC_DL_TBF) + LOGP(DRLCMAC, LOGL_NOTICE, "- No downlink ACK received yet\n"); + + return 0; +} + void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_trx *trx) { for (uint8_t tfi = 0; tfi < 32; tfi++) { diff --git a/src/tbf.h b/src/tbf.h index 74df237..d2aead2 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -91,6 +91,7 @@ struct gprs_rlcmac_tbf { static void free_all(struct gprs_rlcmac_trx *trx); static void free_all(struct gprs_rlcmac_pdch *pdch);
+ int rlcmac_diag();
struct llist_head list; enum gprs_rlcmac_tbf_state state; @@ -229,3 +230,5 @@ void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T,
void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf);
+void tbf_timer_cb(void *_tbf); +
From: Holger Hans Peter Freyther holger@moiji-mobile.com
There really shouldn't be too many callers of state. Instead the tbf should dispatch depending on the internal state. For now introduce state_is and state_is_not accessor functions so we can start to see who is using the internal state. --- src/gprs_rlcmac_data.cpp | 18 +++++++++--------- src/gprs_rlcmac_sched.cpp | 6 +++--- src/tbf.cpp | 18 +++++++++--------- src/tbf.h | 24 +++++++++++++++++++++++- 4 files changed, 44 insertions(+), 22 deletions(-)
diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp index b5ea7c9..17c4b1b 100644 --- a/src/gprs_rlcmac_data.cpp +++ b/src/gprs_rlcmac_data.cpp @@ -98,7 +98,7 @@ int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_tbf *tbf) } tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE; debug_diagram(tbf->diag, "timeout UL-ACK"); - if (tbf->state == GPRS_RLCMAC_FINISHED) { + if (tbf->state_is(GPRS_RLCMAC_FINISHED)) { struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
tbf->dir.ul.n3103++; @@ -687,7 +687,7 @@ static int gprs_rlcmac_assemble_llc(struct gprs_rlcmac_tbf *tbf, uint8_t *data, struct msgb *gprs_rlcmac_send_uplink_ack(struct gprs_rlcmac_tbf *tbf, uint32_t fn) { - int final = (tbf->state == GPRS_RLCMAC_FINISHED); + int final = (tbf->state_is(GPRS_RLCMAC_FINISHED)); struct msgb *msg;
if (final) { @@ -899,7 +899,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t trx, uint8_t ts, }
/* Check CV of last frame in buffer */ - if (tbf->state == GPRS_RLCMAC_FLOW /* still in flow state */ + if (tbf->state_is(GPRS_RLCMAC_FLOW) /* still in flow state */ && tbf->dir.ul.v_q == tbf->dir.ul.v_r) { /* if complete */ struct rlc_ul_header *last_rh = (struct rlc_ul_header *) tbf->rlc_block[(tbf->dir.ul.v_r - 1) & mod_sns_half]; @@ -917,7 +917,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t trx, uint8_t ts,
/* If TLLI is included or if we received half of the window, we send * an ack/nack */ - if (rh->si || rh->ti || tbf->state == GPRS_RLCMAC_FINISHED + if (rh->si || rh->ti || tbf->state_is(GPRS_RLCMAC_FINISHED) || (tbf->dir.ul.rx_counter % SEND_ACK_AFTER_FRAMES) == 0) { if (rh->si) { LOGP(DRLCMACUL, LOGL_NOTICE, "- Scheduling Ack/Nack, " @@ -927,7 +927,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t trx, uint8_t ts, LOGP(DRLCMACUL, LOGL_DEBUG, "- Scheduling Ack/Nack, " "because TLLI is included.\n"); } - if (tbf->state == GPRS_RLCMAC_FINISHED) { + if (tbf->state_is(GPRS_RLCMAC_FINISHED)) { LOGP(DRLCMACUL, LOGL_DEBUG, "- Scheduling Ack/Nack, " "because last block has CV==0.\n"); } @@ -942,7 +942,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t trx, uint8_t ts, debug_diagram(tbf->diag, "sched UL-ACK stall"); if (rh->ti) debug_diagram(tbf->diag, "sched UL-ACK TLLI"); - if (tbf->state == GPRS_RLCMAC_FINISHED) + if (tbf->state_is(GPRS_RLCMAC_FINISHED)) debug_diagram(tbf->diag, "sched UL-ACK CV==0"); if ((tbf->dir.ul.rx_counter % SEND_ACK_AFTER_FRAMES) == 0) debug_diagram(tbf->diag, "sched UL-ACK n=%d", @@ -1200,11 +1200,11 @@ do_resend:
/* if the window has stalled, or transfer is complete, * send an unacknowledged block */ - if (tbf->state == GPRS_RLCMAC_FINISHED + if (tbf->state_is(GPRS_RLCMAC_FINISHED) || ((tbf->dir.dl.v_s - tbf->dir.dl.v_a) & mod_sns) == tbf->ws) { int resend = 0;
- if (tbf->state == GPRS_RLCMAC_FINISHED) + if (tbf->state_is(GPRS_RLCMAC_FINISHED)) LOGP(DRLCMACDL, LOGL_DEBUG, "- Restarting at BSN %d, " "because all blocks have been transmitted.\n", tbf->dir.dl.v_a); @@ -1568,7 +1568,7 @@ int gprs_rlcmac_downlink_ack(struct gprs_rlcmac_tbf *tbf, uint8_t final, "X=Resend-Unacked\n", tbf->dir.dl.v_a, show_v_b, (tbf->dir.dl.v_s - 1) & mod_sns);
- if (tbf->state == GPRS_RLCMAC_FINISHED + if (tbf->state_is(GPRS_RLCMAC_FINISHED) && tbf->dir.dl.v_s == tbf->dir.dl.v_a) { LOGP(DRLCMACDL, LOGL_NOTICE, "Received acknowledge of " "all blocks, but without final ack " diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index f3edaac..476d781 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -103,7 +103,7 @@ uint8_t sched_select_uplink(uint8_t trx, uint8_t ts, uint32_t fn, /* we don't need to give resources in FINISHED state, * because we have received all blocks and only poll * for packet control ack. */ - if (tbf->state != GPRS_RLCMAC_FLOW) + if (tbf->state_is_not(GPRS_RLCMAC_FLOW)) continue;
/* use this USF */ @@ -182,8 +182,8 @@ struct msgb *sched_select_downlink(uint8_t trx, uint8_t ts, uint32_t fn, if (tbf->direction != GPRS_RLCMAC_DL_TBF) continue; /* no DL resources needed, go next */ - if (tbf->state != GPRS_RLCMAC_FLOW - && tbf->state != GPRS_RLCMAC_FINISHED) + if (tbf->state_is_not(GPRS_RLCMAC_FLOW) + && tbf->state_is_not(GPRS_RLCMAC_FINISHED)) continue;
/* waiting for CCCH IMM.ASS confirm */ diff --git a/src/tbf.cpp b/src/tbf.cpp index 918520c..547612f 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -59,7 +59,7 @@ static int tbf_append_data(struct gprs_rlcmac_tbf *tbf, const uint8_t *data, const uint16_t len) { LOGP(DRLCMAC, LOGL_INFO, "TBF: APPEND TFI: %u TLLI: 0x%08x\n", tbf->tfi, tbf->tlli); - if (tbf->state == GPRS_RLCMAC_WAIT_RELEASE) { + if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE)) { LOGP(DRLCMAC, LOGL_DEBUG, "TBF in WAIT RELEASE state " "(T3193), so reuse TBF\n"); memcpy(tbf->llc_frame, data, len); @@ -357,7 +357,7 @@ void tbf_new_state(struct gprs_rlcmac_tbf *tbf, LOGP(DRLCMAC, LOGL_DEBUG, "%s TBF=%d changes state from %s to %s\n", (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, tbf_state_name[tbf->state], tbf_state_name[state]); - tbf->state = state; + tbf->set_state(state); }
void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T, @@ -409,7 +409,7 @@ struct gprs_rlcmac_tbf *tbf_by_tfi(struct gprs_rlcmac_bts *bts, if (!tbf) return NULL;
- if (tbf->state != GPRS_RLCMAC_RELEASING) + if (tbf->state_is_not(GPRS_RLCMAC_RELEASING)) return tbf;
return NULL; @@ -422,13 +422,13 @@ struct gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli, struct gprs_rlcmac_tbf *tbf; if (dir == GPRS_RLCMAC_UL_TBF) { llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { - if (tbf->state != GPRS_RLCMAC_RELEASING + if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) && tbf->tlli == tlli && tbf->tlli_valid) return tbf; } } else { llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { - if (tbf->state != GPRS_RLCMAC_RELEASING + if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) && tbf->tlli == tlli) return tbf; } @@ -443,14 +443,14 @@ struct gprs_rlcmac_tbf *tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) /* only one TBF can poll on specific TS/FN, because scheduler can only * schedule one downlink control block (with polling) at a FN per TS */ llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { - if (tbf->state != GPRS_RLCMAC_RELEASING + if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED && tbf->poll_fn == fn && tbf->trx == trx && tbf->control_ts == ts) return tbf; } llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { - if (tbf->state != GPRS_RLCMAC_RELEASING + if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED && tbf->poll_fn == fn && tbf->trx == trx && tbf->control_ts == ts) @@ -561,7 +561,7 @@ void tbf_timer_cb(void *_tbf) #endif case 0: /* assignment */ if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) { - if (tbf->state == GPRS_RLCMAC_ASSIGN) { + if (tbf->state_is(GPRS_RLCMAC_ASSIGN)) { LOGP(DRLCMAC, LOGL_NOTICE, "Releasing due to " "PACCH assignment timeout.\n"); tbf_free(tbf); @@ -572,7 +572,7 @@ void tbf_timer_cb(void *_tbf) if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) { /* change state to FLOW, so scheduler will start transmission */ tbf->dir.dl.wait_confirm = 0; - if (tbf->state == GPRS_RLCMAC_ASSIGN) { + if (tbf->state_is(GPRS_RLCMAC_ASSIGN)) { tbf_new_state(tbf, GPRS_RLCMAC_FLOW); tbf_assign_control_ts(tbf); } else diff --git a/src/tbf.h b/src/tbf.h index d2aead2..84d558e 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -91,10 +91,13 @@ struct gprs_rlcmac_tbf { static void free_all(struct gprs_rlcmac_trx *trx); static void free_all(struct gprs_rlcmac_pdch *pdch);
+ bool state_is(enum gprs_rlcmac_tbf_state rhs) const; + bool state_is_not(enum gprs_rlcmac_tbf_state rhs) const; + void set_state(enum gprs_rlcmac_tbf_state new_state); + int rlcmac_diag();
struct llist_head list; - enum gprs_rlcmac_tbf_state state; uint32_t state_flags; enum gprs_rlcmac_tbf_direction direction; uint8_t tfi; @@ -187,6 +190,10 @@ struct gprs_rlcmac_tbf { int diag; /* number where TBF is presented in diagram */ int diag_new; /* used to format output of new TBF */ #endif + + /* these should become protected but only after gprs_rlcmac_data.c + * stops to iterate over all tbf in its current form */ + enum gprs_rlcmac_tbf_state state; };
@@ -232,3 +239,18 @@ void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf);
void tbf_timer_cb(void *_tbf);
+ +inline bool gprs_rlcmac_tbf::state_is(enum gprs_rlcmac_tbf_state rhs) const +{ + return state == rhs; +} + +inline bool gprs_rlcmac_tbf::state_is_not(enum gprs_rlcmac_tbf_state rhs) const +{ + return state != rhs; +} + +inline void gprs_rlcmac_tbf::set_state(enum gprs_rlcmac_tbf_state new_state) +{ + state = new_state; +}
osmocom-net-gprs@lists.osmocom.org