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

host/trxcon/scheduler: implement xCCH TX capability

Change-Id: I4da4816dcecc55eb9b4d2d6c631967026a5e4f68
---
M src/host/trxcon/sched_lchan_desc.c
M src/host/trxcon/sched_lchan_handlers.c
M src/host/trxcon/sched_trx.h
3 files changed, 95 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/33/6733/1

diff --git a/src/host/trxcon/sched_lchan_desc.c 
b/src/host/trxcon/sched_lchan_desc.c
index 55edb98..e3998fa 100644
--- a/src/host/trxcon/sched_lchan_desc.c
+++ b/src/host/trxcon/sched_lchan_desc.c
@@ -29,7 +29,6 @@
 #define LID_SACCH      0x40
 
 /* TODO: implement */
-#define tx_data_fn     NULL
 #define tx_pdtch_fn    NULL
 #define tx_tchf_fn     NULL
 #define tx_tchh_fn     NULL
@@ -43,6 +42,10 @@
        uint32_t fn, enum trx_lchan_type chan, uint8_t bid,
        sbit_t *bits, uint16_t nbits, int8_t rssi, float toa);
 
+int tx_data_fn(struct trx_instance *trx, struct trx_ts *ts,
+       uint32_t fn, enum trx_lchan_type chan,
+       uint8_t bid, uint16_t *nbits);
+
 int rx_sch_fn(struct trx_instance *trx, struct trx_ts *ts,
        uint32_t fn, enum trx_lchan_type chan, uint8_t bid,
        sbit_t *bits, uint16_t nbits, int8_t rssi, float toa);
diff --git a/src/host/trxcon/sched_lchan_handlers.c 
b/src/host/trxcon/sched_lchan_handlers.c
index b27f811..078c5fd 100644
--- a/src/host/trxcon/sched_lchan_handlers.c
+++ b/src/host/trxcon/sched_lchan_handlers.c
@@ -164,6 +164,95 @@
        return 0;
 }
 
+int tx_data_fn(struct trx_instance *trx, struct trx_ts *ts,
+       uint32_t fn, enum trx_lchan_type chan,
+       uint8_t bid, uint16_t *nbits)
+{
+       struct trx_lchan_state *lchan;
+       struct trx_ts_prim *prim;
+       struct l1ctl_info_ul *ul;
+       ubit_t burst[GSM_BURST_LEN];
+       ubit_t *buffer, *offset;
+       uint8_t *mask, *l2;
+       int rc;
+
+       /* Find required channel state */
+       lchan = sched_trx_find_lchan(ts, chan);
+       if (lchan == NULL)
+               return -EINVAL;
+
+       /* Set up pointers */
+       mask = &lchan->tx_burst_mask;
+       buffer = lchan->tx_bursts;
+
+       if (bid > 0) {
+               /* If we have encoded bursts */
+               if (*mask)
+                       goto send_burst;
+               else
+                       return 0;
+       }
+
+       /* Encode payload if not yet */
+
+       /* Get a message from TX queue */
+       prim = llist_entry(ts->tx_prims.next, struct trx_ts_prim, list);
+       ul = (struct l1ctl_info_ul *) prim->payload;
+       l2 = (uint8_t *) ul->payload;
+
+       /* Encode bursts */
+       rc = gsm0503_xcch_encode(buffer, l2);
+       if (rc) {
+               LOGP(DSCH, LOGL_ERROR, "Failed to encode L2 payload\n");
+
+               /* Remove primitive from queue and free memory */
+               llist_del(&prim->list);
+               talloc_free(prim);
+
+               return -EINVAL;
+       }
+
+send_burst:
+       /* Determine which burst should be sent */
+       offset = buffer + bid * 116;
+
+       /* Update mask */
+       *mask |= (1 << bid);
+
+       /* If we are sending the last (4/4) burst */
+       if ((*mask & 0x0f) == 0x0f) {
+               /* Remove primitive from queue and free memory */
+               prim = llist_entry(ts->tx_prims.next, struct trx_ts_prim, list);
+               llist_del(&prim->list);
+               talloc_free(prim);
+
+               /* Reset mask */
+               *mask = 0x00;
+       }
+
+       /* Compose a new burst */
+       memset(burst, 0, 3); /* TB */
+       memcpy(burst + 3, offset, 58); /* Payload 1/2 */
+       memcpy(burst + 61, trx->tsc, 26); /* TSC */
+       memcpy(burst + 87, offset + 58, 58); /* Payload 2/2 */
+       memset(burst + 145, 0, 3); /* TB */
+
+       if (nbits)
+               *nbits = GSM_BURST_LEN;
+
+       LOGP(DSCH, LOGL_DEBUG, "Transmitting %s fn=%u ts=%u burst=%u\n",
+               trx_lchan_desc[chan].name, fn, ts->index, bid);
+
+       /* Send burst to transceiver */
+       rc = trx_if_tx_burst(trx, ts->index, fn, 10, burst);
+       if (rc) {
+               LOGP(DSCH, LOGL_ERROR, "Could not send burst to transceiver\n");
+               return rc;
+       }
+
+       return 0;
+}
+
 static void decode_sb(struct gsm_time *time, uint8_t *bsic, uint8_t *sb_info)
 {
        uint8_t t3p;
diff --git a/src/host/trxcon/sched_trx.h b/src/host/trxcon/sched_trx.h
index 725f666..cab290b 100644
--- a/src/host/trxcon/sched_trx.h
+++ b/src/host/trxcon/sched_trx.h
@@ -148,6 +148,8 @@
        uint32_t rx_first_fn;
        /*! \brief Mask of received bursts */
        uint8_t rx_burst_mask;
+       /*! \brief Mask of transmitted bursts */
+       uint8_t tx_burst_mask;
        /*! \brief Burst buffer for RX */
        sbit_t *rx_bursts;
        /*! \brief Burst buffer for TX */

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

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

Reply via email to