diff options
-rw-r--r-- | include/osmo-bts/rsl.h | 1 | ||||
-rw-r--r-- | src/common/rsl.c | 19 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/oml.c | 22 |
3 files changed, 25 insertions, 17 deletions
diff --git a/include/osmo-bts/rsl.h b/include/osmo-bts/rsl.h index 62bc9b1b..0ab2eec2 100644 --- a/include/osmo-bts/rsl.h +++ b/include/osmo-bts/rsl.h @@ -8,6 +8,7 @@ int rsl_tx_chan_rqd(struct gsm_bts_trx *trx, struct gsm_time *gtime, int rsl_tx_est_ind(struct gsm_lchan *lchan, uint8_t link_id, uint8_t *data, int len); int rsl_tx_chan_act_ack(struct gsm_lchan *lchan, struct gsm_time *gtime); +int rsl_tx_chan_act_nack(struct gsm_lchan *lchan, uint8_t cause); int rsl_tx_rf_rel_ack(struct gsm_lchan *lchan); /* call-back for LAPDm code, called when it wants to send msgs UP */ diff --git a/src/common/rsl.c b/src/common/rsl.c index e426aa53..188d4391 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -517,20 +517,21 @@ int rsl_tx_chan_act_ack(struct gsm_lchan *lchan, struct gsm_time *gtime) } /* 8.4.3 sending CHANnel ACTIVation Negative ACK */ -static int rsl_tx_chan_nack(struct gsm_bts_trx *trx, struct msgb *msg, uint8_t cause) +int rsl_tx_chan_act_nack(struct gsm_lchan *lchan, uint8_t cause) { - struct abis_rsl_dchan_hdr *dch = msgb_l2(msg); - uint8_t chan_nr = dch->chan_nr; + struct msgb *msg; + uint8_t chan_nr = gsm_lchan2chan_nr(lchan); LOGP(DRSL, LOGL_NOTICE, "Sending Channel Activated NACK: cause = 0x%02x\n", cause); - msg->len = 0; - msg->data = msg->tail = msg->l3h; + msg = rsl_msgb_alloc(sizeof(struct abis_rsl_dchan_hdr)); + if (!msg) + return -ENOMEM; /* 9.3.26 Cause */ msgb_tlv_put(msg, RSL_IE_CAUSE, 1, &cause); rsl_dch_push_hdr(msg, RSL_MT_CHAN_ACTIV_NACK, chan_nr); - msg->trx = trx; + msg->trx = lchan->ts->trx; return abis_rsl_sendmsg(msg); } @@ -621,16 +622,14 @@ static int rsl_rx_chan_activ(struct msgb *msg) /* 9.3.3 Activation Type */ if (!TLVP_PRESENT(&tp, RSL_IE_ACT_TYPE)) { LOGP(DRSL, LOGL_NOTICE, "missing Activation Type\n"); - rsl_tx_chan_nack(msg->trx, msg, RSL_ERR_MAND_IE_ERROR); - return 1; + return rsl_tx_chan_act_nack(lchan, RSL_ERR_MAND_IE_ERROR); } type = *TLVP_VAL(&tp, RSL_IE_ACT_TYPE); /* 9.3.6 Channel Mode */ if (!TLVP_PRESENT(&tp, RSL_IE_CHAN_MODE)) { LOGP(DRSL, LOGL_NOTICE, "missing Channel Mode\n"); - rsl_tx_chan_nack(msg->trx, msg, RSL_ERR_MAND_IE_ERROR); - return 1; + return rsl_tx_chan_act_nack(lchan, RSL_ERR_MAND_IE_ERROR); } cm = (struct rsl_ie_chan_mode *) TLVP_VAL(&tp, RSL_IE_CHAN_MODE); lchan_tchmode_from_cmode(lchan, cm); diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index 1cc9d39a..4f794d35 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -33,6 +33,7 @@ #include <osmo-bts/rsl.h> #include <osmo-bts/amr.h> #include <osmo-bts/bts.h> +#include <osmo-bts/bts_model.h> #include "l1_if.h" #include "femtobts.h" @@ -424,6 +425,7 @@ static const struct lchan_sapis sapis_for_lchan[_GSM_LCHAN_MAX] = { static int lchan_act_compl_cb(struct msgb *l1_msg, void *data) { + struct gsm_time *time; struct gsm_lchan *lchan = data; GsmL1_Prim_t *l1p = msgb_l1prim(l1_msg); GsmL1_MphActivateCnf_t *ic = &l1p->u.mphActivateCnf; @@ -446,7 +448,11 @@ static int lchan_act_compl_cb(struct msgb *l1_msg, void *data) switch (ic->sapi) { case GsmL1_Sapi_Sdcch: case GsmL1_Sapi_TchF: - /* FIXME: Send RSL CHAN ACT */ + time = bts_model_get_time(lchan->ts->trx->bts); + if (lchan->state == LCHAN_S_ACTIVE) + rsl_tx_chan_act_ack(lchan, time); + else + rsl_tx_chan_act_nack(lchan, RSL_ERR_EQUIPMENT_FAIL); break; default: break; @@ -877,7 +883,8 @@ static int lchan_deact_compl_cb(struct msgb *l1_msg, void *data) switch (ic->sapi) { case GsmL1_Sapi_Sdcch: case GsmL1_Sapi_TchF: - /* FIXME: Send RSL CHAN REL ACK */ + if (ic->dir == GsmL1_Dir_TxDownlink) + rsl_tx_rf_rel_ack(lchan); break; default: break; @@ -888,7 +895,7 @@ static int lchan_deact_compl_cb(struct msgb *l1_msg, void *data) return 0; } -int lchan_deactivate(struct gsm_lchan *lchan) +static int lchan_deactivate(struct gsm_lchan *lchan) { struct femtol1_hdl *fl1h = trx_femtol1_hdl(lchan->ts->trx); const struct lchan_sapis *s4l = &sapis_for_lchan[lchan->type]; @@ -1016,15 +1023,16 @@ int bts_model_rsl_chan_act(struct gsm_lchan *lchan, struct tlv_parsed *tp) lchan->sach_deact = 0; lchan_activate(lchan); - /* FIXME: only do this in case of success */ - - return rsl_tx_chan_act_ack(lchan, bts_model_get_time(lchan->ts->trx->bts)); + return 0; } int bts_model_rsl_chan_rel(struct gsm_lchan *lchan) { + /* A duplicate RF Release Request, ignore it */ + if (lchan->state == LCHAN_S_REL_REQ) + return 0; lchan_deactivate(lchan); - return rsl_tx_rf_rel_ack(lchan); + return 0; } int bts_model_rsl_deact_sacch(struct gsm_lchan *lchan) |