Review at  https://gerrit.osmocom.org/6732

host/trxcon/l1ctl.c: handle L1CTL_DM_{EST,REL}_REQ

Change-Id: Ifdf229a6dd3c73ede313d2bfe384032e3887cc3a
---
M src/host/trxcon/l1ctl.c
M src/host/trxcon/sched_trx.c
M src/host/trxcon/sched_trx.h
M src/host/trxcon/trx_if.h
4 files changed, 144 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/32/6732/1

diff --git a/src/host/trxcon/l1ctl.c b/src/host/trxcon/l1ctl.c
index 3098d9c..34e4b3c 100644
--- a/src/host/trxcon/l1ctl.c
+++ b/src/host/trxcon/l1ctl.c
@@ -470,6 +470,94 @@
        return rc;
 }
 
+static int l1ctl_rx_dm_est_req(struct l1ctl_link *l1l, struct msgb *msg)
+{
+       enum gsm_phys_chan_config config;
+       enum trx_lchan_type lchan_type;
+       struct l1ctl_dm_est_req *est_req;
+       struct l1ctl_info_ul *ul;
+       struct trx_ts *ts;
+       uint16_t band_arfcn;
+       uint8_t chan_nr, tn;
+       int rc = 0;
+
+       ul = (struct l1ctl_info_ul *) msg->l1h;
+       est_req = (struct l1ctl_dm_est_req *) ul->payload;
+
+       band_arfcn = ntohs(est_req->h0.band_arfcn);
+       chan_nr = ul->chan_nr;
+
+       LOGP(DL1C, LOGL_DEBUG, "Recv L1CTL_DM_EST_REQ (arfcn=%u, "
+               "chan_nr=0x%02x, tsc=%u)\n", (band_arfcn &~ ARFCN_FLAG_MASK),
+               chan_nr, est_req->tsc);
+
+       if (est_req->h) {
+               LOGP(DL1C, LOGL_ERROR, "FHSS is not supported\n");
+               rc = -ENOTSUP;
+               goto exit;
+       }
+
+       /* Update TSC (Training Sequence) */
+       /* FIXME: est_req->tsc is a number of TSC */
+       memset(l1l->trx->tsc, 0x00, 26);
+
+       /* Determine channel config */
+       config = sched_trx_chan_nr2pchan_config(chan_nr);
+       if (config == GSM_PCHAN_NONE) {
+               LOGP(DL1C, LOGL_ERROR, "Couldn't determine channel config\n");
+               rc = -EINVAL;
+               goto exit;
+       }
+
+       /* Determine TS index */
+       tn = chan_nr & 0x7;
+       if (tn > 7) {
+               LOGP(DL1C, LOGL_ERROR, "Incorrect TS index %u\n", tn);
+               rc = -EINVAL;
+               goto exit;
+       }
+
+       /* Determine lchan type */
+       lchan_type = sched_trx_chan_nr2lchan_type(chan_nr);
+       if (!lchan_type) {
+               LOGP(DL1C, LOGL_ERROR, "Couldn't determine lchan type\n");
+               rc = -EINVAL;
+               goto exit;
+       }
+
+       /* Configure requested TS */
+       rc = sched_trx_configure_ts(l1l->trx, tn, config);
+       if (rc) {
+               rc = -EINVAL;
+               goto exit;
+       }
+
+       /* Find just configured TS */
+       ts = sched_trx_find_ts(l1l->trx, tn);
+
+       /* Activate only requested lchan, disabling others */
+       sched_trx_deactivate_all_lchans(ts);
+       rc = sched_trx_activate_lchan(ts, lchan_type);
+       if (rc) {
+               LOGP(DL1C, LOGL_ERROR, "Couldn't activate lchan\n");
+               rc = -EINVAL;
+               goto exit;
+       }
+
+exit:
+       msgb_free(msg);
+       return rc;
+}
+
+static int l1ctl_rx_dm_rel_req(struct l1ctl_link *l1l, struct msgb *msg)
+{
+       /* Reset scheduler */
+       sched_trx_reset(l1l->trx);
+
+       msgb_free(msg);
+       return 0;
+}
+
 int l1ctl_rx_cb(struct l1ctl_link *l1l, struct msgb *msg)
 {
        struct l1ctl_hdr *l1h;
@@ -490,6 +578,10 @@
                return l1ctl_rx_ccch_mode_req(l1l, msg);
        case L1CTL_RACH_REQ:
                return l1ctl_rx_rach_req(l1l, msg);
+       case L1CTL_DM_EST_REQ:
+               return l1ctl_rx_dm_est_req(l1l, msg);
+       case L1CTL_DM_REL_REQ:
+               return l1ctl_rx_dm_rel_req(l1l, msg);
        default:
                LOGP(DL1C, LOGL_ERROR, "Unknown MSG: %u\n", l1h->msg_type);
                msgb_free(msg);
diff --git a/src/host/trxcon/sched_trx.c b/src/host/trxcon/sched_trx.c
index 1effeb7..be7a480 100644
--- a/src/host/trxcon/sched_trx.c
+++ b/src/host/trxcon/sched_trx.c
@@ -372,6 +372,54 @@
        return 0;
 }
 
+void sched_trx_deactivate_all_lchans(struct trx_ts *ts)
+{
+       struct trx_lchan_state *lchan;
+       int i, len;
+
+       len = talloc_array_length(ts->lchans);
+       for (i = 0; i < len; i++) {
+               lchan = ts->lchans + i;
+
+               talloc_free(lchan->rx_bursts);
+               talloc_free(lchan->tx_bursts);
+
+               lchan->active = 0;
+       }
+}
+
+enum gsm_phys_chan_config sched_trx_chan_nr2pchan_config(uint8_t chan_nr)
+{
+       uint8_t cbits = chan_nr >> 3;
+
+       if (cbits == 0x01)
+               return GSM_PCHAN_TCH_F;
+       else if ((cbits & 0x1e) == 0x02)
+               return GSM_PCHAN_TCH_H;
+       else if ((cbits & 0x1c) == 0x04)
+               return GSM_PCHAN_CCCH_SDCCH4;
+       else if ((cbits & 0x18) == 0x08)
+               return GSM_PCHAN_SDCCH8_SACCH8C;
+
+       return GSM_PCHAN_NONE;
+}
+
+enum trx_lchan_type sched_trx_chan_nr2lchan_type(uint8_t chan_nr)
+{
+       uint8_t cbits = chan_nr >> 3;
+
+       if (cbits == 0x01)
+               return TRXC_TCHF;
+       else if ((cbits & 0x1e) == 0x02)
+               return TRXC_TCHH_0 + (cbits & 0x1);
+       else if ((cbits & 0x1c) == 0x04)
+               return TRXC_SDCCH4_0 + (cbits & 0x3);
+       else if ((cbits & 0x18) == 0x08)
+               return TRXC_SDCCH8_0 + (cbits & 0x7);
+
+       return TRXC_IDLE;
+}
+
 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/sched_trx.h b/src/host/trxcon/sched_trx.h
index 809a324..725f666 100644
--- a/src/host/trxcon/sched_trx.h
+++ b/src/host/trxcon/sched_trx.h
@@ -258,6 +258,9 @@
        enum gsm_phys_chan_config config);
 
 /* Logical channel management functions */
+enum gsm_phys_chan_config sched_trx_chan_nr2pchan_config(uint8_t chan_nr);
+enum trx_lchan_type sched_trx_chan_nr2lchan_type(uint8_t chan_nr);
+void sched_trx_deactivate_all_lchans(struct trx_ts *ts);
 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,
diff --git a/src/host/trxcon/trx_if.h b/src/host/trxcon/trx_if.h
index 8ba09b8..9e3a32a 100644
--- a/src/host/trxcon/trx_if.h
+++ b/src/host/trxcon/trx_if.h
@@ -32,6 +32,7 @@
        uint16_t pm_arfcn_start;
        uint16_t pm_arfcn_stop;
        uint16_t band_arfcn;
+       uint8_t tsc[26];
        uint8_t bsic;
 
        /* Scheduler stuff */

-- 
To view, visit https://gerrit.osmocom.org/6732
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ifdf229a6dd3c73ede313d2bfe384032e3887cc3a
Gerrit-PatchSet: 1
Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <lafo...@gnumonks.org>

Reply via email to