diff --git a/TODO b/TODO index f2ed92d1..1568b360 100644 --- a/TODO +++ b/TODO @@ -7,3 +7,4 @@ * Replace trx/ts with pointers. E.g. a PDCH should know the trx it is on... then we can omit trx, ts and parameters and just pass the pdch. +* On global free/reset... also flush the timing advance.. diff --git a/src/Makefile.am b/src/Makefile.am index 3c2c78cc..cbb6de0a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -82,7 +82,8 @@ noinst_HEADERS = \ tbf.h \ bts.h \ poll_controller.h \ - encoding.h + encoding.h \ + ta.h osmo_pcu_SOURCES = pcu_main.cpp diff --git a/src/bts.h b/src/bts.h index 0e8adf7e..3a264f76 100644 --- a/src/bts.h +++ b/src/bts.h @@ -28,6 +28,7 @@ extern "C" { } #include "poll_controller.h" +#include "ta.h" #endif #include @@ -122,6 +123,7 @@ public: static BTS* main_bts(); struct gprs_rlcmac_bts *bts_data(); + TimingAdvance *timing_advance(); /** TODO: change the number to unsigned */ void set_current_frame_number(int frame_number); @@ -134,6 +136,7 @@ private: int m_cur_fn; struct gprs_rlcmac_bts m_bts; PollController m_pollController; + TimingAdvance m_ta; private: /* disable copying to avoid slicing */ @@ -145,6 +148,11 @@ inline int BTS::current_frame_number() const { return m_cur_fn; } + +inline TimingAdvance *BTS::timing_advance() +{ + return &m_ta; +} #endif #ifdef __cplusplus diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index bbd5e0c2..c514b4e2 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -161,12 +161,6 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts, int gprs_rlcmac_imm_ass_cnf(uint8_t *data, uint32_t fn); -int remember_timing_advance(uint32_t tlli, uint8_t ta); - -int recall_timing_advance(uint32_t tlli); - -int flush_timing_advance(void); - extern "C" { #endif int alloc_algorithm_a(struct gprs_rlcmac_bts *bts, diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp index 5eab066c..dc3242d6 100644 --- a/src/gprs_rlcmac_data.cpp +++ b/src/gprs_rlcmac_data.cpp @@ -397,14 +397,14 @@ int gprs_rlcmac_rcv_control_block(struct gprs_rlcmac_bts *bts, "in packet ressource request of single " "block, but there is no resource request " "scheduled!\n"); - rc = recall_timing_advance(tlli); + rc = bts->bts->timing_advance()->recall(tlli); if (rc >= 0) ta = rc; else ta = 0; } else { ta = sba->ta; - remember_timing_advance(tlli, ta); + bts->bts->timing_advance()->remember(tlli, ta); llist_del(&sba->list); talloc_free(sba); } @@ -452,7 +452,7 @@ int gprs_rlcmac_rcv_control_block(struct gprs_rlcmac_bts *bts, "block, but there is no resource request " "scheduled!\n"); } else { - remember_timing_advance(ul_control_block->u.Packet_Measurement_Report.TLLI, sba->ta); + bts->bts->timing_advance()->remember(ul_control_block->u.Packet_Measurement_Report.TLLI, sba->ta); llist_del(&sba->list); talloc_free(sba); } @@ -820,7 +820,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(struct gprs_rlcmac_bts *bts, /* mark TLLI valid now */ tbf->tlli_valid = 1; /* store current timing advance */ - remember_timing_advance(tbf->tlli, tbf->ta); + bts->bts->timing_advance()->remember(tbf->tlli, tbf->ta); /* already have TLLI, but we stille get another one */ } else if (rh->ti) { uint32_t tlli; diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index a3b75ac7..92ff07c8 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -250,7 +250,7 @@ int main(int argc, char *argv[]) pcu_l1if_close(); - flush_timing_advance(); + bts->bts->timing_advance()->flush(); talloc_report_full(tall_pcu_ctx, stderr); talloc_free(tall_pcu_ctx); diff --git a/src/ta.cpp b/src/ta.cpp index 7aef867c..05342ea9 100644 --- a/src/ta.cpp +++ b/src/ta.cpp @@ -19,6 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include extern "C" { @@ -36,22 +37,25 @@ extern void *tall_pcu_ctx; /* enable to debug timing advance memory */ //#define DEBUG_TA -static LLIST_HEAD(gprs_rlcmac_ta_list); -static int gprs_rlcmac_ta_num = 0; - struct gprs_rlcmac_ta { struct llist_head list; uint32_t tlli; uint8_t ta; }; +TimingAdvance::TimingAdvance() + : m_ta_len(0) +{ + INIT_LLIST_HEAD(&m_ta_list); +} + /* remember timing advance of a given TLLI */ -int remember_timing_advance(uint32_t tlli, uint8_t ta) +int TimingAdvance::remember(uint32_t tlli, uint8_t ta) { struct gprs_rlcmac_ta *ta_entry; /* check for existing entry */ - llist_for_each_entry(ta_entry, &gprs_rlcmac_ta_list, list) { + llist_for_each_entry(ta_entry, &m_ta_list, list) { if (ta_entry->tlli == tlli) { #ifdef DEBUG_TA fprintf(stderr, "update %08x %d\n", tlli, ta); @@ -59,7 +63,7 @@ int remember_timing_advance(uint32_t tlli, uint8_t ta) ta_entry->ta = ta; /* relink to end of list */ llist_del(&ta_entry->list); - llist_add_tail(&ta_entry->list, &gprs_rlcmac_ta_list); + llist_add_tail(&ta_entry->list, &m_ta_list); return 0; } } @@ -68,12 +72,12 @@ int remember_timing_advance(uint32_t tlli, uint8_t ta) fprintf(stderr, "remember %08x %d\n", tlli, ta); #endif /* if list is full, remove oldest entry */ - if (gprs_rlcmac_ta_num == 30) { - ta_entry = llist_entry(gprs_rlcmac_ta_list.next, + if (m_ta_len == 30) { + ta_entry = llist_entry(m_ta_list.next, struct gprs_rlcmac_ta, list); llist_del(&ta_entry->list); talloc_free(ta_entry); - gprs_rlcmac_ta_num--; + m_ta_len--; } /* create new TA entry */ @@ -83,18 +87,18 @@ int remember_timing_advance(uint32_t tlli, uint8_t ta) ta_entry->tlli = tlli; ta_entry->ta = ta; - llist_add_tail(&ta_entry->list, &gprs_rlcmac_ta_list); - gprs_rlcmac_ta_num++; + llist_add_tail(&ta_entry->list, &m_ta_list); + m_ta_len++; return 0; } -int recall_timing_advance(uint32_t tlli) +int TimingAdvance::recall(uint32_t tlli) { struct gprs_rlcmac_ta *ta_entry; uint8_t ta; - llist_for_each_entry(ta_entry, &gprs_rlcmac_ta_list, list) { + llist_for_each_entry(ta_entry, &m_ta_list, list) { if (ta_entry->tlli == tlli) { ta = ta_entry->ta; #ifdef DEBUG_TA @@ -110,13 +114,13 @@ int recall_timing_advance(uint32_t tlli) return -EINVAL; } -int flush_timing_advance(void) +int TimingAdvance::flush() { struct gprs_rlcmac_ta *ta_entry; int count = 0; - while (!llist_empty(&gprs_rlcmac_ta_list)) { - ta_entry = llist_entry(gprs_rlcmac_ta_list.next, + while (!llist_empty(&m_ta_list)) { + ta_entry = llist_entry(m_ta_list.next, struct gprs_rlcmac_ta, list); #ifdef DEBUG_TA fprintf(stderr, "flush entry %08x %d\n", ta_entry->tlli, @@ -126,7 +130,7 @@ int flush_timing_advance(void) talloc_free(ta_entry); count++; } - gprs_rlcmac_ta_num = 0; + m_ta_len = 0; return count; } diff --git a/src/ta.h b/src/ta.h new file mode 100644 index 00000000..8508acbf --- /dev/null +++ b/src/ta.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2012 Ivan Klyuchnikov + * Copyright (C) 2012 Andreas Eversberg + * Copyright (C) 2013 by Holger Hans Peter Freyther + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#pragma once + +extern "C" { +#include +} + +#include + +class TimingAdvance { +public: + TimingAdvance(); + + int remember(uint32_t tlli, uint8_t ta); + int recall(uint32_t tlli); + int flush(); + +private: + size_t m_ta_len; + llist_head m_ta_list; +}; diff --git a/src/tbf.cpp b/src/tbf.cpp index 27532604..a42a26c1 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -135,7 +135,7 @@ static int tbf_new_dl_assignment(struct gprs_rlcmac_bts *bts, ta = tbf->ta; else { /* recall TA */ - rc = recall_timing_advance(tlli); + rc = bts->bts->timing_advance()->recall(tlli); if (rc < 0) { LOGP(DRLCMAC, LOGL_NOTICE, "TA unknown" ", assuming 0\n");