diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2013-09-01 09:19:45 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2015-09-22 16:39:03 +0200 |
commit | 793e713c4bcf0929c2656760acb42e875f743da9 (patch) | |
tree | 8df08612c8518368418ebbbd76d5a25685a2b1a6 /src/common/l1sap.c | |
parent | faba84b9b7c035691fd831ad26871a63417d22d0 (diff) |
Move chan act/rel/modify from bts_model to PH-/MPH-/TCH-SAP interface
This part replaces channel activation/deactivation/modification routines
by MPH_INFO messages.
Diffstat (limited to 'src/common/l1sap.c')
-rw-r--r-- | src/common/l1sap.c | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 9bbbdf3b..e9d815c2 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -126,6 +126,67 @@ static int l1sap_mph_info_ind(struct gsm_bts_trx *trx, return rc; } +/* activation confirm received from bts model */ +static int l1sap_info_act_cnf(struct gsm_bts_trx *trx, + struct osmo_phsap_prim *l1sap, + struct info_act_cnf_param *info_act_cnf) +{ + struct gsm_lchan *lchan; + + LOGP(DL1P, LOGL_INFO, "activate confirm chan_nr=%02x trx=%d\n", + info_act_cnf->chan_nr, trx->nr); + + lchan = &trx->ts[L1SAP_CHAN2TS(info_act_cnf->chan_nr)] + .lchan[l1sap_chan2ss(info_act_cnf->chan_nr)]; + + if (info_act_cnf->cause) + rsl_tx_chan_act_nack(lchan, info_act_cnf->cause); + else + rsl_tx_chan_act_ack(lchan); + + return 0; +} + +/* activation confirm received from bts model */ +static int l1sap_info_rel_cnf(struct gsm_bts_trx *trx, + struct osmo_phsap_prim *l1sap, + struct info_act_cnf_param *info_act_cnf) +{ + struct gsm_lchan *lchan; + + LOGP(DL1P, LOGL_INFO, "deactivate confirm chan_nr=%02x trx=%d\n", + info_act_cnf->chan_nr, trx->nr); + + lchan = &trx->ts[L1SAP_CHAN2TS(info_act_cnf->chan_nr)] + .lchan[l1sap_chan2ss(info_act_cnf->chan_nr)]; + + rsl_tx_rf_rel_ack(lchan); + + return 0; +} + +/* any L1 MPH_INFO confirm prim recevied from bts model */ +static int l1sap_mph_info_cnf(struct gsm_bts_trx *trx, + struct osmo_phsap_prim *l1sap, struct mph_info_param *info) +{ + int rc = 0; + + switch (info->type) { + case PRIM_INFO_ACTIVATE: + rc = l1sap_info_act_cnf(trx, l1sap, &info->u.act_cnf); + break; + case PRIM_INFO_DEACTIVATE: + rc = l1sap_info_rel_cnf(trx, l1sap, &info->u.act_cnf); + break; + default: + LOGP(DL1P, LOGL_NOTICE, "unknown MPH_INFO cnf type %d\n", + info->type); + break; + } + + return rc; +} + /* PH-RTS-IND prim recevied from bts model */ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, struct ph_data_param *rts_ind) @@ -322,6 +383,9 @@ int l1sap_up(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) case OSMO_PRIM(PRIM_MPH_INFO, PRIM_OP_INDICATION): rc = l1sap_mph_info_ind(trx, l1sap, &l1sap->u.info); break; + case OSMO_PRIM(PRIM_MPH_INFO, PRIM_OP_CONFIRM): + rc = l1sap_mph_info_cnf(trx, l1sap, &l1sap->u.info); + break; case OSMO_PRIM(PRIM_PH_RTS, PRIM_OP_INDICATION): rc = l1sap_ph_rts_ind(trx, l1sap, &l1sap->u.data); break; @@ -376,3 +440,84 @@ int l1sap_pdch_req(struct gsm_bts_trx_ts *ts, int is_ptcch, uint32_t fn, return l1sap_down(ts->trx, l1sap); } + +static int l1sap_chan_act_dact_modify(struct gsm_bts_trx *trx, uint8_t chan_nr, + enum osmo_mph_info_type type, uint8_t sacch_only) +{ + struct osmo_phsap_prim l1sap; + + memset(&l1sap, 0, sizeof(l1sap)); + osmo_prim_init(&l1sap.oph, SAP_GSM_PH, PRIM_MPH_INFO, PRIM_OP_REQUEST, + NULL); + l1sap.u.info.type = type; + l1sap.u.info.u.act_req.chan_nr = chan_nr; + l1sap.u.info.u.act_req.sacch_only = sacch_only; + + return l1sap_down(trx, &l1sap); +} + +int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed *tp) +{ + struct gsm_bts_role_bts *btsb = trx->bts->role; + struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)] + .lchan[l1sap_chan2ss(chan_nr)]; + struct gsm48_chan_desc *cd; + int rc; + + LOGP(DL1P, LOGL_INFO, "activating channel chan_nr=%02x trx=%d\n", + chan_nr, trx->nr); + + if (tp && TLVP_PRESENT(tp, GSM48_IE_CHANDESC_2) && + TLVP_LEN(tp, GSM48_IE_CHANDESC_2) >= sizeof(*cd)) { + cd = (struct gsm48_chan_desc *) + TLVP_VAL(tp, GSM48_IE_CHANDESC_2); + + /* our L1 only supports one global TSC for all channels + * one one TRX, so we need to make sure not to activate + * channels with a different TSC!! */ + if (cd->h0.tsc != (lchan->ts->trx->bts->bsic & 7)) { + LOGP(DRSL, LOGL_ERROR, "lchan TSC %u != BSIC-TSC %u\n", + cd->h0.tsc, lchan->ts->trx->bts->bsic & 7); + return -RSL_ERR_SERV_OPT_UNIMPL; + } + } + + lchan->sacch_deact = 0; + lchan->s = btsb->radio_link_timeout; + + rc = l1sap_chan_act_dact_modify(trx, chan_nr, PRIM_INFO_ACTIVATE, 0); + if (rc) + return -RSL_ERR_EQUIPMENT_FAIL; + return 0; +} + +int l1sap_chan_rel(struct gsm_bts_trx *trx, uint8_t chan_nr) +{ + LOGP(DL1P, LOGL_INFO, "deactivating channel chan_nr=%02x trx=%d\n", + chan_nr, trx->nr); + + return l1sap_chan_act_dact_modify(trx, chan_nr, PRIM_INFO_DEACTIVATE, + 0); +} + +int l1sap_chan_deact_sacch(struct gsm_bts_trx *trx, uint8_t chan_nr) +{ + struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)] + .lchan[l1sap_chan2ss(chan_nr)]; + + LOGP(DL1P, LOGL_INFO, "deactivating sacch chan_nr=%02x trx=%d\n", + chan_nr, trx->nr); + + lchan->sacch_deact = 1; + + return l1sap_chan_act_dact_modify(trx, chan_nr, PRIM_INFO_DEACTIVATE, + 1); +} + +int l1sap_chan_modify(struct gsm_bts_trx *trx, uint8_t chan_nr) +{ + LOGP(DL1P, LOGL_INFO, "modifying channel chan_nr=%02x trx=%d\n", + chan_nr, trx->nr); + + return l1sap_chan_act_dact_modify(trx, chan_nr, PRIM_INFO_MODIFY, 0); +} |