summaryrefslogtreecommitdiffstats
path: root/src/host
diff options
context:
space:
mode:
Diffstat (limited to 'src/host')
-rw-r--r--src/host/layer23/src/common/lapdm.c16
-rw-r--r--src/host/layer23/src/mobile/gsm48_rr.c61
2 files changed, 40 insertions, 37 deletions
diff --git a/src/host/layer23/src/common/lapdm.c b/src/host/layer23/src/common/lapdm.c
index ba191193..f06c738b 100644
--- a/src/host/layer23/src/common/lapdm.c
+++ b/src/host/layer23/src/common/lapdm.c
@@ -524,9 +524,8 @@ static void lapdm_t200_cb(void *data)
send_rll_simple(RSL_MT_REL_IND, &dl->mctx);
/* send MDL ERROR INIDCATION to L3 */
rsl_rll_error(RLL_CAUSE_T200_EXPIRED, &dl->mctx);
- /* flush buffers */
+ /* flush tx buffers */
lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
/* go back to idle state */
lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
/* NOTE: we must not change any other states or buffers
@@ -1871,9 +1870,8 @@ static int rslms_rx_rll_susp_req(struct msgb *msg, struct lapdm_datalink *dl)
} else
LOGP(DLAPDM, LOGL_INFO, "no frame in sendbuffer\n");
- /* Clear transmit and send buffer, if any */
+ /* Clear transmit buffer, but keep send buffer */
lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
msgb_free(msg);
@@ -1906,13 +1904,19 @@ static int rslms_rx_rll_res_req(struct msgb *msg, struct lapdm_datalink *dl)
}
length = TLVP_LEN(&tv, RSL_IE_L3_INFO);
- LOGP(DLAPDM, LOGL_INFO, "perform re-establishment (SABM)\n");
+ LOGP(DLAPDM, LOGL_INFO, "perform re-establishment (SABM) length=%d\n",
+ length);
/* Replace message in the send-buffer (reconnect) */
if (dl->send_buffer)
msgb_free(dl->send_buffer);
dl->send_out = 0;
- dl->send_buffer = msg;
+ if (length) {
+ /* Remove the RSL/RLL header */
+ msgb_pull_l2h(msg);
+ /* Write data into the send buffer, to be sent first */
+ dl->send_buffer = msg;
+ }
/* Discard partly received L3 message */
if (dl->rcv_buffer) {
diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c
index 54df48e7..9e852691 100644
--- a/src/host/layer23/src/mobile/gsm48_rr.c
+++ b/src/host/layer23/src/mobile/gsm48_rr.c
@@ -3779,11 +3779,12 @@ static int gsm48_rr_tx_ass_cpl(struct osmocom_ms *ms, uint8_t cause)
/* RR_CAUSE */
ac->rr_cause = cause;
- return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg);
+ return gsm48_send_rsl(ms, RSL_MT_RES_REQ, nmsg);
}
/* 9.1.4 sending ASSIGNMENT FAILURE */
-static int gsm48_rr_tx_ass_fail(struct osmocom_ms *ms, uint8_t cause)
+static int gsm48_rr_tx_ass_fail(struct osmocom_ms *ms, uint8_t cause,
+ uint8_t rsl_prim)
{
struct msgb *nmsg;
struct gsm48_hdr *gh;
@@ -3803,7 +3804,7 @@ static int gsm48_rr_tx_ass_fail(struct osmocom_ms *ms, uint8_t cause)
/* RR_CAUSE */
af->rr_cause = cause;
- return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg);
+ return gsm48_send_rsl(ms, rsl_prim, nmsg);
}
/* 9.1.2 ASSIGNMENT COMMAND is received */
@@ -4073,15 +4074,15 @@ static int gsm48_rr_rx_ass_cmd(struct osmocom_ms *ms, struct msgb *msg)
/* check if channels are valid */
cause = gsm48_rr_check_mode(ms, cda->chan_nr, cda->mode);
if (cause)
- return gsm48_rr_tx_ass_fail(ms, cause);
+ return gsm48_rr_tx_ass_fail(ms, cause, RSL_MT_DATA_REQ);
if (before_time) {
cause = gsm48_rr_render_ma(ms, cdb, ma, &ma_len);
if (cause)
- return gsm48_rr_tx_ass_fail(ms, cause);
+ return gsm48_rr_tx_ass_fail(ms, cause, RSL_MT_DATA_REQ);
}
cause = gsm48_rr_render_ma(ms, cda, ma, &ma_len);
if (cause)
- return gsm48_rr_tx_ass_fail(ms, cause);
+ return gsm48_rr_tx_ass_fail(ms, cause, RSL_MT_DATA_REQ);
#if 0
@@ -4142,11 +4143,12 @@ static int gsm48_rr_tx_hando_cpl(struct osmocom_ms *ms, uint8_t cause)
// FIXME: mobile observed time
- return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg);
+ return gsm48_send_rsl(ms, RSL_MT_RES_REQ, nmsg);
}
/* 9.1.4 sending HANDOVER FAILURE */
-static int gsm48_rr_tx_hando_fail(struct osmocom_ms *ms, uint8_t cause)
+static int gsm48_rr_tx_hando_fail(struct osmocom_ms *ms, uint8_t cause,
+ uint8_t rsl_prim)
{
struct msgb *nmsg;
struct gsm48_hdr *gh;
@@ -4166,7 +4168,7 @@ static int gsm48_rr_tx_hando_fail(struct osmocom_ms *ms, uint8_t cause)
/* RR_CAUSE */
hf->rr_cause = cause;
- return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg);
+ return gsm48_send_rsl(ms, rsl_prim, nmsg);
}
/* receiving HANDOVER COMMAND message (9.1.15) */
@@ -4455,11 +4457,11 @@ static int gsm48_rr_rx_hando_cmd(struct osmocom_ms *ms, struct msgb *msg)
if (before_time) {
cause = gsm48_rr_render_ma(ms, cdb, ma, &ma_len);
if (cause)
- return gsm48_rr_tx_hando_fail(ms, cause);
+ return gsm48_rr_tx_hando_fail(ms, cause, RSL_MT_DATA_REQ);
}
cause = gsm48_rr_render_ma(ms, cda, ma, &ma_len);
if (cause)
- return gsm48_rr_tx_hando_fail(ms, cause);
+ return gsm48_rr_tx_hando_fail(ms, cause, RSL_MT_DATA_REQ);
#if 0
@@ -4518,21 +4520,6 @@ static int gsm48_rr_estab_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
LOGP(DRR, LOGL_INFO, "data link is resumed\n");
- switch (rr->modify_state) {
- case GSM48_RR_MOD_ASSIGN:
- gsm48_rr_tx_ass_cpl(ms, GSM48_RR_CAUSE_NORMAL);
- break;
- case GSM48_RR_MOD_HANDO:
- gsm48_rr_tx_hando_cpl(ms, GSM48_RR_CAUSE_NORMAL);
- break;
- case GSM48_RR_MOD_ASSIGN_RESUME:
- gsm48_rr_tx_ass_fail(ms, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
- break;
- case GSM48_RR_MOD_HANDO_RESUME:
- gsm48_rr_tx_hando_fail(ms, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
- break;
- }
-
/* transmit queued frames during ho / ass transition */
gsm48_rr_dequeue_down(ms);
@@ -4547,7 +4534,6 @@ static int gsm48_rr_susp_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
struct gsm48_rrlayer *rr = &ms->rrlayer;
if (rr->modify_state) {
- struct msgb *nmsg;
uint16_t ma[64];
uint8_t ma_len;
@@ -4589,10 +4575,23 @@ static int gsm48_rr_susp_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
/* send DL-RESUME REQUEST */
LOGP(DRR, LOGL_INFO, "request resume of data link\n");
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gsm48_send_rsl(ms, RSL_MT_RES_REQ, nmsg);
+ switch (rr->modify_state) {
+ case GSM48_RR_MOD_ASSIGN:
+ gsm48_rr_tx_ass_cpl(ms, GSM48_RR_CAUSE_NORMAL);
+ break;
+ case GSM48_RR_MOD_HANDO:
+ gsm48_rr_tx_hando_cpl(ms, GSM48_RR_CAUSE_NORMAL);
+ break;
+ case GSM48_RR_MOD_ASSIGN_RESUME:
+ gsm48_rr_tx_ass_fail(ms, GSM48_RR_CAUSE_PROT_ERROR_UNSPC,
+ RSL_MT_RECON_REQ);
+ break;
+ case GSM48_RR_MOD_HANDO_RESUME:
+ gsm48_rr_tx_hando_fail(ms,
+ GSM48_RR_CAUSE_PROT_ERROR_UNSPC,
+ RSL_MT_RECON_REQ);
+ break;
+ }
#ifdef TODO
/* trigger RACH */