mirror of https://gerrit.osmocom.org/libosmocore
LAPD: Indicate sequence error after indicating received data
First indicated the received data in an I frame, if possible. Then indicate the sequence error using MDL-ERROR-INDICATION. This way the data is delivered before the error is handled by BSC. Also there is no reason to indicate sequence error on supervisory frames. See §8.7.4 of 3GPP TS 44.006. Related: OS#5968 Change-Id: I535c18018bf0df4124a5e9618238028fa31be289
This commit is contained in:
parent
bd2b897b72
commit
6cc5301e4c
|
@ -796,8 +796,9 @@ static void lapd_t203_cb(void *data)
|
||||||
lapd_start_t200(dl);
|
lapd_start_t200(dl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 5.5.3.1: Common function to acknowlege frames up to the given N(R) value */
|
/* 5.5.3.1: Common function to acknowlege frames up to the given N(R) value
|
||||||
static void lapd_acknowledge(struct lapd_msg_ctx *lctx)
|
* In case of a sequence error, the cause is returned with negative sign. */
|
||||||
|
static int lapd_acknowledge(struct lapd_msg_ctx *lctx)
|
||||||
{
|
{
|
||||||
struct lapd_datalink *dl = lctx->dl;
|
struct lapd_datalink *dl = lctx->dl;
|
||||||
uint8_t nr = lctx->n_recv;
|
uint8_t nr = lctx->n_recv;
|
||||||
|
@ -838,7 +839,7 @@ static void lapd_acknowledge(struct lapd_msg_ctx *lctx)
|
||||||
*/
|
*/
|
||||||
if (sub_mod(nr, dl->v_ack, dl->v_range) > sub_mod(dl->v_send, dl->v_ack, dl->v_range)) {
|
if (sub_mod(nr, dl->v_ack, dl->v_range) > sub_mod(dl->v_send, dl->v_ack, dl->v_range)) {
|
||||||
LOGDL(dl, LOGL_NOTICE, "N(R) sequence error\n");
|
LOGDL(dl, LOGL_NOTICE, "N(R) sequence error\n");
|
||||||
mdl_error(MDL_CAUSE_SEQ_ERR, lctx);
|
return -MDL_CAUSE_SEQ_ERR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -861,6 +862,8 @@ static void lapd_acknowledge(struct lapd_msg_ctx *lctx)
|
||||||
/* Start T203, if T200 is not running in MF EST state, if enabled */
|
/* Start T203, if T200 is not running in MF EST state, if enabled */
|
||||||
if (!lapd_is_t200_started(dl) && (dl->t203_sec || dl->t203_usec) && (dl->state == LAPD_STATE_MF_EST))
|
if (!lapd_is_t200_started(dl) && (dl->t203_sec || dl->t203_usec) && (dl->state == LAPD_STATE_MF_EST))
|
||||||
lapd_start_t203(dl);
|
lapd_start_t203(dl);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* L1 -> L2 */
|
/* L1 -> L2 */
|
||||||
|
@ -1576,6 +1579,7 @@ static int lapd_rx_i(struct msgb *msg, struct lapd_msg_ctx *lctx)
|
||||||
int length = lctx->length;
|
int length = lctx->length;
|
||||||
int rc;
|
int rc;
|
||||||
bool i_frame_in_queue = false;
|
bool i_frame_in_queue = false;
|
||||||
|
int mdl_cause = 0;
|
||||||
|
|
||||||
LOGDL(dl, LOGL_INFO, "I received in state %s on SAPI(%u)\n",
|
LOGDL(dl, LOGL_INFO, "I received in state %s on SAPI(%u)\n",
|
||||||
lapd_state_name(dl->state), lctx->sapi);
|
lapd_state_name(dl->state), lctx->sapi);
|
||||||
|
@ -1652,7 +1656,9 @@ static int lapd_rx_i(struct msgb *msg, struct lapd_msg_ctx *lctx)
|
||||||
}
|
}
|
||||||
/* Even if N(s) sequence error, acknowledge to N(R)-1 */
|
/* Even if N(s) sequence error, acknowledge to N(R)-1 */
|
||||||
/* 5.5.3.1: Acknowlege all transmitted frames up the N(R)-1 */
|
/* 5.5.3.1: Acknowlege all transmitted frames up the N(R)-1 */
|
||||||
lapd_acknowledge(lctx); /* V(A) is also set here */
|
mdl_cause = lapd_acknowledge(lctx); /* V(A) is also set here */
|
||||||
|
if (mdl_cause < 0)
|
||||||
|
mdl_error(-mdl_cause, lctx);
|
||||||
|
|
||||||
/* Send message, if possible due to acknowledged data */
|
/* Send message, if possible due to acknowledged data */
|
||||||
lapd_send_i(dl, __LINE__, false);
|
lapd_send_i(dl, __LINE__, false);
|
||||||
|
@ -1673,7 +1679,7 @@ static int lapd_rx_i(struct msgb *msg, struct lapd_msg_ctx *lctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 5.5.3.1: Acknowlege all transmitted frames up the the N(R)-1 */
|
/* 5.5.3.1: Acknowlege all transmitted frames up the the N(R)-1 */
|
||||||
lapd_acknowledge(lctx); /* V(A) is also set here */
|
mdl_cause = lapd_acknowledge(lctx); /* V(A) is also set here */
|
||||||
|
|
||||||
/* Only if we are not in own receiver busy condition */
|
/* Only if we are not in own receiver busy condition */
|
||||||
if (!dl->own_busy) {
|
if (!dl->own_busy) {
|
||||||
|
@ -1718,6 +1724,10 @@ static int lapd_rx_i(struct msgb *msg, struct lapd_msg_ctx *lctx)
|
||||||
} else
|
} else
|
||||||
LOGDL(dl, LOGL_INFO, "I frame ignored during own receiver busy condition\n");
|
LOGDL(dl, LOGL_INFO, "I frame ignored during own receiver busy condition\n");
|
||||||
|
|
||||||
|
/* Indicate sequence error, if exists. */
|
||||||
|
if (mdl_cause < 0)
|
||||||
|
mdl_error(-mdl_cause, lctx);
|
||||||
|
|
||||||
/* Check for P bit */
|
/* Check for P bit */
|
||||||
if (lctx->p_f) {
|
if (lctx->p_f) {
|
||||||
/* 5.5.2.1 */
|
/* 5.5.2.1 */
|
||||||
|
|
Loading…
Reference in New Issue