diff options
author | Vadim Yanitskiy <axilirator@gmail.com> | 2017-07-15 22:46:54 +0700 |
---|---|---|
committer | Vadim Yanitskiy <axilirator@gmail.com> | 2017-11-19 17:35:07 +0700 |
commit | 74f85951560712c97af36b9679edd9ec2922887f (patch) | |
tree | 7f2fe72cae3a05a688bb40fcc359babb763d179a /src/host/trxcon | |
parent | 824bfa299d66039480da67e8d387a58fff845383 (diff) |
host/trxcon/scheduler: implement xCCH TX capability
Change-Id: I4da4816dcecc55eb9b4d2d6c631967026a5e4f68
Diffstat (limited to 'src/host/trxcon')
-rw-r--r-- | src/host/trxcon/sched_lchan_desc.c | 5 | ||||
-rw-r--r-- | src/host/trxcon/sched_lchan_handlers.c | 89 | ||||
-rw-r--r-- | src/host/trxcon/sched_trx.h | 2 |
3 files changed, 95 insertions, 1 deletions
diff --git a/src/host/trxcon/sched_lchan_desc.c b/src/host/trxcon/sched_lchan_desc.c index 55edb989..e3998fa8 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 @@ int rx_data_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); +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 b27f811d..078c5fde 100644 --- a/src/host/trxcon/sched_lchan_handlers.c +++ b/src/host/trxcon/sched_lchan_handlers.c @@ -164,6 +164,95 @@ int rx_data_fn(struct trx_instance *trx, struct trx_ts *ts, 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 725f666d..cab290b8 100644 --- a/src/host/trxcon/sched_trx.h +++ b/src/host/trxcon/sched_trx.h @@ -148,6 +148,8 @@ struct trx_lchan_state { 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 */ |