summaryrefslogtreecommitdiffstats
path: root/src/host/layer23
diff options
context:
space:
mode:
authorAndreas.Eversberg2010-07-13 20:12:54 +0200
committerAndreas.Eversberg2010-07-13 20:12:54 +0200
commitabdb8ca4640be36c106abc9c4306dcd7dc3a2ae6 (patch)
treee37b606a79fd04245a3f670a1356803eb945c12a /src/host/layer23
parent[layer23] Fixed call answer/reject at mnccms.c (diff)
downloadosmocom-abdb8ca4640be36c106abc9c4306dcd7dc3a2ae6.tar.gz
osmocom-abdb8ca4640be36c106abc9c4306dcd7dc3a2ae6.tar.xz
osmocom-abdb8ca4640be36c106abc9c4306dcd7dc3a2ae6.zip
[layer23] Fixed RSL release request
The forward release (DISC request) still seems to be broken at lapdm.c.
Diffstat (limited to 'src/host/layer23')
-rw-r--r--src/host/layer23/src/gsm48_rr.c24
-rw-r--r--src/host/layer23/src/lapdm.c12
2 files changed, 27 insertions, 9 deletions
diff --git a/src/host/layer23/src/gsm48_rr.c b/src/host/layer23/src/gsm48_rr.c
index bd918cb..31559dc 100644
--- a/src/host/layer23/src/gsm48_rr.c
+++ b/src/host/layer23/src/gsm48_rr.c
@@ -350,6 +350,18 @@ static int gsm48_send_rsl(struct osmocom_ms *ms, uint8_t msg_type,
return rslms_recvmsg(msg, ms);
}
+/* push rsl header + release mode and send (RSL-SAP) */
+static int gsm48_send_rsl_rel(struct osmocom_ms *ms, uint8_t msg_type,
+ struct msgb *msg)
+{
+ struct gsm48_rrlayer *rr = &ms->rrlayer;
+
+ rsl_rll_push_hdr(msg, msg_type, rr->cd_now.chan_nr,
+ rr->cd_now.link_id, 1);
+
+ return rslms_recvmsg(msg, ms);
+}
+
/* enqueue messages (RSL-SAP) */
static int gsm48_rx_rsl(struct msgb *msg, struct osmocom_ms *ms)
{
@@ -410,7 +422,7 @@ static void timeout_rr_t3110(void *arg)
mode = msgb_put(nmsg, 2);
mode[0] = RSL_IE_RELEASE_MODE;
mode[1] = 1; /* local release */
- gsm48_send_rsl(ms, RSL_MT_REL_REQ, nmsg);
+ gsm48_send_rsl_rel(ms, RSL_MT_REL_REQ, nmsg);
return;
}
@@ -2959,7 +2971,7 @@ int gsm48_rr_los(struct osmocom_ms *ms)
mode[0] = RSL_IE_RELEASE_MODE;
mode[1] = 1; /* local release */
/* start release */
- return gsm48_send_rsl(ms, RSL_MT_REL_REQ, nmsg);
+ return gsm48_send_rsl_rel(ms, RSL_MT_REL_REQ, nmsg);
case GSM48_RR_ST_REL_PEND:
LOGP(DRR, LOGL_INFO, "LOS during RR release procedure, release "
"locally\n");
@@ -3109,7 +3121,7 @@ static int gsm48_rr_estab_cnf(struct osmocom_ms *ms, struct msgb *msg)
mode[0] = RSL_IE_RELEASE_MODE;
mode[1] = 0; /* normal release */
/* start release */
- return gsm48_send_rsl(ms, RSL_MT_REL_REQ, nmsg);
+ return gsm48_send_rsl_rel(ms, RSL_MT_REL_REQ, nmsg);
}
/* 3.3.1.1.4 */
@@ -3194,7 +3206,7 @@ static int gsm48_rr_rx_chan_rel(struct osmocom_ms *ms, struct msgb *msg)
mode = msgb_put(nmsg, 2);
mode[0] = RSL_IE_RELEASE_MODE;
mode[1] = 0; /* normal release */
- return gsm48_send_rsl(ms, RSL_MT_REL_REQ, nmsg);
+ return gsm48_send_rsl_rel(ms, RSL_MT_REL_REQ, nmsg);
}
/*
@@ -3752,13 +3764,13 @@ static int gsm48_rr_abort_req(struct osmocom_ms *ms, struct msgb *msg)
mode = msgb_put(nmsg, 2);
mode[0] = RSL_IE_RELEASE_MODE;
mode[1] = 0; /* normal release */
- return gsm48_send_rsl(ms, RSL_MT_REL_REQ, nmsg);
+ return gsm48_send_rsl_rel(ms, RSL_MT_REL_REQ, nmsg);
}
LOGP(DRR, LOGL_INFO, "Abort in connection pending state, return to "
"idle state.\n");
/* return idle */
- new_rr_state(rr, GSM48_RR_ST_REL_PEND);
+ new_rr_state(rr, GSM48_RR_ST_IDLE);
return 0;
}
diff --git a/src/host/layer23/src/lapdm.c b/src/host/layer23/src/lapdm.c
index 9e4b4a1..08b6f25 100644
--- a/src/host/layer23/src/lapdm.c
+++ b/src/host/layer23/src/lapdm.c
@@ -1943,8 +1943,13 @@ static int rslms_rx_rll_rel_req(struct msgb *msg, struct lapdm_datalink *dl)
lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
/* send notification to L3 */
return send_rll_simple(RSL_MT_REL_CONF, &dl->mctx);
- } else
- LOGP(DLAPDM, LOGL_INFO, "perform normal release (DISC)\n");
+ }
+
+ /* in case we are already disconnecting */
+ if (dl->state == LAPDm_STATE_DISC_SENT)
+ return -EBUSY;
+
+ LOGP(DLAPDM, LOGL_INFO, "perform normal release (DISC)\n");
/* Create new msgb */
msgb_pull_l2h(msg);
@@ -2109,7 +2114,8 @@ static struct l2downstate {
/* create and send DISC command */
{SBIT(LAPDm_STATE_SABM_SENT) |
SBIT(LAPDm_STATE_MF_EST) |
- SBIT(LAPDm_STATE_TIMER_RECOV),
+ SBIT(LAPDm_STATE_TIMER_RECOV) |
+ SBIT(LAPDm_STATE_DISC_SENT),
RSL_MT_REL_REQ, rslms_rx_rll_rel_req},
/* release in idle state */