lchan: Send the ACT ACK/NACK after the Layer1 has handled act/deact
Send the RSL ACT ACK/NACK after the Layer1 firmware has acked the activation/deactivation. In case the channel can not be activated we will send a NACK. In case the channel can not be deactivated we will send an ACK and the next time the channel is activated we will send a NACK. The release ack will be sent once the TxDownlink of the TCH/SDCCH is closed. Change the rsl_tx_chan_nack method to create a new msgb to be used by the hardware layer, change the return value to ask the caller to delete the msgb.
This commit is contained in:
parent
1e2b3259b9
commit
d7718280c9
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue