Unify BTS into a C usable structure

Previous work on BTS class started to get stuff out of the C++ struct
 into a C struct (BTS -> struct gprs_glcmac_bts) so that some parts of
it were accessible from C code. Doing so, however, ended up being messy
too, since all code needs to be switching from one object to another,
which actually refer to the same logical component.

Let's instead rejoin the structures and make sure the struct is
accessible and usable from both C and C++ code by rewriting all methods
to be C compatible and converting 3 allocated suboject as pointers.
This way BTS can internally still use those C++ objects while providing
a clean APi to both C and C++ code.

Change-Id: I7d12c896c5ded659ca9d3bff4cf3a3fc857db9dd
This commit is contained in:
Pau Espin 2021-01-14 16:48:38 +01:00
parent 793583ea21
commit 2182e627cd
41 changed files with 1048 additions and 1194 deletions

View File

@ -31,6 +31,8 @@
#include <gprs_debug.h>
#include <cxx_linuxlist.h>
#include <pdch.h>
#include <gprs_ms_storage.h>
#include <sba.h>
extern "C" {
#include <osmocom/core/talloc.h>
@ -190,9 +192,20 @@ static const struct osmo_stat_item_group_desc bts_statg_desc = {
bts_stat_item_description,
};
static void bts_init(struct gprs_rlcmac_bts *bts, BTS* bts_obj)
static void bts_init(struct gprs_rlcmac_bts *bts, struct gprs_pcu *pcu)
{
memset(bts, 0, sizeof(*bts));
bts->pcu = pcu;
bts->pollController = new PollController(*bts);
bts->sba = new SBAController(*bts);
bts->ms_store = new GprsMsStorage(bts);
bts->cur_fn = 0;
bts->cur_blk_fn = -1;
bts->max_cs_dl = MAX_GPRS_CS;
bts->max_cs_ul = MAX_GPRS_CS;
bts->max_mcs_dl = MAX_EDGE_MCS;
bts->max_mcs_ul = MAX_EDGE_MCS;
bts->initial_cs_dl = bts->initial_cs_ul = 1;
bts->initial_mcs_dl = bts->initial_mcs_ul = 1;
bts->cs_mask = 1 << 0; /* CS-1 always enabled by default */
@ -202,15 +215,17 @@ static void bts_init(struct gprs_rlcmac_bts *bts, BTS* bts_obj)
bts->si13_is_set = false;
bts->app_info = NULL;
bts->bts = bts_obj;
bts->T_defs_bts = T_defs_bts;
osmo_tdefs_reset(bts->T_defs_bts);
INIT_LLIST_HEAD(&bts->ul_tbfs);
INIT_LLIST_HEAD(&bts->dl_tbfs);
/* initialize back pointers */
for (size_t trx_no = 0; trx_no < ARRAY_SIZE(bts->trx); ++trx_no) {
struct gprs_rlcmac_trx *trx = &bts->trx[trx_no];
trx->trx_no = trx_no;
trx->bts = bts_obj;
trx->bts = bts;
for (size_t ts_no = 0; ts_no < ARRAY_SIZE(trx->pdch); ++ts_no) {
struct gprs_rlcmac_pdch *pdch = &trx->pdch[ts_no];
@ -219,89 +234,57 @@ static void bts_init(struct gprs_rlcmac_bts *bts, BTS* bts_obj)
pdch->trx = trx;
}
}
}
BTS* BTS::main_bts()
{
return the_pcu->bts;
}
struct gprs_rlcmac_bts *BTS::bts_data()
{
return &m_bts;
}
struct gprs_rlcmac_bts *bts_main_data()
{
return BTS::main_bts()->bts_data();
}
void bts_cleanup()
{
return BTS::main_bts()->cleanup();
}
struct rate_ctr_group *bts_main_data_stats()
{
return BTS::main_bts()->rate_counters();
}
BTS::BTS(struct gprs_pcu *pcu)
: pcu(pcu)
, m_cur_fn(0)
, m_cur_blk_fn(-1)
, m_max_cs_dl(MAX_GPRS_CS)
, m_max_cs_ul(MAX_GPRS_CS)
, m_max_mcs_dl(MAX_EDGE_MCS)
, m_max_mcs_ul(MAX_EDGE_MCS)
, m_pollController(*this)
, m_sba(*this)
, m_ms_store(this)
{
bts_init(&m_bts, this);
/* The static allocator might have already registered the counter group.
If this happens and we still called explicitly (in tests/ for example)
than just allocate the group with different index.
This shall be removed once weget rid of BTS singleton */
if (rate_ctr_get_group_by_name_idx(bts_ctrg_desc.group_name_prefix, 0))
m_ratectrs = rate_ctr_group_alloc(tall_pcu_ctx, &bts_ctrg_desc, 1);
bts->ratectrs = rate_ctr_group_alloc(tall_pcu_ctx, &bts_ctrg_desc, 1);
else
m_ratectrs = rate_ctr_group_alloc(tall_pcu_ctx, &bts_ctrg_desc, 0);
OSMO_ASSERT(m_ratectrs);
bts->ratectrs = rate_ctr_group_alloc(tall_pcu_ctx, &bts_ctrg_desc, 0);
OSMO_ASSERT(bts->ratectrs);
m_statg = osmo_stat_item_group_alloc(tall_pcu_ctx, &bts_statg_desc, 0);
OSMO_ASSERT(m_statg);
bts->statg = osmo_stat_item_group_alloc(tall_pcu_ctx, &bts_statg_desc, 0);
OSMO_ASSERT(bts->statg);
}
void BTS::cleanup()
struct gprs_rlcmac_bts *bts_main_data()
{
return the_pcu->bts;
}
struct rate_ctr_group *bts_main_data_stats()
{
return bts_rate_counters(the_pcu->bts);
}
static void bts_cleanup(gprs_rlcmac_bts *bts)
{
/* this can cause counter updates and must not be left to the
* m_ms_store's destructor */
m_ms_store.cleanup();
bts->ms_store->cleanup();
delete bts->ms_store;
delete bts->sba;
delete bts->pollController;
if (m_ratectrs) {
rate_ctr_group_free(m_ratectrs);
m_ratectrs = NULL;
if (bts->ratectrs) {
rate_ctr_group_free(bts->ratectrs);
bts->ratectrs = NULL;
}
if (m_statg) {
osmo_stat_item_group_free(m_statg);
m_statg = NULL;
if (bts->statg) {
osmo_stat_item_group_free(bts->statg);
bts->statg = NULL;
}
if (m_bts.app_info) {
msgb_free(m_bts.app_info);
m_bts.app_info = NULL;
if (bts->app_info) {
msgb_free(bts->app_info);
bts->app_info = NULL;
}
}
BTS::~BTS()
{
cleanup();
}
void BTS::set_current_frame_number(int fn)
void bts_set_current_frame_number(struct gprs_rlcmac_bts *bts, int fn)
{
/* The UL frame numbers lag 3 behind the DL frames and the data
* indication is only sent after all 4 frames of the block have been
@ -314,8 +297,8 @@ void BTS::set_current_frame_number(int fn)
* Values up to 50 frames have been observed under load. */
const static int max_delay = 60;
m_cur_fn = fn;
m_pollController.expireTimedout(m_cur_fn, max_delay);
bts->cur_fn = fn;
bts->pollController->expireTimedout(bts->cur_fn, max_delay);
}
static inline int delta_fn(int fn, int to)
@ -323,7 +306,7 @@ static inline int delta_fn(int fn, int to)
return (fn + GSM_MAX_FN * 3 / 2 - to) % GSM_MAX_FN - GSM_MAX_FN/2;
}
void BTS::set_current_block_frame_number(int fn, unsigned max_delay)
void bts_set_current_block_frame_number(struct gprs_rlcmac_bts *bts, int fn, unsigned max_delay)
{
int delay = 0;
const int late_block_delay_thresh = 13;
@ -332,41 +315,41 @@ void BTS::set_current_block_frame_number(int fn, unsigned max_delay)
/* frame numbers in the received blocks are assumed to be strongly
* monotonic. */
if (m_cur_blk_fn >= 0) {
int delta = delta_fn(fn, m_cur_blk_fn);
if (bts->cur_blk_fn >= 0) {
int delta = delta_fn(fn, bts->cur_blk_fn);
if (delta <= 0)
return;
}
/* Check block delay vs. the current frame number */
if (current_frame_number() != 0)
delay = delta_fn(fn, current_frame_number());
if (bts_current_frame_number(bts) != 0)
delay = delta_fn(fn, bts_current_frame_number(bts));
if (delay <= -late_block_delay_thresh) {
LOGP(DRLCMAC, LOGL_NOTICE,
"Late RLC block, FN delta: %d FN: %d curFN: %d\n",
delay, fn, current_frame_number());
do_rate_ctr_inc(CTR_RLC_LATE_BLOCK);
delay, fn, bts_current_frame_number(bts));
bts_do_rate_ctr_inc(bts, CTR_RLC_LATE_BLOCK);
}
m_cur_blk_fn = fn;
bts->cur_blk_fn = fn;
if (delay < fn_update_ok_min_delay || delay > fn_update_ok_max_delay ||
current_frame_number() == 0)
m_cur_fn = fn;
bts_current_frame_number(bts) == 0)
bts->cur_fn = fn;
m_pollController.expireTimedout(fn, max_delay);
bts->pollController->expireTimedout(fn, max_delay);
}
int BTS::add_paging(uint8_t chan_needed, const struct osmo_mobile_identity *mi)
int bts_add_paging(struct gprs_rlcmac_bts *bts, uint8_t chan_needed, const struct osmo_mobile_identity *mi)
{
uint8_t l, trx, ts, any_tbf = 0;
struct gprs_rlcmac_tbf *tbf;
LListHead<gprs_rlcmac_tbf> *pos;
struct llist_item *pos;
uint8_t slot_mask[8];
int8_t first_ts; /* must be signed */
LListHead<gprs_rlcmac_tbf> *tbfs_lists[] = {
&m_ul_tbfs,
&m_dl_tbfs,
struct llist_head *tbfs_lists[] = {
&bts->ul_tbfs,
&bts->dl_tbfs,
NULL
};
@ -382,8 +365,8 @@ int BTS::add_paging(uint8_t chan_needed, const struct osmo_mobile_identity *mi)
* Don't mark, if TBF uses a different slot that is already marked. */
memset(slot_mask, 0, sizeof(slot_mask));
for (l = 0; tbfs_lists[l]; l++) {
llist_for_each(pos, tbfs_lists[l]) {
tbf = pos->entry();
llist_for_each_entry(pos, tbfs_lists[l], list) {
tbf = (struct gprs_rlcmac_tbf *)pos->entry;
first_ts = -1;
for (ts = 0; ts < 8; ts++) {
if (tbf->pdch[ts]) {
@ -418,7 +401,7 @@ int BTS::add_paging(uint8_t chan_needed, const struct osmo_mobile_identity *mi)
for (ts = 0; ts < 8; ts++) {
if ((slot_mask[trx] & (1 << ts))) {
/* schedule */
if (!m_bts.trx[trx].pdch[ts].add_paging(chan_needed, mi))
if (!bts->trx[trx].pdch[ts].add_paging(chan_needed, mi))
return -ENOMEM;
LOGP(DRLCMAC, LOGL_INFO, "Paging on PACCH of TRX=%d TS=%d\n", trx, ts);
@ -433,7 +416,8 @@ int BTS::add_paging(uint8_t chan_needed, const struct osmo_mobile_identity *mi)
return 0;
}
void BTS::send_gsmtap_rach(enum pcu_gsmtap_category categ, uint8_t channel,
void bts_send_gsmtap_rach(struct gprs_rlcmac_bts *bts,
enum pcu_gsmtap_category categ, uint8_t channel,
const struct rach_ind_params *rip)
{
struct pcu_l1_meas meas = { 0 };
@ -450,37 +434,39 @@ void BTS::send_gsmtap_rach(enum pcu_gsmtap_category categ, uint8_t channel,
ra_buf[0] = (uint8_t) (rip->ra & 0xff);
}
send_gsmtap_meas(categ, true, rip->trx_nr, rip->ts_nr, channel,
rfn_to_fn(rip->rfn), ra_buf,
bts_send_gsmtap_meas(bts, categ, true, rip->trx_nr, rip->ts_nr, channel,
bts_rfn_to_fn(bts, rip->rfn), ra_buf,
rip->is_11bit ? 2 : 1, &meas);
}
void BTS::send_gsmtap(enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no,
void bts_send_gsmtap(struct gprs_rlcmac_bts *bts,
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 = { 0 };
send_gsmtap_meas(categ, uplink, trx_no, ts_no, channel, fn, data, len, &meas);
bts_send_gsmtap_meas(bts, categ, uplink, trx_no, ts_no, channel, fn, data, len, &meas);
}
void BTS::send_gsmtap_meas(enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no,
void bts_send_gsmtap_meas(struct gprs_rlcmac_bts *bts,
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)
{
uint16_t arfcn;
/* check if category is activated at all */
if (!(pcu->gsmtap_categ_mask & (1 << categ)))
if (!(bts->pcu->gsmtap_categ_mask & (1 << categ)))
return;
arfcn = m_bts.trx[trx_no].arfcn;
arfcn = bts->trx[trx_no].arfcn;
if (uplink)
arfcn |= GSMTAP_ARFCN_F_UPLINK;
/* GSMTAP needs the SNR here, but we only have C/I (meas->link_qual).
Those are not the same, but there is no known way to convert them,
let's pass C/I instead of nothing */
gsmtap_send(pcu->gsmtap, arfcn, ts_no, channel, 0, fn,
gsmtap_send(bts->pcu->gsmtap, arfcn, ts_no, channel, 0, fn,
meas->rssi, meas->link_qual, data, len);
}
@ -493,48 +479,52 @@ static inline bool tbf_check(gprs_rlcmac_tbf *tbf, uint32_t fn, uint8_t trx_no,
return false;
}
gprs_rlcmac_dl_tbf *BTS::dl_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts)
struct gprs_rlcmac_dl_tbf *bts_dl_tbf_by_poll_fn(struct gprs_rlcmac_bts *bts, uint32_t fn, uint8_t trx, uint8_t ts)
{
LListHead<gprs_rlcmac_tbf> *pos;
struct llist_item *pos;
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(pos, &m_dl_tbfs) {
if (tbf_check(pos->entry(), fn, trx, ts))
return as_dl_tbf(pos->entry());
llist_for_each_entry(pos, &bts->dl_tbfs, list) {
tbf = (struct gprs_rlcmac_tbf *)pos->entry;
if (tbf_check(tbf, fn, trx, ts))
return as_dl_tbf(tbf);
}
return NULL;
}
gprs_rlcmac_ul_tbf *BTS::ul_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts)
struct gprs_rlcmac_ul_tbf *bts_ul_tbf_by_poll_fn(struct gprs_rlcmac_bts *bts, uint32_t fn, uint8_t trx, uint8_t ts)
{
LListHead<gprs_rlcmac_tbf> *pos;
struct llist_item *pos;
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(pos, &m_ul_tbfs) {
if (tbf_check(pos->entry(), fn, trx, ts))
return as_ul_tbf(pos->entry());
llist_for_each_entry(pos, &bts->ul_tbfs, list) {
tbf = (struct gprs_rlcmac_tbf *)pos->entry;
if (tbf_check(tbf, fn, trx, ts))
return as_ul_tbf(tbf);
}
return NULL;
}
/* lookup downlink TBF Entity (by TFI) */
gprs_rlcmac_dl_tbf *BTS::dl_tbf_by_tfi(uint8_t tfi, uint8_t trx, uint8_t ts)
struct gprs_rlcmac_dl_tbf *bts_dl_tbf_by_tfi(struct gprs_rlcmac_bts *bts, uint8_t tfi, uint8_t trx, uint8_t ts)
{
if (trx >= 8 || ts >= 8)
return NULL;
return m_bts.trx[trx].pdch[ts].dl_tbf_by_tfi(tfi);
return bts->trx[trx].pdch[ts].dl_tbf_by_tfi(tfi);
}
/* lookup uplink TBF Entity (by TFI) */
gprs_rlcmac_ul_tbf *BTS::ul_tbf_by_tfi(uint8_t tfi, uint8_t trx, uint8_t ts)
struct gprs_rlcmac_ul_tbf *bts_ul_tbf_by_tfi(struct gprs_rlcmac_bts *bts, uint8_t tfi, uint8_t trx, uint8_t ts)
{
if (trx >= 8 || ts >= 8)
return NULL;
return m_bts.trx[trx].pdch[ts].ul_tbf_by_tfi(tfi);
return bts->trx[trx].pdch[ts].ul_tbf_by_tfi(tfi);
}
static unsigned int trx_count_free_tfi(const struct gprs_rlcmac_trx *trx, enum gprs_rlcmac_tbf_direction dir, uint8_t *first_free_tfi)
@ -576,7 +566,8 @@ static unsigned int trx_count_free_tfi(const struct gprs_rlcmac_trx *trx, enum g
* that is currently not used in any PDCH of a the TRX with least TFIs currently
* assigned. Negative values indicate errors.
*/
int BTS::tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t use_trx) const
int bts_tfi_find_free(const struct gprs_rlcmac_bts *bts, enum gprs_rlcmac_tbf_direction dir,
uint8_t *_trx, int8_t use_trx)
{
uint8_t trx_from, trx_to, trx;
uint8_t best_trx_nr = 0xff;
@ -594,7 +585,7 @@ int BTS::tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t
for (trx = trx_from; trx <= trx_to; trx++) {
uint8_t tmp_first_tfi;
unsigned int tmp_cnt;
tmp_cnt = trx_count_free_tfi(&m_bts.trx[trx], dir, &tmp_first_tfi);
tmp_cnt = trx_count_free_tfi(&bts->trx[trx], dir, &tmp_first_tfi);
if (tmp_cnt > best_cnt) {
best_cnt = tmp_cnt;
best_first_tfi = tmp_first_tfi;
@ -615,7 +606,7 @@ int BTS::tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t
return best_first_tfi;
}
int BTS::rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn)
int bts_rcv_imm_ass_cnf(struct gprs_rlcmac_bts *bts, const uint8_t *data, uint32_t fn)
{
struct gprs_rlcmac_dl_tbf *dl_tbf = NULL;
uint8_t plen;
@ -640,7 +631,7 @@ int BTS::rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn)
tlli |= (*data++) << 4;
tlli |= (*data++) >> 4;
ms = ms_by_tlli(tlli);
ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
if (ms)
dl_tbf = ms_dl_tbf(ms);
if (!dl_tbf) {
@ -658,7 +649,7 @@ int BTS::rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn)
}
/* Determine the full frame number from a relative frame number */
uint32_t BTS::rfn_to_fn(int32_t rfn)
uint32_t bts_rfn_to_fn(const struct gprs_rlcmac_bts *bts, int32_t rfn)
{
int32_t m_cur_rfn;
int32_t fn;
@ -682,11 +673,11 @@ uint32_t BTS::rfn_to_fn(int32_t rfn)
/* Compute an internal relative frame number from the full internal
frame number */
m_cur_rfn = m_cur_fn % RFN_MODULUS;
m_cur_rfn = bts->cur_fn % RFN_MODULUS;
/* Compute a "rounded" version of the internal frame number, which
* exactly fits in the RFN_MODULUS raster */
fn_rounded = m_cur_fn - m_cur_rfn;
fn_rounded = bts->cur_fn - m_cur_rfn;
/* If the delta between the internal and the external relative frame
* number exceeds a certain limit, we need to assume that the incoming
@ -695,7 +686,7 @@ uint32_t BTS::rfn_to_fn(int32_t rfn)
if (abs(rfn - m_cur_rfn) > RFN_THRESHOLD) {
LOGP(DRLCMAC, LOGL_DEBUG,
"Race condition between rfn (%u) and m_cur_fn (%u) detected: rfn belongs to the previous modulus %u cycle, wrapping...\n",
rfn, m_cur_fn, RFN_MODULUS);
rfn, bts->cur_fn, RFN_MODULUS);
if (fn_rounded < RFN_MODULUS) {
LOGP(DRLCMAC, LOGL_DEBUG,
"Cornercase detected: wrapping crosses %u border\n",
@ -819,7 +810,7 @@ static int parse_rach_ind(const struct rach_ind_params *rip,
return 0;
}
int BTS::rcv_rach(const struct rach_ind_params *rip)
int bts_rcv_rach(struct gprs_rlcmac_bts *bts, const struct rach_ind_params *rip)
{
struct chan_req_params chan_req = { 0 };
struct gprs_rlcmac_ul_tbf *tbf = NULL;
@ -829,16 +820,16 @@ int BTS::rcv_rach(const struct rach_ind_params *rip)
uint8_t tsc = 0;
int plen, rc;
do_rate_ctr_inc(CTR_RACH_REQUESTS);
bts_do_rate_ctr_inc(bts, CTR_RACH_REQUESTS);
if (rip->is_11bit)
do_rate_ctr_inc(CTR_11BIT_RACH_REQUESTS);
bts_do_rate_ctr_inc(bts, CTR_11BIT_RACH_REQUESTS);
/* Determine full frame number */
uint32_t Fn = rfn_to_fn(rip->rfn);
uint32_t Fn = bts_rfn_to_fn(bts, rip->rfn);
uint8_t ta = qta2ta(rip->qta);
send_gsmtap_rach(PCU_GSMTAP_C_UL_RACH, GSMTAP_CHANNEL_RACH, rip);
bts_send_gsmtap_rach(bts, PCU_GSMTAP_C_UL_RACH, GSMTAP_CHANNEL_RACH, rip);
LOGP(DRLCMAC, LOGL_DEBUG, "MS requests Uplink resource on CCCH/RACH: "
"ra=0x%02x (%d bit) Fn=%u qta=%d\n", rip->ra,
@ -851,7 +842,7 @@ int BTS::rcv_rach(const struct rach_ind_params *rip)
if (chan_req.single_block)
LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block allocation\n");
else if (pcu->vty.force_two_phase) {
else if (bts->pcu->vty.force_two_phase) {
LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block allocation, "
"but we force two phase access\n");
chan_req.single_block = true;
@ -864,7 +855,7 @@ int BTS::rcv_rach(const struct rach_ind_params *rip)
/* Should we allocate a single block or an Uplink TBF? */
if (chan_req.single_block) {
rc = sba()->alloc(&trx_no, &ts_no, &sb_fn, ta);
rc = bts_sba(bts)->alloc(&trx_no, &ts_no, &sb_fn, ta);
if (rc < 0) {
LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource for "
"single block allocation: rc=%d\n", rc);
@ -872,12 +863,12 @@ int BTS::rcv_rach(const struct rach_ind_params *rip)
goto send_imm_ass_rej;
}
tsc = m_bts.trx[trx_no].pdch[ts_no].tsc;
tsc = bts->trx[trx_no].pdch[ts_no].tsc;
LOGP(DRLCMAC, LOGL_DEBUG, "Allocated a single block at "
"SBFn=%u TRX=%u TS=%u\n", sb_fn, trx_no, ts_no);
} else {
GprsMs *ms = ms_alloc(0, chan_req.egprs_mslot_class);
tbf = tbf_alloc_ul_tbf(&m_bts, ms, -1, true);
GprsMs *ms = bts_alloc_ms(bts, 0, chan_req.egprs_mslot_class);
tbf = tbf_alloc_ul_tbf(bts, ms, -1, true);
if (!tbf) {
LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource for Uplink TBF\n");
/* Send RR Immediate Assignment Reject */
@ -905,18 +896,18 @@ send_imm_ass_rej:
LOGP(DRLCMAC, LOGL_DEBUG, "Tx Immediate Assignment Reject on AGCH\n");
plen = Encoding::write_immediate_assignment_reject(
bv, rip->ra, Fn, rip->burst_type);
do_rate_ctr_inc(CTR_IMMEDIATE_ASSIGN_REJ);
bts_do_rate_ctr_inc(bts, CTR_IMMEDIATE_ASSIGN_REJ);
} else {
LOGP(DRLCMAC, LOGL_DEBUG, "Tx Immediate Assignment on AGCH: "
"TRX=%u (ARFCN %u) TS=%u TA=%u TSC=%u TFI=%d USF=%d\n",
trx_no, m_bts.trx[trx_no].arfcn & ~ARFCN_FLAG_MASK,
trx_no, bts->trx[trx_no].arfcn & ~ARFCN_FLAG_MASK,
ts_no, ta, tsc, tbf ? tbf->tfi() : -1, usf);
plen = Encoding::write_immediate_assignment(
&m_bts.trx[trx_no].pdch[ts_no], tbf, bv,
&bts->trx[trx_no].pdch[ts_no], tbf, bv,
false, rip->ra, Fn, ta, usf, false, sb_fn,
pcu->vty.alpha, pcu->vty.gamma, -1,
bts->pcu->vty.alpha, bts->pcu->vty.gamma, -1,
rip->burst_type);
do_rate_ctr_inc(CTR_IMMEDIATE_ASSIGN_UL_TBF);
bts_do_rate_ctr_inc(bts, CTR_IMMEDIATE_ASSIGN_UL_TBF);
}
if (plen >= 0)
@ -937,14 +928,13 @@ static uint32_t ptcch_slot_map[PTCCH_TAI_NUM] = {
324, 350, 376, 402,
};
int BTS::rcv_ptcch_rach(const struct rach_ind_params *rip)
int bts_rcv_ptcch_rach(struct gprs_rlcmac_bts *bts, const struct rach_ind_params *rip)
{
uint32_t fn416 = rfn_to_fn(rip->rfn) % 416;
struct gprs_rlcmac_bts *bts = bts_data();
uint32_t fn416 = bts_rfn_to_fn(bts, rip->rfn) % 416;
struct gprs_rlcmac_pdch *pdch;
uint8_t ss;
send_gsmtap_rach(PCU_GSMTAP_C_UL_PTCCH, GSMTAP_CHANNEL_PTCCH, rip);
bts_send_gsmtap_rach(bts, PCU_GSMTAP_C_UL_PTCCH, GSMTAP_CHANNEL_PTCCH, rip);
/* Prevent buffer overflow */
if (rip->trx_nr >= ARRAY_SIZE(bts->trx) || rip->ts_nr >= 8) {
@ -979,7 +969,7 @@ int BTS::rcv_ptcch_rach(const struct rach_ind_params *rip)
return 0;
}
void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup)
void bts_snd_dl_ass(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup)
{
uint8_t trx_no = tbf->trx->trx_no;
uint8_t ts_no = tbf->first_ts;
@ -992,14 +982,14 @@ void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup)
* so the assignment will not conflict with possible RACH requests. */
LOGP(DRLCMAC, LOGL_DEBUG, " - TRX=%d (%d) TS=%d TA=%d pollFN=%d\n",
trx_no, tbf->trx->arfcn, ts_no, tbf->ta(), poll ? tbf->poll_fn : -1);
plen = Encoding::write_immediate_assignment(&m_bts.trx[trx_no].pdch[ts_no],
plen = Encoding::write_immediate_assignment(&bts->trx[trx_no].pdch[ts_no],
tbf, immediate_assignment, true, 125,
(tbf->pdch[ts_no]->last_rts_fn + 21216) % GSM_MAX_FN,
tbf->ta(), 7, poll, tbf->poll_fn,
pcu->vty.alpha, pcu->vty.gamma, -1,
bts->pcu->vty.alpha, bts->pcu->vty.gamma, -1,
GSM_L1_BURST_TYPE_ACCESS_0);
if (plen >= 0) {
do_rate_ctr_inc(CTR_IMMEDIATE_ASSIGN_DL_TBF);
bts_do_rate_ctr_inc(bts, CTR_IMMEDIATE_ASSIGN_DL_TBF);
pcu_l1if_tx_pch(immediate_assignment, plen, pgroup);
}
@ -1007,70 +997,70 @@ void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup)
}
/* return maximum DL CS supported by BTS and allowed by VTY */
uint8_t BTS::max_cs_dl(void) const
uint8_t bts_max_cs_dl(const struct gprs_rlcmac_bts* bts)
{
return m_max_cs_dl;
return bts->max_cs_dl;
}
/* return maximum UL CS supported by BTS and allowed by VTY */
uint8_t BTS::max_cs_ul(void) const
uint8_t bts_max_cs_ul(const struct gprs_rlcmac_bts* bts)
{
return m_max_cs_ul;
return bts->max_cs_ul;
}
/* return maximum DL MCS supported by BTS and allowed by VTY */
uint8_t BTS::max_mcs_dl(void) const
uint8_t bts_max_mcs_dl(const struct gprs_rlcmac_bts* bts)
{
return m_max_mcs_dl;
return bts->max_mcs_dl;
}
/* return maximum UL MCS supported by BTS and allowed by VTY */
uint8_t BTS::max_mcs_ul(void) const
uint8_t bts_max_mcs_ul(const struct gprs_rlcmac_bts* bts)
{
return m_max_mcs_ul;
return bts->max_mcs_ul;
}
/* Set maximum DL CS supported by BTS and allowed by VTY */
void BTS::set_max_cs_dl(uint8_t cs_dl)
void bts_set_max_cs_dl(struct gprs_rlcmac_bts* bts, uint8_t cs_dl)
{
m_max_cs_dl = cs_dl;
bts->max_cs_dl = cs_dl;
}
/* Set maximum UL CS supported by BTS and allowed by VTY */
void BTS::set_max_cs_ul(uint8_t cs_ul)
void bts_set_max_cs_ul(struct gprs_rlcmac_bts* bts, uint8_t cs_ul)
{
m_max_cs_ul = cs_ul;
bts->max_cs_ul = cs_ul;
}
/* Set maximum DL MCS supported by BTS and allowed by VTY */
void BTS::set_max_mcs_dl(uint8_t mcs_dl)
void bts_set_max_mcs_dl(struct gprs_rlcmac_bts* bts, uint8_t mcs_dl)
{
m_max_mcs_dl = mcs_dl;
bts->max_mcs_dl = mcs_dl;
}
/* Set maximum UL MCS supported by BTS and allowed by VTY */
void BTS::set_max_mcs_ul(uint8_t mcs_ul)
void bts_set_max_mcs_ul(struct gprs_rlcmac_bts* bts, uint8_t mcs_ul)
{
m_max_mcs_ul = mcs_ul;
bts->max_mcs_ul = mcs_ul;
}
bool BTS::cs_dl_is_supported(CodingScheme cs)
bool bts_cs_dl_is_supported(const struct gprs_rlcmac_bts* bts, CodingScheme cs)
{
OSMO_ASSERT(mcs_is_valid(cs));
uint8_t num = mcs_chan_code(cs);
if (mcs_is_gprs(cs)) {
return (max_cs_dl() >= num) && (m_bts.cs_mask & (1U << num));
return (bts_max_cs_dl(bts) >= num) && (bts->cs_mask & (1U << num));
} else {
return (max_mcs_dl() >= num) && (m_bts.mcs_mask & (1U << num));
return (bts_max_mcs_dl(bts) >= num) && (bts->mcs_mask & (1U << num));
}
}
GprsMs *BTS::ms_alloc(uint8_t ms_class, uint8_t egprs_ms_class)
GprsMs *bts_alloc_ms(struct gprs_rlcmac_bts* bts, uint8_t ms_class, uint8_t egprs_ms_class)
{
GprsMs *ms;
ms = ms_store().create_ms();
ms = bts_ms_store(bts)->create_ms();
ms_set_timeout(ms, osmo_tdef_get(pcu->T_defs, -2030, OSMO_TDEF_S, -1));
ms_set_timeout(ms, osmo_tdef_get(bts->pcu->T_defs, -2030, OSMO_TDEF_S, -1));
ms_set_ms_class(ms, ms_class);
ms_set_egprs_ms_class(ms, egprs_ms_class);
@ -1078,23 +1068,38 @@ GprsMs *BTS::ms_alloc(uint8_t ms_class, uint8_t egprs_ms_class)
}
static int bts_talloc_destructor(struct BTS* bts)
static int bts_talloc_destructor(struct gprs_rlcmac_bts* bts)
{
bts->~BTS();
bts_cleanup(bts);
return 0;
}
struct BTS* bts_alloc(struct gprs_pcu *pcu)
struct gprs_rlcmac_bts* bts_alloc(struct gprs_pcu *pcu)
{
struct BTS* bts;
bts = talloc(pcu, struct BTS);
struct gprs_rlcmac_bts* bts;
bts = talloc_zero(pcu, struct gprs_rlcmac_bts);
if (!bts)
return bts;
talloc_set_destructor(bts, bts_talloc_destructor);
new (bts) BTS(pcu);
bts_init(bts, pcu);
return bts;
}
struct SBAController *bts_sba(struct gprs_rlcmac_bts *bts)
{
return bts->sba;
}
struct GprsMsStorage *bts_ms_store(struct gprs_rlcmac_bts *bts)
{
return bts->ms_store;
}
struct GprsMs *bts_ms_by_tlli(struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t old_tlli)
{
return bts_ms_store(bts)->get_ms(tlli, old_tlli);
}
/* update TA based on TA provided by PH-DATA-IND */
void update_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, int8_t ta_delta)
{
@ -1136,7 +1141,7 @@ void set_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, uint8_t ta)
void bts_update_tbf_ta(const char *p, uint32_t fn, uint8_t trx_no, uint8_t ts, int8_t ta, bool is_rach)
{
struct gprs_rlcmac_ul_tbf *tbf =
bts_main_data()->bts->ul_tbf_by_poll_fn(fn, trx_no, ts);
bts_ul_tbf_by_poll_fn(the_pcu->bts, fn, trx_no, ts);
if (!tbf)
LOGP(DL1IF, LOGL_DEBUG, "[%s] update TA = %u ignored due to "
"unknown UL TBF on TRX = %d, TS = %d, FN = %d\n",
@ -1182,7 +1187,7 @@ void bts_recalc_initial_cs(struct gprs_rlcmac_bts *bts)
return;
}
max_cs_dl = bts->bts->max_cs_dl();
max_cs_dl = bts_max_cs_dl(bts);
if (bts->pcuif_info_ind.initial_cs > max_cs_dl) {
LOGP(DL1IF, LOGL_DEBUG, " downgrading initial_cs_dl to %d\n", max_cs_dl);
bts->initial_cs_dl = max_cs_dl;
@ -1192,7 +1197,7 @@ void bts_recalc_initial_cs(struct gprs_rlcmac_bts *bts)
if (bts->initial_cs_dl == 0)
bts->initial_cs_dl = 1; /* CS1 Must always be supported */
max_cs_ul = bts->bts->max_cs_ul();
max_cs_ul = bts_max_cs_ul(bts);
if (bts->pcuif_info_ind.initial_cs > max_cs_ul) {
LOGP(DL1IF, LOGL_DEBUG, " downgrading initial_cs_ul to %d\n", max_cs_ul);
bts->initial_cs_ul = max_cs_ul;
@ -1212,14 +1217,14 @@ void bts_recalc_initial_mcs(struct gprs_rlcmac_bts *bts)
return;
}
max_mcs_dl = bts->bts->max_mcs_dl();
max_mcs_dl = bts_max_mcs_dl(bts);
if (bts->pcuif_info_ind.initial_mcs > max_mcs_dl) {
LOGP(DL1IF, LOGL_DEBUG, " downgrading initial_mcs_dl to %d\n", max_mcs_dl);
bts->initial_mcs_dl = max_mcs_dl;
} else {
bts->initial_mcs_dl = bts->pcuif_info_ind.initial_mcs;
}
max_mcs_ul = bts->bts->max_mcs_ul();
max_mcs_ul = bts_max_mcs_ul(bts);
if (bts->pcuif_info_ind.initial_mcs > max_mcs_ul) {
LOGP(DL1IF, LOGL_DEBUG, " downgrading initial_mcs_ul to %d\n", max_mcs_ul);
bts->initial_mcs_ul = max_mcs_ul;
@ -1232,7 +1237,7 @@ void bts_recalc_max_cs(struct gprs_rlcmac_bts *bts)
{
int i;
uint8_t cs_dl, cs_ul;
struct gprs_pcu *pcu = bts->bts->pcu;
struct gprs_pcu *pcu = bts->pcu;
cs_dl = 0;
for (i = pcu->vty.max_cs_dl - 1; i >= 0; i--) {
@ -1251,15 +1256,15 @@ void bts_recalc_max_cs(struct gprs_rlcmac_bts *bts)
}
LOGP(DRLCMAC, LOGL_DEBUG, "New max CS: DL=%u UL=%u\n", cs_dl, cs_ul);
bts->bts->set_max_cs_dl(cs_dl);
bts->bts->set_max_cs_ul(cs_ul);
bts_set_max_cs_dl(bts, cs_dl);
bts_set_max_cs_ul(bts, cs_ul);
}
void bts_recalc_max_mcs(struct gprs_rlcmac_bts *bts)
{
int i;
uint8_t mcs_dl, mcs_ul;
struct gprs_pcu *pcu = bts->bts->pcu;
struct gprs_pcu *pcu = bts->pcu;
mcs_dl = 0;
for (i = pcu->vty.max_mcs_dl - 1; i >= 0; i--) {
@ -1278,37 +1283,11 @@ void bts_recalc_max_mcs(struct gprs_rlcmac_bts *bts)
}
LOGP(DRLCMAC, LOGL_DEBUG, "New max MCS: DL=%u UL=%u\n", mcs_dl, mcs_ul);
bts->bts->set_max_mcs_dl(mcs_dl);
bts->bts->set_max_mcs_ul(mcs_ul);
bts_set_max_mcs_dl(bts, mcs_dl);
bts_set_max_mcs_ul(bts, mcs_ul);
}
struct gprs_rlcmac_bts *bts_data(struct BTS *bts)
struct GprsMs *bts_ms_by_imsi(struct gprs_rlcmac_bts *bts, const char *imsi)
{
return &bts->m_bts;
}
struct GprsMs *bts_ms_by_imsi(struct BTS *bts, const char *imsi)
{
return bts->ms_by_imsi(imsi);
}
uint8_t bts_max_cs_dl(const struct BTS *bts)
{
return bts->max_cs_dl();
}
uint8_t bts_max_cs_ul(const struct BTS *bts)
{
return bts->max_cs_ul();
}
uint8_t bts_max_mcs_dl(const struct BTS *bts)
{
return bts->max_mcs_dl();
}
uint8_t bts_max_mcs_ul(const struct BTS *bts)
{
return bts->max_mcs_ul();
return bts_ms_store(bts)->get_ms(0, 0, imsi);
}

338
src/bts.h
View File

@ -20,11 +20,13 @@
#pragma once
#include <pdch.h>
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stat_item.h>
@ -40,21 +42,11 @@ extern "C" {
}
#endif
#ifdef __cplusplus
#include "poll_controller.h"
#include "sba.h"
#include "tbf.h"
#include "gprs_ms_storage.h"
#include "coding_scheme.h"
#include <cxx_linuxlist.h>
#endif
#include <pdch.h>
#include <stdint.h>
#include <stdbool.h>
struct BTS;
struct GprsMs;
struct gprs_rlcmac_bts;
struct gprs_rlcmac_trx {
void *fl1h;
@ -62,11 +54,12 @@ struct gprs_rlcmac_trx {
struct gprs_rlcmac_pdch pdch[8];
/* back pointers */
struct BTS *bts;
struct gprs_rlcmac_bts *bts;
uint8_t trx_no;
};
#ifdef __cplusplus
extern "C" {
#endif
@ -78,48 +71,7 @@ void bts_update_tbf_ta(const char *p, uint32_t fn, uint8_t trx_no, uint8_t ts, i
}
#endif
/**
* 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.
*/
struct gprs_rlcmac_bts {
bool active;
uint8_t bsic;
uint8_t cs_mask; /* Allowed CS mask from BTS */
uint16_t mcs_mask; /* Allowed MCS mask from BTS */
struct { /* information stored from last received PCUIF info_ind message */
uint8_t initial_cs;
uint8_t initial_mcs;
} pcuif_info_ind;
uint8_t initial_cs_dl, initial_cs_ul;
uint8_t initial_mcs_dl, initial_mcs_ul;
/* Timer defintions */
struct osmo_tdef *T_defs_bts; /* timers controlled by BTS, received through PCUIF */
uint8_t n3101;
uint8_t n3103;
uint8_t n3105;
struct gprs_rlcmac_trx trx[8];
uint8_t si13[GSM_MACBLOCK_LEN];
bool si13_is_set;
/* State for dynamic algorithm selection */
int multislot_disabled;
/**
* Point back to the C++ object. This is used during the transition
* period.
*/
struct BTS *bts;
/* 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 */
/* main nsei */
struct gprs_ns2_nse *nse;
};
enum {
CTR_TBF_DL_ALLOCATED,
@ -230,176 +182,142 @@ struct chan_req_params {
bool single_block;
};
#ifdef __cplusplus
struct PollController;
struct SBAController;
struct GprsMsStorage;
struct pcu_l1_meas;
/**
* 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:
BTS(struct gprs_pcu *pcu);
~BTS();
void cleanup();
struct gprs_rlcmac_bts {
bool active;
uint8_t bsic;
uint8_t cs_mask; /* Allowed CS mask from BTS */
uint16_t mcs_mask; /* Allowed MCS mask from BTS */
struct { /* information stored from last received PCUIF info_ind message */
uint8_t initial_cs;
uint8_t initial_mcs;
} pcuif_info_ind;
uint8_t initial_cs_dl, initial_cs_ul;
uint8_t initial_mcs_dl, initial_mcs_ul;
/* Timer defintions */
struct osmo_tdef *T_defs_bts; /* timers controlled by BTS, received through PCUIF */
uint8_t n3101;
uint8_t n3103;
uint8_t n3105;
struct gprs_rlcmac_trx trx[8];
static BTS* main_bts();
uint8_t si13[GSM_MACBLOCK_LEN];
bool si13_is_set;
struct gprs_rlcmac_bts *bts_data();
SBAController *sba();
/* State for dynamic algorithm selection */
int multislot_disabled;
/** TODO: change the number to unsigned */
void set_current_frame_number(int frame_number);
void set_current_block_frame_number(int frame_number, unsigned max_delay);
int current_frame_number() const;
/* 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 */
/** add paging to paging queue(s) */
int add_paging(uint8_t chan_needed, const struct osmo_mobile_identity *mi);
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);
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);
int tfi_find_free(enum gprs_rlcmac_tbf_direction dir, uint8_t *_trx, int8_t use_trx) const;
int rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn);
uint32_t rfn_to_fn(int32_t rfn);
int rcv_rach(const struct rach_ind_params *rip);
int rcv_ptcch_rach(const struct rach_ind_params *rip);
void snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup);
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);
bool cs_dl_is_supported(CodingScheme cs);
GprsMsStorage &ms_store();
GprsMs *ms_by_tlli(uint32_t tlli, uint32_t old_tlli = GSM_RESERVED_TMSI);
GprsMs *ms_by_imsi(const char *imsi);
GprsMs *ms_alloc(uint8_t ms_class, uint8_t egprs_ms_class = 0);
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);
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);
void send_gsmtap_rach(enum pcu_gsmtap_category categ, uint8_t channel,
const struct rach_ind_params *rip);
/*
* Below for C interface for the VTY
*/
struct rate_ctr_group *rate_counters() const;
struct osmo_stat_item_group *stat_items() const;
void do_rate_ctr_inc(unsigned int ctr_id);
void do_rate_ctr_add(unsigned int ctr_id, int inc);
void stat_item_add(unsigned int stat_id, int inc);
LListHead<gprs_rlcmac_tbf>& ul_tbfs();
LListHead<gprs_rlcmac_tbf>& dl_tbfs();
struct gprs_rlcmac_bts m_bts;
/* main nsei */
struct gprs_ns2_nse *nse;
/* back pointer to PCU object */
struct gprs_pcu *pcu;
private:
int m_cur_fn;
int m_cur_blk_fn;
uint8_t m_max_cs_dl, m_max_cs_ul;
uint8_t m_max_mcs_dl, m_max_mcs_ul;
PollController m_pollController;
SBAController m_sba;
struct rate_ctr_group *m_ratectrs;
struct osmo_stat_item_group *m_statg;
int cur_fn;
int cur_blk_fn;
uint8_t max_cs_dl, max_cs_ul;
uint8_t max_mcs_dl, max_mcs_ul;
struct PollController *pollController;
struct SBAController *sba;
struct rate_ctr_group *ratectrs;
struct osmo_stat_item_group *statg;
GprsMsStorage m_ms_store;
struct GprsMsStorage *ms_store;
/* list of uplink TBFs */
LListHead<gprs_rlcmac_tbf> m_ul_tbfs;
struct llist_head ul_tbfs; /* list of gprs_rlcmac_tbf */
/* list of downlink TBFs */
LListHead<gprs_rlcmac_tbf> m_dl_tbfs;
/* disable copying to avoid slicing */
BTS(const BTS&);
BTS& operator=(const BTS&);
struct llist_head dl_tbfs; /* list of gprs_rlcmac_tbf */
};
inline int BTS::current_frame_number() const
{
return m_cur_fn;
}
inline SBAController *BTS::sba()
{
return &m_sba;
}
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);
}
inline GprsMs *BTS::ms_by_imsi(const char *imsi)
{
return ms_store().get_ms(0, 0, imsi);
}
inline LListHead<gprs_rlcmac_tbf>& BTS::ul_tbfs()
{
return m_ul_tbfs;
}
inline LListHead<gprs_rlcmac_tbf>& BTS::dl_tbfs()
{
return m_dl_tbfs;
}
inline struct rate_ctr_group *BTS::rate_counters() const
{
return m_ratectrs;
}
inline struct osmo_stat_item_group *BTS::stat_items() const
{
return m_statg;
}
inline void BTS::do_rate_ctr_inc(unsigned int ctr_id) {
rate_ctr_inc(&m_ratectrs->ctr[ctr_id]);
}
inline void BTS::do_rate_ctr_add(unsigned int ctr_id, int inc) {
rate_ctr_add(&m_ratectrs->ctr[ctr_id], inc);
}
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);
}
struct gprs_pcu;
struct BTS* bts_alloc(struct gprs_pcu *pcu);
#endif
#ifdef __cplusplus
extern "C" {
#endif
void bts_cleanup();
struct gprs_rlcmac_bts *bts_data(struct BTS *bts);
struct GprsMs *bts_alloc_ms(struct gprs_rlcmac_bts *bts, uint8_t ms_class, uint8_t egprs_ms_class);
int bts_add_paging(struct gprs_rlcmac_bts *bts, uint8_t chan_needed, const struct osmo_mobile_identity *mi);
uint32_t bts_rfn_to_fn(const struct gprs_rlcmac_bts *bts, int32_t rfn);
struct gprs_rlcmac_dl_tbf *bts_dl_tbf_by_poll_fn(struct gprs_rlcmac_bts *bts, uint32_t fn, uint8_t trx, uint8_t ts);
struct gprs_rlcmac_ul_tbf *bts_ul_tbf_by_poll_fn(struct gprs_rlcmac_bts *bts, uint32_t fn, uint8_t trx, uint8_t ts);
struct gprs_rlcmac_dl_tbf *bts_dl_tbf_by_tfi(struct gprs_rlcmac_bts *bts, uint8_t tfi, uint8_t trx, uint8_t ts);
struct gprs_rlcmac_ul_tbf *bts_ul_tbf_by_tfi(struct gprs_rlcmac_bts *bts, uint8_t tfi, uint8_t trx, uint8_t ts);
void bts_snd_dl_ass(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup);
/** TODO: change the number to unsigned */
void bts_set_current_frame_number(struct gprs_rlcmac_bts *bts, int frame_number);
void bts_set_current_block_frame_number(struct gprs_rlcmac_bts *bts, int frame_number, unsigned max_delay);
static inline int bts_current_frame_number(const struct gprs_rlcmac_bts *bts)
{
return bts->cur_fn;
}
int bts_tfi_find_free(const struct gprs_rlcmac_bts *bts, enum gprs_rlcmac_tbf_direction dir,
uint8_t *_trx, int8_t use_trx);
int bts_rcv_rach(struct gprs_rlcmac_bts *bts, const struct rach_ind_params *rip);
int bts_rcv_ptcch_rach(struct gprs_rlcmac_bts *bts, const struct rach_ind_params *rip);
int bts_rcv_imm_ass_cnf(struct gprs_rlcmac_bts *bts, const uint8_t *data, uint32_t fn);
void bts_send_gsmtap(struct gprs_rlcmac_bts *bts,
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);
void bts_send_gsmtap_meas(struct gprs_rlcmac_bts *bts,
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);
void bts_send_gsmtap_rach(struct gprs_rlcmac_bts *bts,
enum pcu_gsmtap_category categ, uint8_t channel,
const struct rach_ind_params *rip);
struct SBAController *bts_sba(struct gprs_rlcmac_bts *bts);
struct GprsMsStorage *bts_ms_store(struct gprs_rlcmac_bts *bts);
struct GprsMs *bts_ms_by_tlli(struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_t old_tlli);
static inline struct rate_ctr_group *bts_rate_counters(struct gprs_rlcmac_bts *bts)
{
return bts->ratectrs;
}
static inline struct osmo_stat_item_group *bts_stat_items(struct gprs_rlcmac_bts *bts)
{
return bts->statg;
}
static inline void bts_do_rate_ctr_inc(struct gprs_rlcmac_bts *bts, unsigned int ctr_id) {
rate_ctr_inc(&bts->ratectrs->ctr[ctr_id]);
}
static inline void bts_do_rate_ctr_add(struct gprs_rlcmac_bts *bts, unsigned int ctr_id, int inc) {
rate_ctr_add(&bts->ratectrs->ctr[ctr_id], inc);
}
static inline void bts_stat_item_add(struct gprs_rlcmac_bts *bts, unsigned int stat_id, int inc) {
int32_t val = osmo_stat_item_get_last(bts->statg->items[stat_id]);
osmo_stat_item_set(bts->statg->items[stat_id], val + inc);
}
struct gprs_rlcmac_bts *bts_alloc(struct gprs_pcu *pcu);
struct gprs_rlcmac_bts *bts_main_data();
struct rate_ctr_group *bts_main_data_stats();
struct osmo_stat_item_group *bts_main_data_stat_items();
@ -407,12 +325,16 @@ extern "C" {
void bts_recalc_initial_mcs(struct gprs_rlcmac_bts *bts);
void bts_recalc_max_cs(struct gprs_rlcmac_bts *bts);
void bts_recalc_max_mcs(struct gprs_rlcmac_bts *bts);
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);
struct GprsMs *bts_ms_by_imsi(struct gprs_rlcmac_bts *bts, const char *imsi);
uint8_t bts_max_cs_dl(const struct gprs_rlcmac_bts *bts);
uint8_t bts_max_cs_ul(const struct gprs_rlcmac_bts *bts);
uint8_t bts_max_mcs_dl(const struct gprs_rlcmac_bts *bts);
uint8_t bts_max_mcs_ul(const struct gprs_rlcmac_bts *bts);
void bts_set_max_cs_dl(struct gprs_rlcmac_bts *bts, uint8_t cs_dl);
void bts_set_max_cs_ul(struct gprs_rlcmac_bts *bts, uint8_t cs_ul);
void bts_set_max_mcs_dl(struct gprs_rlcmac_bts *bts, uint8_t mcs_dl);
void bts_set_max_mcs_ul(struct gprs_rlcmac_bts *bts, uint8_t mcs_ul);
bool bts_cs_dl_is_supported(const struct gprs_rlcmac_bts *bts, enum CodingScheme cs);
#ifdef __cplusplus
}
#endif

View File

@ -24,6 +24,7 @@
#include <bts.h>
#include <tbf.h>
#include <tbf_ul.h>
#include <tbf_dl.h>
#include <gprs_debug.h>
#include <egprs_rlc_compression.h>

View File

@ -34,6 +34,7 @@ extern "C" {
#include <osmocom/core/utils.h>
#include <osmocom/gsm/gsm48.h>
#include "coding_scheme.h"
#include "tbf_dl.h"
}
/* Tuning parameters for BSSGP flow control */
@ -208,7 +209,7 @@ static int gprs_bssgp_pcu_rx_paging_cs(struct msgb *msg, const struct tlv_parsed
if ((rc = get_paging_mi(&mi, tp)) > 0)
return bssgp_tx_status((enum gprs_bssgp_cause) rc, NULL, msg);
return BTS::main_bts()->add_paging(tlvp_val8(tp, BSSGP_IE_CHAN_NEEDED, 0), &mi);
return bts_add_paging(the_pcu->bts, tlvp_val8(tp, BSSGP_IE_CHAN_NEEDED, 0), &mi);
}
static int gprs_bssgp_pcu_rx_paging_ps(struct msgb *msg, const struct tlv_parsed *tp)
@ -761,8 +762,8 @@ static enum CodingScheme max_coding_scheme_dl(struct gprs_rlcmac_bts *bts)
} else {
/* We found "num" for free in the loop above */
}
} else if (bts->bts->max_mcs_dl()) {
num = bts->bts->max_mcs_dl();
} else if (bts_max_mcs_dl(bts)) {
num = bts_max_mcs_dl(bts);
} else {
num = 9;
}
@ -782,8 +783,8 @@ static enum CodingScheme max_coding_scheme_dl(struct gprs_rlcmac_bts *bts)
}
}
}
} else if (bts->bts->max_cs_dl()) {
num = bts->bts->max_cs_dl();
} else if (bts_max_cs_dl(bts)) {
num = bts_max_cs_dl(bts);
}
if (!num)

View File

@ -91,7 +91,7 @@ void ms_timeout(void *data)
}
static int ms_talloc_destructor(struct GprsMs *ms);
struct GprsMs *ms_alloc(struct BTS *bts, uint32_t tlli)
struct GprsMs *ms_alloc(struct gprs_rlcmac_bts *bts, uint32_t tlli)
{
struct GprsMs *ms = talloc_zero(tall_pcu_ctx, struct GprsMs);
@ -249,13 +249,13 @@ void ms_set_mode(struct GprsMs *ms, enum mcs_kind mode)
case GPRS:
if (!mcs_is_gprs(ms->current_cs_ul)) {
ms->current_cs_ul = mcs_get_gprs_by_num(
bts_data(ms->bts)->initial_cs_ul);
ms->bts->initial_cs_ul);
if (!mcs_is_valid(ms->current_cs_ul))
ms->current_cs_ul = CS1;
}
if (!mcs_is_gprs(ms->current_cs_dl)) {
ms->current_cs_dl = mcs_get_gprs_by_num(
bts_data(ms->bts)->initial_cs_dl);
ms->bts->initial_cs_dl);
if (!mcs_is_valid(ms->current_cs_dl))
ms->current_cs_dl = CS1;
}
@ -265,13 +265,13 @@ void ms_set_mode(struct GprsMs *ms, enum mcs_kind mode)
case EGPRS:
if (!mcs_is_edge(ms->current_cs_ul)) {
ms->current_cs_ul = mcs_get_egprs_by_num(
bts_data(ms->bts)->initial_mcs_ul);
ms->bts->initial_mcs_ul);
if (!mcs_is_valid(ms->current_cs_ul))
ms->current_cs_ul = MCS1;
}
if (!mcs_is_edge(ms->current_cs_dl)) {
ms->current_cs_dl = mcs_get_egprs_by_num(
bts_data(ms->bts)->initial_mcs_dl);
ms->bts->initial_mcs_dl);
if (!mcs_is_valid(ms->current_cs_dl))
ms->current_cs_dl = MCS1;
}

View File

@ -49,7 +49,7 @@ enum ms_counter_id {
MS_CTR_DL_CTRL_MSG_SCHED,
};
struct BTS;
struct gprs_rlcmac_bts;
struct gprs_rlcmac_trx;
struct GprsMs;
@ -63,7 +63,7 @@ struct GprsMs {
struct gpr_ms_callback cb;
bool app_info_pending;
struct BTS *bts;
struct gprs_rlcmac_bts *bts;
struct gprs_rlcmac_ul_tbf *ul_tbf;
struct gprs_rlcmac_dl_tbf *dl_tbf;
struct llist_head old_tbfs; /* list of gprs_rlcmac_tbf */
@ -102,7 +102,7 @@ struct GprsMs {
struct rate_ctr_group *ctrs;
};
struct GprsMs *ms_alloc(struct BTS *bts, uint32_t tlli);
struct GprsMs *ms_alloc(struct gprs_rlcmac_bts *bts, uint32_t tlli);
int ms_first_common_ts(const struct GprsMs *ms);
void ms_set_reserved_slots(struct GprsMs *ms, struct gprs_rlcmac_trx *trx,

View File

@ -35,7 +35,7 @@ static void ms_storage_ms_idle_cb(struct GprsMs *ms)
{
llist_del(&ms->list);
if (ms->bts)
ms->bts->stat_item_add(STAT_MS_PRESENT, -1);
bts_stat_item_add(ms->bts, STAT_MS_PRESENT, -1);
if (ms_is_idle(ms))
talloc_free(ms);
}
@ -50,7 +50,7 @@ static struct gpr_ms_callback ms_storage_ms_cb = {
.ms_active = ms_storage_ms_active_cb,
};
GprsMsStorage::GprsMsStorage(BTS *bts) :
GprsMsStorage::GprsMsStorage(struct gprs_rlcmac_bts *bts) :
m_bts(bts)
{
INIT_LLIST_HEAD(&m_list);
@ -109,7 +109,7 @@ GprsMs *GprsMsStorage::create_ms()
ms_set_callback(ms, &ms_storage_ms_cb);
llist_add(&ms->list, &m_list);
if (m_bts)
m_bts->stat_item_add(STAT_MS_PRESENT, 1);
bts_stat_item_add(m_bts, STAT_MS_PRESENT, 1);
return ms;
}

View File

@ -25,11 +25,11 @@
#include <stdint.h>
#include <stddef.h>
struct BTS;
struct gprs_rlcmac_bts;
class GprsMsStorage {
struct GprsMsStorage {
public:
GprsMsStorage(BTS *bts);
GprsMsStorage(struct gprs_rlcmac_bts *bts);
~GprsMsStorage();
void cleanup();
@ -39,6 +39,6 @@ public:
const struct llist_head* ms_list() const {return &m_list;}
private:
BTS *m_bts;
struct gprs_rlcmac_bts *m_bts;
struct llist_head m_list; /* list of struct GprsMs */
};

View File

@ -109,8 +109,7 @@ void gprs_pcu_set_initial_cs(struct gprs_pcu *pcu, uint8_t cs_dl, uint8_t cs_ul)
the_pcu->vty.initial_cs_ul = cs_ul;
/*TODO: once we support multiple bts, foreach(bts) apply */
struct gprs_rlcmac_bts *bts = bts_data(pcu->bts);
bts_recalc_initial_cs(bts);
bts_recalc_initial_cs(pcu->bts);
}
void gprs_pcu_set_initial_mcs(struct gprs_pcu *pcu, uint8_t mcs_dl, uint8_t mcs_ul)
{
@ -118,8 +117,7 @@ void gprs_pcu_set_initial_mcs(struct gprs_pcu *pcu, uint8_t mcs_dl, uint8_t mcs_
the_pcu->vty.initial_mcs_ul = mcs_ul;
/*TODO: once we support multiple bts, foreach(bts) apply */
struct gprs_rlcmac_bts *bts = bts_data(pcu->bts);
bts_recalc_initial_mcs(bts);
bts_recalc_initial_mcs(pcu->bts);
}
void gprs_pcu_set_max_cs(struct gprs_pcu *pcu, uint8_t cs_dl, uint8_t cs_ul)
@ -127,14 +125,12 @@ void gprs_pcu_set_max_cs(struct gprs_pcu *pcu, uint8_t cs_dl, uint8_t cs_ul)
the_pcu->vty.max_cs_dl = cs_dl;
the_pcu->vty.max_cs_ul = cs_ul;
/*TODO: once we support multiple bts, foreach(bts) apply */
struct gprs_rlcmac_bts *bts = bts_data(pcu->bts);
bts_recalc_max_cs(bts);
bts_recalc_max_cs(pcu->bts);
}
void gprs_pcu_set_max_mcs(struct gprs_pcu *pcu, uint8_t mcs_dl, uint8_t mcs_ul)
{
the_pcu->vty.max_mcs_dl = mcs_dl;
the_pcu->vty.max_mcs_ul = mcs_ul;
/* TODO: once we support multiple bts, foreach(bts) apply */
struct gprs_rlcmac_bts *bts = bts_data(pcu->bts);
bts_recalc_max_mcs(bts);
bts_recalc_max_mcs(pcu->bts);
}

View File

@ -55,7 +55,6 @@ enum pcu_gsmtap_category {
PCU_GSMTAP_C_UL_PTCCH = 21, /* uplink PTCCH bursts */
};
struct BTS;
struct gprs_rlcmac_bts;
struct GprsMs;
struct gprs_rlcmac_tbf;
@ -108,7 +107,7 @@ struct gprs_pcu {
struct gsmtap_inst *gsmtap;
uint32_t gsmtap_categ_mask;
struct BTS *bts;
struct gprs_rlcmac_bts *bts;
struct gprs_ns2_inst *nsi;

View File

@ -41,13 +41,13 @@ struct tbf_sched_candidates {
struct gprs_rlcmac_ul_tbf *ul_ack;
};
static uint32_t sched_poll(BTS *bts,
static uint32_t sched_poll(struct gprs_rlcmac_bts *bts,
uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr,
struct tbf_sched_candidates *tbf_cand)
{
struct gprs_rlcmac_ul_tbf *ul_tbf;
struct gprs_rlcmac_dl_tbf *dl_tbf;
LListHead<gprs_rlcmac_tbf> *pos;
struct llist_item *pos;
uint32_t poll_fn;
/* check special TBF for events */
@ -55,8 +55,8 @@ static uint32_t sched_poll(BTS *bts,
if ((block_nr % 3) == 2)
poll_fn ++;
poll_fn = poll_fn % GSM_MAX_FN;
llist_for_each(pos, &bts->ul_tbfs()) {
ul_tbf = as_ul_tbf(pos->entry());
llist_for_each_entry(pos, &bts->ul_tbfs, list) {
ul_tbf = as_ul_tbf((struct gprs_rlcmac_tbf *)pos->entry);
OSMO_ASSERT(ul_tbf);
/* this trx, this ts */
if (ul_tbf->trx->trx_no != trx || !ul_tbf->is_control_ts(ts))
@ -74,8 +74,8 @@ static uint32_t sched_poll(BTS *bts,
/* FIXME: Is this supposed to be fair? The last TBF for each wins? Maybe use llist_add_tail and skip once we have all
states? */
}
llist_for_each(pos, &bts->dl_tbfs()) {
dl_tbf = as_dl_tbf(pos->entry());
llist_for_each_entry(pos, &bts->dl_tbfs, list) {
dl_tbf = as_dl_tbf((struct gprs_rlcmac_tbf *)pos->entry);
OSMO_ASSERT(dl_tbf);
/* this trx, this ts */
if (dl_tbf->trx->trx_no != trx || !dl_tbf->is_control_ts(ts))
@ -136,7 +136,7 @@ struct msgb *sched_app_info(struct gprs_rlcmac_tbf *tbf) {
if (!tbf || !tbf->ms()->app_info_pending)
return NULL;
bts_data = BTS::main_bts()->bts_data();
bts_data = the_pcu->bts;
if (bts_data->app_info) {
LOGP(DRLCMACSCHED, LOGL_DEBUG, "Sending Packet Application Information message\n");
@ -367,7 +367,7 @@ static struct msgb *sched_dummy(void)
return msg;
}
static inline void tap_n_acc(const struct msgb *msg, const struct gprs_rlcmac_bts *bts, uint8_t trx, uint8_t ts,
static inline void tap_n_acc(const struct msgb *msg, struct gprs_rlcmac_bts *bts, uint8_t trx, uint8_t ts,
uint32_t fn, enum pcu_gsmtap_category cat)
{
if (!msg)
@ -375,19 +375,19 @@ static inline void tap_n_acc(const struct msgb *msg, const struct gprs_rlcmac_bt
switch(cat) {
case PCU_GSMTAP_C_DL_CTRL:
bts->bts->do_rate_ctr_inc(CTR_RLC_SENT_CONTROL);
bts->bts->send_gsmtap(PCU_GSMTAP_C_DL_CTRL, false, trx, ts, GSMTAP_CHANNEL_PACCH, fn, msg->data,
bts_do_rate_ctr_inc(bts, CTR_RLC_SENT_CONTROL);
bts_send_gsmtap(bts, PCU_GSMTAP_C_DL_CTRL, false, trx, ts, GSMTAP_CHANNEL_PACCH, fn, msg->data,
msg->len);
break;
case PCU_GSMTAP_C_DL_DATA_GPRS:
case PCU_GSMTAP_C_DL_DATA_EGPRS:
bts->bts->do_rate_ctr_inc(CTR_RLC_SENT);
bts->bts->send_gsmtap(cat, false, trx, ts, GSMTAP_CHANNEL_PDTCH, fn, msg->data,
bts_do_rate_ctr_inc(bts, CTR_RLC_SENT);
bts_send_gsmtap(bts, cat, false, trx, ts, GSMTAP_CHANNEL_PDTCH, fn, msg->data,
msg->len);
break;
case PCU_GSMTAP_C_DL_DUMMY:
bts->bts->do_rate_ctr_inc(CTR_RLC_SENT_DUMMY);
bts->bts->send_gsmtap(PCU_GSMTAP_C_DL_DUMMY, false, trx, ts, GSMTAP_CHANNEL_PACCH, fn, msg->data,
bts_do_rate_ctr_inc(bts, CTR_RLC_SENT_DUMMY);
bts_send_gsmtap(bts, PCU_GSMTAP_C_DL_DUMMY, false, trx, ts, GSMTAP_CHANNEL_PACCH, fn, msg->data,
msg->len);
break;
default:
@ -438,7 +438,7 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts,
req_mcs_kind = EGPRS; /* all kinds are fine */
}
poll_fn = sched_poll(bts->bts, trx, ts, fn, block_nr, &tbf_cand);
poll_fn = sched_poll(bts, trx, ts, fn, block_nr, &tbf_cand);
/* check uplink resource for polling */
if (tbf_cand.poll) {
LOGP(DRLCMACSCHED, LOGL_DEBUG, "Received RTS for PDCH: TRX=%d "
@ -447,7 +447,7 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts,
block_nr, poll_fn, tbf_name(tbf_cand.poll));
usf = USF_UNUSED;
/* else. check for sba */
} else if ((sba_fn = bts->bts->sba()->sched(trx, ts, fn, block_nr)) != 0xffffffff) {
} else if ((sba_fn = bts_sba(bts)->sched(trx, ts, fn, block_nr)) != 0xffffffff) {
LOGP(DRLCMACSCHED, LOGL_DEBUG, "Received RTS for PDCH: TRX=%d "
"TS=%d FN=%d block_nr=%d scheduling free USF for "
"single block allocation at FN=%d\n", trx, ts, fn,
@ -493,7 +493,7 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts,
}
/* msg is now available */
bts->bts->do_rate_ctr_add(CTR_RLC_DL_BYTES, msg->data_len);
bts_do_rate_ctr_add(bts, CTR_RLC_DL_BYTES, msg->data_len);
/* set USF */
OSMO_ASSERT(msgb_length(msg) > 0);

View File

@ -305,7 +305,7 @@ static bool idle_pdch_avail(const struct gprs_rlcmac_bts *bts_data)
* \param[out] trx_no_ TRX number on which TFI was found
* \returns negative error code or 0 on success
*/
static int tfi_find_free(const BTS *bts, const gprs_rlcmac_trx *trx, const GprsMs *ms,
static int tfi_find_free(const struct gprs_rlcmac_bts *bts, const gprs_rlcmac_trx *trx, const GprsMs *ms,
enum gprs_rlcmac_tbf_direction dir, int8_t use_trx, uint8_t *trx_no_)
{
int tfi;
@ -323,7 +323,7 @@ static int tfi_find_free(const BTS *bts, const gprs_rlcmac_trx *trx, const GprsM
if (use_trx == -1 && ms_current_trx(ms))
use_trx = ms_current_trx(ms)->trx_no;
tfi = bts->tfi_find_free(dir, &trx_no, use_trx);
tfi = bts_tfi_find_free(bts, dir, &trx_no, use_trx);
if (tfi < 0)
return -EBUSY;
@ -423,7 +423,7 @@ int alloc_algorithm_a(struct gprs_rlcmac_bts *bts, GprsMs *ms_, struct gprs_rlcm
ms_set_reserved_slots(ms_, trx, 1 << ts, 1 << ts);
tbf_->upgrade_to_multislot = 0;
bts->bts->do_rate_ctr_inc(CTR_TBF_ALLOC_ALGO_A);
bts_do_rate_ctr_inc(bts, CTR_TBF_ALLOC_ALGO_A);
return 0;
}
@ -888,7 +888,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, GprsMs *ms_, struct gprs_rlcm
trx = ms_current_trx(ms);
/* Step 2a: Find usable TRX and TFI */
tfi = tfi_find_free(bts->bts, trx, ms, tbf->direction, use_trx, &trx_no);
tfi = tfi_find_free(bts, trx, ms, tbf->direction, use_trx, &trx_no);
if (tfi < 0) {
LOGPAL(tbf, "B", single, use_trx, LOGL_NOTICE, "failed to allocate a TFI\n");
return tfi;
@ -966,7 +966,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, GprsMs *ms_, struct gprs_rlcm
else
assign_ul_tbf_slots(as_ul_tbf(tbf_), trx, ul_slots, tfi, usf);
bts->bts->do_rate_ctr_inc(CTR_TBF_ALLOC_ALGO_B);
bts_do_rate_ctr_inc(bts, CTR_TBF_ALLOC_ALGO_B);
return 0;
}

View File

@ -45,7 +45,7 @@ static struct rb_root timer_root = RB_ROOT;
*/
int get_current_fn()
{
return BTS::main_bts()->current_frame_number();
return bts_current_frame_number(the_pcu->bts);
}
static void __add_gsm_timer(struct osmo_gsm_timer_list *timer)
@ -232,4 +232,3 @@ int osmo_gsm_timers_check(void)
}
/*! }@ */

View File

@ -122,13 +122,13 @@ void gprs_llc_queue::enqueue(struct msgb *llc_msg, const struct timespec *expire
msgb_enqueue(&m_queue, llc_msg);
}
void llc_queue_clear(struct gprs_llc_queue *q, struct BTS *bts)
void llc_queue_clear(struct gprs_llc_queue *q, struct gprs_rlcmac_bts *bts)
{
struct msgb *msg;
while ((msg = msgb_dequeue(&q->m_queue))) {
if (bts)
bts->do_rate_ctr_inc(CTR_LLC_FRAME_DROPPED);
bts_do_rate_ctr_inc(bts, CTR_LLC_FRAME_DROPPED);
msgb_free(msg);
}
@ -221,7 +221,7 @@ struct msgb *gprs_llc_queue::dequeue(const MetaInfo **info)
return msg;
}
void gprs_llc_queue::calc_pdu_lifetime(BTS *bts, const uint16_t pdu_delay_csec, struct timespec *tv)
void gprs_llc_queue::calc_pdu_lifetime(struct gprs_rlcmac_bts *bts, const uint16_t pdu_delay_csec, struct timespec *tv)
{
uint16_t delay_csec;
if (bts->pcu->vty.force_llc_lifetime)

View File

@ -32,7 +32,7 @@ extern "C" {
#define LLC_MAX_LEN 1543
struct BTS;
struct gprs_rlcmac_bts;
/**
* I represent the LLC data to a MS
@ -65,7 +65,7 @@ struct MetaInfo {
*/
struct gprs_llc_queue {
#ifdef __cplusplus
static void calc_pdu_lifetime(BTS *bts, const uint16_t pdu_delay_csec,
static void calc_pdu_lifetime(struct gprs_rlcmac_bts *bts, const uint16_t pdu_delay_csec,
struct timespec *tv);
static bool is_frame_expired(const struct timespec *now,
const struct timespec *tv);
@ -84,7 +84,7 @@ struct gprs_llc_queue {
extern "C" {
#endif
void llc_queue_init(struct gprs_llc_queue *q);
void llc_queue_clear(struct gprs_llc_queue *q, struct BTS *bts);
void llc_queue_clear(struct gprs_llc_queue *q, struct gprs_rlcmac_bts *bts);
void llc_queue_move_and_merge(struct gprs_llc_queue *q, struct gprs_llc_queue *o);
static inline uint16_t llc_chunk_size(const struct gprs_llc *llc)

View File

@ -53,6 +53,7 @@ extern "C" {
#include <pdch.h>
#include <tbf_ul.h>
#include <tbf_dl.h>
#include <gprs_ms_storage.h>
// FIXME: move this, when changed from c++ to c.
extern "C" {
@ -271,13 +272,13 @@ void pcu_l1if_tx_pch(bitvec * block, int plen, uint16_t pgroup)
extern "C" void pcu_rx_block_time(uint16_t arfcn, uint32_t fn, uint8_t ts_no)
{
BTS::main_bts()->set_current_block_frame_number(fn, 0);
bts_set_current_block_frame_number(the_pcu->bts,fn, 0);
}
extern "C" void pcu_rx_ra_time(uint16_t arfcn, uint32_t fn, uint8_t ts_no)
{
/* access bursts may arrive some bursts earlier */
BTS::main_bts()->set_current_block_frame_number(fn, 5);
bts_set_current_block_frame_number(the_pcu->bts,fn, 5);
}
extern "C" int pcu_rx_data_ind_pdtch(uint8_t trx_no, uint8_t ts_no, uint8_t *data,
@ -368,7 +369,7 @@ static int pcu_rx_data_cnf(struct gsm_pcu_if_data *data_cnf)
switch (data_cnf->sapi) {
case PCU_IF_SAPI_PCH:
if (data_cnf->data[2] == 0x3f)
BTS::main_bts()->rcv_imm_ass_cnf(data_cnf->data, data_cnf->fn);
bts_rcv_imm_ass_cnf(the_pcu->bts, data_cnf->data, data_cnf->fn);
break;
default:
LOGP(DL1IF, LOGL_ERROR, "Received PCU data confirm with "
@ -447,7 +448,7 @@ extern "C" int pcu_rx_rach_ind_ptcch(uint8_t trx_nr, uint8_t ts_nr, uint32_t fn,
.qta = qta,
};
return BTS::main_bts()->rcv_ptcch_rach(&rip);
return bts_rcv_ptcch_rach(the_pcu->bts, &rip);
}
static int pcu_rx_rach_ind(const struct gsm_pcu_if_rach_ind *rach_ind)
@ -471,10 +472,10 @@ static int pcu_rx_rach_ind(const struct gsm_pcu_if_rach_ind *rach_ind)
switch (rach_ind->sapi) {
case PCU_IF_SAPI_RACH:
rc = BTS::main_bts()->rcv_rach(&rip);
rc = bts_rcv_rach(the_pcu->bts, &rip);
break;
case PCU_IF_SAPI_PTCCH:
rc = BTS::main_bts()->rcv_ptcch_rach(&rip);
rc = bts_rcv_ptcch_rach(the_pcu->bts, &rip);
break;
default:
LOGP(DL1IF, LOGL_ERROR, "Received PCU rach request with "
@ -751,7 +752,7 @@ static int pcu_rx_time_ind(struct gsm_pcu_if_time_ind *time_ind)
LOGP(DL1IF, LOGL_DEBUG, "Time indication received: %d\n", time_ind->fn % 52);
BTS::main_bts()->set_current_frame_number(time_ind->fn);
bts_set_current_frame_number(the_pcu->bts, time_ind->fn);
return 0;
}
@ -776,12 +777,12 @@ static int pcu_rx_pag_req(struct gsm_pcu_if_pag_req *pag_req)
return -EINVAL;
}
return BTS::main_bts()->add_paging(pag_req->chan_needed, &mi);
return bts_add_paging(the_pcu->bts, pag_req->chan_needed, &mi);
}
static int pcu_rx_susp_req(struct gsm_pcu_if_susp_req *susp_req)
{
BTS *bts = BTS::main_bts();
struct gprs_rlcmac_bts *bts = the_pcu->bts;
struct bssgp_bvc_ctx *bctx = gprs_bssgp_pcu_current_bctx();
GprsMs *ms;
struct gprs_rlcmac_dl_tbf *dl_tbf;
@ -793,7 +794,7 @@ static int pcu_rx_susp_req(struct gsm_pcu_if_susp_req *susp_req)
LOGP(DL1IF, LOGL_INFO, "GPRS Suspend request received: TLLI=0x%08x RAI=%s\n",
susp_req->tlli, osmo_rai_name(&ra_id));
if ((ms = bts->ms_store().get_ms(susp_req->tlli))) {
if ((ms = bts_ms_store(bts)->get_ms(susp_req->tlli))) {
/* We need to catch both pointers here since MS may become freed
after first tbf_free(dl_tbf) if only DL TBF was available */
dl_tbf = ms_dl_tbf(ms);
@ -812,15 +813,15 @@ static int pcu_rx_susp_req(struct gsm_pcu_if_susp_req *susp_req)
static int pcu_rx_app_info_req(struct gsm_pcu_if_app_info_req *app_info_req)
{
BTS *bts = BTS::main_bts();
struct gprs_rlcmac_bts *bts_data = bts->bts_data();
struct gprs_rlcmac_bts *bts = the_pcu->bts;
struct gprs_rlcmac_bts *bts_data = bts;
struct llist_head *tmp;
LOGP(DL1IF, LOGL_DEBUG, "Application Information Request received: type=0x%08x len=%i\n",
app_info_req->application_type, app_info_req->len);
bts_data->app_info_pending = 0;
llist_for_each(tmp, bts->ms_store().ms_list()) {
llist_for_each(tmp, bts_ms_store(bts)->ms_list()) {
GprsMs *ms = llist_entry(tmp, typeof(*ms), list);
if (!ms_dl_tbf(ms))
continue;

View File

@ -342,7 +342,7 @@ int main(int argc, char *argv[])
pcu_l1if_close();
bts_cleanup();
TALLOC_FREE(the_pcu);
talloc_report_full(tall_pcu_ctx, stderr);
talloc_free(tall_pcu_ctx);

View File

@ -101,21 +101,23 @@ static void tbf_print_vty_info(struct vty *vty, gprs_rlcmac_tbf *tbf)
vty_out(vty, "%s%s", VTY_NEWLINE, VTY_NEWLINE);
}
int pcu_vty_show_tbf_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data, uint32_t flags)
int pcu_vty_show_tbf_all(struct vty *vty, struct gprs_rlcmac_bts *bts, uint32_t flags)
{
BTS *bts = bts_data->bts;
LListHead<gprs_rlcmac_tbf> *iter;
struct llist_item *iter;
struct gprs_rlcmac_tbf *tbf;
vty_out(vty, "UL TBFs%s", VTY_NEWLINE);
llist_for_each(iter, &bts->ul_tbfs()) {
if (iter->entry()->state_flags & flags)
tbf_print_vty_info(vty, iter->entry());
llist_for_each_entry(iter, &bts->ul_tbfs, list) {
tbf = (struct gprs_rlcmac_tbf *)iter->entry;
if (tbf->state_flags & flags)
tbf_print_vty_info(vty, tbf);
}
vty_out(vty, "%sDL TBFs%s", VTY_NEWLINE, VTY_NEWLINE);
llist_for_each(iter, &bts->dl_tbfs()) {
if (iter->entry()->state_flags & flags)
tbf_print_vty_info(vty, iter->entry());
llist_for_each_entry(iter, &bts->dl_tbfs, list) {
tbf = (struct gprs_rlcmac_tbf *)iter->entry;
if (tbf->state_flags & flags)
tbf_print_vty_info(vty, tbf);
}
return CMD_SUCCESS;
@ -204,12 +206,11 @@ static int show_ms(struct vty *vty, GprsMs *ms)
return CMD_SUCCESS;
}
int pcu_vty_show_ms_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data)
int pcu_vty_show_ms_all(struct vty *vty, struct gprs_rlcmac_bts *bts)
{
BTS *bts = bts_data->bts;
struct llist_head *tmp;
llist_for_each(tmp, bts->ms_store().ms_list()) {
llist_for_each(tmp, bts_ms_store(bts)->ms_list()) {
GprsMs *ms_iter = llist_entry(tmp, typeof(*ms_iter), list);
show_ms(vty, ms_iter);
}
@ -217,11 +218,10 @@ int pcu_vty_show_ms_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data)
return CMD_SUCCESS;
}
int pcu_vty_show_ms_by_tlli(struct vty *vty, struct gprs_rlcmac_bts *bts_data,
int pcu_vty_show_ms_by_tlli(struct vty *vty, struct gprs_rlcmac_bts *bts,
uint32_t tlli)
{
BTS *bts = bts_data->bts;
GprsMs *ms = bts->ms_store().get_ms(tlli);
GprsMs *ms = bts_ms_store(bts)->get_ms(tlli);
if (!ms) {
vty_out(vty, "Unknown TLLI %08x.%s", tlli, VTY_NEWLINE);
return CMD_WARNING;
@ -230,11 +230,10 @@ int pcu_vty_show_ms_by_tlli(struct vty *vty, struct gprs_rlcmac_bts *bts_data,
return show_ms(vty, ms);
}
int pcu_vty_show_ms_by_imsi(struct vty *vty, struct gprs_rlcmac_bts *bts_data,
int pcu_vty_show_ms_by_imsi(struct vty *vty, struct gprs_rlcmac_bts *bts,
const char *imsi)
{
BTS *bts = bts_data->bts;
GprsMs *ms = bts->ms_store().get_ms(0, 0, imsi);
GprsMs *ms = bts_ms_store(bts)->get_ms(0, 0, imsi);
if (!ms) {
vty_out(vty, "Unknown IMSI '%s'.%s", imsi, VTY_NEWLINE);
return CMD_WARNING;

View File

@ -113,9 +113,9 @@ static void get_meas(struct pcu_l1_meas *meas,
}
}
static inline void sched_ul_ass_or_rej(BTS *bts, gprs_rlcmac_bts *bts_data, struct gprs_rlcmac_dl_tbf *tbf)
static inline void sched_ul_ass_or_rej(struct gprs_rlcmac_bts *bts, gprs_rlcmac_bts *bts_data, struct gprs_rlcmac_dl_tbf *tbf)
{
bts->do_rate_ctr_inc(CTR_CHANNEL_REQUEST_DESCRIPTION);
bts_do_rate_ctr_inc(bts, CTR_CHANNEL_REQUEST_DESCRIPTION);
/* This call will register the new TBF with the MS on success */
gprs_rlcmac_ul_tbf *ul_tbf = tbf_alloc_ul(bts_data, tbf->ms(), tbf->trx->trx_no, tbf->tlli());
@ -158,7 +158,7 @@ void gprs_rlcmac_pdch::free_resources()
while ((pag = dequeue_paging()))
talloc_free(pag);
trx->bts->sba()->free_resources(this);
bts_sba(trx->bts)->free_resources(this);
}
struct gprs_rlcmac_paging *gprs_rlcmac_pdch::dequeue_paging()
@ -292,12 +292,12 @@ void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet,
{
struct gprs_rlcmac_tbf *tbf, *new_tbf;
uint32_t tlli = packet->TLLI;
GprsMs *ms = bts()->ms_by_tlli(tlli);
GprsMs *ms = bts_ms_by_tlli(bts(), tlli, GSM_RESERVED_TMSI);
gprs_rlcmac_ul_tbf *ul_tbf;
tbf = bts()->ul_tbf_by_poll_fn(fn, trx_no(), ts_no);
tbf = bts_ul_tbf_by_poll_fn(bts(), fn, trx_no(), ts_no);
if (!tbf)
tbf = bts()->dl_tbf_by_poll_fn(fn, trx_no(), ts_no);
tbf = bts_dl_tbf_by_poll_fn(bts(), fn, trx_no(), ts_no);
if (!tbf) {
LOGP(DRLCMAC, LOGL_NOTICE, "PACKET CONTROL ACK with "
@ -410,7 +410,7 @@ void gprs_rlcmac_pdch::rcv_control_dl_ack_nack(Packet_Downlink_Ack_Nack_t *ack_n
char show_bits[RLC_GPRS_WS + 1];
tfi = ack_nack->DOWNLINK_TFI;
tbf = bts()->dl_tbf_by_poll_fn(fn, trx_no(), ts_no);
tbf = bts_dl_tbf_by_poll_fn(bts(), fn, trx_no(), ts_no);
if (!tbf) {
LOGP(DRLCMAC, LOGL_NOTICE, "PACKET DOWNLINK ACK with "
"unknown FN=%u TFI=%d (TRX %d TS %d)\n",
@ -477,7 +477,7 @@ void gprs_rlcmac_pdch::rcv_control_egprs_dl_ack_nack(EGPRS_PD_AckNack_t *ack_nac
int bsn_begin, bsn_end;
tfi = ack_nack->DOWNLINK_TFI;
tbf = bts()->dl_tbf_by_poll_fn(fn, trx_no(), ts_no);
tbf = bts_dl_tbf_by_poll_fn(bts(), fn, trx_no(), ts_no);
if (!tbf) {
LOGP(DRLCMAC, LOGL_NOTICE, "EGPRS PACKET DOWNLINK ACK with "
"unknown FN=%u TFI=%d (TRX %d TS %d)\n",
@ -566,10 +566,10 @@ void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request,
uint32_t tlli = request->ID.u.TLLI;
bool ms_found = true;
GprsMs *ms = bts()->ms_by_tlli(tlli);
GprsMs *ms = bts_ms_by_tlli(bts(), tlli, GSM_RESERVED_TMSI);
if (!ms) {
ms_found = false;
ms = bts()->ms_alloc(0, 0); /* ms class updated later */
ms = bts_alloc_ms(bts(), 0, 0); /* ms class updated later */
ms_set_tlli(ms, tlli);
}
ul_tbf = ms_ul_tbf(ms); /* hence ul_tbf may be NULL */
@ -580,10 +580,10 @@ void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request,
LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF "
"in packet resource request of single "
"block, so we provide one:\n");
sba = bts()->sba()->find(this, fn);
sba = bts_sba(bts())->find(this, fn);
if (sba) {
ms_set_ta(ms, sba->ta);
bts()->sba()->free_sba(sba);
bts_sba(bts())->free_sba(sba);
} else if (!ul_tbf || !ul_tbf->state_is(GPRS_RLCMAC_FINISHED)) {
LOGPTBFUL(ul_tbf, LOGL_NOTICE,
"MS requests UL TBF in PACKET RESOURCE REQ of "
@ -640,7 +640,7 @@ return_unref:
if (request->ID.u.Global_TFI.UnionType) {
struct gprs_rlcmac_dl_tbf *dl_tbf;
int8_t tfi = request->ID.u.Global_TFI.u.DOWNLINK_TFI;
dl_tbf = bts()->dl_tbf_by_tfi(tfi, trx_no(), ts_no);
dl_tbf = bts_dl_tbf_by_tfi(bts(), tfi, trx_no(), ts_no);
if (!dl_tbf) {
LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESOURCE REQ unknown downlink TFI=%d\n", tfi);
return;
@ -653,7 +653,7 @@ return_unref:
} else {
struct gprs_rlcmac_ul_tbf *ul_tbf;
int8_t tfi = request->ID.u.Global_TFI.u.UPLINK_TFI;
ul_tbf = bts()->ul_tbf_by_tfi(tfi, trx_no(), ts_no);
ul_tbf = bts_ul_tbf_by_tfi(bts(), tfi, trx_no(), ts_no);
if (!ul_tbf) {
LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESOURCE REQ unknown uplink TFI=%d\n", tfi);
return;
@ -671,16 +671,16 @@ void gprs_rlcmac_pdch::rcv_measurement_report(Packet_Measurement_Report_t *repor
struct gprs_rlcmac_sba *sba;
GprsMs *ms;
ms = bts()->ms_by_tlli(report->TLLI);
ms = bts_ms_by_tlli(bts(), report->TLLI, GSM_RESERVED_TMSI);
if (!ms) {
LOGP(DRLCMAC, LOGL_NOTICE, "MS send measurement "
"but TLLI 0x%08x is unknown\n", report->TLLI);
ms = bts()->ms_alloc(0, 0);
ms = bts_alloc_ms(bts(), 0, 0);
ms_set_tlli(ms, report->TLLI);
}
if ((sba = bts()->sba()->find(this, fn))) {
if ((sba = bts_sba(bts())->find(this, fn))) {
ms_set_ta(ms, sba->ta);
bts()->sba()->free_sba(sba);
bts_sba(bts())->free_sba(sba);
}
gprs_rlcmac_meas_rep(ms, report);
}
@ -703,9 +703,9 @@ int gprs_rlcmac_pdch::rcv_control_block(const uint8_t *data, uint8_t data_len,
rc = decode_gsm_rlcmac_uplink(rlc_block, ul_control_block);
if (ul_control_block->u.MESSAGE_TYPE == MT_PACKET_UPLINK_DUMMY_CONTROL_BLOCK)
bts()->send_gsmtap_meas(PCU_GSMTAP_C_UL_DUMMY, true, trx_no(), ts_no, GSMTAP_CHANNEL_PACCH, fn, data, data_len, meas);
bts_send_gsmtap_meas(bts(), PCU_GSMTAP_C_UL_DUMMY, true, trx_no(), ts_no, GSMTAP_CHANNEL_PACCH, fn, data, data_len, meas);
else
bts()->send_gsmtap_meas(PCU_GSMTAP_C_UL_CTRL, true, trx_no(), ts_no, GSMTAP_CHANNEL_PACCH, fn, data, data_len, meas);
bts_send_gsmtap_meas(bts(), PCU_GSMTAP_C_UL_CTRL, true, trx_no(), ts_no, GSMTAP_CHANNEL_PACCH, fn, data, data_len, meas);
if (rc < 0) {
LOGP(DRLCMACUL, LOGL_ERROR, "Dropping Uplink Control Block with invalid "
@ -714,7 +714,7 @@ int gprs_rlcmac_pdch::rcv_control_block(const uint8_t *data, uint8_t data_len,
}
LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- RX : Uplink Control Block -------------------------\n");
bts()->do_rate_ctr_inc(CTR_RLC_RECV_CONTROL);
bts_do_rate_ctr_inc(bts(), CTR_RLC_RECV_CONTROL);
switch (ul_control_block->u.MESSAGE_TYPE) {
case MT_PACKET_CONTROL_ACK:
rcv_control_ack(&ul_control_block->u.Packet_Control_Acknowledgement, fn);
@ -735,7 +735,7 @@ int gprs_rlcmac_pdch::rcv_control_block(const uint8_t *data, uint8_t data_len,
/* ignoring it. change the SI to not force sending these? */
break;
default:
bts()->do_rate_ctr_inc(CTR_DECODE_ERRORS);
bts_do_rate_ctr_inc(bts(), CTR_DECODE_ERRORS);
LOGP(DRLCMAC, LOGL_NOTICE,
"RX: [PCU <- BTS] unknown control block(%d) received\n",
ul_control_block->u.MESSAGE_TYPE);
@ -752,13 +752,13 @@ int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn,
{
enum CodingScheme cs = mcs_get_by_size_ul(len);
if (!cs) {
bts()->do_rate_ctr_inc(CTR_DECODE_ERRORS);
bts_do_rate_ctr_inc(bts(), CTR_DECODE_ERRORS);
LOGP(DRLCMACUL, LOGL_ERROR, "Dropping data block with invalid "
"length %d: %s\n", len, osmo_hexdump(data, len));
return -EINVAL;
}
bts()->do_rate_ctr_add(CTR_RLC_UL_BYTES, len);
bts_do_rate_ctr_add(bts(), CTR_RLC_UL_BYTES, len);
LOGP(DRLCMACUL, LOGL_DEBUG, "Got RLC block, coding scheme: %s, "
"length: %d (%d))\n", mcs_name(cs), len, mcs_used_size_ul(cs));
@ -769,7 +769,7 @@ int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn,
if (mcs_is_edge(cs))
return rcv_data_block(data, len, fn, meas, cs);
bts()->do_rate_ctr_inc(CTR_DECODE_ERRORS);
bts_do_rate_ctr_inc(bts(), CTR_DECODE_ERRORS);
LOGP(DRLCMACUL, LOGL_ERROR, "Unsupported coding scheme %s\n",
mcs_name(cs));
return -EINVAL;
@ -788,11 +788,11 @@ int gprs_rlcmac_pdch::rcv_data_block(uint8_t *data, uint8_t data_len, uint32_t f
* control blocks (see 44.060, section 10.3, 1st par.)
*/
if (mcs_is_edge(cs)) {
bts()->send_gsmtap_meas(PCU_GSMTAP_C_UL_DATA_EGPRS, true,
bts_send_gsmtap_meas(bts(), PCU_GSMTAP_C_UL_DATA_EGPRS, true,
trx_no(), ts_no, GSMTAP_CHANNEL_PDTCH, fn,
data, data_len, meas);
} else {
bts()->send_gsmtap_meas(PCU_GSMTAP_C_UL_DATA_GPRS, true,
bts_send_gsmtap_meas(bts(), PCU_GSMTAP_C_UL_DATA_GPRS, true,
trx_no(), ts_no, GSMTAP_CHANNEL_PDTCH, fn,
data, data_len, meas);
}
@ -804,7 +804,7 @@ int gprs_rlcmac_pdch::rcv_data_block(uint8_t *data, uint8_t data_len, uint32_t f
LOGP(DRLCMACUL, LOGL_ERROR,
"Got %s RLC block but header parsing has failed\n",
mcs_name(cs));
bts()->do_rate_ctr_inc(CTR_DECODE_ERRORS);
bts_do_rate_ctr_inc(bts(), CTR_DECODE_ERRORS);
return rc;
}
@ -974,7 +974,7 @@ void gprs_rlcmac_pdch::unreserve(enum gprs_rlcmac_tbf_direction dir)
m_num_reserved[dir] -= 1;
}
inline BTS *gprs_rlcmac_pdch::bts() const
inline struct gprs_rlcmac_bts *gprs_rlcmac_pdch::bts() const
{
return trx->bts;
}
@ -986,7 +986,7 @@ uint8_t gprs_rlcmac_pdch::trx_no() const
inline gprs_rlcmac_bts *gprs_rlcmac_pdch::bts_data() const
{
return trx->bts->bts_data();
return trx->bts;
}
/* PTCCH (Packet Timing Advance Control Channel) */

View File

@ -70,7 +70,7 @@ struct gprs_rlcmac_pdch {
struct pcu_l1_meas *meas, enum CodingScheme cs);
gprs_rlcmac_bts *bts_data() const;
BTS *bts() const;
struct gprs_rlcmac_bts *bts() const;
uint8_t trx_no() const;
struct gprs_rlcmac_ul_tbf *ul_tbf_by_tfi(uint8_t tfi);

View File

@ -24,6 +24,7 @@
#include <bts.h>
#include <tbf.h>
#include <tbf_ul.h>
#include <tbf_dl.h>
#include <cxx_linuxlist.h>
#include <sba.h>
@ -32,7 +33,7 @@ extern "C" {
#include <osmocom/gsm/gsm_utils.h>
}
PollController::PollController(BTS& bts)
PollController::PollController(struct gprs_rlcmac_bts& bts)
: m_bts(bts)
{}
@ -51,26 +52,26 @@ void PollController::expireTimedout(int frame_number, unsigned max_delay)
struct gprs_rlcmac_dl_tbf *dl_tbf;
struct gprs_rlcmac_ul_tbf *ul_tbf;
struct gprs_rlcmac_sba *sba, *sba2;
LListHead<gprs_rlcmac_tbf> *pos;
struct llist_item *pos;
llist_for_each(pos, &m_bts.ul_tbfs()) {
ul_tbf = as_ul_tbf(pos->entry());
llist_for_each_entry(pos, &m_bts.ul_tbfs, list) {
ul_tbf = as_ul_tbf((struct gprs_rlcmac_tbf *)pos->entry);
if (ul_tbf->poll_scheduled()) {
if (elapsed_fn_check(max_delay, frame_number, ul_tbf->poll_fn))
ul_tbf->poll_timeout();
}
}
llist_for_each(pos, &m_bts.dl_tbfs()) {
dl_tbf = as_dl_tbf(pos->entry());
llist_for_each_entry(pos, &m_bts.dl_tbfs, list) {
dl_tbf = as_dl_tbf((struct gprs_rlcmac_tbf *)pos->entry);
if (dl_tbf->poll_scheduled()) {
if (elapsed_fn_check(max_delay, frame_number, dl_tbf->poll_fn))
dl_tbf->poll_timeout();
}
}
llist_for_each_entry_safe(sba, sba2, &m_bts.sba()->m_sbas, list) {
llist_for_each_entry_safe(sba, sba2, &bts_sba(&m_bts)->m_sbas, list) {
if (elapsed_fn_check(max_delay, frame_number, sba->fn)) {
/* sba will be freed here */
m_bts.sba()->timeout(sba);
bts_sba(&m_bts)->timeout(sba);
}
}

View File

@ -21,22 +21,22 @@
#pragma once
struct BTS;
struct gprs_rlcmac_bts;
/**
* I belong to a BTS and I am responsible for finding TBFs and
* SBAs that should have been polled and execute the timeout
* action on them.
*/
class PollController {
struct PollController {
public:
PollController(BTS& bts);
PollController(struct gprs_rlcmac_bts& bts);
/* check for poll timeout */
void expireTimedout(int frame_number, unsigned max_delay);
private:
BTS& m_bts;
struct gprs_rlcmac_bts& m_bts;
private:
/* disable copying to avoid slicing */

View File

@ -127,7 +127,7 @@ static uint16_t bitnum_to_bsn(int bitnum, uint16_t ssn)
return (ssn - 1 - bitnum);
}
void gprs_rlc_dl_window::update(BTS *bts, const struct bitvec *rbb,
void gprs_rlc_dl_window::update(struct gprs_rlcmac_bts *bts, const struct bitvec *rbb,
uint16_t first_bsn, uint16_t *lost,
uint16_t *received)
{
@ -154,13 +154,13 @@ void gprs_rlc_dl_window::update(BTS *bts, const struct bitvec *rbb,
} else {
LOGP(DRLCMACDL, LOGL_DEBUG, "- got NACK for BSN=%d\n", bsn);
m_v_b.mark_nacked(bsn);
bts->do_rate_ctr_inc(CTR_RLC_NACKED);
bts_do_rate_ctr_inc(bts, CTR_RLC_NACKED);
*lost += 1;
}
}
}
void gprs_rlc_dl_window::update(BTS *bts, char *show_rbb, uint16_t ssn,
void gprs_rlc_dl_window::update(struct gprs_rlcmac_bts *bts, char *show_rbb, uint16_t ssn,
uint16_t *lost, uint16_t *received)
{
/* SSN - 1 is in range V(A)..V(S)-1 */
@ -178,7 +178,7 @@ void gprs_rlc_dl_window::update(BTS *bts, char *show_rbb, uint16_t ssn,
} else {
LOGP(DRLCMACDL, LOGL_DEBUG, "- got NACK for BSN=%d\n", bsn);
m_v_b.mark_nacked(bsn);
bts->do_rate_ctr_inc(CTR_RLC_NACKED);
bts_do_rate_ctr_inc(bts, CTR_RLC_NACKED);
*lost += 1;
}
}

View File

@ -38,7 +38,7 @@ extern "C" {
#define RLC_MAX_WS RLC_EGPRS_MAX_WS
#define RLC_MAX_LEN 74 /* MCS-9 data unit */
struct BTS;
struct gprs_rlcmac_bts;
/* The state of a BSN in the send/receive window */
enum gprs_rlc_ul_bsn_state {
@ -307,9 +307,9 @@ struct gprs_rlc_dl_window: public gprs_rlc_window {
/* Methods to manage reception */
int resend_needed() const;
int mark_for_resend();
void update(BTS *bts, char *show_rbb, uint16_t ssn,
void update(struct gprs_rlcmac_bts *bts, char *show_rbb, uint16_t ssn,
uint16_t *lost, uint16_t *received);
void update(BTS *bts, const struct bitvec *rbb,
void update(struct gprs_rlcmac_bts *bts, const struct bitvec *rbb,
uint16_t first_bsn, uint16_t *lost,
uint16_t *received);
int move_window();

View File

@ -40,7 +40,7 @@ extern void *tall_pcu_ctx;
* This offset must be a multiple of 13. */
#define AGCH_START_OFFSET 52
SBAController::SBAController(BTS &bts)
SBAController::SBAController(struct gprs_rlcmac_bts &bts)
: m_bts(bts)
{
INIT_LLIST_HEAD(&m_sbas);
@ -64,7 +64,7 @@ int SBAController::alloc(
for (trx = 0; trx < 8; trx++) {
for (ts = 7; ts >= 0; ts--) {
pdch = &m_bts.bts_data()->trx[trx].pdch[ts];
pdch = &m_bts.trx[trx].pdch[ts];
if (!pdch->is_enabled())
continue;
break;
@ -86,7 +86,7 @@ int SBAController::alloc(
sba->ta = ta;
llist_add(&sba->list, &m_sbas);
m_bts.do_rate_ctr_inc(CTR_SBA_ALLOCATED);
bts_do_rate_ctr_inc(&m_bts, CTR_SBA_ALLOCATED);
*_trx = trx;
*_ts = ts;
@ -132,14 +132,14 @@ int SBAController::timeout(struct gprs_rlcmac_sba *sba)
LOGP(DRLCMAC, LOGL_NOTICE,
"Poll timeout for SBA (TRX=%u, TS=%u, FN=%u, TA=%u)\n", sba->trx_no,
sba->ts_no, sba->fn, sba->ta);
m_bts.do_rate_ctr_inc(CTR_SBA_TIMEDOUT);
bts_do_rate_ctr_inc(&m_bts, CTR_SBA_TIMEDOUT);
free_sba(sba);
return 0;
}
void SBAController::free_sba(gprs_rlcmac_sba *sba)
{
m_bts.do_rate_ctr_inc(CTR_SBA_FREED);
bts_do_rate_ctr_inc(&m_bts, CTR_SBA_FREED);
llist_del(&sba->list);
talloc_free(sba);
}

View File

@ -26,7 +26,7 @@ extern "C" {
#include <osmocom/core/linuxlist.h>
}
struct BTS;
struct gprs_rlcmac_bts;
struct gprs_rlcmac_pdch;
/*
@ -45,10 +45,10 @@ struct gprs_rlcmac_sba {
*
* TODO: Add a flush method..
*/
class SBAController {
struct SBAController {
friend class PollController;
public:
SBAController(BTS &bts);
SBAController(struct gprs_rlcmac_bts &bts);
int alloc(uint8_t *_trx, uint8_t *_ts, uint32_t *_fn, uint8_t ta);
gprs_rlcmac_sba *find(uint8_t trx, uint8_t ts, uint32_t fn);
@ -62,6 +62,6 @@ public:
void free_sba(gprs_rlcmac_sba *sba);
private:
BTS &m_bts;
struct gprs_rlcmac_bts &m_bts;
llist_head m_sbas;
};

View File

@ -124,7 +124,7 @@ gprs_rlcmac_tbf::Meas::Meas() :
timespecclear(&rssi_tv);
}
gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, GprsMs *ms, gprs_rlcmac_tbf_direction dir) :
gprs_rlcmac_tbf::gprs_rlcmac_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms, gprs_rlcmac_tbf_direction dir) :
state_flags(0),
direction(dir),
trx(NULL),
@ -147,7 +147,6 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, GprsMs *ms, gprs_rlcmac_tbf_directio
ul_ass_state(GPRS_RLCMAC_UL_ASS_NONE),
ul_ack_state(GPRS_RLCMAC_UL_ACK_NONE),
poll_state(GPRS_RLCMAC_POLL_NONE),
m_list(this),
m_egprs_enabled(false)
{
/* The classes of these members do not have proper constructors yet.
@ -160,6 +159,9 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, GprsMs *ms, gprs_rlcmac_tbf_directio
memset(&m_ms_list, 0, sizeof(m_ms_list));
m_ms_list.entry = this;
memset(&m_bts_list, 0, sizeof(m_bts_list));
m_bts_list.entry = this;
m_rlc.init();
m_llc.init();
@ -168,7 +170,7 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, GprsMs *ms, gprs_rlcmac_tbf_directio
gprs_rlcmac_bts *gprs_rlcmac_tbf::bts_data() const
{
return bts->bts_data();
return bts;
}
uint32_t gprs_rlcmac_tbf::tlli() const
@ -245,7 +247,7 @@ void gprs_rlcmac_tbf::update_ms(uint32_t tlli, enum gprs_rlcmac_tbf_direction di
if (!ms_check_tlli(ms(), tlli)) {
GprsMs *old_ms;
old_ms = bts->ms_store().get_ms(tlli, 0, NULL);
old_ms = bts_ms_store(bts)->get_ms(tlli, 0, NULL);
if (old_ms)
ms_merge_and_clear_ms(ms(), old_ms);
}
@ -274,9 +276,9 @@ void tbf_free(struct gprs_rlcmac_tbf *tbf)
/* update counters */
if (tbf->direction == GPRS_RLCMAC_UL_TBF) {
gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(tbf);
tbf->bts->do_rate_ctr_inc(CTR_TBF_UL_FREED);
bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_UL_FREED);
if (tbf->state_is(GPRS_RLCMAC_FLOW))
tbf->bts->do_rate_ctr_inc(CTR_TBF_UL_ABORTED);
bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_UL_ABORTED);
rate_ctr_group_free(ul_tbf->m_ul_egprs_ctrs);
rate_ctr_group_free(ul_tbf->m_ul_gprs_ctrs);
} else {
@ -286,9 +288,9 @@ void tbf_free(struct gprs_rlcmac_tbf *tbf)
} else {
rate_ctr_group_free(dl_tbf->m_dl_gprs_ctrs);
}
tbf->bts->do_rate_ctr_inc(CTR_TBF_DL_FREED);
bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_DL_FREED);
if (tbf->state_is(GPRS_RLCMAC_FLOW))
tbf->bts->do_rate_ctr_inc(CTR_TBF_DL_ABORTED);
bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_DL_ABORTED);
}
/* Give final measurement report */
@ -304,7 +306,7 @@ void tbf_free(struct gprs_rlcmac_tbf *tbf)
tbf->stop_timers("freeing TBF");
/* TODO: Could/Should generate bssgp_tx_llc_discarded */
tbf_unlink_pdch(tbf);
llist_del(&tbf->list());
llist_del(tbf_bts_list(tbf));
if (tbf->ms())
tbf->set_ms(NULL);
@ -326,7 +328,7 @@ uint16_t egprs_window_size(const struct gprs_rlcmac_bts *bts_data, uint8_t slots
int gprs_rlcmac_tbf::update()
{
struct gprs_rlcmac_bts *bts_data = bts->bts_data();
struct gprs_rlcmac_bts *bts_data = bts;
int rc;
if (direction != GPRS_RLCMAC_DL_TBF)
@ -399,13 +401,13 @@ bool gprs_rlcmac_tbf::n_inc(enum tbf_counters n)
switch(n) {
case N3101:
chk = bts->bts_data()->n3101;
chk = bts->n3101;
break;
case N3103:
chk = bts->bts_data()->n3103;
chk = bts->n3103;
break;
case N3105:
chk = bts->bts_data()->n3105;
chk = bts->n3105;
break;
default:
LOGPTBF(this, LOGL_ERROR, "unhandled counter %s\n",
@ -492,7 +494,7 @@ void gprs_rlcmac_tbf::t_start(enum tbf_timers t, int T, const char *reason, bool
int microsec;
struct osmo_tdef *tdef;
if (!(tdef = osmo_tdef_get_entry(bts->bts_data()->T_defs_bts, T)))
if (!(tdef = osmo_tdef_get_entry(bts->T_defs_bts, T)))
tdef = osmo_tdef_get_entry(bts->pcu->T_defs, T);
if (t >= T_MAX || !tdef) {
@ -563,7 +565,7 @@ int gprs_rlcmac_tbf::check_polling(uint32_t fn, uint8_t ts,
LOGPTBF(this, LOGL_DEBUG, "Polling is already scheduled\n");
return -EBUSY;
}
if (bts->sba()->find(trx->trx_no, ts, next_fn(fn, 13))) {
if (bts_sba(bts)->find(trx->trx_no, ts, next_fn(fn, 13))) {
LOGPTBF(this, LOGL_DEBUG, "Polling is already scheduled "
"for single block allocation at FN %d TS %d ...\n",
new_poll_fn, ts);
@ -628,7 +630,7 @@ void gprs_rlcmac_tbf::poll_timeout()
gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(this);
LOGPTBF(this, LOGL_NOTICE, "poll timeout for FN=%d, TS=%d (curr FN %d)\n",
poll_fn, poll_ts, bts->current_frame_number());
poll_fn, poll_ts, bts_current_frame_number(bts));
poll_state = GPRS_RLCMAC_POLL_NONE;
@ -644,11 +646,11 @@ void gprs_rlcmac_tbf::poll_timeout()
"Timeout for polling PACKET CONTROL ACK for PACKET UPLINK ACK: %s\n",
rlcmac_diag().c_str());
}
bts->do_rate_ctr_inc(CTR_RLC_ACK_TIMEDOUT);
bts->do_rate_ctr_inc(CTR_PUAN_POLL_TIMEDOUT);
bts_do_rate_ctr_inc(bts, CTR_RLC_ACK_TIMEDOUT);
bts_do_rate_ctr_inc(bts, CTR_PUAN_POLL_TIMEDOUT);
if (state_is(GPRS_RLCMAC_FINISHED)) {
if (ul_tbf->n_inc(N3103)) {
bts->do_rate_ctr_inc(CTR_PUAN_POLL_FAILED);
bts_do_rate_ctr_inc(bts, CTR_PUAN_POLL_FAILED);
TBF_SET_STATE(ul_tbf, GPRS_RLCMAC_RELEASING);
T_START(ul_tbf, T3169, 3169, "MAX N3103 reached", false);
return;
@ -665,13 +667,13 @@ void gprs_rlcmac_tbf::poll_timeout()
state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS);
}
ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE;
bts->do_rate_ctr_inc(CTR_RLC_ASS_TIMEDOUT);
bts->do_rate_ctr_inc(CTR_PUA_POLL_TIMEDOUT);
bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_TIMEDOUT);
bts_do_rate_ctr_inc(bts, CTR_PUA_POLL_TIMEDOUT);
if (n_inc(N3105)) {
TBF_SET_STATE(this, GPRS_RLCMAC_RELEASING);
T_START(this, T3195, 3195, "MAX N3105 reached", true);
bts->do_rate_ctr_inc(CTR_RLC_ASS_FAILED);
bts->do_rate_ctr_inc(CTR_PUA_POLL_FAILED);
bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_FAILED);
bts_do_rate_ctr_inc(bts, CTR_PUA_POLL_FAILED);
return;
}
/* reschedule UL assignment */
@ -684,13 +686,13 @@ void gprs_rlcmac_tbf::poll_timeout()
state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS);
}
dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
bts->do_rate_ctr_inc(CTR_RLC_ASS_TIMEDOUT);
bts->do_rate_ctr_inc(CTR_PDA_POLL_TIMEDOUT);
bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_TIMEDOUT);
bts_do_rate_ctr_inc(bts, CTR_PDA_POLL_TIMEDOUT);
if (n_inc(N3105)) {
TBF_SET_STATE(this, GPRS_RLCMAC_RELEASING);
T_START(this, T3195, 3195, "MAX N3105 reached", true);
bts->do_rate_ctr_inc(CTR_RLC_ASS_FAILED);
bts->do_rate_ctr_inc(CTR_PDA_POLL_FAILED);
bts_do_rate_ctr_inc(bts, CTR_RLC_ASS_FAILED);
bts_do_rate_ctr_inc(bts, CTR_PDA_POLL_FAILED);
return;
}
/* reschedule DL assignment */
@ -706,17 +708,17 @@ void gprs_rlcmac_tbf::poll_timeout()
}
if (dl_tbf->state_is(GPRS_RLCMAC_RELEASING))
bts->do_rate_ctr_inc(CTR_RLC_REL_TIMEDOUT);
bts_do_rate_ctr_inc(bts, CTR_RLC_REL_TIMEDOUT);
else {
bts->do_rate_ctr_inc(CTR_RLC_ACK_TIMEDOUT);
bts->do_rate_ctr_inc(CTR_PDAN_POLL_TIMEDOUT);
bts_do_rate_ctr_inc(bts, CTR_RLC_ACK_TIMEDOUT);
bts_do_rate_ctr_inc(bts, CTR_PDAN_POLL_TIMEDOUT);
}
if (dl_tbf->n_inc(N3105)) {
TBF_SET_STATE(dl_tbf, GPRS_RLCMAC_RELEASING);
T_START(dl_tbf, T3195, 3195, "MAX N3105 reached", true);
bts->do_rate_ctr_inc(CTR_PDAN_POLL_FAILED);
bts->do_rate_ctr_inc(CTR_RLC_ACK_FAILED);
bts_do_rate_ctr_inc(bts, CTR_PDAN_POLL_FAILED);
bts_do_rate_ctr_inc(bts, CTR_RLC_ACK_FAILED);
return;
}
/* resend IMM.ASS on CCCH on timeout */
@ -727,7 +729,7 @@ void gprs_rlcmac_tbf::poll_timeout()
/* send immediate assignment */
if ((pgroup = imsi2paging_group(imsi())) > 999)
LOGPTBF(dl_tbf, LOGL_ERROR, "IMSI to paging group failed! (%s)\n", imsi());
dl_tbf->bts->snd_dl_ass(dl_tbf, false, pgroup);
bts_snd_dl_ass(dl_tbf->bts, dl_tbf, false, pgroup);
dl_tbf->m_wait_confirm = 1;
}
} else
@ -736,7 +738,7 @@ void gprs_rlcmac_tbf::poll_timeout()
int gprs_rlcmac_tbf::setup(int8_t use_trx, bool single_slot)
{
struct gprs_rlcmac_bts *bts_data = bts->bts_data();
struct gprs_rlcmac_bts *bts_data = bts;
int rc;
if (ms_mode(m_ms) != GPRS)
@ -935,7 +937,7 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts)
goto free_ret;
}
LOGP(DTBF, LOGL_DEBUG, "------------------------- TX : Packet Downlink Assignment -------------------------\n");
bts->do_rate_ctr_inc(CTR_PKT_DL_ASSIGNMENT);
bts_do_rate_ctr_inc(bts, CTR_PKT_DL_ASSIGNMENT);
if (poll_ass_dl) {
set_polling(new_poll_fn, ts, GPRS_RLCMAC_POLL_DL_ASS);
@ -970,7 +972,7 @@ struct msgb *gprs_rlcmac_tbf::create_packet_access_reject()
Encoding::write_packet_access_reject(
packet_access_rej, tlli());
bts->do_rate_ctr_inc(CTR_PKT_ACCESS_REJ);
bts_do_rate_ctr_inc(bts, CTR_PKT_ACCESS_REJ);
bitvec_pack(packet_access_rej, msgb_put(msg, GSM_MACBLOCK_LEN));
@ -1039,7 +1041,7 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts)
goto free_ret;
}
LOGP(DTBF, LOGL_DEBUG, "------------------------- TX : Packet Uplink Assignment -------------------------\n");
bts->do_rate_ctr_inc(CTR_PKT_UL_ASSIGNMENT);
bts_do_rate_ctr_inc(bts, CTR_PKT_UL_ASSIGNMENT);
set_polling(new_poll_fn, ts, GPRS_RLCMAC_POLL_UL_ASS);
@ -1076,9 +1078,9 @@ int gprs_rlcmac_tbf::establish_dl_tbf_on_pacch()
{
struct gprs_rlcmac_dl_tbf *new_tbf = NULL;
bts->do_rate_ctr_inc(CTR_TBF_REUSED);
bts_do_rate_ctr_inc(bts, CTR_TBF_REUSED);
new_tbf = tbf_alloc_dl_tbf(bts->bts_data(), ms(),
new_tbf = tbf_alloc_dl_tbf(bts, ms(),
this->trx->trx_no, false);
if (!new_tbf) {
@ -1112,11 +1114,11 @@ const char *gprs_rlcmac_tbf::name() const
void gprs_rlcmac_tbf::rotate_in_list()
{
llist_del(&list());
llist_del(tbf_bts_list((struct gprs_rlcmac_tbf *)this));
if (direction == GPRS_RLCMAC_UL_TBF)
llist_add(&list(), &bts->ul_tbfs());
llist_add(tbf_bts_list((struct gprs_rlcmac_tbf *)this), &bts->ul_tbfs);
else
llist_add(&list(), &bts->dl_tbfs());
llist_add(tbf_bts_list((struct gprs_rlcmac_tbf *)this), &bts->dl_tbfs);
}
uint8_t gprs_rlcmac_tbf::tsc() const
@ -1186,6 +1188,11 @@ struct llist_head *tbf_ms_list(struct gprs_rlcmac_tbf *tbf)
return &tbf->m_ms_list.list;
}
struct llist_head *tbf_bts_list(struct gprs_rlcmac_tbf *tbf)
{
return &tbf->m_bts_list.list;
}
struct GprsMs *tbf_ms(struct gprs_rlcmac_tbf *tbf)
{
return tbf->ms();

View File

@ -196,6 +196,7 @@ enum gprs_rlcmac_tbf_state tbf_state(const struct gprs_rlcmac_tbf *tbf);
enum gprs_rlcmac_tbf_direction tbf_direction(const struct gprs_rlcmac_tbf *tbf);
void tbf_set_ms(struct gprs_rlcmac_tbf *tbf, struct GprsMs *ms);
struct llist_head *tbf_ms_list(struct gprs_rlcmac_tbf *tbf);
struct llist_head *tbf_bts_list(struct gprs_rlcmac_tbf *tbf);
struct GprsMs *tbf_ms(struct gprs_rlcmac_tbf *tbf);
bool tbf_timers_pending(struct gprs_rlcmac_tbf *tbf, enum tbf_timers t);
void tbf_free(struct gprs_rlcmac_tbf *tbf);
@ -212,7 +213,7 @@ int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf);
#ifdef __cplusplus
struct gprs_rlcmac_tbf {
gprs_rlcmac_tbf(BTS *bts_, GprsMs *ms, gprs_rlcmac_tbf_direction dir);
gprs_rlcmac_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms, gprs_rlcmac_tbf_direction dir);
virtual ~gprs_rlcmac_tbf() {}
static void free_all(struct gprs_rlcmac_trx *trx);
@ -296,9 +297,6 @@ struct gprs_rlcmac_tbf {
/* attempt to make things a bit more fair */
void rotate_in_list();
LListHead<gprs_rlcmac_tbf>& list();
const LListHead<gprs_rlcmac_tbf>& list() const;
uint32_t state_flags;
enum gprs_rlcmac_tbf_direction direction;
struct gprs_rlcmac_trx *trx;
@ -335,7 +333,7 @@ struct gprs_rlcmac_tbf {
uint8_t upgrade_to_multislot;
/* store the BTS this TBF belongs to */
BTS *bts;
struct gprs_rlcmac_bts *bts;
/*
* private fields. We can't make it private as it is breaking the
@ -347,6 +345,7 @@ struct gprs_rlcmac_tbf {
struct rate_ctr_group *m_ctrs;
enum gprs_rlcmac_tbf_state state;
struct llist_item m_ms_list;
struct llist_item m_bts_list;
protected:
gprs_rlcmac_bts *bts_data() const;
@ -364,7 +363,6 @@ private:
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;
LListHead<gprs_rlcmac_tbf> m_list;
bool m_egprs_enabled;
struct osmo_timer_list Tarr[T_MAX];
uint8_t Narr[N_MAX];
@ -522,16 +520,6 @@ inline bool gprs_rlcmac_tbf::check_n_clear(uint8_t state_flag)
return false;
}
inline LListHead<gprs_rlcmac_tbf>& gprs_rlcmac_tbf::list()
{
return this->m_list;
}
inline const LListHead<gprs_rlcmac_tbf>& gprs_rlcmac_tbf::list() const
{
return this->m_list;
}
inline GprsMs *gprs_rlcmac_tbf::ms() const
{
return m_ms;

View File

@ -139,7 +139,7 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, GprsMs
return NULL;
talloc_set_destructor(tbf, dl_tbf_dtor);
new (tbf) gprs_rlcmac_dl_tbf(bts->bts, ms);
new (tbf) gprs_rlcmac_dl_tbf(bts, ms);
rc = tbf->setup(use_trx, single_slot);
/* if no resource */
@ -169,8 +169,8 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, GprsMs
}
}
llist_add(&tbf->list(), &bts->bts->dl_tbfs());
tbf->bts->do_rate_ctr_inc(CTR_TBF_DL_ALLOCATED);
llist_add(tbf_bts_list((struct gprs_rlcmac_tbf *)tbf), &bts->dl_tbfs);
bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_DL_ALLOCATED);
tbf->m_last_dl_poll_fn = -1;
tbf->m_last_dl_drained_fn = -1;
@ -181,7 +181,7 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, GprsMs
return tbf;
}
gprs_rlcmac_dl_tbf::gprs_rlcmac_dl_tbf(BTS *bts_, GprsMs *ms) :
gprs_rlcmac_dl_tbf::gprs_rlcmac_dl_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms) :
gprs_rlcmac_tbf(bts_, ms, GPRS_RLCMAC_DL_TBF),
m_tx_counter(0),
m_wait_confirm(0),
@ -289,10 +289,10 @@ int gprs_rlcmac_dl_tbf::handle(struct gprs_rlcmac_bts *bts,
GprsMs *ms, *ms_old;
/* check for existing TBF */
ms = bts->bts->ms_store().get_ms(tlli, tlli_old, imsi);
ms = bts_ms_store(bts)->get_ms(tlli, tlli_old, imsi);
if (ms && strlen(ms_imsi(ms)) == 0) {
ms_old = bts->bts->ms_store().get_ms(0, 0, imsi);
ms_old = bts_ms_store(bts)->get_ms(0, 0, imsi);
if (ms_old && ms_old != ms) {
/* The TLLI has changed (RAU), so there are two MS
* objects for the same MS */
@ -317,7 +317,7 @@ int gprs_rlcmac_dl_tbf::handle(struct gprs_rlcmac_bts *bts,
}
if (!ms)
ms = bts->bts->ms_alloc(ms_class, egprs_ms_class);
ms = bts_alloc_ms(bts, ms_class, egprs_ms_class);
ms_set_imsi(ms, imsi);
ms_confirm_tlli(ms, tlli);
if (!ms_ms_class(ms) && ms_class) {
@ -391,12 +391,12 @@ struct msgb *gprs_rlcmac_dl_tbf::llc_dequeue(bssgp_bvc_ctx *bctx)
break;
}
bts->do_rate_ctr_inc(CTR_LLC_FRAME_TIMEDOUT);
bts_do_rate_ctr_inc(bts, CTR_LLC_FRAME_TIMEDOUT);
drop_frame:
frames++;
octets += msg->len;
msgb_free(msg);
bts->do_rate_ctr_inc(CTR_LLC_FRAME_DROPPED);
bts_do_rate_ctr_inc(bts, CTR_LLC_FRAME_DROPPED);
continue;
}
@ -463,9 +463,9 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn,
* MCS1-4, because USF for GPRS-only MS will be sent */
force_cs = ms_current_cs_dl(m_ms);
if (force_cs > MCS4) {
force_cs = bts->cs_dl_is_supported(MCS4) ? MCS4 :
bts->cs_dl_is_supported(MCS3) ? MCS3 :
bts->cs_dl_is_supported(MCS2) ? MCS2 :
force_cs = bts_cs_dl_is_supported(bts, MCS4) ? MCS4 :
bts_cs_dl_is_supported(bts, MCS3) ? MCS3 :
bts_cs_dl_is_supported(bts, MCS2) ? MCS2 :
MCS1;
LOGPTBFDL(this, LOGL_DEBUG,
"Force downgrading DL %s -> %s due to USF for GPRS-only MS\n",
@ -515,7 +515,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn,
LOGPTBFDL(this, LOGL_DEBUG, "Resending BSN %d\n", bsn);
/* re-send block with negative aknowlegement */
m_window.m_v_b.mark_unacked(bsn);
bts->do_rate_ctr_inc(CTR_RLC_RESENT);
bts_do_rate_ctr_inc(bts, CTR_RLC_RESENT);
} else if (state_is(GPRS_RLCMAC_FINISHED)) {
/* If the TBF is in finished, we already sent all packages at least once.
* If any packages could have been sent (because of unacked) it should have
@ -523,7 +523,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn,
LOGPTBFDL(this, LOGL_DEBUG,
"Restarting at BSN %d, because all blocks have been transmitted.\n",
m_window.v_a());
bts->do_rate_ctr_inc(CTR_RLC_RESTARTED);
bts_do_rate_ctr_inc(bts, CTR_RLC_RESTARTED);
if (restart_bsn_cycle())
return take_next_bsn(fn, previous_bsn, req_mcs_kind, may_combine);
} else if (dl_window_stalled()) {
@ -532,7 +532,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn,
LOGPTBFDL(this, LOGL_NOTICE,
"Restarting at BSN %d, because the window is stalled.\n",
m_window.v_a());
bts->do_rate_ctr_inc(CTR_RLC_STALLED);
bts_do_rate_ctr_inc(bts, CTR_RLC_STALLED);
if (restart_bsn_cycle())
return take_next_bsn(fn, previous_bsn, req_mcs_kind, may_combine);
} else if (have_data()) {
@ -551,7 +551,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn,
LOGPTBFDL(this, LOGL_DEBUG,
"Restarting at BSN %d, because all blocks have been transmitted (FLOW).\n",
m_window.v_a());
bts->do_rate_ctr_inc(CTR_RLC_RESTARTED);
bts_do_rate_ctr_inc(bts, CTR_RLC_RESTARTED);
if (restart_bsn_cycle())
return take_next_bsn(fn, previous_bsn, req_mcs_kind, may_combine);
} else {
@ -568,8 +568,8 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn,
LOGPTBFDL(this, LOGL_DEBUG,
"Nothing else to send, Re-transmit final block!\n");
bsn = m_window.v_s_mod(-1);
bts->do_rate_ctr_inc(CTR_RLC_FINAL_BLOCK_RESENT);
bts->do_rate_ctr_inc(CTR_RLC_RESENT);
bts_do_rate_ctr_inc(bts, CTR_RLC_FINAL_BLOCK_RESENT);
bts_do_rate_ctr_inc(bts, CTR_RLC_RESENT);
}
*may_combine = num_data_blocks(mcs_header_type(m_rlc.block(bsn)->cs_current_trans)) > 1;
@ -628,7 +628,7 @@ void gprs_rlcmac_dl_tbf::trigger_ass(struct gprs_rlcmac_tbf *old_tbf)
/* send immediate assignment */
if ((pgroup = imsi2paging_group(imsi())) > 999)
LOGPTBFDL(this, LOGL_ERROR, "IMSI to paging group failed! (%s)\n", imsi());
bts->snd_dl_ass(this, false, pgroup);
bts_snd_dl_ass(bts, this, false, pgroup);
m_wait_confirm = 1;
}
}
@ -648,7 +648,7 @@ void gprs_rlcmac_dl_tbf::schedule_next_frame()
LOGPTBFDL(this, LOGL_DEBUG, "Dequeue next LLC (len=%d)\n", msg->len);
m_llc.put_frame(msg->data, msg->len);
bts->do_rate_ctr_inc(CTR_LLC_FRAME_SCHED);
bts_do_rate_ctr_inc(bts, CTR_LLC_FRAME_SCHED);
msgb_free(msg);
m_last_dl_drained_fn = -1;
}
@ -742,14 +742,14 @@ int gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, enum CodingScheme cs)
&m_llc, &write_offset, &num_chunks, data, is_final, &payload_written);
if (payload_written > 0)
bts->do_rate_ctr_add(CTR_RLC_DL_PAYLOAD_BYTES, payload_written);
bts_do_rate_ctr_add(bts, CTR_RLC_DL_PAYLOAD_BYTES, payload_written);
if (ar == Encoding::AR_NEED_MORE_BLOCKS)
break;
LOGPTBFDL(this, LOGL_DEBUG, "Complete DL frame, len=%d\n", llc_frame_length(&m_llc));
gprs_rlcmac_dl_bw(this, llc_frame_length(&m_llc));
bts->do_rate_ctr_add(CTR_LLC_DL_BYTES, llc_frame_length(&m_llc));
bts_do_rate_ctr_add(bts, CTR_LLC_DL_BYTES, llc_frame_length(&m_llc));
m_llc.reset();
if (is_final) {
@ -1472,15 +1472,15 @@ enum egprs_rlcmac_dl_spb gprs_rlcmac_dl_tbf::get_egprs_dl_spb(const int bsn)
*/
if (block_status_dl == EGPRS_RESEG_FIRST_SEG_SENT) {
/* statistics */
bts->do_rate_ctr_inc(CTR_SPB_DL_SECOND_SEGMENT);
bts_do_rate_ctr_inc(bts, CTR_SPB_DL_SECOND_SEGMENT);
return EGPRS_RLCMAC_DL_SEC_SEG;
} else if ((ht_cs_init == HEADER_EGPRS_DATA_TYPE_1) ||
(ht_cs_init == HEADER_EGPRS_DATA_TYPE_2)) {
bts->do_rate_ctr_inc(CTR_SPB_DL_FIRST_SEGMENT);
bts_do_rate_ctr_inc(bts, CTR_SPB_DL_FIRST_SEGMENT);
return EGPRS_RLCMAC_DL_FIRST_SEG;
} else if ((cs_init == MCS4) &&
(cs_current_trans == MCS1)) {
bts->do_rate_ctr_inc(CTR_SPB_DL_FIRST_SEGMENT);
bts_do_rate_ctr_inc(bts, CTR_SPB_DL_FIRST_SEGMENT);
return EGPRS_RLCMAC_DL_FIRST_SEG;
}
}
@ -1490,7 +1490,7 @@ enum egprs_rlcmac_dl_spb gprs_rlcmac_dl_tbf::get_egprs_dl_spb(const int bsn)
void gprs_rlcmac_dl_tbf::set_window_size()
{
const struct gprs_rlcmac_bts *b = bts->bts_data();
const struct gprs_rlcmac_bts *b = bts;
uint16_t ws = egprs_window_size(b, dl_slots());
LOGPTBFDL(this, LOGL_INFO, "setting EGPRS DL window size to %u, base(%u) slots(%u) ws_pdch(%u)\n",
@ -1502,55 +1502,55 @@ void gprs_rlcmac_dl_tbf::update_coding_scheme_counter_dl(enum CodingScheme cs)
{
switch (cs) {
case CS1:
bts->do_rate_ctr_inc(CTR_GPRS_DL_CS1);
bts_do_rate_ctr_inc(bts, CTR_GPRS_DL_CS1);
rate_ctr_inc(&m_dl_gprs_ctrs->ctr[TBF_CTR_GPRS_DL_CS1]);
break;
case CS2:
bts->do_rate_ctr_inc(CTR_GPRS_DL_CS2);
bts_do_rate_ctr_inc(bts, CTR_GPRS_DL_CS2);
rate_ctr_inc(&m_dl_gprs_ctrs->ctr[TBF_CTR_GPRS_DL_CS2]);
break;
case CS3:
bts->do_rate_ctr_inc(CTR_GPRS_DL_CS3);
bts_do_rate_ctr_inc(bts, CTR_GPRS_DL_CS3);
rate_ctr_inc(&m_dl_gprs_ctrs->ctr[TBF_CTR_GPRS_DL_CS3]);
break;
case CS4:
bts->do_rate_ctr_inc(CTR_GPRS_DL_CS4);
bts_do_rate_ctr_inc(bts, CTR_GPRS_DL_CS4);
rate_ctr_inc(&m_dl_gprs_ctrs->ctr[TBF_CTR_GPRS_DL_CS4]);
break;
case MCS1:
bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS1);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS1);
rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS1]);
break;
case MCS2:
bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS2);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS2);
rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS2]);
break;
case MCS3:
bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS3);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS3);
rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS3]);
break;
case MCS4:
bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS4);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS4);
rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS4]);
break;
case MCS5:
bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS5);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS5);
rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS5]);
break;
case MCS6:
bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS6);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS6);
rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS6]);
break;
case MCS7:
bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS7);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS7);
rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS7]);
break;
case MCS8:
bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS8);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS8);
rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS8]);
break;
case MCS9:
bts->do_rate_ctr_inc(CTR_EGPRS_DL_MCS9);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_DL_MCS9);
rate_ctr_inc(&m_dl_egprs_ctrs->ctr[TBF_CTR_EGPRS_DL_MCS9]);
break;
default:

View File

@ -39,7 +39,7 @@ enum tbf_dl_prio {
#define LOGPTBFDL(tbf, level, fmt, args...) LOGP(DTBFDL, level, "%s " fmt, tbf_name(tbf), ## args)
struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf {
gprs_rlcmac_dl_tbf(BTS *bts, GprsMs *ms);
gprs_rlcmac_dl_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms);
gprs_rlc_window *window();
void cleanup();
/* dispatch Unitdata.DL messages */

View File

@ -111,7 +111,7 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, GprsMs
if (!tbf)
return NULL;
talloc_set_destructor(tbf, ul_tbf_dtor);
new (tbf) gprs_rlcmac_ul_tbf(bts->bts, ms);
new (tbf) gprs_rlcmac_ul_tbf(bts, ms);
rc = tbf->setup(use_trx, single_slot);
@ -134,8 +134,8 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, GprsMs
return NULL;
}
llist_add(&tbf->list(), &bts->bts->ul_tbfs());
tbf->bts->do_rate_ctr_inc(CTR_TBF_UL_ALLOCATED);
llist_add_tail(tbf_bts_list(tbf), &bts->ul_tbfs);
bts_do_rate_ctr_inc(tbf->bts, CTR_TBF_UL_ALLOCATED);
return tbf;
}
@ -171,7 +171,7 @@ struct gprs_rlcmac_ul_tbf *handle_tbf_reject(struct gprs_rlcmac_bts *bts,
struct gprs_rlcmac_trx *trx = &bts->trx[trx_no];
if (!ms)
ms = bts->bts->ms_alloc(0, 0);
ms = bts_alloc_ms(bts, 0, 0);
ms_set_tlli(ms, tlli);
ul_tbf = talloc(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
@ -179,10 +179,10 @@ struct gprs_rlcmac_ul_tbf *handle_tbf_reject(struct gprs_rlcmac_bts *bts,
return ul_tbf;
talloc_set_destructor(ul_tbf, ul_tbf_dtor);
new (ul_tbf) gprs_rlcmac_ul_tbf(bts->bts, ms);
new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);
llist_add(&ul_tbf->list(), &bts->bts->ul_tbfs());
ul_tbf->bts->do_rate_ctr_inc(CTR_TBF_UL_ALLOCATED);
llist_add(tbf_bts_list((struct gprs_rlcmac_tbf *)ul_tbf), &bts->ul_tbfs);
bts_do_rate_ctr_inc(ul_tbf->bts, CTR_TBF_UL_ALLOCATED);
TBF_SET_ASS_ON(ul_tbf, GPRS_RLCMAC_FLAG_PACCH, false);
ms_attach_tbf(ms, ul_tbf);
@ -206,7 +206,7 @@ struct gprs_rlcmac_ul_tbf *handle_tbf_reject(struct gprs_rlcmac_bts *bts,
return ul_tbf;
}
gprs_rlcmac_ul_tbf::gprs_rlcmac_ul_tbf(BTS *bts_, GprsMs *ms) :
gprs_rlcmac_ul_tbf::gprs_rlcmac_ul_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms) :
gprs_rlcmac_tbf(bts_, ms, GPRS_RLCMAC_UL_TBF),
m_rx_counter(0),
m_contention_resolution_done(0),
@ -243,7 +243,7 @@ int gprs_rlcmac_ul_tbf::assemble_forward_llc(const gprs_rlc_data *_data)
frame = frames + i;
if (frame->length) {
bts->do_rate_ctr_add(CTR_RLC_UL_PAYLOAD_BYTES, frame->length);
bts_do_rate_ctr_add(bts, CTR_RLC_UL_PAYLOAD_BYTES, frame->length);
LOGPTBFUL(this, LOGL_DEBUG, "Frame %d "
"starts at offset %d, "
@ -259,7 +259,7 @@ int gprs_rlcmac_ul_tbf::assemble_forward_llc(const gprs_rlc_data *_data)
/* send frame to SGSN */
LOGPTBFUL(this, LOGL_DEBUG, "complete UL frame len=%d\n", llc_frame_length(&m_llc));
snd_ul_ud();
bts->do_rate_ctr_add(CTR_LLC_UL_BYTES, llc_frame_length(&m_llc));
bts_do_rate_ctr_add(bts, CTR_LLC_UL_BYTES, llc_frame_length(&m_llc));
m_llc.reset();
}
}
@ -440,7 +440,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged(
rdbi, rlc->cs, rlc_data, NULL, 0, &new_tlli);
if (num_chunks < 0) {
bts->do_rate_ctr_inc(CTR_DECODE_ERRORS);
bts_do_rate_ctr_inc(bts, CTR_DECODE_ERRORS);
LOGPTBFUL(this, LOGL_NOTICE,
"Failed to decode TLLI of %s UL DATA TFI=%d.\n",
mcs_name(rlc->cs), rlc->tfi);
@ -589,7 +589,7 @@ egprs_rlc_ul_reseg_bsn_state gprs_rlcmac_ul_tbf::handle_egprs_ul_second_seg(
union split_block_status *spb_status = &block->spb_status;
uint8_t *rlc_data = &block->block[0];
bts->do_rate_ctr_inc(CTR_SPB_UL_SECOND_SEGMENT);
bts_do_rate_ctr_inc(bts, CTR_SPB_UL_SECOND_SEGMENT);
if (spb_status->block_status_ul &
EGPRS_RESEG_FIRST_SEG_RXD) {
@ -622,7 +622,7 @@ egprs_rlc_ul_reseg_bsn_state gprs_rlcmac_ul_tbf::handle_egprs_ul_first_seg(
uint8_t *rlc_data = &block->block[0];
union split_block_status *spb_status = &block->spb_status;
bts->do_rate_ctr_inc(CTR_SPB_UL_FIRST_SEGMENT);
bts_do_rate_ctr_inc(bts, CTR_SPB_UL_FIRST_SEGMENT);
if (spb_status->block_status_ul & EGPRS_RESEG_SECOND_SEG_RXD) {
LOGPTBFUL(this, LOGL_DEBUG,
@ -702,55 +702,55 @@ void gprs_rlcmac_ul_tbf::update_coding_scheme_counter_ul(enum CodingScheme cs)
{
switch (cs) {
case CS1:
bts->do_rate_ctr_inc(CTR_GPRS_UL_CS1);
bts_do_rate_ctr_inc(bts, CTR_GPRS_UL_CS1);
rate_ctr_inc(&m_ul_gprs_ctrs->ctr[TBF_CTR_GPRS_UL_CS1]);
break;
case CS2:
bts->do_rate_ctr_inc(CTR_GPRS_UL_CS2);
bts_do_rate_ctr_inc(bts, CTR_GPRS_UL_CS2);
rate_ctr_inc(&m_ul_gprs_ctrs->ctr[TBF_CTR_GPRS_UL_CS2]);
break;
case CS3:
bts->do_rate_ctr_inc(CTR_GPRS_UL_CS3);
bts_do_rate_ctr_inc(bts, CTR_GPRS_UL_CS3);
rate_ctr_inc(&m_ul_gprs_ctrs->ctr[TBF_CTR_GPRS_UL_CS3]);
break;
case CS4:
bts->do_rate_ctr_inc(CTR_GPRS_UL_CS4);
bts_do_rate_ctr_inc(bts, CTR_GPRS_UL_CS4);
rate_ctr_inc(&m_ul_gprs_ctrs->ctr[TBF_CTR_GPRS_UL_CS4]);
break;
case MCS1:
bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS1);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS1);
rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS1]);
break;
case MCS2:
bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS2);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS2);
rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS2]);
break;
case MCS3:
bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS3);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS3);
rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS3]);
break;
case MCS4:
bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS4);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS4);
rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS4]);
break;
case MCS5:
bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS5);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS5);
rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS5]);
break;
case MCS6:
bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS6);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS6);
rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS6]);
break;
case MCS7:
bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS7);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS7);
rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS7]);
break;
case MCS8:
bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS8);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS8);
rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS8]);
break;
case MCS9:
bts->do_rate_ctr_inc(CTR_EGPRS_UL_MCS9);
bts_do_rate_ctr_inc(bts, CTR_EGPRS_UL_MCS9);
rate_ctr_inc(&m_ul_egprs_ctrs->ctr[TBF_CTR_EGPRS_UL_MCS9]);
break;
default:
@ -761,7 +761,7 @@ void gprs_rlcmac_ul_tbf::update_coding_scheme_counter_ul(enum CodingScheme cs)
void gprs_rlcmac_ul_tbf::set_window_size()
{
const struct gprs_rlcmac_bts *b = bts->bts_data();
const struct gprs_rlcmac_bts *b = bts;
uint16_t ws = egprs_window_size(b, ul_slots());
LOGPTBFUL(this, LOGL_INFO, "setting EGPRS UL window size to %u, base(%u) slots(%u) ws_pdch(%u)\n",
ws, bts->pcu->vty.ws_base, pcu_bitcount(ul_slots()), bts->pcu->vty.ws_pdch);

View File

@ -50,7 +50,7 @@ enum tbf_egprs_ul_counters {
#define LOGPTBFUL(tbf, level, fmt, args...) LOGP(DTBFUL, level, "%s " fmt, tbf_name(tbf), ## args)
struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf {
gprs_rlcmac_ul_tbf(BTS *bts, GprsMs *ms);
gprs_rlcmac_ul_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms);
gprs_rlc_window *window();
struct msgb *create_ul_ack(uint32_t fn, uint8_t ts);
bool ctrl_ack_to_toggle();

View File

@ -21,7 +21,9 @@
#include "gprs_debug.h"
#include "tbf.h"
#include "tbf_ul.h"
#include "tbf_dl.h"
#include "bts.h"
#include "gprs_ms.h"
#include <string.h>
#include <stdio.h>
@ -51,17 +53,17 @@ static gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts,
return tbf_alloc_dl_tbf(bts, ms, use_trx, single_slot);
}
static void check_tfi_usage(BTS *the_bts)
static void check_tfi_usage(struct gprs_rlcmac_bts *bts)
{
int pdch_no;
struct gprs_rlcmac_tbf *tfi_usage[8][8][2][32] = {{{{NULL}}}};
LListHead<gprs_rlcmac_tbf> *tbf_lists[2] = {
&the_bts->ul_tbfs(),
&the_bts->dl_tbfs()
struct llist_head *tbf_lists[2] = {
&bts->ul_tbfs,
&bts->dl_tbfs
};
LListHead<gprs_rlcmac_tbf> *pos;
struct llist_item *pos;
gprs_rlcmac_tbf *tbf;
unsigned list_idx;
struct gprs_rlcmac_tbf **tbf_var;
@ -69,8 +71,8 @@ static void check_tfi_usage(BTS *the_bts)
for (list_idx = 0; list_idx < ARRAY_SIZE(tbf_lists); list_idx += 1)
{
llist_for_each(pos, tbf_lists[list_idx]) {
tbf = pos->entry();
llist_for_each_entry(pos, tbf_lists[list_idx], list) {
tbf = (struct gprs_rlcmac_tbf *)pos->entry;
for (pdch_no = 0; pdch_no < 8; pdch_no += 1) {
struct gprs_rlcmac_pdch *pdch = tbf->pdch[pdch_no];
if (pdch == NULL)
@ -86,14 +88,14 @@ static void check_tfi_usage(BTS *the_bts)
if (tbf->direction == GPRS_RLCMAC_DL_TBF) {
OSMO_ASSERT(pdch->dl_tbf_by_tfi(
tbf->tfi()) == tbf);
OSMO_ASSERT(the_bts->dl_tbf_by_tfi(
OSMO_ASSERT(bts_dl_tbf_by_tfi(bts,
tbf->tfi(),
tbf->trx->trx_no,
pdch_no) == tbf);
} else {
OSMO_ASSERT(pdch->ul_tbf_by_tfi(
tbf->tfi()) == tbf);
OSMO_ASSERT(the_bts->ul_tbf_by_tfi(
OSMO_ASSERT(bts_ul_tbf_by_tfi(bts,
tbf->tfi(),
tbf->trx->trx_no,
pdch_no) == tbf);
@ -112,14 +114,12 @@ static void test_alloc_a(gprs_rlcmac_tbf_direction dir,
int tfi;
int i;
uint8_t used_trx, tmp_trx;
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
GprsMs *ms;
struct gprs_rlcmac_bts *bts;
struct gprs_rlcmac_tbf *tbfs[32*8+1] = { 0, };
printf("Testing alloc_a direction(%d)\n", dir);
bts = the_bts.bts_data();
the_pcu->alloc_algorithm = alloc_algorithm_a;
struct gprs_rlcmac_trx *trx = &bts->trx[0];
@ -136,17 +136,17 @@ static void test_alloc_a(gprs_rlcmac_tbf_direction dir,
* least this part is working okay.
*/
for (i = 0; i < (int)ARRAY_SIZE(tbfs); ++i) {
ms = bts->bts->ms_alloc(0, 0);
ms = bts_alloc_ms(bts, 0, 0);
tbfs[i] = tbf_alloc(bts, ms, dir, -1, 0);
if (tbfs[i] == NULL)
break;
used_trx = tbfs[i]->trx->trx_no;
tfi = the_bts.tfi_find_free(dir, &tmp_trx, used_trx);
tfi = bts_tfi_find_free(bts, dir, &tmp_trx, used_trx);
OSMO_ASSERT(tbfs[i]->tfi() != tfi);
}
check_tfi_usage(&the_bts);
check_tfi_usage(bts);
OSMO_ASSERT(i == count);
@ -154,10 +154,11 @@ static void test_alloc_a(gprs_rlcmac_tbf_direction dir,
if (tbfs[i])
tbf_free(tbfs[i]);
ms = bts->bts->ms_alloc(0, 0);
ms = bts_alloc_ms(bts, 0, 0);
tbfs[0] = tbf_alloc(bts, ms, dir, -1, 0);
OSMO_ASSERT(tbfs[0]);
tbf_free(tbfs[0]);
talloc_free(bts);
}
static void test_alloc_a()
@ -205,8 +206,7 @@ static inline void enable_ts_on_bts(struct gprs_rlcmac_bts *bts,
static inline bool test_alloc_b_ul_dl(bool ts0, bool ts1, bool ts2, bool ts3, bool ts4, bool ts5, bool ts6, bool ts7,
uint8_t ms_class, bool verbose)
{
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts = the_bts.bts_data();
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
GprsMs *ms;
gprs_rlcmac_ul_tbf *ul_tbf;
gprs_rlcmac_dl_tbf *dl_tbf;
@ -218,7 +218,7 @@ static inline bool test_alloc_b_ul_dl(bool ts0, bool ts1, bool ts2, bool ts3, bo
enable_ts_on_bts(bts, ts0, ts1, ts2, ts3, ts4, ts5, ts6, ts7);
ms = the_bts.ms_alloc(ms_class, 0);
ms = bts_alloc_ms(bts, ms_class, 0);
/* Avoid delaying free to avoid tons of to-be-freed ms objects queuing */
ms_set_timeout(ms, 0);
ul_tbf = tbf_alloc_ul_tbf(bts, ms, -1, true);
@ -239,19 +239,18 @@ static inline bool test_alloc_b_ul_dl(bool ts0, bool ts1, bool ts2, bool ts3, bo
OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts);
check_tfi_usage(&the_bts);
check_tfi_usage(bts);
tbf_free(dl_tbf);
tbf_free(ul_tbf);
talloc_free(bts);
return true;
}
static inline bool test_alloc_b_dl_ul(bool ts0, bool ts1, bool ts2, bool ts3, bool ts4, bool ts5, bool ts6, bool ts7,
uint8_t ms_class, bool verbose)
{
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts = the_bts.bts_data();
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
GprsMs *ms;
gprs_rlcmac_ul_tbf *ul_tbf;
gprs_rlcmac_dl_tbf *dl_tbf;
@ -263,7 +262,7 @@ static inline bool test_alloc_b_dl_ul(bool ts0, bool ts1, bool ts2, bool ts3, bo
enable_ts_on_bts(bts, ts0, ts1, ts2, ts3, ts4, ts5, ts6, ts7);
ms = the_bts.ms_alloc(ms_class, 0);
ms = bts_alloc_ms(bts, ms_class, 0);
/* Avoid delaying free to avoid tons of to-be-freed ms objects queuing */
ms_set_timeout(ms, 0);
dl_tbf = tbf_alloc_dl_tbf(bts, ms, -1, true);
@ -292,18 +291,17 @@ static inline bool test_alloc_b_dl_ul(bool ts0, bool ts1, bool ts2, bool ts3, bo
dump_assignment(dl_tbf, "DL", verbose);
OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts);
check_tfi_usage(&the_bts);
check_tfi_usage(bts);
tbf_free(dl_tbf);
tbf_free(ul_tbf);
talloc_free(bts);
return true;
}
static inline bool test_alloc_b_jolly(uint8_t ms_class)
{
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts = the_bts.bts_data();
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
GprsMs *ms;
int tfi;
uint8_t trx_no;
@ -315,9 +313,9 @@ static inline bool test_alloc_b_jolly(uint8_t ms_class)
enable_ts_on_bts(bts, false, true, true, true, true, false, false, false);
tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
OSMO_ASSERT(tfi >= 0);
ms = the_bts.ms_alloc(ms_class, 0);
ms = bts_alloc_ms(bts, ms_class, 0);
/* Avoid delaying free to avoid tons of to-be-freed ms objects queuing */
ms_set_timeout(ms, 0);
ul_tbf = tbf_alloc_ul_tbf(bts, ms, -1, false);
@ -338,11 +336,11 @@ static inline bool test_alloc_b_jolly(uint8_t ms_class)
OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts);
check_tfi_usage(&the_bts);
check_tfi_usage(bts);
tbf_free(dl_tbf);
tbf_free(ul_tbf);
talloc_free(bts);
return true;
}
@ -459,16 +457,13 @@ static inline char *test_mode_descr(enum test_mode t)
}
}
static GprsMs *alloc_tbfs(BTS *the_bts, struct GprsMs *old_ms, enum test_mode mode)
static GprsMs *alloc_tbfs(struct gprs_rlcmac_bts *bts, struct GprsMs *old_ms, enum test_mode mode)
{
struct gprs_rlcmac_bts *bts;
struct GprsMs *ms, *new_ms;
uint8_t trx_no = -1;
OSMO_ASSERT(old_ms != NULL);
bts = the_bts->bts_data();
gprs_rlcmac_tbf *tbf = NULL;
if (ms_current_trx(old_ms))
@ -517,12 +512,12 @@ static GprsMs *alloc_tbfs(BTS *the_bts, struct GprsMs *old_ms, enum test_mode mo
case TEST_MODE_DL_AFTER_UL:
case TEST_MODE_UL_AND_DL:
new_ms = alloc_tbfs(the_bts, ms, TEST_MODE_DL_ONLY);
new_ms = alloc_tbfs(bts, ms, TEST_MODE_DL_ONLY);
break;
case TEST_MODE_UL_AFTER_DL:
case TEST_MODE_DL_AND_UL:
new_ms = alloc_tbfs(the_bts, ms, TEST_MODE_UL_ONLY);
new_ms = alloc_tbfs(bts, ms, TEST_MODE_UL_ONLY);
break;
}
@ -546,7 +541,7 @@ static GprsMs *alloc_tbfs(BTS *the_bts, struct GprsMs *old_ms, enum test_mode mo
return new_ms;
}
static unsigned alloc_many_tbfs(BTS *the_bts, unsigned min_class,
static unsigned alloc_many_tbfs(struct gprs_rlcmac_bts *bts, unsigned min_class,
unsigned max_class, enum test_mode mode)
{
unsigned counter;
@ -566,11 +561,11 @@ static unsigned alloc_many_tbfs(BTS *the_bts, unsigned min_class,
enum gprs_rlcmac_tbf_direction dir;
uint32_t tlli = counter + 0xc0000000;
ms = the_bts->ms_by_tlli(tlli);
ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
if (!ms)
ms = the_bts->ms_alloc(0, 0);
ms = bts_alloc_ms(bts, 0, 0);
ms_set_ms_class(ms, ms_class);
ms = alloc_tbfs(the_bts, ms, mode);
ms = alloc_tbfs(bts, ms, mode);
if (!ms)
break;
@ -630,7 +625,7 @@ static unsigned alloc_many_tbfs(BTS *the_bts, unsigned min_class,
if (tfi >= 0) {
OSMO_ASSERT(ms_current_trx(ms));
tfi2 = the_bts->tfi_find_free(dir, &trx_no2,
tfi2 = bts_tfi_find_free(bts, dir, &trx_no2,
ms_current_trx(ms)->trx_no);
OSMO_ASSERT(tfi != tfi2);
OSMO_ASSERT(tfi2 < 0 ||
@ -649,15 +644,13 @@ static void test_successive_allocation(algo_t algo, unsigned min_class,
unsigned max_class, enum test_mode mode,
unsigned expect_num, const char *text)
{
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts;
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
struct gprs_rlcmac_trx *trx;
unsigned counter;
printf("Going to test assignment with many TBF, algorithm %s class %u..%u (%s)\n",
text, min_class, max_class, test_mode_descr(mode));
bts = the_bts.bts_data();
the_pcu->alloc_algorithm = algo;
trx = &bts->trx[0];
@ -667,7 +660,7 @@ static void test_successive_allocation(algo_t algo, unsigned min_class,
trx->pdch[6].enable();
trx->pdch[7].enable();
counter = alloc_many_tbfs(&the_bts, min_class, max_class, mode);
counter = alloc_many_tbfs(bts, min_class, max_class, mode);
printf(" Successfully allocated %u UL TBFs, algorithm %s class %u..%u (%s)\n",
counter, text, min_class, max_class, test_mode_descr(mode));
@ -677,14 +670,14 @@ static void test_successive_allocation(algo_t algo, unsigned min_class,
OSMO_ASSERT(counter == expect_num);
check_tfi_usage(&the_bts);
check_tfi_usage(bts);
talloc_free(bts);
}
static void test_many_connections(algo_t algo, unsigned expect_num,
const char *text)
{
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts;
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
struct gprs_rlcmac_trx *trx;
int counter1, counter2 = -1;
unsigned i;
@ -697,7 +690,6 @@ static void test_many_connections(algo_t algo, unsigned expect_num,
printf("Going to test assignment with many connections, algorithm %s\n", text);
bts = the_bts.bts_data();
the_pcu->alloc_algorithm = algo;
trx = &bts->trx[0];
@ -708,11 +700,11 @@ static void test_many_connections(algo_t algo, unsigned expect_num,
trx->pdch[7].enable();
for (i = 0; i < ARRAY_SIZE(mode_seq); i += 1) {
counter1 = alloc_many_tbfs(&the_bts, 1, mslot_class_max(), mode_seq[i]);
counter1 = alloc_many_tbfs(bts, 1, mslot_class_max(), mode_seq[i]);
fprintf(stderr, " Allocated %d TBFs (previously %d)\n",
counter1, counter2);
check_tfi_usage(&the_bts);
check_tfi_usage(bts);
/* This will stop earlier due to USF shortage */
if (mode_seq[i] == TEST_MODE_UL_ONLY)
@ -733,6 +725,7 @@ static void test_many_connections(algo_t algo, unsigned expect_num,
fprintf(stderr, " Expected %d TBFs (got %d) for algorithm %s\n", expect_num, counter1, text);
OSMO_ASSERT(expect_num == (unsigned)counter1);
talloc_free(bts);
}
static inline void test_a_b_dyn(enum test_mode mode, uint8_t exp_A, uint8_t exp_B, uint8_t exp_dyn)
@ -761,9 +754,8 @@ static void test_successive_allocations()
static void test_2_consecutive_dl_tbfs()
{
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
GprsMs *ms;
struct gprs_rlcmac_bts *bts;
struct gprs_rlcmac_trx *trx;
uint8_t ms_class = 11;
uint8_t egprs_ms_class = 11;
@ -772,7 +764,6 @@ static void test_2_consecutive_dl_tbfs()
printf("Testing DL TS allocation for Multi UEs\n");
bts = the_bts.bts_data();
the_pcu->alloc_algorithm = alloc_algorithm_b;
trx = &bts->trx[0];
@ -781,7 +772,7 @@ static void test_2_consecutive_dl_tbfs()
trx->pdch[6].enable();
trx->pdch[7].enable();
ms = the_bts.ms_alloc(ms_class, egprs_ms_class);
ms = bts_alloc_ms(bts, ms_class, egprs_ms_class);
dl_tbf1 = tbf_alloc_dl_tbf(bts, ms, 0, false);
OSMO_ASSERT(dl_tbf1);
@ -792,7 +783,7 @@ static void test_2_consecutive_dl_tbfs()
OSMO_ASSERT(numTs1 == 4);
printf("TBF1: numTs(%d)\n", numTs1);
ms = the_bts.ms_alloc(ms_class, egprs_ms_class);
ms = bts_alloc_ms(bts, ms_class, egprs_ms_class);
dl_tbf2 = tbf_alloc_dl_tbf(bts, ms, 0, false);
OSMO_ASSERT(dl_tbf2);
@ -810,6 +801,7 @@ static void test_2_consecutive_dl_tbfs()
tbf_free(dl_tbf1);
tbf_free(dl_tbf2);
talloc_free(bts);
}
int main(int argc, char **argv)

View File

@ -62,15 +62,12 @@ static inline void test_all_classes(struct gprs_rlcmac_trx *trx, bool clear_mask
static inline void test_multislot_total_ascending(bool seq)
{
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts;
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
struct gprs_rlcmac_trx *trx;
int i;
printf("%s(): %s\n", __func__, seq ? "sequential" : "accumulative");
bts = the_bts.bts_data();
trx = &bts->trx[0];
for (i = 0; i < 8; i++) {
@ -79,19 +76,17 @@ static inline void test_multislot_total_ascending(bool seq)
test_all_classes(trx, seq);
}
talloc_free(bts);
}
static inline void test_multislot_total_descending(bool seq)
{
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts;
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
struct gprs_rlcmac_trx *trx;
int i;
printf("%s(): %s\n", __func__, seq ? "sequential" : "accumulative");
bts = the_bts.bts_data();
trx = &bts->trx[0];
for (i = 7; i >= 0; i--) {
@ -100,18 +95,16 @@ static inline void test_multislot_total_descending(bool seq)
test_all_classes(trx, seq);
}
talloc_free(bts);
}
static inline void test_multislot_middle(bool seq)
{
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts;
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
struct gprs_rlcmac_trx *trx;
printf("%s(): %s\n", __func__, seq ? "sequential" : "accumulative");
bts = the_bts.bts_data();
trx = &bts->trx[0];
trx->pdch[2].enable();
@ -119,24 +112,23 @@ static inline void test_multislot_middle(bool seq)
trx->pdch[4].enable();
test_all_classes(trx, seq);
talloc_free(bts);
}
static inline void test_multislot_ends(bool seq)
{
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts;
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
struct gprs_rlcmac_trx *trx;
printf("%s(): %s\n", __func__, seq ? "sequential" : "accumulative");
bts = the_bts.bts_data();
trx = &bts->trx[0];
trx->pdch[0].enable();
trx->pdch[7].enable();
test_all_classes(trx, seq);
talloc_free(bts);
}
static inline void test_window_wrapper()

View File

@ -20,6 +20,7 @@
#include <assert.h>
#include "gprs_rlcmac.h"
#include "bts.h"
#include "tbf_dl.h"
extern "C" {
#include <osmocom/vty/telnet_interface.h>
@ -77,25 +78,23 @@ void test_pcu_rx_no_subscr_with_active_tbf()
void prepare_bts_with_two_dl_tbf_subscr()
{
BTS *bts = BTS::main_bts();
struct gprs_rlcmac_bts *bts_data;
struct gprs_rlcmac_bts *bts = the_pcu->bts;
struct gprs_rlcmac_trx *trx;
fprintf(stderr, "--- %s ---\n", __func__);
bts_data = bts->bts_data();
the_pcu->alloc_algorithm = alloc_algorithm_b;
trx = bts_data->trx;
trx = bts->trx;
trx->pdch[4].enable();
trx->pdch[5].enable();
trx->pdch[6].enable();
trx->pdch[7].enable();
ms1 = bts->ms_alloc(10, 11);
tbf1 = tbf_alloc_dl_tbf(bts_data, ms1, 0, false);
ms2 = bts->ms_alloc(12, 13);
tbf2 = tbf_alloc_dl_tbf(bts_data, ms2, 0, false);
ms1 = bts_alloc_ms(bts, 10, 11);
tbf1 = tbf_alloc_dl_tbf(bts, ms1, 0, false);
ms2 = bts_alloc_ms(bts, 12, 13);
tbf2 = tbf_alloc_dl_tbf(bts, ms2, 0, false);
fprintf(stderr, "\n");
}
@ -122,15 +121,15 @@ void test_sched_app_info_ok(const struct gsm_pcu_if_app_info_req *req)
void test_sched_app_info_missing_app_info_in_bts(const struct gsm_pcu_if_app_info_req *req)
{
struct gprs_rlcmac_bts *bts_data = BTS::main_bts()->bts_data();
struct gprs_rlcmac_bts *bts = the_pcu->bts;
struct gsm_pcu_if pcu_prim = {PCU_IF_MSG_APP_INFO_REQ, };
fprintf(stderr, "--- %s ---\n", __func__);
pcu_prim.u.app_info_req = *req;
pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);
msgb_free(bts_data->app_info);
bts_data->app_info = NULL;
msgb_free(bts->app_info);
bts->app_info = NULL;
assert(sched_app_info(tbf1) == NULL);
@ -154,8 +153,8 @@ void cleanup()
tbf_free(tbf1);
tbf_free(tbf2);
BTS::main_bts()->cleanup();
/* FIXME: talloc report disabled, because bts->ms_alloc() in prepare_bts_with_two_dl_tbf_subscr() causes leak */
TALLOC_FREE(the_pcu->bts);
/* FIXME: talloc report disabled, because bts_alloc_ms(bts, ) in prepare_bts_with_two_dl_tbf_subscr() causes leak */
/* talloc_report_full(tall_pcu_ctx, stderr); */
talloc_free(the_pcu);
talloc_free(tall_pcu_ctx);

View File

@ -1151,19 +1151,17 @@ static void test_rlc_info_init()
printf("=== end %s ===\n", __func__);
}
static void setup_bts(BTS *the_bts, uint8_t ts_no, uint8_t cs = 1)
static void setup_bts(struct gprs_rlcmac_bts *bts, uint8_t ts_no, uint8_t cs = 1)
{
gprs_rlcmac_bts *bts;
gprs_rlcmac_trx *trx;
bts = the_bts->bts_data();
the_pcu->alloc_algorithm = alloc_algorithm_a;
bts->initial_cs_dl = cs;
bts->initial_cs_ul = cs;
trx = &bts->trx[0];
trx->pdch[ts_no].enable();
}
static void uplink_header_type_2_parsing_test(BTS *the_bts,
static void uplink_header_type_2_parsing_test(struct gprs_rlcmac_bts *bts,
uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
uint8_t ms_class)
{
@ -1254,7 +1252,7 @@ static void uplink_header_type_2_parsing_test(BTS *the_bts,
static void uplink_header_type2_test(void)
{
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
int ts_no = 7;
uint32_t fn = 2654218;
uint16_t qta = 31;
@ -1262,14 +1260,15 @@ static void uplink_header_type2_test(void)
uint8_t ms_class = 1;
printf("=== start %s ===\n", __func__);
setup_bts(&the_bts, ts_no, 10);
setup_bts(bts, ts_no, 10);
uplink_header_type_2_parsing_test(&the_bts, ts_no,
uplink_header_type_2_parsing_test(bts, ts_no,
tlli, &fn, qta, ms_class);
printf("=== end %s ===\n", __func__);
talloc_free(bts);
}
static void uplink_header_type_1_parsing_test(BTS *the_bts,
static void uplink_header_type_1_parsing_test(struct gprs_rlcmac_bts *bts,
uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
uint8_t ms_class)
{
@ -1371,7 +1370,7 @@ static void uplink_header_type_1_parsing_test(BTS *the_bts,
void uplink_header_type1_test(void)
{
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
int ts_no = 7;
uint32_t fn = 2654218;
uint16_t qta = 31;
@ -1379,8 +1378,8 @@ void uplink_header_type1_test(void)
uint8_t ms_class = 1;
printf("=== start %s ===\n", __func__);
setup_bts(&the_bts, ts_no, 12);
uplink_header_type_1_parsing_test(&the_bts, ts_no, tlli, &fn,
setup_bts(bts, ts_no, 12);
uplink_header_type_1_parsing_test(bts, ts_no, tlli, &fn,
qta, ms_class);
printf("=== end %s ===\n", __func__);
}

View File

@ -142,7 +142,7 @@ int main(int argc, char **argv)
init_pcu(pcu);
init_main_bts();
bssgp_set_bssgp_callback(gprs_gp_send_cb, pcu->nsi);
create_and_connect_bssgp(bts_data(pcu->bts), INADDR_LOOPBACK, 23000);
create_and_connect_bssgp(pcu->bts, INADDR_LOOPBACK, 23000);
for (;;)
osmo_select_main(0);

View File

@ -36,24 +36,24 @@ extern "C" {
int16_t spoof_mnc = 0, spoof_mcc = 0;
bool spoof_mnc_3_digits = false;
static uint32_t calc_fn(BTS * bts, uint32_t rfn)
static uint32_t calc_fn(struct gprs_rlcmac_bts * bts, uint32_t rfn)
{
uint32_t fn;
fn = bts->rfn_to_fn(rfn);
fn = bts_rfn_to_fn(bts, rfn);
printf("rfn=%i ==> fn=%i\n", rfn, fn);
return fn;
}
static void set_fn(BTS * bts, uint32_t fn)
static void set_fn(struct gprs_rlcmac_bts * bts, uint32_t fn)
{
printf("\n");
bts->set_current_frame_number(fn);
bts_set_current_frame_number(bts, fn);
printf("bts: fn=%i\n", fn);
}
static void run_test()
{
BTS bts(the_pcu);
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
uint32_t fn;
printf("RFN_MODULUS=%i\n",RFN_MODULUS);
@ -63,20 +63,20 @@ static void run_test()
/* Test with a collection of real world examples,
* all all of them are not critical and do not
* assume the occurence of any race contions */
set_fn(&bts, 1320462);
fn = calc_fn(&bts, 5066);
set_fn(bts, 1320462);
fn = calc_fn(bts, 5066);
OSMO_ASSERT(fn == 1320458);
set_fn(&bts, 8246);
fn = calc_fn(&bts, 8244);
set_fn(bts, 8246);
fn = calc_fn(bts, 8244);
OSMO_ASSERT(fn == 8244);
set_fn(&bts, 10270);
fn = calc_fn(&bts, 10269);
set_fn(bts, 10270);
fn = calc_fn(bts, 10269);
OSMO_ASSERT(fn == 10269);
set_fn(&bts, 311276);
fn = calc_fn(&bts, 14250);
set_fn(bts, 311276);
fn = calc_fn(bts, 14250);
OSMO_ASSERT(fn == 311274);
@ -84,20 +84,20 @@ static void run_test()
* just wrapped over a little bit above the
* modulo 42432 raster, but the rach request
* occurred before the wrapping */
set_fn(&bts, RFN_MODULUS + 30);
fn = calc_fn(&bts, RFN_MODULUS - 10);
set_fn(bts, RFN_MODULUS + 30);
fn = calc_fn(bts, RFN_MODULUS - 10);
OSMO_ASSERT(fn == 42422);
set_fn(&bts, RFN_MODULUS + 1);
fn = calc_fn(&bts, RFN_MODULUS - 1);
set_fn(bts, RFN_MODULUS + 1);
fn = calc_fn(bts, RFN_MODULUS - 1);
OSMO_ASSERT(fn == 42431);
set_fn(&bts, RFN_MODULUS * 123 + 16);
fn = calc_fn(&bts, RFN_MODULUS - 4);
set_fn(bts, RFN_MODULUS * 123 + 16);
fn = calc_fn(bts, RFN_MODULUS - 4);
OSMO_ASSERT(fn == 5219132);
set_fn(&bts, RFN_MODULUS * 123 + 451);
fn = calc_fn(&bts, RFN_MODULUS - 175);
set_fn(bts, RFN_MODULUS * 123 + 451);
fn = calc_fn(bts, RFN_MODULUS - 175);
OSMO_ASSERT(fn == 5218961);
@ -105,41 +105,42 @@ static void run_test()
* the BTS just wrapped its internal frame number
* but we still get rach requests with high relative
* frame numbers. */
set_fn(&bts, 0);
fn = calc_fn(&bts, RFN_MODULUS - 13);
set_fn(bts, 0);
fn = calc_fn(bts, RFN_MODULUS - 13);
OSMO_ASSERT(fn == 2715635);
set_fn(&bts, 453);
fn = calc_fn(&bts, RFN_MODULUS - 102);
set_fn(bts, 453);
fn = calc_fn(bts, RFN_MODULUS - 102);
OSMO_ASSERT(fn == 2715546);
set_fn(&bts, 10);
fn = calc_fn(&bts, RFN_MODULUS - 10);
set_fn(bts, 10);
fn = calc_fn(bts, RFN_MODULUS - 10);
OSMO_ASSERT(fn == 2715638);
set_fn(&bts, 23);
fn = calc_fn(&bts, RFN_MODULUS - 42);
set_fn(bts, 23);
fn = calc_fn(bts, RFN_MODULUS - 42);
OSMO_ASSERT(fn == 2715606);
/* Also check with some corner case
* values where Fn and RFn reach its
* maximum/minimum valid range */
set_fn(&bts, GSM_MAX_FN);
fn = calc_fn(&bts, RFN_MODULUS-1);
set_fn(bts, GSM_MAX_FN);
fn = calc_fn(bts, RFN_MODULUS-1);
OSMO_ASSERT(fn == GSM_MAX_FN-1);
set_fn(&bts, 0);
fn = calc_fn(&bts, RFN_MODULUS-1);
set_fn(bts, 0);
fn = calc_fn(bts, RFN_MODULUS-1);
OSMO_ASSERT(fn == GSM_MAX_FN-1);
set_fn(&bts, GSM_MAX_FN);
fn = calc_fn(&bts, 0);
set_fn(bts, GSM_MAX_FN);
fn = calc_fn(bts, 0);
OSMO_ASSERT(fn == GSM_MAX_FN);
set_fn(&bts, 0);
fn = calc_fn(&bts, 0);
set_fn(bts, 0);
fn = calc_fn(bts, 0);
OSMO_ASSERT(fn == 0);
talloc_free(bts);
}
int main(int argc, char **argv)

View File

@ -51,18 +51,18 @@ static void test_ms_state()
uint32_t tlli = 0xffeeddbb;
gprs_rlcmac_dl_tbf *dl_tbf;
gprs_rlcmac_ul_tbf *ul_tbf;
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
GprsMs *ms;
printf("=== start %s ===\n", __func__);
ms = ms_alloc(&the_bts, tlli);
ms = ms_alloc(bts, tlli);
OSMO_ASSERT(ms_is_idle(ms));
dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms);
new (dl_tbf) gprs_rlcmac_dl_tbf(bts, ms);
ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);
new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);
ms_attach_tbf(ms, ul_tbf);
OSMO_ASSERT(!ms_is_idle(ms));
@ -88,7 +88,7 @@ static void test_ms_state()
talloc_free(dl_tbf);
talloc_free(ul_tbf);
talloc_free(bts);
printf("=== end %s ===\n", __func__);
}
@ -114,21 +114,21 @@ static void test_ms_callback()
uint32_t tlli = 0xffeeddbb;
gprs_rlcmac_dl_tbf *dl_tbf;
gprs_rlcmac_ul_tbf *ul_tbf;
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
GprsMs *ms;
last_cb = CB_UNKNOWN;
printf("=== start %s ===\n", __func__);
ms = ms_alloc(&the_bts, tlli);
ms = ms_alloc(bts, tlli);
ms_set_callback(ms, &ms_cb);
OSMO_ASSERT(ms_is_idle(ms));
dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms);
new (dl_tbf) gprs_rlcmac_dl_tbf(bts, ms);
ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);
new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);
OSMO_ASSERT(last_cb == CB_UNKNOWN);
@ -163,7 +163,7 @@ static void test_ms_callback()
talloc_free(dl_tbf);
talloc_free(ul_tbf);
talloc_free(bts);
printf("=== end %s ===\n", __func__);
}
@ -188,23 +188,23 @@ static void test_ms_replace_tbf()
uint32_t tlli = 0xffeeddbb;
gprs_rlcmac_dl_tbf *dl_tbf[2];
gprs_rlcmac_ul_tbf *ul_tbf;
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
GprsMs *ms;
printf("=== start %s ===\n", __func__);
ms = ms_alloc(&the_bts, tlli);
ms = ms_alloc(bts, tlli);
ms_set_callback(ms, &ms_replace_tbf_cb);
OSMO_ASSERT(ms_is_idle(ms));
was_idle = false;
dl_tbf[0] = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
new (dl_tbf[0]) gprs_rlcmac_dl_tbf(&the_bts, ms);
new (dl_tbf[0]) gprs_rlcmac_dl_tbf(bts, ms);
dl_tbf[1] = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
new (dl_tbf[1]) gprs_rlcmac_dl_tbf(&the_bts, ms);
new (dl_tbf[1]) gprs_rlcmac_dl_tbf(bts, ms);
ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);
new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);
ms_attach_tbf(ms, dl_tbf[0]);
OSMO_ASSERT(!ms_is_idle(ms));
@ -253,7 +253,7 @@ static void test_ms_replace_tbf()
talloc_free(dl_tbf[0]);
talloc_free(dl_tbf[1]);
talloc_free(ul_tbf);
talloc_free(bts);
printf("=== end %s ===\n", __func__);
}
@ -262,12 +262,12 @@ static void test_ms_change_tlli()
uint32_t start_tlli = 0xaa000000;
uint32_t new_ms_tlli = 0xff001111;
uint32_t other_sgsn_tlli = 0xff00eeee;
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
GprsMs *ms;
printf("=== start %s ===\n", __func__);
ms = ms_alloc(&the_bts, start_tlli);
ms = ms_alloc(bts, start_tlli);
OSMO_ASSERT(ms_is_idle(ms));
@ -347,7 +347,7 @@ static void test_ms_change_tlli()
OSMO_ASSERT(!ms_check_tlli(ms, start_tlli));
talloc_free(ms);
talloc_free(bts);
printf("=== end %s ===\n", __func__);
}
@ -374,9 +374,9 @@ static void test_ms_storage()
const char *imsi2 = "001001987654322";
gprs_rlcmac_ul_tbf *ul_tbf;
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
GprsMs *ms, *ms_tmp;
GprsMsStorage store(&the_bts);
GprsMsStorage store(bts);
printf("=== start %s ===\n", __func__);
@ -420,7 +420,7 @@ static void test_ms_storage()
ms = store.get_ms(tlli + 0);
OSMO_ASSERT(ms != NULL);
ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);
new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);
ms_attach_tbf(ms, ul_tbf);
ms_detach_tbf(ms, ul_tbf);
ms = store.get_ms(tlli + 0);
@ -437,7 +437,7 @@ static void test_ms_storage()
OSMO_ASSERT(ms == NULL);
talloc_free(ul_tbf);
talloc_free(bts);
printf("=== end %s ===\n", __func__);
}
@ -446,22 +446,22 @@ static void test_ms_timeout()
uint32_t tlli = 0xffeeddbb;
gprs_rlcmac_dl_tbf *dl_tbf;
gprs_rlcmac_ul_tbf *ul_tbf;
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
GprsMs *ms;
last_cb = CB_UNKNOWN;
printf("=== start %s ===\n", __func__);
ms = ms_alloc(&the_bts, tlli);
ms = ms_alloc(bts, tlli);
ms_set_callback(ms, &ms_cb);
ms_set_timeout(ms, 1);
OSMO_ASSERT(ms_is_idle(ms));
dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms);
new (dl_tbf) gprs_rlcmac_dl_tbf(bts, ms);
ul_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ul_tbf);
new (ul_tbf) gprs_rlcmac_ul_tbf(&the_bts, ms);
new (ul_tbf) gprs_rlcmac_ul_tbf(bts, ms);
OSMO_ASSERT(last_cb == CB_UNKNOWN);
@ -493,14 +493,13 @@ static void test_ms_timeout()
talloc_free(ms);
talloc_free(dl_tbf);
talloc_free(ul_tbf);
talloc_free(bts);
printf("=== end %s ===\n", __func__);
}
static void test_ms_cs_selection()
{
BTS the_bts(the_pcu);
gprs_rlcmac_bts *bts = the_bts.bts_data();
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
uint32_t tlli = 0xffeeddbb;
gprs_rlcmac_dl_tbf *dl_tbf;
@ -513,12 +512,12 @@ static void test_ms_cs_selection()
the_pcu->vty.cs_downgrade_threshold = 0;
the_pcu->vty.cs_adj_lower_limit = 0;
ms = ms_alloc(&the_bts, tlli);
ms = ms_alloc(bts, tlli);
OSMO_ASSERT(ms_is_idle(ms));
dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms);
new (dl_tbf) gprs_rlcmac_dl_tbf(bts, ms);
ms_attach_tbf(ms, dl_tbf);
OSMO_ASSERT(!ms_is_idle(ms));
@ -530,7 +529,7 @@ static void test_ms_cs_selection()
OSMO_ASSERT(mcs_chan_code(ms_current_cs_dl(ms)) == 2);
talloc_free(dl_tbf);
talloc_free(bts);
printf("=== end %s ===\n", __func__);
}
@ -545,8 +544,7 @@ static void dump_ms(const GprsMs *ms, const char *pref)
static void test_ms_mcs_mode()
{
BTS the_bts(the_pcu);
gprs_rlcmac_bts *bts = the_bts.bts_data();
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
uint32_t tlli = 0xdeadbeef;
gprs_rlcmac_dl_tbf *dl_tbf;
@ -554,18 +552,18 @@ static void test_ms_mcs_mode()
printf("=== start %s ===\n", __func__);
ms1 = ms_alloc(&the_bts, tlli);
ms1 = ms_alloc(bts, tlli);
dump_ms(ms1, "1: no BTS defaults ");
bts->initial_cs_dl = 4;
bts->initial_cs_ul = 1;
the_pcu->vty.cs_downgrade_threshold = 0;
ms2 = ms_alloc(&the_bts, tlli + 1);
ms2 = ms_alloc(bts, tlli + 1);
dump_ms(ms2, "2: with BTS defaults");
dl_tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf);
new (dl_tbf) gprs_rlcmac_dl_tbf(&the_bts, ms2);
new (dl_tbf) gprs_rlcmac_dl_tbf(bts, ms2);
ms_attach_tbf(ms2, dl_tbf);
dump_ms(ms2, "2: after TBF attach ");
@ -599,7 +597,7 @@ static void test_ms_mcs_mode()
dump_ms(ms2, "2: after mode set ");
talloc_free(dl_tbf);
talloc_free(bts);
printf("=== end %s ===\n", __func__);
}

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@
#include "bts.h"
#include "tbf.h"
#include "tbf_ul.h"
#include "tbf_dl.h"
#include "pcu_utils.h"
#include "gprs_debug.h"
#include "encoding.h"
@ -352,7 +353,7 @@ static void test_rlc_dl_ul_basic()
uint16_t lost = 0, recv = 0;
char show_rbb[65];
uint8_t bits_data[8];
BTS dummy_bts(the_pcu);
struct gprs_rlcmac_bts *dummy_bts = bts_alloc(the_pcu);
gprs_rlc_dl_window dl_win;
bitvec bits;
int bsn_begin, bsn_end, num_blocks;
@ -391,7 +392,7 @@ static void test_rlc_dl_ul_basic()
Decoding::extract_rbb(&bits, show_rbb);
printf("show_rbb: %s\n", show_rbb);
dl_win.update(&dummy_bts, &bits, 0, &lost, &recv);
dl_win.update(dummy_bts, &bits, 0, &lost, &recv);
OSMO_ASSERT(lost == 0);
OSMO_ASSERT(recv == 35);
OSMO_ASSERT(bsn_begin == 0);
@ -423,7 +424,7 @@ static void test_rlc_dl_ul_basic()
printf("show_rbb: %s\n", show_rbb);
lost = recv = 0;
dl_win.update(&dummy_bts, &bits, 0, &lost, &recv);
dl_win.update(dummy_bts, &bits, 0, &lost, &recv);
OSMO_ASSERT(lost == 5);
OSMO_ASSERT(recv == 3);
OSMO_ASSERT(bitvec_get_bit_pos(&bits, 0) == 0);
@ -431,6 +432,7 @@ static void test_rlc_dl_ul_basic()
OSMO_ASSERT(bsn_begin == 35);
OSMO_ASSERT(bsn_end == 43);
OSMO_ASSERT(num_blocks == 8);
talloc_free(dummy_bts);
}
}
@ -669,12 +671,12 @@ static void test_egprs_ul_ack_nack()
fprintf(stderr, "############## test_egprs_ul_ack_nack\n");
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
the_pcu->alloc_algorithm = alloc_algorithm_a;
the_bts.bts_data()->trx[0].pdch[4].enable();
bts->trx[0].pdch[4].enable();
GprsMs *ms = the_bts.ms_alloc(1, 1);
struct gprs_rlcmac_ul_tbf *tbf = tbf_alloc_ul_tbf(the_bts.bts_data(), ms, 0, true);
GprsMs *ms = bts_alloc_ms(bts, 1, 1);
struct gprs_rlcmac_ul_tbf *tbf = tbf_alloc_ul_tbf(bts, ms, 0, true);
struct crbb_test crbb_test = {0};
bitvec *rbb = NULL;
unsigned int rbb_size;
@ -722,6 +724,7 @@ static void test_egprs_ul_ack_nack()
extract_egprs_ul_ack_nack(tbf, dest, &ssn, &crbb_test, &rbb, false);
check_egprs_bitmap(tbf, ssn, &crbb_test, rbb, &rbb_size);
free_egprs_ul_ack_nack(&rbb, &crbb_test);
talloc_free(bts);
}
static void check_imm_ass(struct gprs_rlcmac_tbf *tbf, bool dl, enum ph_burst_type bt, const uint8_t *exp, uint8_t len,
@ -759,13 +762,13 @@ static void check_imm_ass(struct gprs_rlcmac_tbf *tbf, bool dl, enum ph_burst_ty
void test_immediate_assign_dl()
{
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
the_pcu->alloc_algorithm = alloc_algorithm_a;
the_bts.bts_data()->trx[0].pdch[2].enable();
the_bts.bts_data()->trx[0].pdch[3].enable();
GprsMs *ms = the_bts.ms_alloc(1, 0);
bts->trx[0].pdch[2].enable();
bts->trx[0].pdch[3].enable();
GprsMs *ms = bts_alloc_ms(bts, 1, 0);
struct gprs_rlcmac_tbf *tbf = tbf_alloc_dl_tbf(the_bts.bts_data(), ms, 0, false);
struct gprs_rlcmac_tbf *tbf = tbf_alloc_dl_tbf(bts, ms, 0, false);
static uint8_t res[] = { 0x06,
0x3f, /* Immediate Assignment Message Type */
0x30, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
@ -779,17 +782,18 @@ void test_immediate_assign_dl()
0xdf, 0xff, 0xff, 0xff, 0xf8, 0x17, 0x47, 0x08, 0x0b, 0x5b, 0x2b, 0x2b, };
check_imm_ass(tbf, true, GSM_L1_BURST_TYPE_ACCESS_2, res, sizeof(res), "ia_rest_downlink");
talloc_free(bts);
}
void test_immediate_assign_ul0m()
{
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
the_pcu->alloc_algorithm = alloc_algorithm_a;
the_bts.bts_data()->trx[0].pdch[4].enable();
the_bts.bts_data()->trx[0].pdch[5].enable();
bts->trx[0].pdch[4].enable();
bts->trx[0].pdch[5].enable();
GprsMs *ms = the_bts.ms_alloc(1, 0);
struct gprs_rlcmac_tbf *tbf = tbf_alloc_ul_tbf(the_bts.bts_data(), ms, 0, false);
GprsMs *ms = bts_alloc_ms(bts, 1, 0);
struct gprs_rlcmac_tbf *tbf = tbf_alloc_ul_tbf(bts, ms, 0, false);
static uint8_t res[] = { 0x06,
0x3f, /* Immediate Assignment Message Type */
0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
@ -803,6 +807,7 @@ void test_immediate_assign_ul0m()
0xc8, 0x02, 0x1b, 0xa2, 0x0b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };
check_imm_ass(tbf, false, GSM_L1_BURST_TYPE_ACCESS_0, res, sizeof(res), "ia_rest_uplink(MBA)");
talloc_free(bts);
}
void test_immediate_assign_ul0s()
@ -824,13 +829,13 @@ void test_immediate_assign_ul0s()
void test_immediate_assign_ul1s()
{
BTS the_bts(the_pcu);
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu);
the_pcu->alloc_algorithm = alloc_algorithm_a;
the_bts.bts_data()->trx[0].pdch[1].enable();
the_bts.bts_data()->trx[0].pdch[2].enable();
bts->trx[0].pdch[1].enable();
bts->trx[0].pdch[2].enable();
GprsMs *ms = the_bts.ms_alloc(1, 1);
struct gprs_rlcmac_tbf *tbf = tbf_alloc_ul_tbf(the_bts.bts_data(), ms, 0, false);
GprsMs *ms = bts_alloc_ms(bts, 1, 1);
struct gprs_rlcmac_tbf *tbf = tbf_alloc_ul_tbf(bts, ms, 0, false);
static uint8_t res[] = { 0x06,
0x3f, /* Immediate Assignment Message Type */
0x10, /* §10.5.2.26 Page Mode and §10.5.2.25b Dedicated mode/TBF */
@ -844,6 +849,7 @@ void test_immediate_assign_ul1s()
0x46, 0xa0, 0x08, 0x00, 0x17, 0x44, 0x0b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, };
check_imm_ass(tbf, false, GSM_L1_BURST_TYPE_ACCESS_1, res, sizeof(res), "ia_rest_egprs_uplink(SBA)");
talloc_free(bts);
}
void test_immediate_assign_ul1m()