From b119eff1abc3a8f8393ce174446cf902630671ed Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 4 Jul 2016 17:13:57 +0200 Subject: Attempt at extending dynamic PDCH support to Ericcson RBS2000 In Ericsson RBS2000, all PDCH's are dynamic, i.e. there is only one shared PCHAN type for TCH/F, TCH/H and PDCH. The PDCH needs to be activated with a RSL CHAN ACT with some proprietary coding of the Channel Number IE. Change-Id: I48089fcf8328d52f57e97b003790ffdeed766367 --- openbsc/include/openbsc/abis_rsl.h | 2 +- openbsc/src/libbsc/abis_rsl.c | 55 +++++++++++++++++++++++++++++++++++--- openbsc/src/libbsc/bsc_dyn_ts.c | 2 +- openbsc/src/libbsc/bsc_vty.c | 11 +++++--- 4 files changed, 61 insertions(+), 9 deletions(-) diff --git a/openbsc/include/openbsc/abis_rsl.h b/openbsc/include/openbsc/abis_rsl.h index 758c5557a..b2c43f0e2 100644 --- a/openbsc/include/openbsc/abis_rsl.h +++ b/openbsc/include/openbsc/abis_rsl.h @@ -64,7 +64,7 @@ int rsl_ipacc_crcx(struct gsm_lchan *lchan); int rsl_ipacc_mdcx(struct gsm_lchan *lchan, uint32_t ip, uint16_t port, uint8_t rtp_payload2); int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan); -int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act); +int rsl_dyn_pdch_activate(struct gsm_bts_trx_ts *ts, int is_activation); int abis_rsl_rcvmsg(struct msgb *msg); diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c index 316fc3fed..95a18cfa6 100644 --- a/openbsc/src/libbsc/abis_rsl.c +++ b/openbsc/src/libbsc/abis_rsl.c @@ -53,6 +53,7 @@ enum sacch_deact { SACCH_DEACTIVATE, }; +static int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act); static int rsl_send_imm_assignment(struct gsm_lchan *lchan); static void error_timeout_cb(void *data); static int dyn_ts_switchover_continue(struct gsm_bts_trx_ts *ts); @@ -472,6 +473,37 @@ static int rsl_chan_activate_lchan_as_pdch(struct gsm_lchan *lchan) return abis_rsl_sendmsg(msg); } +static int rsl_rbs2k_pdch_activate(struct gsm_bts_trx_ts *ts, int is_activation) +{ + struct gsm_bts_trx *trx = ts->trx; + struct gsm_lchan *lchan = &ts->lchan[0]; + struct abis_rsl_dchan_hdr *dh; + struct msgb *msg; + uint8_t chan_nr; + + OSMO_ASSERT(trx->bts->type == GSM_BTS_TYPE_RBS2000); + + /* Ericsson proprietary encoding of PDCH channel number */ + chan_nr = (0x18 << 3) | (ts->nr & 0x7); + + msg = rsl_msgb_alloc(); + dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh)); + + if (is_activation) { + rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ); + init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV); + dh->chan_nr = chan_nr; + } else { + rsl_lchan_set_state(lchan, LCHAN_S_REL_REQ); + init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL); + dh->chan_nr = chan_nr; + } + + msg->dst = trx->rsl_link; + + return abis_rsl_sendmsg(msg); +} + /* Chapter 8.4.1 */ int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type, uint8_t ho_ref) @@ -491,7 +523,7 @@ int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type, /* store activation type and handover reference */ lchan->dyn.act_type = act_type; lchan->dyn.ho_ref = ho_ref; - return rsl_ipacc_pdch_activate(lchan->ts, 0); + return rsl_dyn_pdch_activate(lchan->ts, 0); } /* @@ -722,6 +754,7 @@ int rsl_deact_sacch(struct gsm_lchan *lchan) return abis_rsl_sendmsg(msg); } + static bool dyn_ts_should_switch_to_pdch(struct gsm_bts_trx_ts *ts) { int ss; @@ -756,6 +789,19 @@ static bool dyn_ts_should_switch_to_pdch(struct gsm_bts_trx_ts *ts) return true; } +int rsl_dyn_pdch_activate(struct gsm_bts_trx_ts *ts, int is_activation) +{ + switch (ts->trx->bts->type) { + case GSM_BTS_TYPE_NANOBTS: + case GSM_BTS_TYPE_OSMO_SYSMO: + return rsl_ipacc_pdch_activate(ts, is_activation); + case GSM_BTS_TYPE_RBS2000: + return rsl_rbs2k_pdch_activate(ts, is_activation); + default: + return -1; + } +} + static void error_timeout_cb(void *data) { struct gsm_lchan *lchan = data; @@ -772,7 +818,7 @@ static void error_timeout_cb(void *data) /* Put PDCH channel back into PDCH mode, if GPRS is enabled */ if (lchan->ts->pchan == GSM_PCHAN_TCH_F_PDCH && lchan->ts->trx->bts->gprs.mode != BTS_GPRS_NONE) - rsl_ipacc_pdch_activate(lchan->ts, 1); + rsl_dyn_pdch_activate(lchan->ts, 1); if (dyn_ts_should_switch_to_pdch(lchan->ts)) dyn_ts_switchover_start(lchan->ts, GSM_PCHAN_PDCH); @@ -941,7 +987,8 @@ static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan) return 0; if (ts->pchan == GSM_PCHAN_TCH_F_PDCH && lchan->state == LCHAN_S_NONE) - return rsl_ipacc_pdch_activate(ts, 1); + return rsl_dyn_pdch_activate(lchan->ts, 1); + return 0; } @@ -2210,7 +2257,7 @@ int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan) return rc; } -int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act) +static int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act) { struct msgb *msg = rsl_msgb_alloc(); struct abis_rsl_dchan_hdr *dh; diff --git a/openbsc/src/libbsc/bsc_dyn_ts.c b/openbsc/src/libbsc/bsc_dyn_ts.c index e5422fc5c..4bff88353 100644 --- a/openbsc/src/libbsc/bsc_dyn_ts.c +++ b/openbsc/src/libbsc/bsc_dyn_ts.c @@ -37,7 +37,7 @@ void tchf_pdch_ts_init(struct gsm_bts_trx_ts *ts) LOGP(DRSL, LOGL_DEBUG, "%s: trying to PDCH ACT\n", gsm_ts_and_pchan_name(ts)); - rc = rsl_ipacc_pdch_activate(ts, 1); + rc = rsl_dyn_pdch_activate(ts, 1); if (rc != 0) LOGP(DRSL, LOGL_ERROR, "%s %s: PDCH ACT failed\n", gsm_ts_name(ts), gsm_pchan_name(ts->pchan)); diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index cb0b1d8c8..a58c064c0 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -3996,8 +3996,13 @@ DEFUN(pdch_act, pdch_act_cmd, return CMD_WARNING; } - if (!is_ipaccess_bts(bts)) { - vty_out(vty, "%% This command only works for ipaccess BTS%s", + switch (bts->type) { + case GSM_BTS_TYPE_RBS2000: + case GSM_BTS_TYPE_NANOBTS: + case GSM_BTS_TYPE_OSMO_SYSMO: + break; + default: + vty_out(vty, "%% This command only works for IPA and RBS2000 BTS%s", VTY_NEWLINE); return CMD_WARNING; } @@ -4020,7 +4025,7 @@ DEFUN(pdch_act, pdch_act_cmd, else activate = 0; - rsl_ipacc_pdch_activate(ts, activate); + rsl_dyn_pdch_activate(ts, activate); return CMD_SUCCESS; -- cgit v1.2.3