aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <vyanitskiy@sysmocom.de>2020-06-17 05:08:54 +0700
committerfixeria <vyanitskiy@sysmocom.de>2020-06-25 18:02:10 +0000
commit2f18578dcc82b73ea06464dc59e215874eaf1e0b (patch)
treea4c767914900838f8e75a40a04c92c9bc26716dd
parent7a7168f0a86431a082836f59288cac683c485004 (diff)
Use libosmocore's TDMA frame number API (constatns & arithmetic)
-rw-r--r--include/osmo-bts/gsm_data.h4
-rw-r--r--src/common/l1sap.c4
-rw-r--r--src/common/scheduler.c14
-rw-r--r--src/osmo-bts-trx/scheduler_trx.c37
-rw-r--r--src/osmo-bts-trx/trx_if.c6
-rw-r--r--src/osmo-bts-virtual/scheduler_virtbts.c18
6 files changed, 31 insertions, 52 deletions
diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h
index 416864fb..255c871d 100644
--- a/include/osmo-bts/gsm_data.h
+++ b/include/osmo-bts/gsm_data.h
@@ -12,6 +12,7 @@
#include <osmocom/codec/ecu.h>
#include <osmocom/gsm/lapdm.h>
#include <osmocom/gsm/gsm23003.h>
+#include <osmocom/gsm/gsm0502.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/gsm/rxlev_stat.h>
@@ -35,9 +36,6 @@
#define GSM_HR_BYTES 14 /* TS 101318 Chapter 5.2: 112 bits, no sig */
#define GSM_EFR_BYTES 31 /* TS 101318 Chapter 5.3: 244 bits + 4bit sig */
-#define GSM_SUPERFRAME (26*51) /* 1326 TDMA frames */
-#define GSM_HYPERFRAME (2048*GSM_SUPERFRAME) /* GSM_HYPERFRAME frames */
-
#define GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DEFAULT 41
#define GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE 999999
#define GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT 41
diff --git a/src/common/l1sap.c b/src/common/l1sap.c
index dad1b494..17a6c5d4 100644
--- a/src/common/l1sap.c
+++ b/src/common/l1sap.c
@@ -621,7 +621,7 @@ static int l1sap_info_time_ind(struct gsm_bts *bts,
/* increment number of RACH slots that have passed by since the
* last time indication */
for (i = 0; i < frames_expired; i++) {
- uint32_t fn = (info_time_ind->fn + GSM_HYPERFRAME - i) % GSM_HYPERFRAME;
+ uint32_t fn = GSM_TDMA_FN_SUB(info_time_ind->fn, i);
bts->load.rach.total += calc_exprd_rach_frames(bts, fn);
}
@@ -891,7 +891,7 @@ int32_t bts_get_avg_fn_advance(struct gsm_bts *bts)
static void l1sap_update_fnstats(struct gsm_bts *bts, uint32_t rts_fn)
{
- int32_t delta = (rts_fn + GSM_HYPERFRAME - bts->gsm_time.fn) % GSM_HYPERFRAME;
+ int32_t delta = GSM_TDMA_FN_SUB(rts_fn, bts->gsm_time.fn);
if (delta < bts->fn_stats.min)
bts->fn_stats.min = delta;
diff --git a/src/common/scheduler.c b/src/common/scheduler.c
index 01edc69c..62efed41 100644
--- a/src/common/scheduler.c
+++ b/src/common/scheduler.c
@@ -684,7 +684,7 @@ struct msgb *_sched_dequeue_prim(struct l1sched_trx *l1t, int8_t tn, uint32_t fn
LOGL1S(DL1P, LOGL_ERROR, l1t, tn, chan, fn, "Prim has wrong type.\n");
goto free_msg;
}
- prim_fn = ((l1sap_fn + GSM_HYPERFRAME - fn) % GSM_HYPERFRAME);
+ prim_fn = GSM_TDMA_FN_SUB(l1sap_fn, fn);
if (prim_fn > 100) { /* l1sap_fn < fn */
LOGL1S(DL1P, LOGL_NOTICE, l1t, tn, chan, fn,
"Prim %u is out of range (%u vs exp %u), or channel %s with "
@@ -1248,12 +1248,6 @@ no_data:
}
}
-#define TDMA_FN_SUM(a, b) \
- ((a + GSM_HYPERFRAME + b) % GSM_HYPERFRAME)
-
-#define TDMA_FN_SUB(a, b) \
- ((a + GSM_HYPERFRAME - b) % GSM_HYPERFRAME)
-
static int trx_sched_calc_frame_loss(struct l1sched_trx *l1t,
struct l1sched_chan_state *l1cs, uint8_t tn, uint32_t fn)
{
@@ -1291,7 +1285,7 @@ static int trx_sched_calc_frame_loss(struct l1sched_trx *l1t,
}
/* How many frames elapsed since the last one? */
- elapsed_fs = TDMA_FN_SUB(fn, l1cs->last_tdma_fn);
+ elapsed_fs = GSM_TDMA_FN_SUB(fn, l1cs->last_tdma_fn);
if (elapsed_fs > l1ts->mf_period) { /* Too many! */
LOGL1S(DL1P, LOGL_ERROR, l1t, tn, frame_head->ul_chan, fn,
"Too many (>%u) contiguous TDMA frames=%u elapsed "
@@ -1310,7 +1304,7 @@ static int trx_sched_calc_frame_loss(struct l1sched_trx *l1t,
* Start counting from the last_fn + 1.
*/
for (i = 1; i < elapsed_fs; i++) {
- fn_i = TDMA_FN_SUM(l1cs->last_tdma_fn, i);
+ fn_i = GSM_TDMA_FN_SUM(l1cs->last_tdma_fn, i);
offset = fn_i % l1ts->mf_period;
frame = l1ts->mf_frames + offset;
@@ -1343,7 +1337,7 @@ static int trx_sched_calc_frame_loss(struct l1sched_trx *l1t,
};
for (i = 1; i < elapsed_fs; i++) {
- fn_i = TDMA_FN_SUM(l1cs->last_tdma_fn, i);
+ fn_i = GSM_TDMA_FN_SUM(l1cs->last_tdma_fn, i);
offset = fn_i % l1ts->mf_period;
frame = l1ts->mf_frames + offset;
func = trx_chan_desc[frame->ul_chan].ul_fn;
diff --git a/src/osmo-bts-trx/scheduler_trx.c b/src/osmo-bts-trx/scheduler_trx.c
index d4a38b61..3936124c 100644
--- a/src/osmo-bts-trx/scheduler_trx.c
+++ b/src/osmo-bts-trx/scheduler_trx.c
@@ -74,7 +74,7 @@ static int trx_sched_fn(struct gsm_bts *bts, uint32_t fn)
/* advance frame number, so the transceiver has more
* time until it must be transmitted. */
- fn = (fn + plink->u.osmotrx.clock_advance) % GSM_HYPERFRAME;
+ fn = GSM_TDMA_FN_SUM(fn, plink->u.osmotrx.clock_advance);
/* we don't schedule, if power is off */
if (!trx_if_powered(l1h))
@@ -83,8 +83,7 @@ static int trx_sched_fn(struct gsm_bts *bts, uint32_t fn)
/* process every TS of TRX */
for (tn = 0; tn < ARRAY_SIZE(l1t->ts); tn++) {
/* ready-to-send */
- _sched_rts(l1t, tn,
- (fn + plink->u.osmotrx.rts_advance) % GSM_HYPERFRAME);
+ _sched_rts(l1t, tn, GSM_TDMA_FN_SUM(fn, plink->u.osmotrx.rts_advance));
/* All other parameters to be set by _sched_dl_burst() */
br = (struct trx_dl_burst_req) {
@@ -105,10 +104,6 @@ static int trx_sched_fn(struct gsm_bts *bts, uint32_t fn)
return 0;
}
-/*! duration of a GSM frame in nano-seconds. (120ms/26) */
-#define FRAME_DURATION_nS 4615384
-/*! duration of a GSM frame in micro-seconds (120s/26) */
-#define FRAME_DURATION_uS (FRAME_DURATION_nS/1000)
/*! maximum number of 'missed' frame periods we can tolerate of OS doesn't schedule us*/
#define MAX_FN_SKEW 50
/*! maximum number of frame periods we can tolerate without TRX Clock Indication*/
@@ -126,9 +121,9 @@ static inline int64_t compute_elapsed_us(const struct timespec *last, const stru
/*! compute the number of frame number intervals elapsed between \a last and \a now */
static inline int compute_elapsed_fn(const uint32_t last, const uint32_t now)
{
- int elapsed_fn = (now + GSM_HYPERFRAME - last) % GSM_HYPERFRAME;
+ int elapsed_fn = GSM_TDMA_FN_SUB(now, last);
if (elapsed_fn >= 135774)
- elapsed_fn -= GSM_HYPERFRAME;
+ elapsed_fn -= GSM_TDMA_HYPERFRAME;
return elapsed_fn;
}
@@ -139,9 +134,6 @@ static inline void normalize_timespec(struct timespec *ts)
ts->tv_nsec = ts->tv_nsec % 1000000000;
}
-/*! Increment a GSM frame number modulo GSM_HYPERFRAME */
-#define INCREMENT_FN(fn) (fn) = (((fn) + 1) % GSM_HYPERFRAME)
-
extern int quit;
/*! this is the timerfd-callback firing for every FN to be processed */
@@ -178,7 +170,7 @@ static int trx_fn_timer_cb(struct osmo_fd *ofd, unsigned int what)
/* compute actual elapsed time and resulting OS scheduling error */
clock_gettime(CLOCK_MONOTONIC, &tv_now);
elapsed_us = compute_elapsed_us(&tcs->last_fn_timer.tv, &tv_now);
- error_us = elapsed_us - FRAME_DURATION_uS;
+ error_us = elapsed_us - GSM_TDMA_FN_DURATION_uS;
#ifdef DEBUG_CLOCK
printf("%s(): %09ld, elapsed_us=%05" PRId64 ", error_us=%-d: fn=%d\n", __func__,
tv_now.tv_nsec, elapsed_us, error_us, tcs->last_fn_timer.fn+1);
@@ -186,17 +178,15 @@ static int trx_fn_timer_cb(struct osmo_fd *ofd, unsigned int what)
tcs->last_fn_timer.tv = tv_now;
/* if someone played with clock, or if the process stalled */
- if (elapsed_us > FRAME_DURATION_uS * MAX_FN_SKEW || elapsed_us < 0) {
+ if (elapsed_us > GSM_TDMA_FN_DURATION_uS * MAX_FN_SKEW || elapsed_us < 0) {
LOGP(DL1C, LOGL_ERROR, "PC clock skew: elapsed_us=%" PRId64 ", error_us=%" PRId64 "\n",
elapsed_us, error_us);
goto no_clock;
}
/* call trx_sched_fn() for all expired FN */
- for (i = 0; i < expire_count; i++) {
- INCREMENT_FN(tcs->last_fn_timer.fn);
- trx_sched_fn(bts, tcs->last_fn_timer.fn);
- }
+ for (i = 0; i < expire_count; i++)
+ trx_sched_fn(bts, GSM_TDMA_FN_INC(tcs->last_fn_timer.fn));
return 0;
@@ -281,7 +271,7 @@ int trx_sched_clock(struct gsm_bts *bts, uint32_t fn)
int elapsed_fn;
int64_t elapsed_us, elapsed_us_since_clk, elapsed_fn_since_clk, error_us_since_clk;
unsigned int fn_caught_up = 0;
- const struct timespec interval = { .tv_sec = 0, .tv_nsec = FRAME_DURATION_nS };
+ const struct timespec interval = { .tv_sec = 0, .tv_nsec = GSM_TDMA_FN_DURATION_nS };
if (quit)
return 0;
@@ -307,7 +297,7 @@ int trx_sched_clock(struct gsm_bts *bts, uint32_t fn)
elapsed_us_since_clk = compute_elapsed_us(&tcs->last_clk_ind.tv, &tv_now);
elapsed_fn_since_clk = compute_elapsed_fn(tcs->last_clk_ind.fn, fn);
/* error (delta) between local clock since last CLK and CLK based on FN clock at TRX */
- error_us_since_clk = elapsed_us_since_clk - (FRAME_DURATION_uS * elapsed_fn_since_clk);
+ error_us_since_clk = elapsed_us_since_clk - (GSM_TDMA_FN_DURATION_uS * elapsed_fn_since_clk);
LOGP(DL1C, LOGL_INFO, "TRX Clock Ind: elapsed_us=%7"PRId64", "
"elapsed_fn=%3"PRId64", error_us=%+5"PRId64"\n",
elapsed_us_since_clk, elapsed_fn_since_clk, error_us_since_clk);
@@ -328,14 +318,14 @@ int trx_sched_clock(struct gsm_bts *bts, uint32_t fn)
}
LOGP(DL1C, LOGL_INFO, "GSM clock jitter: %" PRId64 "us (elapsed_fn=%d)\n",
- elapsed_fn * FRAME_DURATION_uS - elapsed_us, elapsed_fn);
+ elapsed_fn * GSM_TDMA_FN_DURATION_uS - elapsed_us, elapsed_fn);
/* too many frames have been processed already */
if (elapsed_fn < 0) {
struct timespec first = interval;
/* set clock to the time or last FN should have been
* transmitted. */
- first.tv_nsec += (0 - elapsed_fn) * FRAME_DURATION_nS;
+ first.tv_nsec += (0 - elapsed_fn) * GSM_TDMA_FN_DURATION_nS;
normalize_timespec(&first);
LOGP(DL1C, LOGL_NOTICE, "We were %d FN faster than TRX, compensating\n", -elapsed_fn);
/* set time to the time our next FN has to be transmitted */
@@ -345,8 +335,7 @@ int trx_sched_clock(struct gsm_bts *bts, uint32_t fn)
/* transmit what we still need to transmit */
while (fn != tcs->last_fn_timer.fn) {
- INCREMENT_FN(tcs->last_fn_timer.fn);
- trx_sched_fn(bts, tcs->last_fn_timer.fn);
+ trx_sched_fn(bts, GSM_TDMA_FN_INC(tcs->last_fn_timer.fn));
fn_caught_up++;
}
diff --git a/src/osmo-bts-trx/trx_if.c b/src/osmo-bts-trx/trx_if.c
index 6fe0ecd6..58f74553 100644
--- a/src/osmo-bts-trx/trx_if.c
+++ b/src/osmo-bts-trx/trx_if.c
@@ -121,8 +121,8 @@ static int trx_clk_read_cb(struct osmo_fd *ofd, unsigned int what)
LOGPPHI(pinst, DTRX, LOGL_INFO, "Clock indication: fn=%u\n", fn);
- if (fn >= GSM_HYPERFRAME) {
- fn %= GSM_HYPERFRAME;
+ if (fn >= GSM_TDMA_HYPERFRAME) {
+ fn %= GSM_TDMA_HYPERFRAME;
LOGPPHI(pinst, DTRX, LOGL_ERROR, "Indicated clock's FN is not "
"wrapping correctly, correcting to fn=%u\n", fn);
}
@@ -737,7 +737,7 @@ static int trx_data_handle_hdr_v0(struct trx_l1h *l1h,
bi->rssi = -(int8_t)buf[5];
bi->toa256 = (int16_t) osmo_load16be(buf + 6);
- if (bi->fn >= GSM_HYPERFRAME) {
+ if (bi->fn >= GSM_TDMA_HYPERFRAME) {
LOGPPHI(l1h->phy_inst, DTRX, LOGL_ERROR,
"Illegal TDMA fn=%u\n", bi->fn);
return -EINVAL;
diff --git a/src/osmo-bts-virtual/scheduler_virtbts.c b/src/osmo-bts-virtual/scheduler_virtbts.c
index d3fdf1ab..1c2b057e 100644
--- a/src/osmo-bts-virtual/scheduler_virtbts.c
+++ b/src/osmo-bts-virtual/scheduler_virtbts.c
@@ -532,7 +532,6 @@ void _sched_act_rach_det(struct l1sched_trx *l1t, uint8_t tn, uint8_t ss, int ac
***********************************************************************/
#define RTS_ADVANCE 5 /* about 20ms */
-#define FRAME_DURATION_uS 4615
static int vbts_sched_fn(struct gsm_bts *bts, uint32_t fn)
{
@@ -558,7 +557,7 @@ static int vbts_sched_fn(struct gsm_bts *bts, uint32_t fn)
* --> Handle and process non-transparent RSL-Messages (activate channel, )
* --> Forward transparent RSL-DATA-Messages to the ms by appending them to
* the l1-dl-queue */
- _sched_rts(l1t, br.tn, (fn + RTS_ADVANCE) % GSM_HYPERFRAME);
+ _sched_rts(l1t, br.tn, GSM_TDMA_FN_SUM(fn, RTS_ADVANCE));
/* schedule transmit backend functions */
/* Process data in the l1-dlqueue and forward it
* to MS */
@@ -587,28 +586,27 @@ static void vbts_fn_timer_cb(void *data)
+ (tv_now.tv_usec - tv_clock->tv_usec);
/* not so good somehow a lot of time passed between two timer callbacks */
- if (elapsed_us > 2 *FRAME_DURATION_uS)
+ if (elapsed_us > 2 *GSM_TDMA_FN_DURATION_uS)
LOGP(DL1P, LOGL_NOTICE, "vbts_fn_timer_cb after %d us\n", elapsed_us);
/* schedule the current frame/s (fn = frame number)
* this loop will be called at least once, but can also be executed
* multiple times if more than one frame duration (4615us) passed till the last callback */
- while (elapsed_us > FRAME_DURATION_uS / 2) {
+ while (elapsed_us > GSM_TDMA_FN_DURATION_uS / 2) {
const struct timeval tv_frame = {
.tv_sec = 0,
- .tv_usec = FRAME_DURATION_uS,
+ .tv_usec = GSM_TDMA_FN_DURATION_uS,
};
timeradd(tv_clock, &tv_frame, tv_clock);
/* increment the frame number in the BTS model instance */
- bts_virt->last_fn = (bts_virt->last_fn + 1) % GSM_HYPERFRAME;
- vbts_sched_fn(bts, bts_virt->last_fn);
- elapsed_us -= FRAME_DURATION_uS;
+ vbts_sched_fn(bts, GSM_TDMA_FN_INC(bts_virt->last_fn));
+ elapsed_us -= GSM_TDMA_FN_DURATION_uS;
}
/* re-schedule the timer */
/* timer is set to frame duration - elapsed time to guarantee that this cb method will be
* periodically executed every 4.615ms */
- osmo_timer_schedule(&bts_virt->fn_timer, 0, FRAME_DURATION_uS - elapsed_us);
+ osmo_timer_schedule(&bts_virt->fn_timer, 0, GSM_TDMA_FN_DURATION_uS - elapsed_us);
}
int vbts_sched_start(struct gsm_bts *bts)
@@ -622,7 +620,7 @@ int vbts_sched_start(struct gsm_bts *bts)
gettimeofday(&bts_virt->tv_clock, NULL);
/* trigger the first timer after 4615us (a frame duration) */
- osmo_timer_schedule(&bts_virt->fn_timer, 0, FRAME_DURATION_uS);
+ osmo_timer_schedule(&bts_virt->fn_timer, 0, GSM_TDMA_FN_DURATION_uS);
return 0;
}