Added sequence number to L3 messages (see GSM 04.08 Clause 3.1.4.3)

This is required to detect duplicated messages during assignment or
handover. Each PDISC uses its own sequence number, but MM+CC+SS share the
same. The sequence number is only required in uplink direction.

Dieter: Please check, if your tester eats it now. Also try to trace if the
sequence number is set correctly.
This commit is contained in:
Andreas.Eversberg 2010-08-10 19:31:07 +00:00
parent 72523a02a6
commit 6439e4f279
3 changed files with 58 additions and 2 deletions

View File

@ -132,6 +132,9 @@ struct gsm48_rrlayer {
uint8_t cr_ra; /* stores requested ra until confirmed */
struct gsm48_cr_hist cr_hist[3];
/* V(SD) sequence numbers */
uint16_t v_sd; /* 16 PD 1-bit sequence numbers packed */
/* current channel descriptions */
struct gsm48_rr_cd cd_now;

View File

@ -795,7 +795,7 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
struct tlv_parsed tp;
struct gsm_mncc setup;
LOGP(DCC, LOGL_INFO, "sending SETUP\n");
LOGP(DCC, LOGL_INFO, "received SETUP\n");
memset(&setup, 0, sizeof(struct gsm_mncc));
setup.callref = trans->callref;

View File

@ -192,6 +192,49 @@ static int gsm48_decode_ba_range(const uint8_t *ba, uint8_t ba_len,
return 0;
}
/* 3.1.4.3 set sequence number and increment */
static int gsm48_apply_v_sd(struct gsm48_rrlayer *rr, struct msgb *msg)
{
struct gsm48_hdr *gh = msgb_l3(msg);
uint8_t pdisc = gh->proto_discr & 0x0f;
uint8_t v_sd;
switch (pdisc) {
case GSM48_PDISC_MM:
case GSM48_PDISC_CC:
case GSM48_PDISC_NC_SS:
/* all thre pdiscs share the same V(SD) */
pdisc = GSM48_PDISC_MM;
// fall through
case GSM48_PDISC_GROUP_CC:
case GSM48_PDISC_BCAST_CC:
case GSM48_PDISC_PDSS1:
case GSM48_PDISC_PDSS2:
/* extract v_sd(pdisc) */
v_sd = (rr->v_sd >> pdisc) & 1;
/* replace bit 7 vy v_sd */
gh->msg_type &= 0xbf;
gh->msg_type |= (v_sd << 6);
/* increment V(SD) */
rr->v_sd ^= (1 << pdisc);
LOGP(DRR, LOGL_INFO, "Using and incrementing V(SD) = %d "
"(pdisc %x)\n", v_sd, pdisc);
break;
case GSM48_PDISC_RR:
case GSM48_PDISC_SMS:
/* no V(VSD) is required */
break;
default:
LOGP(DRR, LOGL_ERROR, "Error, V(SD) of pdisc %x not handled\n",
pdisc);
return -ENOTSUP;
}
return 0;
}
/*
* state transition
*/
@ -2687,12 +2730,19 @@ static int gsm48_rr_dl_est(struct osmocom_ms *ms)
/* 3.3.1.1.3.1 */
stop_rr_t3126(rr);
/* clear all sequence numbers for all possible PDs */
rr->v_sd = 0;
/* send DL_EST_REQ */
if (rr->rr_est_msg) {
LOGP(DRR, LOGL_INFO, "sending establish message\n");
/* use queued message */
nmsg = rr->rr_est_msg;
rr->rr_est_msg = 0;
LOGP(DRR, LOGL_INFO, "sending establish message\n");
/* set sequence number and increment */
gsm48_apply_v_sd(rr, nmsg);
} else {
/* create paging response */
nmsg = gsm48_l3_msgb_alloc();
@ -3225,6 +3275,9 @@ static int gsm48_rr_data_req(struct osmocom_ms *ms, struct msgb *msg)
/* pull RR header */
msgb_pull(msg, sizeof(struct gsm48_rr_hdr));
/* set sequence number and increment */
gsm48_apply_v_sd(rr, msg);
/* queue message, during handover or assignment procedure */
if (rr->hando_susp_state || rr->assign_susp_state) {
LOGP(DRR, LOGL_INFO, "Queueing message during suspend.\n");