diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/llc.cpp | 26 | ||||
-rw-r--r-- | src/llc.h | 10 | ||||
-rw-r--r-- | src/tbf_dl.cpp | 27 |
3 files changed, 38 insertions, 25 deletions
diff --git a/src/llc.cpp b/src/llc.cpp index 8930d2c8..53a89356 100644 --- a/src/llc.cpp +++ b/src/llc.cpp @@ -104,10 +104,19 @@ void gprs_llc_queue::init() m_avg_queue_delay = 0; } -void gprs_llc_queue::enqueue(struct msgb *llc_msg) +void gprs_llc_queue::enqueue(struct msgb *llc_msg, const MetaInfo *info) { + static const MetaInfo def_meta = {{0}}; + MetaInfo *meta_storage; + + osmo_static_assert(sizeof(*info) <= sizeof(llc_msg->cb), info_does_not_fit); + m_queue_size += 1; - m_queue_octets += msgb_length(llc_msg) - 2*sizeof(struct timeval); + m_queue_octets += msgb_length(llc_msg); + + meta_storage = (MetaInfo *)&llc_msg->cb[0]; + *meta_storage = info ? *info : def_meta; + msgb_enqueue(&m_queue, llc_msg); } @@ -127,24 +136,29 @@ void gprs_llc_queue::clear(BTS *bts) #define ALPHA 0.5f -struct msgb *gprs_llc_queue::dequeue() +struct msgb *gprs_llc_queue::dequeue(const MetaInfo **info) { struct msgb *msg; struct timeval *tv, tv_now, tv_result; uint32_t lifetime; - + const MetaInfo *meta_storage; msg = msgb_dequeue(&m_queue); if (!msg) return NULL; + meta_storage = (MetaInfo *)&msg->cb[0]; + + if (info) + *info = meta_storage; + m_queue_size -= 1; - m_queue_octets -= msgb_length(msg) - 2*sizeof(struct timeval); + m_queue_octets -= msgb_length(msg); /* take the second time */ gettimeofday(&tv_now, NULL); tv = (struct timeval *)&msg->data[sizeof(*tv)]; - timersub(&tv_now, tv, &tv_result); + timersub(&tv_now, &meta_storage->recv_time, &tv_result); lifetime = tv_result.tv_sec*1000 + tv_result.tv_usec/1000; m_avg_queue_delay = m_avg_queue_delay * ALPHA + lifetime * (1-ALPHA); @@ -24,6 +24,7 @@ extern "C" { #include <stdint.h> #include <string.h> +#include <time.h> #define LLC_MAX_LEN 1543 @@ -63,6 +64,11 @@ struct gprs_llc { * I store the LLC frames that come from the SGSN. */ struct gprs_llc_queue { + struct MetaInfo { + struct timeval recv_time; + struct timeval expire_time; + }; + static void calc_pdu_lifetime(BTS *bts, const uint16_t pdu_delay_csec, struct timeval *tv); static bool is_frame_expired(const struct timeval *now, @@ -71,8 +77,8 @@ struct gprs_llc_queue { void init(); - void enqueue(struct msgb *llc_msg); - struct msgb *dequeue(); + void enqueue(struct msgb *llc_msg, const MetaInfo *info = 0); + struct msgb *dequeue(const MetaInfo **info = 0); void clear(BTS *bts); size_t size() const; size_t octets() const; diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 68e6fab7..853821ca 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -99,20 +99,15 @@ int gprs_rlcmac_dl_tbf::append_data(const uint8_t ms_class, const uint8_t *data, const uint16_t len) { LOGP(DRLCMAC, LOGL_INFO, "%s append\n", tbf_name(this)); - /* TODO: put this path into an llc_enqueue method */ - /* the TBF exists, so we must write it in the queue - * we prepend lifetime in front of PDU */ - struct timeval *tv; - struct msgb *llc_msg = msgb_alloc(len + sizeof(*tv) * 2, - "llc_pdu_queue"); + gprs_llc_queue::MetaInfo info; + struct msgb *llc_msg = msgb_alloc(len, "llc_pdu_queue"); if (!llc_msg) return -ENOMEM; - tv = (struct timeval *)msgb_put(llc_msg, sizeof(*tv)); - gprs_llc_queue::calc_pdu_lifetime(bts, pdu_delay_csec, tv); - tv = (struct timeval *)msgb_put(llc_msg, sizeof(*tv)); - gettimeofday(tv, NULL); + + gprs_llc_queue::calc_pdu_lifetime(bts, pdu_delay_csec, &info.expire_time); + gettimeofday(&info.recv_time, NULL); memcpy(msgb_put(llc_msg, len), data, len); - llc_queue()->enqueue(llc_msg); + llc_queue()->enqueue(llc_msg, &info); tbf_update_ms_class(this, ms_class); start_llc_timer(); @@ -238,11 +233,11 @@ int gprs_rlcmac_dl_tbf::handle(struct gprs_rlcmac_bts *bts, struct msgb *gprs_rlcmac_dl_tbf::llc_dequeue(bssgp_bvc_ctx *bctx) { struct msgb *msg; - struct timeval *tv_recv, *tv_disc; struct timeval tv_now, tv_now2; uint32_t octets = 0, frames = 0; struct timeval hyst_delta = {0, 0}; const unsigned keep_small_thresh = 60; + const gprs_llc_queue::MetaInfo *info; if (bts_data()->llc_discard_csec) csecs_to_timeval(bts_data()->llc_discard_csec, &hyst_delta); @@ -250,11 +245,9 @@ struct msgb *gprs_rlcmac_dl_tbf::llc_dequeue(bssgp_bvc_ctx *bctx) gettimeofday(&tv_now, NULL); timeradd(&tv_now, &hyst_delta, &tv_now2); - while ((msg = llc_queue()->dequeue())) { - tv_disc = (struct timeval *)msg->data; - msgb_pull(msg, sizeof(*tv_disc)); - tv_recv = (struct timeval *)msg->data; - msgb_pull(msg, sizeof(*tv_recv)); + while ((msg = llc_queue()->dequeue(&info))) { + const struct timeval *tv_disc = &info->expire_time; + const struct timeval *tv_recv = &info->recv_time; gprs_bssgp_update_queue_delay(tv_recv, &tv_now); |