aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-06-22 12:37:41 +0800
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-06-22 12:40:30 +0800
commitd7cb8aa275101cb7b59d2f40fed5d8b8041987ff (patch)
treeb5f1aef3cf24a3f84fd1f3d00626b61cb1a1f437 /openbsc
parent38454904cbeb1881f63a3507fc48dde6e0cdcd3f (diff)
abis_rsl: Send the IMMEDIATE Assignment after the Channel Ack.
The Channel Activate might be sent to a different TRX than the Immediate Assignment. So we need to make sure that the channel is activated before we send the immediate assignment for the RACH. Another reason for that is according to GSM 08.58 we should take the frame number from the activate and use it for the starting time inside the immediate assignment message. We obviously do not do this yet. The code assumes that the BTS will either respond with a CHAN ACK or a CHAN NACK if not the lchan will remain in the request state. Conflicts: openbsc/include/openbsc/gsm_data.h openbsc/src/abis_rsl.c openbsc/src/chan_alloc.c
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 dcb2fe66..9e9dc6d5 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 8fd29bd7..aa285e26 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 1a189fb3..2886c9a3 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;