summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas.Eversberg <jolly@eversberg.eu>2010-08-10 19:31:07 +0000
committerAndreas.Eversberg <jolly@eversberg.eu>2010-08-10 19:31:07 +0000
commit6439e4f2796deb1498de7d805757bf2b8f56b1c4 (patch)
tree4c72a2d43eeecaa80a7a3abc82e7e0024864074d /src
parent72523a02a6dfb7b207e44510776a39e072541ac2 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h3
-rw-r--r--src/host/layer23/src/mobile/gsm48_cc.c2
-rw-r--r--src/host/layer23/src/mobile/gsm48_rr.c55
3 files changed, 58 insertions, 2 deletions
diff --git a/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h b/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h
index f5d52206..f88d7a9a 100644
--- a/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h
+++ b/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h
@@ -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;
diff --git a/src/host/layer23/src/mobile/gsm48_cc.c b/src/host/layer23/src/mobile/gsm48_cc.c
index d7bfca5d..36105207 100644
--- a/src/host/layer23/src/mobile/gsm48_cc.c
+++ b/src/host/layer23/src/mobile/gsm48_cc.c
@@ -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;
diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c
index 3e5c8537..21f86dd9 100644
--- a/src/host/layer23/src/mobile/gsm48_rr.c
+++ b/src/host/layer23/src/mobile/gsm48_rr.c
@@ -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");