diff --git a/src/gprs_debug.cpp b/src/gprs_debug.cpp index bc19b77e..2b9b690b 100644 --- a/src/gprs_debug.cpp +++ b/src/gprs_debug.cpp @@ -40,6 +40,7 @@ static const struct log_info_cat default_categories[] = { {"DRLCMACDL", "\033[1;33m", "GPRS RLC/MAC layer Data (RLCMAC)", LOGL_INFO, 1}, {"DRLCMACUL", "\033[1;36m", "GPRS RLC/MAC layer Data (RLCMAC)", LOGL_INFO, 1}, {"DRLCMACSCHED", "\033[0;36m", "GPRS RLC/MAC layer Data (RLCMAC)", LOGL_INFO, 1}, + {"DRLCMACBW", "\033[1;31m", "GPRS RLC/MAC layer (RLCMAC)", LOGL_INFO, 1}, {"DBSSGP", "\033[1;34m", "GPRS BSS Gateway Protocol (BSSGP)", LOGL_INFO , 1}, {"DPCU", "\033[1;35m", "GPRS Packet Control Unit (PCU)", LOGL_NOTICE, 1}, }; diff --git a/src/gprs_debug.h b/src/gprs_debug.h index b5b42767..1a5f01a0 100644 --- a/src/gprs_debug.h +++ b/src/gprs_debug.h @@ -34,6 +34,7 @@ enum { DRLCMACDL, DRLCMACUL, DRLCMACSCHED, + DRLCMACBW, DBSSGP, DPCU, aDebug_LastEntry diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index d1f0b549..e54c5b0c 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -278,6 +278,9 @@ struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_tbf *old_tbf, return NULL; } + /* set timestamp */ + gettimeofday(&tbf->bw_tv, NULL); + INIT_LLIST_HEAD(&tbf->llc_queue); if (dir == GPRS_RLCMAC_UL_TBF) llist_add(&tbf->list, &gprs_rlcmac_ul_tbfs); diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index 41fd2067..7291f77a 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -199,6 +199,9 @@ struct gprs_rlcmac_tbf { struct osmo_gsm_timer_list gsm_timer; unsigned int fT; /* fTxxxx number */ unsigned int num_fT_exp; /* number of consecutive fT expirations */ + + struct timeval bw_tv; /* timestamp for bandwidth calculation */ + uint32_t bw_octets; /* number of octets transmitted since bw_tv */ }; extern struct llist_head gprs_rlcmac_ul_tbfs; /* list of uplink TBFs */ diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp index e2549d41..687a75da 100644 --- a/src/gprs_rlcmac_data.cpp +++ b/src/gprs_rlcmac_data.cpp @@ -941,6 +941,28 @@ static struct msgb *llc_dequeue(struct gprs_rlcmac_tbf *tbf) return msg; } +static int gprs_rlcmac_debug_bw(struct gprs_rlcmac_tbf *tbf, uint16_t octets) +{ + struct timeval now_tv, *bw_tv = &tbf->bw_tv; + uint32_t elapsed; + + tbf->bw_octets += octets; + + gettimeofday(&now_tv, NULL); + elapsed = ((now_tv.tv_sec - bw_tv->tv_sec) << 7) + + ((now_tv.tv_usec - bw_tv->tv_usec) << 7) / 1000000; + if (elapsed < 128) + return 0; + + LOGP(DRLCMACBW, LOGL_DEBUG, "DL Bandwitdh of TLLI=0x%08x: %d KBits/s\n", + tbf->tlli, tbf->bw_octets / elapsed); + + /* reset bandwidth values timestamp */ + memcpy(bw_tv, &now_tv, sizeof(struct timeval)); + tbf->bw_octets = 0; + + return 0; +} /* send DL data block * @@ -1095,6 +1117,7 @@ do_resend: LOGP(DRLCMACDL, LOGL_INFO, "Complete DL frame for " "TBF=%d that fits precisely in last block: " "len=%d\n", tbf->tfi, tbf->llc_length); + gprs_rlcmac_debug_bw(tbf, tbf->llc_length); /* block is filled, so there is no extension */ *e_pointer |= 0x01; /* fill space */ @@ -1154,6 +1177,7 @@ do_resend: space -= chunk; LOGP(DRLCMACDL, LOGL_INFO, "Complete DL frame for TBF=%d: " "len=%d\n", tbf->tfi, tbf->llc_length); + gprs_rlcmac_debug_bw(tbf, tbf->llc_length); /* reset LLC frame */ tbf->llc_index = tbf->llc_length = 0; /* dequeue next LLC frame, if any */