Added debugging of downlink bandwidth
diff --git a/src/gprs_debug.cpp b/src/gprs_debug.cpp
index bc19b77..2b9b690 100644
--- a/src/gprs_debug.cpp
+++ b/src/gprs_debug.cpp
@@ -40,6 +40,7 @@
  	{"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 b5b4276..1a5f01a 100644
--- a/src/gprs_debug.h
+++ b/src/gprs_debug.h
@@ -34,6 +34,7 @@
 	DRLCMACDL,
 	DRLCMACUL,
 	DRLCMACSCHED,
+	DRLCMACBW,
 	DBSSGP,
 	DPCU,
 	aDebug_LastEntry
diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp
index d1f0b54..e54c5b0 100644
--- a/src/gprs_rlcmac.cpp
+++ b/src/gprs_rlcmac.cpp
@@ -278,6 +278,9 @@
 		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 41fd206..7291f77 100644
--- a/src/gprs_rlcmac.h
+++ b/src/gprs_rlcmac.h
@@ -199,6 +199,9 @@
 	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 e2549d4..687a75d 100644
--- a/src/gprs_rlcmac_data.cpp
+++ b/src/gprs_rlcmac_data.cpp
@@ -941,6 +941,28 @@
 	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 @@
 			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 @@
 		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 */