aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/gsm_data.h3
-rw-r--r--openbsc/src/abis_rsl.c54
-rw-r--r--openbsc/src/chan_alloc.c8
3 files changed, 53 insertions, 12 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index dcb2fe66c..9e9dc6d52 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -266,6 +266,9 @@ struct gsm_lchan {
*/
struct bss_sccp_connection_data *msc_data;
+ /* GSM Random Access data */
+ struct gsm48_req_ref *rqd_ref;
+ uint8_t rqd_ta;
/* cache of last measurement reports on this lchan */
struct gsm_meas_rep meas_rep[6];
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 */
diff --git a/openbsc/src/chan_alloc.c b/openbsc/src/chan_alloc.c
index 1a189fb3c..2886c9a38 100644
--- a/openbsc/src/chan_alloc.c
+++ b/openbsc/src/chan_alloc.c
@@ -34,6 +34,8 @@
#include <openbsc/debug.h>
#include <openbsc/signal.h>
+#include <osmocore/talloc.h>
+
static int ts_is_usable(struct gsm_bts_trx_ts *ts)
{
/* FIXME: How does this behave for BS-11 ? */
@@ -330,6 +332,12 @@ void lchan_free(struct gsm_lchan *lchan)
}
for (i = 0; i < ARRAY_SIZE(lchan->neigh_meas); i++)
lchan->neigh_meas[i].arfcn = 0;
+
+ if (lchan->rqd_ref) {
+ talloc_free(lchan->rqd_ref);
+ lchan->rqd_ref = NULL;
+ lchan->rqd_ta = 0;
+ }
lchan->conn.silent_call = 0;
sig.lchan = lchan;