diff options
Diffstat (limited to 'openbsc/src/abis_rsl.c')
-rw-r--r-- | openbsc/src/abis_rsl.c | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c index 8fd29bd73..aa285e26b 100644 --- a/openbsc/src/abis_rsl.c +++ b/openbsc/src/abis_rsl.c @@ -42,11 +42,15 @@ #include <openbsc/rtp_proxy.h> #include <osmocore/rsl.h> +#include <osmocore/talloc.h> + #define RSL_ALLOC_SIZE 1024 #define RSL_ALLOC_HEADROOM 128 #define MAX(a, b) (a) >= (b) ? (a) : (b) +static int rsl_send_imm_assignment(struct gsm_lchan *lchan); + static u_int8_t mdisc_by_msgtype(u_int8_t msg_type) { /* mask off the transparent bit ? */ @@ -791,6 +795,13 @@ static int rsl_rx_chan_act_ack(struct msgb *msg) gsm_lchans_name(msg->lchan->state)); rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE); + if (msg->lchan->rqd_ref) { + rsl_send_imm_assignment(msg->lchan); + talloc_free(msg->lchan->rqd_ref); + msg->lchan->rqd_ref = NULL; + msg->lchan->rqd_ta = 0; + } + dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_ACK, msg->lchan); return 0; @@ -1134,12 +1145,10 @@ static int rsl_rx_chan_rqd(struct msgb *msg) struct gsm_bts *bts = msg->trx->bts; struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg); struct gsm48_req_ref *rqd_ref; - struct gsm48_imm_ass ia; enum gsm_chan_t lctype; enum gsm_chreq_reason_t chreq_reason; struct gsm_lchan *lchan; u_int8_t rqd_ta; - int ret; int is_lu; u_int16_t arfcn; @@ -1185,6 +1194,17 @@ static int rsl_rx_chan_rqd(struct msgb *msg) gsm_lchans_name(lchan->state)); rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ); + /* save the RACH data as we need it after the CHAN ACT ACK */ + lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref); + if (!lchan->rqd_ref) { + LOGP(DRSL, LOGL_ERROR, "Failed to allocate gsm48_req_ref.\n"); + lchan_free(lchan); + return -ENOMEM; + } + + memcpy(lchan->rqd_ref, rqd_ref, sizeof(*rqd_ref)); + lchan->rqd_ta = rqd_ta; + ts_number = lchan->ts->nr; arfcn = lchan->ts->trx->arfcn; subch = lchan->nr; @@ -1194,8 +1214,25 @@ static int rsl_rx_chan_rqd(struct msgb *msg) lchan->bs_power = 0; /* 0dB reduction, output power = Pn */ lchan->rsl_cmode = RSL_CMOD_SPD_SIGN; lchan->tch_mode = GSM48_CMODE_SIGN; + + /* FIXME: Start another timer or assume the BTS sends a ACK/NACK? */ rsl_chan_activate_lchan(lchan, 0x00, rqd_ta, 0); + DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s " + "r=%s ra=0x%02x\n", gsm_lchan_name(lchan), arfcn, subch, + gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason), + rqd_ref->ra); + return 0; +} + +static int rsl_send_imm_assignment(struct gsm_lchan *lchan) +{ + struct gsm_bts *bts = lchan->ts->trx->bts; + struct gsm48_imm_ass ia; + u_int16_t arfcn; + + arfcn = lchan->ts->trx->arfcn; + /* create IMMEDIATE ASSIGN 04.08 messge */ memset(&ia, 0, sizeof(ia)); ia.l2_plen = 0x2d; @@ -1208,24 +1245,17 @@ static int rsl_rx_chan_rqd(struct msgb *msg) ia.chan_desc.h0.arfcn_low = arfcn & 0xff; ia.chan_desc.h0.tsc = bts->tsc; /* use request reference extracted from CHAN_RQD */ - memcpy(&ia.req_ref, rqd_ref, sizeof(ia.req_ref)); - ia.timing_advance = rqd_ta; + memcpy(&ia.req_ref, lchan->rqd_ref, sizeof(ia.req_ref)); + ia.timing_advance = lchan->rqd_ta; ia.mob_alloc_len = 0; - DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s " - "r=%s ra=0x%02x\n", gsm_lchan_name(lchan), arfcn, subch, - gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason), - rqd_ref->ra); - /* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */ lchan->T3101.cb = t3101_expired; lchan->T3101.data = lchan; bsc_schedule_timer(&lchan->T3101, bts->network->T3101, 0); /* send IMMEDIATE ASSIGN CMD on RSL to BTS (to send on CCCH to MS) */ - ret = rsl_imm_assign_cmd(bts, sizeof(ia), (u_int8_t *) &ia); - - return ret; + return rsl_imm_assign_cmd(bts, sizeof(ia), (u_int8_t *) &ia); } /* MS has requested a channel on the RACH */ |