aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Kluchnikov <kluchnikovi@gmail.com>2012-04-12 15:22:06 +0400
committerIvan Kluchnikov <kluchnikovi@gmail.com>2012-04-12 15:22:06 +0400
commit61a33f7c7a10100f000a371da0fc819fdfe95a7e (patch)
tree0cfd3503af3050f90c4187910072ed4b97a39936
parentff447cdf890215d2908802763b504f1a3bee32fc (diff)
Added support of osmo_timers and osmo_gsm_timers for TBF.
-rw-r--r--gprs_rlcmac.cpp69
-rw-r--r--gprs_rlcmac.h10
-rw-r--r--pcu_main.cpp13
3 files changed, 86 insertions, 6 deletions
diff --git a/gprs_rlcmac.cpp b/gprs_rlcmac.cpp
index 72a1e296..eb636815 100644
--- a/gprs_rlcmac.cpp
+++ b/gprs_rlcmac.cpp
@@ -22,7 +22,6 @@
#include <Threads.h>
#include <gprs_rlcmac.h>
-
LLIST_HEAD(gprs_rlcmac_tbfs);
void *rlcmac_tall_ctx;
@@ -89,6 +88,69 @@ static void tbf_free(struct gprs_rlcmac_tbf *tbf)
talloc_free(tbf);
}
+
+static void tbf_timer_cb(void *_tbf)
+{
+ struct gprs_rlcmac_tbf *tbf = (struct gprs_rlcmac_tbf *)_tbf;
+
+ tbf->num_T_exp++;
+
+ switch (tbf->T) {
+ case 1111:
+ // TODO: We should add timers for TBF.
+ break;
+ default:
+ COUT("Timer expired in unknown mode" << tbf->T);
+ }
+}
+
+static void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T,
+ unsigned int seconds)
+{
+ if (osmo_timer_pending(&tbf->timer))
+ COUT("Starting TBF timer %u while old timer %u pending" << T << tbf->T);
+ tbf->T = T;
+ tbf->num_T_exp = 0;
+
+ /* FIXME: we should do this only once ? */
+ tbf->timer.data = tbf;
+ tbf->timer.cb = &tbf_timer_cb;
+
+ osmo_timer_schedule(&tbf->timer, seconds, 0);
+}
+
+
+static void tbf_gsm_timer_cb(void *_tbf)
+{
+ struct gprs_rlcmac_tbf *tbf = (struct gprs_rlcmac_tbf *)_tbf;
+
+ tbf->num_fT_exp++;
+
+ switch (tbf->fT) {
+ case 0:
+ // This is timer for delay RLC/MAC data sending after Downlink Immediate Assignment on CCCH.
+ gprs_rlcmac_segment_llc_pdu(tbf);
+ break;
+ default:
+ COUT("Timer expired in unknown mode" << tbf->fT);
+ }
+}
+
+static void tbf_gsm_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int fT,
+ int frames)
+{
+ if (osmo_gsm_timer_pending(&tbf->gsm_timer))
+ COUT("Starting TBF timer %u while old timer %u pending" << fT << tbf->fT);
+ tbf->fT = fT;
+ tbf->num_fT_exp = 0;
+
+ /* FIXME: we should do this only once ? */
+ tbf->gsm_timer.data = tbf;
+ tbf->gsm_timer.cb = &tbf_gsm_timer_cb;
+
+ osmo_gsm_timer_schedule(&tbf->gsm_timer, frames);
+}
+
void write_packet_downlink_assignment(BitVector * dest, uint8_t tfi, uint32_t tlli)
{
// TODO We should use our implementation of encode RLC/MAC Control messages.
@@ -526,13 +588,10 @@ void gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf)
void gprs_rlcmac_downlink_assignment(gprs_rlcmac_tbf *tbf)
{
-
COUT("SEND IA Rest Octets Downlink Assignment>>>>>>>>>>>>>>>>>>");
BitVector ia_rest_octets_downlink_assignment(23*8);
ia_rest_octets_downlink_assignment.unhex("2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
write_ia_rest_octets_downlink_assignment(&ia_rest_octets_downlink_assignment, tbf->tfi, tbf->tlli);
pcu_l1if_tx(&ia_rest_octets_downlink_assignment);
-
- usleep(500000);
- gprs_rlcmac_segment_llc_pdu(tbf);
+ tbf_gsm_timer_start(tbf, 0, 120);
}
diff --git a/gprs_rlcmac.h b/gprs_rlcmac.h
index eadafd14..38e29630 100644
--- a/gprs_rlcmac.h
+++ b/gprs_rlcmac.h
@@ -22,9 +22,11 @@
#include <BitVector.h>
#include <gsm_rlcmac.h>
+#include <gsm_timer.h>
extern "C" {
#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/timer.h>
}
enum gprs_rlcmac_tbf_state {
@@ -47,6 +49,14 @@ struct gprs_rlcmac_tbf {
uint8_t rlc_data[60];
uint16_t data_index;
uint8_t bsn;
+
+ struct osmo_timer_list timer;
+ unsigned int T; /* Txxxx number */
+ unsigned int num_T_exp; /* number of consecutive T expirations */
+
+ struct osmo_gsm_timer_list gsm_timer;
+ unsigned int fT; /* fTxxxx number */
+ unsigned int num_fT_exp; /* number of consecutive fT expirations */
};
extern struct llist_head gprs_rlcmac_tbfs;
diff --git a/pcu_main.cpp b/pcu_main.cpp
index d4b3938b..2417d08b 100644
--- a/pcu_main.cpp
+++ b/pcu_main.cpp
@@ -21,6 +21,7 @@
#include <Threads.h>
#include <Sockets.h>
#include <pcu_l1_if.h>
+#include <gsm_timer.h>
// TODO: We should move this parameters to config file.
#define SGSN_IP "127.0.0.1"
@@ -85,7 +86,7 @@ static int udp_write_cb(struct osmo_fd *ofd, struct msgb *msg)
int rc;
struct l1fwd_hdl *l1fh = (l1fwd_hdl *)ofd->data;
- DEBUGP(DGPRS, "UDP: Writing %u bytes for MQ_L1_WRITE queue\n", msgb_l1len(msg));
+ //DEBUGP(DGPRS, "UDP: Writing %u bytes for MQ_L1_WRITE queue\n", msgb_l1len(msg));
rc = sendto(ofd->fd, msg->l1h, msgb_l1len(msg), 0,
(const struct sockaddr *)&l1fh->remote_sa, l1fh->remote_sa_len);
@@ -115,6 +116,12 @@ int pcu_l1if_open()
l1fh->fl1h = fl1h;
fl1h->priv = l1fh;
+ struct osmo_wqueue * queue = &((l1fh->fl1h)->write_q);
+ osmo_wqueue_init(queue, 10);
+ queue->bfd.when |= BSC_FD_READ;
+ queue->bfd.data = l1fh;
+ queue->bfd.priv_nr = 0;
+
/* Open UDP */
struct osmo_wqueue *wq = &l1fh->udp_wq;
@@ -170,6 +177,10 @@ int main(int argc, char *argv[])
unsigned i = 0;
while (1)
{
+ osmo_gsm_timers_check();
+ osmo_gsm_timers_prepare();
+ osmo_gsm_timers_update();
+
osmo_select_main(0);
if (i == 7)
{