summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <axilirator@gmail.com>2017-07-04 21:12:25 +0700
committerVadim Yanitskiy <axilirator@gmail.com>2017-10-23 22:05:49 +0330
commit40375003b7e6eeeb34fe047306a5b907af6c1ba6 (patch)
tree3cc9519aad7e8cd3943e7ccc9044c3a9cf932309
parent8e1553470b79c4571c12efdee4e8816f40d33272 (diff)
host/trxcon/scheduler: handle bursts from TRX interface
-rw-r--r--src/host/trxcon/sched_trx.c76
-rw-r--r--src/host/trxcon/sched_trx.h3
-rw-r--r--src/host/trxcon/trx_if.c4
3 files changed, 82 insertions, 1 deletions
diff --git a/src/host/trxcon/sched_trx.c b/src/host/trxcon/sched_trx.c
index a0a2ed5..5cf8779 100644
--- a/src/host/trxcon/sched_trx.c
+++ b/src/host/trxcon/sched_trx.c
@@ -326,3 +326,79 @@ int sched_trx_deactivate_lchan(struct trx_ts *ts, enum trx_lchan_type chan)
return 0;
}
+
+int sched_trx_handle_rx_burst(struct trx_instance *trx, uint8_t ts_num,
+ uint32_t burst_fn, sbit_t *bits, uint16_t nbits, int8_t rssi, float toa)
+{
+ struct trx_lchan_state *lchan;
+ const struct trx_frame *frame;
+ struct trx_ts *ts;
+
+ trx_lchan_rx_func *handler;
+ enum trx_lchan_type chan;
+ uint32_t fn, elapsed;
+ uint8_t offset, bid;
+
+ /* Check whether required timeslot is enabled / configured */
+ ts = sched_trx_find_ts(trx, ts_num);
+ if (ts == NULL) {
+ LOGP(DSCH, LOGL_ERROR, "TDMA timeslot #%u isn't configured, "
+ "ignoring burst...\n", ts_num);
+ return -EINVAL;
+ }
+
+ /* Calculate how many frames have been elapsed */
+ elapsed = (burst_fn + GSM_HYPERFRAME - ts->mf_last_fn);
+ elapsed %= GSM_HYPERFRAME;
+
+ /**
+ * If not too many frames have been elapsed,
+ * start counting from last fn + 1
+ */
+ if (elapsed < 10)
+ fn = (ts->mf_last_fn + 1) % GSM_HYPERFRAME;
+ else
+ fn = burst_fn;
+
+ while (1) {
+ /* Get frame from multiframe */
+ offset = fn % ts->mf_layout->period;
+ frame = ts->mf_layout->frames + offset;
+
+ /* Get required info from frame */
+ bid = frame->dl_bid;
+ chan = frame->dl_chan;
+ handler = trx_lchan_desc[chan].rx_fn;
+
+ /* Omit bursts which have no handler, like IDLE bursts */
+ if (!handler)
+ goto next_frame;
+
+ /* Find required channel state */
+ lchan = sched_trx_find_lchan(ts, chan);
+ if (lchan == NULL) /* FIXME: what should we do here? */
+ goto next_frame;
+
+ /* Ensure that channel is active */
+ if (!lchan->active)
+ goto next_frame;
+
+ /* Put burst to handler */
+ if (fn == burst_fn) {
+ /* TODO: decrypt if required */
+ handler(trx, ts, fn, chan, bid, bits, nbits, rssi, toa);
+ }
+
+next_frame:
+ /* Reached current fn */
+ if (fn == burst_fn)
+ break;
+
+ fn = (fn + 1) % GSM_HYPERFRAME;
+ }
+
+ /* Set last processed frame number */
+ ts->mf_last_fn = fn;
+
+ return 0;
+}
diff --git a/src/host/trxcon/sched_trx.h b/src/host/trxcon/sched_trx.h
index bcb4df9..563ee19 100644
--- a/src/host/trxcon/sched_trx.h
+++ b/src/host/trxcon/sched_trx.h
@@ -252,3 +252,6 @@ int sched_trx_activate_lchan(struct trx_ts *ts, enum trx_lchan_type chan);
int sched_trx_deactivate_lchan(struct trx_ts *ts, enum trx_lchan_type chan);
struct trx_lchan_state *sched_trx_find_lchan(struct trx_ts *ts,
enum trx_lchan_type chan);
+
+int sched_trx_handle_rx_burst(struct trx_instance *trx, uint8_t ts_num,
+ uint32_t burst_fn, sbit_t *bits, uint16_t nbits, int8_t rssi, float toa);
diff --git a/src/host/trxcon/trx_if.c b/src/host/trxcon/trx_if.c
index 83db173..eb868ce 100644
--- a/src/host/trxcon/trx_if.c
+++ b/src/host/trxcon/trx_if.c
@@ -570,7 +570,9 @@ static int trx_data_read_cb(struct osmo_fd *ofd, unsigned int what)
LOGP(DTRX, LOGL_DEBUG, "RX burst tn=%u fn=%u rssi=%d toa=%.2f\n",
tn, fn, rssi, toa);
- /* TODO: poke scheduler here! */
+ /* Poke scheduler */
+ sched_trx_handle_rx_burst(trx, tn, fn, bits, 148, rssi, toa);
+
return 0;
}