PTCCH: properly handle RACH.ind for PCU_IF_SAPI_PTCCH
Change-Id: I482d60a46b9d253dfe0b16140eac9fea6420b30c Related: OS#1545
This commit is contained in:
parent
17954da56c
commit
ffebd24456
47
src/bts.cpp
47
src/bts.cpp
|
@ -842,6 +842,53 @@ int BTS::rcv_rach(uint16_t ra, uint32_t Fn, int16_t qta, bool is_11bit,
|
||||||
return rc;
|
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 the 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)
|
void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, const char *imsi)
|
||||||
{
|
{
|
||||||
int plen;
|
int plen;
|
||||||
|
|
|
@ -301,6 +301,7 @@ public:
|
||||||
uint32_t rfn_to_fn(int32_t rfn);
|
uint32_t rfn_to_fn(int32_t rfn);
|
||||||
int rcv_rach(uint16_t ra, uint32_t Fn, int16_t qta, bool is_11bit,
|
int rcv_rach(uint16_t ra, uint32_t Fn, int16_t qta, bool is_11bit,
|
||||||
enum ph_burst_type burst_type);
|
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);
|
void snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, const char *imsi);
|
||||||
|
|
||||||
|
|
|
@ -223,10 +223,6 @@ static int handle_ph_data_ind(struct lc15l1_hdl *fl1h,
|
||||||
data_ind->u32Fn,
|
data_ind->u32Fn,
|
||||||
&meas);
|
&meas);
|
||||||
break;
|
break;
|
||||||
case GsmL1_Sapi_Ptcch:
|
|
||||||
// FIXME
|
|
||||||
rc = -1;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
LOGP(DL1IF, LOGL_NOTICE, "Rx PH-DATA.ind for unknown L1 SAPI %s\n",
|
LOGP(DL1IF, LOGL_NOTICE, "Rx PH-DATA.ind for unknown L1 SAPI %s\n",
|
||||||
get_value_string(lc15bts_l1sapi_names, data_ind->sapi));
|
get_value_string(lc15bts_l1sapi_names, data_ind->sapi));
|
||||||
|
@ -251,8 +247,21 @@ static int handle_ph_ra_ind(struct lc15l1_hdl *fl1h, GsmL1_PhRaInd_t *ra_ind)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
DEBUGP(DL1IF, "Rx PH-RA.ind");
|
DEBUGP(DL1IF, "Rx PH-RA.ind");
|
||||||
bts_update_tbf_ta("PH-RA", ra_ind->u32Fn, fl1h->trx_no, ra_ind->u8Tn,
|
|
||||||
qta2ta(ra_ind->measParam.i16BurstTiming), true);
|
switch (ra_ind->sapi) {
|
||||||
|
case GsmL1_Sapi_Pdtch:
|
||||||
|
bts_update_tbf_ta("PH-RA", ra_ind->u32Fn, fl1h->trx_no, ra_ind->u8Tn,
|
||||||
|
qta2ta(ra_ind->measParam.i16BurstTiming), true);
|
||||||
|
break;
|
||||||
|
case GsmL1_Sapi_Ptcch:
|
||||||
|
pcu_rx_rach_ind_pdtch(fl1h->trx_no, ra_ind->u8Tn, ra_ind->u32Fn,
|
||||||
|
ra_ind->measParam.i16BurstTiming);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOGP(DL1IF, LOGL_NOTICE, "Rx PH-RA.ind for unknown L1 SAPI %s\n",
|
||||||
|
get_value_string(lc15bts_l1sapi_names, ra_ind->sapi));
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,9 +229,6 @@ static int handle_ph_data_ind(struct oc2gl1_hdl *fl1h,
|
||||||
data_ind->u32Fn,
|
data_ind->u32Fn,
|
||||||
&meas);
|
&meas);
|
||||||
break;
|
break;
|
||||||
case GsmL1_Sapi_Ptcch:
|
|
||||||
// FIXME
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
LOGP(DL1IF, LOGL_NOTICE, "Rx PH-DATA.ind for unknown L1 SAPI %s\n",
|
LOGP(DL1IF, LOGL_NOTICE, "Rx PH-DATA.ind for unknown L1 SAPI %s\n",
|
||||||
get_value_string(oc2gbts_l1sapi_names, data_ind->sapi));
|
get_value_string(oc2gbts_l1sapi_names, data_ind->sapi));
|
||||||
|
@ -250,8 +247,20 @@ static int handle_ph_ra_ind(struct oc2gl1_hdl *fl1h, GsmL1_PhRaInd_t *ra_ind)
|
||||||
|
|
||||||
LOGP(DL1IF, LOGL_DEBUG, "PH-RA-IND L1 qta=%d\n", ra_ind->measParam.i16BurstTiming);
|
LOGP(DL1IF, LOGL_DEBUG, "PH-RA-IND L1 qta=%d\n", ra_ind->measParam.i16BurstTiming);
|
||||||
|
|
||||||
bts_update_tbf_ta("PH-RA", ra_ind->u32Fn, fl1h->trx_no, ra_ind->u8Tn,
|
switch (ra_ind->sapi) {
|
||||||
qta2ta(ra_ind->measParam.i16BurstTiming), true);
|
case GsmL1_Sapi_Pdtch:
|
||||||
|
bts_update_tbf_ta("PH-RA", ra_ind->u32Fn, fl1h->trx_no, ra_ind->u8Tn,
|
||||||
|
qta2ta(ra_ind->measParam.i16BurstTiming), true);
|
||||||
|
break;
|
||||||
|
case GsmL1_Sapi_Ptcch:
|
||||||
|
pcu_rx_rach_ind_pdtch(fl1h->trx_no, ra_ind->u8Tn, ra_ind->u32Fn,
|
||||||
|
ra_ind->measParam.i16BurstTiming);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOGP(DL1IF, LOGL_NOTICE, "Rx PH-RA.ind for unknown L1 SAPI %s\n",
|
||||||
|
get_value_string(oc2gbts_l1sapi_names, ra_ind->sapi));
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,10 +208,6 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1h,
|
||||||
data_ind->u32Fn,
|
data_ind->u32Fn,
|
||||||
&meas);
|
&meas);
|
||||||
break;
|
break;
|
||||||
case GsmL1_Sapi_Ptcch:
|
|
||||||
// FIXME
|
|
||||||
rc = -1;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
LOGP(DL1IF, LOGL_NOTICE, "Rx PH-DATA.ind for unknown L1 SAPI %s\n",
|
LOGP(DL1IF, LOGL_NOTICE, "Rx PH-DATA.ind for unknown L1 SAPI %s\n",
|
||||||
get_value_string(femtobts_l1sapi_names, data_ind->sapi));
|
get_value_string(femtobts_l1sapi_names, data_ind->sapi));
|
||||||
|
@ -240,8 +236,21 @@ static int handle_ph_ra_ind(struct femtol1_hdl *fl1h, GsmL1_PhRaInd_t *ra_ind)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
DEBUGP(DL1IF, "Rx PH-RA.ind");
|
DEBUGP(DL1IF, "Rx PH-RA.ind");
|
||||||
bts_update_tbf_ta("PH-RA", ra_ind->u32Fn, fl1h->trx_no, ra_ind->u8Tn,
|
|
||||||
qta2ta(ra_ind->measParam.i16BurstTiming), true);
|
switch (ra_ind->sapi) {
|
||||||
|
case GsmL1_Sapi_Pdtch:
|
||||||
|
bts_update_tbf_ta("PH-RA", ra_ind->u32Fn, fl1h->trx_no, ra_ind->u8Tn,
|
||||||
|
qta2ta(ra_ind->measParam.i16BurstTiming), true);
|
||||||
|
break;
|
||||||
|
case GsmL1_Sapi_Ptcch:
|
||||||
|
pcu_rx_rach_ind_pdtch(fl1h->trx_no, ra_ind->u8Tn, ra_ind->u32Fn,
|
||||||
|
ra_ind->measParam.i16BurstTiming);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOGP(DL1IF, LOGL_NOTICE, "Rx PH-RA.ind for unknown L1 SAPI %s\n",
|
||||||
|
get_value_string(femtobts_l1sapi_names, ra_ind->sapi));
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -405,6 +405,12 @@ static int pcu_rx_rts_req(struct gsm_pcu_if_rts_req *rts_req)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* C -> C++ adapter for direct DSP access code (e.g. osmo-bts-sysmo) */
|
||||||
|
extern "C" int pcu_rx_rach_ind_pdtch(uint8_t trx_nr, uint8_t ts_nr, uint32_t fn, int16_t qta)
|
||||||
|
{
|
||||||
|
return BTS::main_bts()->rcv_ptcch_rach(trx_nr, ts_nr, fn, qta);
|
||||||
|
}
|
||||||
|
|
||||||
static int pcu_rx_rach_ind(struct gsm_pcu_if_rach_ind *rach_ind)
|
static int pcu_rx_rach_ind(struct gsm_pcu_if_rach_ind *rach_ind)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
@ -421,6 +427,11 @@ static int pcu_rx_rach_ind(struct gsm_pcu_if_rach_ind *rach_ind)
|
||||||
rach_ind->qta, rach_ind->is_11bit,
|
rach_ind->qta, rach_ind->is_11bit,
|
||||||
(ph_burst_type)rach_ind->burst_type);
|
(ph_burst_type)rach_ind->burst_type);
|
||||||
break;
|
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:
|
default:
|
||||||
LOGP(DL1IF, LOGL_ERROR, "Received PCU rach request with "
|
LOGP(DL1IF, LOGL_ERROR, "Received PCU rach request with "
|
||||||
"unsupported sapi %d\n", rach_ind->sapi);
|
"unsupported sapi %d\n", rach_ind->sapi);
|
||||||
|
|
|
@ -178,6 +178,7 @@ int pcu_rx_rts_req_pdtch(uint8_t trx, uint8_t ts,
|
||||||
int pcu_rx_rts_req_ptcch(uint8_t trx, uint8_t ts,
|
int pcu_rx_rts_req_ptcch(uint8_t trx, uint8_t ts,
|
||||||
uint32_t fn, uint8_t block_nr);
|
uint32_t fn, uint8_t block_nr);
|
||||||
|
|
||||||
|
int pcu_rx_rach_ind_pdtch(uint8_t trx_nr, uint8_t ts_nr, uint32_t fn, int16_t qta);
|
||||||
int pcu_rx_data_ind_pdtch(uint8_t trx, uint8_t ts, uint8_t *data,
|
int pcu_rx_data_ind_pdtch(uint8_t trx, uint8_t ts, uint8_t *data,
|
||||||
uint8_t len, uint32_t fn, struct pcu_l1_meas *meas);
|
uint8_t len, uint32_t fn, struct pcu_l1_meas *meas);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue