aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bts.cpp20
-rw-r--r--src/encoding.cpp4
-rw-r--r--src/gprs_ms.cpp13
-rw-r--r--src/gprs_ms.h9
-rw-r--r--src/tbf.cpp32
-rw-r--r--src/tbf.h6
-rw-r--r--src/tbf_dl.cpp25
7 files changed, 67 insertions, 42 deletions
diff --git a/src/bts.cpp b/src/bts.cpp
index 6bcfea0d..010b8e88 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -438,7 +438,7 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta)
/* FIXME: send reject */
return -EBUSY;
}
- tbf->ta = qta >> 2;
+ tbf->set_ta(qta >> 2);
tbf->set_state(GPRS_RLCMAC_FLOW);
tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_CCCH);
tbf_timer_start(tbf, 3169, m_bts.t3169, 0);
@@ -461,7 +461,7 @@ int BTS::rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta)
m_bts.alpha, m_bts.gamma, -1);
else
plen = Encoding::write_immediate_assignment(&m_bts, immediate_assignment, 0, ra,
- Fn, tbf->ta, tbf->trx->arfcn, tbf->first_ts, tbf->tsc(),
+ Fn, tbf->ta(), tbf->trx->arfcn, tbf->first_ts, tbf->tsc(),
tbf->tfi(), tbf->m_usf[tbf->first_ts], 0, 0, 0, 0,
m_bts.alpha, m_bts.gamma, -1);
pcu_l1if_tx_agch(immediate_assignment, plen);
@@ -486,8 +486,6 @@ void BTS::trigger_dl_ass(
old_tbf->was_releasing = old_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE);
- /* use TA from old TBF */
- dl_tbf->ta = old_tbf->ta;
/* change state */
dl_tbf->set_state(GPRS_RLCMAC_ASSIGN);
dl_tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH);
@@ -515,7 +513,7 @@ void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, uint8_t poll, const char *imsi)
/* use request reference that has maximum distance to current time,
* so the assignment will not conflict with possible RACH requests. */
plen = Encoding::write_immediate_assignment(&m_bts, immediate_assignment, 1, 125,
- (tbf->pdch[tbf->first_ts]->last_rts_fn + 21216) % 2715648, tbf->ta,
+ (tbf->pdch[tbf->first_ts]->last_rts_fn + 21216) % 2715648, tbf->ta(),
tbf->trx->arfcn, tbf->first_ts, tbf->tsc(), tbf->tfi(), 0, tbf->tlli(), poll,
tbf->poll_fn, 0, m_bts.alpha, m_bts.gamma, -1);
pcu_l1if_tx_pch(immediate_assignment, plen, imsi);
@@ -836,7 +834,7 @@ void gprs_rlcmac_pdch::rcv_control_dl_ack_nack(Packet_Downlink_Ack_Nack_t *ack_n
/* This call will register the new TBF with the MS on success */
tbf_alloc_ul(bts_data(), tbf->trx->trx_no, tbf->ms_class,
- tbf->tlli(), tbf->ta, tbf);
+ tbf->tlli(), tbf->ta(), tbf);
/* schedule uplink assignment */
tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
@@ -846,14 +844,13 @@ void gprs_rlcmac_pdch::rcv_control_dl_ack_nack(Packet_Downlink_Ack_Nack_t *ack_n
void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request, uint32_t fn)
{
struct gprs_rlcmac_sba *sba;
- int rc;
if (request->ID.UnionType) {
struct gprs_rlcmac_ul_tbf *ul_tbf = NULL;
struct gprs_rlcmac_dl_tbf *dl_tbf = NULL;
uint32_t tlli = request->ID.u.TLLI;
uint8_t ms_class = 0;
- uint8_t ta;
+ uint8_t ta = 0;
GprsMs *ms = bts()->ms_by_tlli(tlli);
/* Keep the ms, even if it gets idle temporarily */
@@ -862,6 +859,7 @@ void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request,
if (ms) {
ul_tbf = ms->ul_tbf();
dl_tbf = ms->dl_tbf();
+ ta = ms->ta();
}
if (ul_tbf) {
@@ -890,14 +888,8 @@ void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request,
"in packet resource request of single "
"block, but there is no resource request "
"scheduled!\n");
- rc = bts()->timing_advance()->recall(tlli);
- if (rc >= 0)
- ta = rc;
- else
- ta = 0;
} else {
ta = sba->ta;
- bts()->timing_advance()->remember(tlli, ta);
bts()->sba()->free_sba(sba);
}
if (request->Exist_MS_Radio_Access_capability)
diff --git a/src/encoding.cpp b/src/encoding.cpp
index ffd61080..167bfd4c 100644
--- a/src/encoding.cpp
+++ b/src/encoding.cpp
@@ -195,7 +195,7 @@ void Encoding::write_packet_uplink_assignment(
bitvec_write_field(dest, wp,bts->initial_cs_ul-1, 2); // CHANNEL_CODING_COMMAND
bitvec_write_field(dest, wp,0x1,1); // TLLI_BLOCK_CHANNEL_CODING
bitvec_write_field(dest, wp,0x1,1); // switch TIMING_ADVANCE_VALUE = on
- bitvec_write_field(dest, wp,tbf->ta,6); // TIMING_ADVANCE_VALUE
+ bitvec_write_field(dest, wp,tbf->ta(),6); // TIMING_ADVANCE_VALUE
if (ta_idx < 0) {
bitvec_write_field(dest, wp,0x0,1); // switch TIMING_ADVANCE_INDEX = off
} else {
@@ -275,7 +275,7 @@ void Encoding::write_packet_downlink_assignment(RlcMacDownlink_t * block, uint8_
}
block->u.Packet_Downlink_Assignment.Packet_Timing_Advance.Exist_TIMING_ADVANCE_VALUE = 0x1; // TIMING_ADVANCE_VALUE = on
- block->u.Packet_Downlink_Assignment.Packet_Timing_Advance.TIMING_ADVANCE_VALUE = tbf->ta; // TIMING_ADVANCE_VALUE
+ block->u.Packet_Downlink_Assignment.Packet_Timing_Advance.TIMING_ADVANCE_VALUE = tbf->ta(); // TIMING_ADVANCE_VALUE
if (ta_idx < 0) {
block->u.Packet_Downlink_Assignment.Packet_Timing_Advance.Exist_IndexAndtimeSlot = 0x0; // TIMING_ADVANCE_INDEX = off
} else {
diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp
index c2320a29..d6520c31 100644
--- a/src/gprs_ms.cpp
+++ b/src/gprs_ms.cpp
@@ -60,6 +60,7 @@ GprsMs::GprsMs(uint32_t tlli) :
m_tlli(tlli),
m_new_ul_tlli(0),
m_new_dl_tlli(0),
+ m_ta(0),
m_is_idle(true),
m_ref(0),
m_list(this)
@@ -263,3 +264,15 @@ void GprsMs::set_imsi(const char *imsi)
m_imsi[sizeof(m_imsi) - 1] = '\0';
}
+void GprsMs::set_ta(uint8_t ta_)
+{
+ if (ta_ == m_ta)
+ return;
+
+ LOGP(DRLCMAC, LOGL_INFO,
+ "Modifying MS object, TLLI = 0x%08x, TA %d -> %d\n",
+ tlli(), m_ta, ta_);
+
+ m_ta = ta_;
+}
+
diff --git a/src/gprs_ms.h b/src/gprs_ms.h
index 7f8af414..9c3acb4f 100644
--- a/src/gprs_ms.h
+++ b/src/gprs_ms.h
@@ -59,6 +59,9 @@ public:
const char *imsi() const;
void set_imsi(const char *imsi);
+ uint8_t ta() const;
+ void set_ta(uint8_t ta);
+
void attach_tbf(gprs_rlcmac_tbf *tbf);
void attach_ul_tbf(gprs_rlcmac_ul_tbf *tbf);
void attach_dl_tbf(gprs_rlcmac_dl_tbf *tbf);
@@ -88,6 +91,7 @@ private:
/* store IMSI for look-up and PCH retransmission */
char m_imsi[16];
+ uint8_t m_ta;
bool m_is_idle;
int m_ref;
@@ -111,3 +115,8 @@ inline const char *GprsMs::imsi() const
{
return m_imsi;
}
+
+inline uint8_t GprsMs::ta() const
+{
+ return m_ta;
+}
diff --git a/src/tbf.cpp b/src/tbf.cpp
index ac0cdf3f..53f1ae13 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -89,13 +89,32 @@ void gprs_rlcmac_tbf::assign_imsi(const char *imsi_)
m_ms->set_imsi(imsi_);
}
+uint8_t gprs_rlcmac_tbf::ta() const
+{
+ return m_ms ? m_ms->ta() : m_ta;
+}
+
+void gprs_rlcmac_tbf::set_ta(uint8_t ta)
+{
+ if (ms())
+ ms()->set_ta(ta);
+
+ m_ta = ta;
+}
+
void gprs_rlcmac_tbf::set_ms(GprsMs *ms)
{
if (m_ms == ms)
return;
- if (m_ms)
+ if (m_ms) {
+ /* Save the TA locally. This will also be called, if the MS
+ * object detaches itself from the TBF, for instance if
+ * attach_tbf() is called */
+ m_ta = m_ms->ta();
+
m_ms->detach_tbf(this);
+ }
m_ms = ms;
@@ -110,6 +129,9 @@ void gprs_rlcmac_tbf::update_ms(uint32_t tlli, enum gprs_rlcmac_tbf_direction di
if (!new_ms)
new_ms = bts->ms_store().create_ms(tlli, dir);
+ if (dir == GPRS_RLCMAC_UL_TBF)
+ new_ms->set_ta(m_ta);
+
set_ms(new_ms);
return;
}
@@ -144,11 +166,13 @@ gprs_rlcmac_ul_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts,
return NULL;
}
tbf->m_contention_resolution_done = 1;
- tbf->ta = ta; /* use current TA */
tbf->set_state(GPRS_RLCMAC_ASSIGN);
tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH);
tbf_timer_start(tbf, 3169, bts->t3169, 0);
tbf->update_ms(tlli, GPRS_RLCMAC_UL_TBF);
+ OSMO_ASSERT(tbf->ms());
+
+ tbf->ms()->set_ta(ta);
return tbf;
}
@@ -786,8 +810,6 @@ void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_pdch *pdch)
void gprs_rlcmac_tbf::update_tlli(uint32_t tlli)
{
- /* update the timing advance for the new tlli */
- bts->timing_advance()->update(0, tlli, ta);
}
int gprs_rlcmac_tbf::extract_tlli(const uint8_t *data, const size_t len)
@@ -843,8 +865,6 @@ int gprs_rlcmac_tbf::extract_tlli(const uint8_t *data, const size_t len)
tbf_free(ul_tbf);
ul_tbf = NULL;
}
- /* store current timing advance */
- bts->timing_advance()->remember(tlli(), ta);
return 1;
}
diff --git a/src/tbf.h b/src/tbf.h
index 5ea6d4ef..d288669d 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -149,6 +149,8 @@ struct gprs_rlcmac_tbf {
const char *imsi() const;
void assign_imsi(const char *imsi);
+ uint8_t ta() const;
+ void set_ta(uint8_t);
time_t created_ts() const;
@@ -165,7 +167,6 @@ struct gprs_rlcmac_tbf {
uint8_t control_ts; /* timeslot control messages and polling */
uint8_t ms_class;
struct gprs_rlcmac_pdch *pdch[8]; /* list of PDCHs allocated to TBF */
- uint16_t ta;
gprs_llc m_llc;
@@ -225,6 +226,9 @@ protected:
static const char *tbf_state_name[6];
class GprsMs *m_ms;
+
+ /* Field to take the TA value if no MS is associated */
+ uint8_t m_ta;
private:
mutable char m_name_buf[60];
};
diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp
index edaf2987..2289e3f0 100644
--- a/src/tbf_dl.cpp
+++ b/src/tbf_dl.cpp
@@ -151,42 +151,30 @@ static int tbf_new_dl_assignment(struct gprs_rlcmac_bts *bts,
const uint8_t ms_class,
const uint8_t *data, const uint16_t len)
{
- uint8_t trx, ta, ss;
+ uint8_t trx, ss;
int8_t use_trx;
+ uint16_t ta = 0;
struct gprs_rlcmac_ul_tbf *ul_tbf = NULL, *old_ul_tbf;
struct gprs_rlcmac_dl_tbf *dl_tbf = NULL;
int8_t tfi; /* must be signed */
- int rc;
GprsMs *ms;
/* check for uplink data, so we copy our informations */
#warning "Do the same look up for IMSI, TLLI and OLD_TLLI"
#warning "Refactor the below lines... into a new method"
ms = bts->bts->ms_store().get_ms(tlli, tlli_old, imsi);
- if (ms)
+ if (ms) {
ul_tbf = ms->ul_tbf();
+ ta = ms->ta();
+ }
if (ul_tbf && ul_tbf->m_contention_resolution_done
&& !ul_tbf->m_final_ack_sent) {
use_trx = ul_tbf->trx->trx_no;
- ta = ul_tbf->ta;
ss = 0;
old_ul_tbf = ul_tbf;
} else {
use_trx = -1;
- /* we already have an uplink TBF, so we use that TA */
- if (ul_tbf)
- ta = ul_tbf->ta;
- else {
- /* recall TA */
- rc = bts->bts->timing_advance()->recall(tlli);
- if (rc < 0) {
- LOGP(DRLCMAC, LOGL_NOTICE, "TA unknown"
- ", assuming 0\n");
- ta = 0;
- } else
- ta = rc;
- }
ss = 1; /* PCH assignment only allows one timeslot */
old_ul_tbf = NULL;
}
@@ -205,8 +193,8 @@ static int tbf_new_dl_assignment(struct gprs_rlcmac_bts *bts,
bts->bts->llc_dropped_frame();
return -EBUSY;
}
- dl_tbf->ta = ta;
dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
+ dl_tbf->ms()->set_ta(ta);
LOGP(DRLCMAC, LOGL_DEBUG, "%s [DOWNLINK] START\n", tbf_name(dl_tbf));
@@ -801,7 +789,6 @@ void gprs_rlcmac_dl_tbf::reuse_tbf(const uint8_t *data, const uint16_t len)
}
new_tbf->set_ms(ms());
- new_tbf->ta = ta;
/* Copy over all data to the new TBF */
new_tbf->m_llc.put_frame(data, len);