aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <axilirator@gmail.com>2019-10-05 23:45:31 +0700
committerVadim Yanitskiy <axilirator@gmail.com>2019-10-05 23:50:43 +0700
commit98d7582d483d9e3e3ecdd352be5c81b9f6db6b09 (patch)
treeb4826c3dd8d7b84d7a2fceac380fbfe70bec4ff5
parentcad1862118e2ef8b189604e286719adad608b911 (diff)
PTCCH: properly handle RACH.ind for PCU_IF_SAPI_PTCCHfixeria/ptcch
-rw-r--r--src/bts.cpp47
-rw-r--r--src/bts.h1
-rw-r--r--src/pcu_l1_if.cpp5
3 files changed, 53 insertions, 0 deletions
diff --git a/src/bts.cpp b/src/bts.cpp
index 4b2f117..f33ce21 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -839,6 +839,53 @@ int BTS::rcv_rach(uint16_t ra, uint32_t Fn, int16_t qta, bool is_11bit,
return rc;
}
+/* PTCCH/U sub-slot / frame-number mapping (see 3GPP TS 45.002, table 6) */
+static uint32_t ptcch_slot_map[PTCCH_TAI_NUM] = {
+ 12, 38, 64, 90,
+ 116, 142, 168, 194,
+ 220, 246, 272, 298,
+ 324, 350, 376, 402,
+};
+
+int BTS::rcv_ptcch_rach(uint8_t trx_nr, uint8_t ts_nr, uint32_t fn, int16_t qta)
+{
+ struct gprs_rlcmac_bts *bts = bts_data();
+ struct gprs_rlcmac_pdch *pdch;
+ uint32_t fn416 = fn % 416;
+ uint8_t ss;
+
+ /* Prevent buffer overflow */
+ if (trx_nr >= ARRAY_SIZE(bts->trx) || ts_nr >= 8) {
+ LOGP(DRLCMAC, LOGL_ERROR, "Malformed RACH.ind message "
+ "(TRX=%u TS=%u FN=%u)\n", trx_nr, ts_nr, fn);
+ return -EINVAL;
+ }
+
+ /* Make sure PDCH time-slot is enabled */
+ pdch = &bts->trx[trx_nr].pdch[ts_nr];
+ if (!pdch->m_is_enabled) {
+ LOGP(DRLCMAC, LOGL_NOTICE, "Rx PTCCH RACH.ind for inactive PDCH "
+ "(TRX=%u TS=%u FN=%u)\n", trx_nr, ts_nr, fn);
+ return -EAGAIN;
+ }
+
+ /* Convert TDMA frame-number to PTCCH/U sub-slot number */
+ for (ss = 0; ss < PTCCH_TAI_NUM; ss++)
+ if (ptcch_slot_map[ss] == fn416)
+ break;
+ if (ss == PTCCH_TAI_NUM) {
+ LOGP(DRLCMAC, LOGL_ERROR, "Failed to map PTCCH/U sub-slot for fn=%u\n", fn);
+ return -ENODEV;
+ }
+
+ /* Apply a new Timing Advance value */
+ LOGP(DRLCMAC, LOGL_INFO, "Continuous Timing Advance update "
+ "for TAI %u, new TA is %u\n", ss, qta2ta(qta));
+ pdch->update_ta(ss, qta2ta(qta));
+
+ return 0;
+}
+
void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, const char *imsi)
{
int plen;
diff --git a/src/bts.h b/src/bts.h
index fab9bcb..991eda8 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -298,6 +298,7 @@ public:
uint32_t rfn_to_fn(int32_t rfn);
int rcv_rach(uint16_t ra, uint32_t Fn, int16_t qta, bool is_11bit,
enum ph_burst_type burst_type);
+ int rcv_ptcch_rach(uint8_t trx_nr, uint8_t ts_nr, uint32_t fn, int16_t qta);
void snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, const char *imsi);
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index a13e4d9..df39a1a 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -407,6 +407,11 @@ static int pcu_rx_rach_ind(struct gsm_pcu_if_rach_ind *rach_ind)
rach_ind->qta, rach_ind->is_11bit,
(ph_burst_type)rach_ind->burst_type);
break;
+ case PCU_IF_SAPI_PTCCH:
+ rc = BTS::main_bts()->rcv_ptcch_rach(
+ rach_ind->trx_nr, rach_ind->ts_nr,
+ rach_ind->fn, rach_ind->qta);
+ break;
default:
LOGP(DL1IF, LOGL_ERROR, "Received PCU rach request with "
"unsupported sapi %d\n", rach_ind->sapi);