pespin has uploaded this change for review. (
https://gerrit.osmocom.org/c/libosmo-gprs/+/32909 )
Change subject: gmm: Initial implementation of READY timer
......................................................................
gmm: Initial implementation of READY timer
Change-Id: I451ce08d80fb247c28819de065136e2e4d49f3f5
---
M include/osmocom/gprs/gmm/gmm_private.h
M src/gmm/gmm.c
M src/gmm/gmm_pdu.c
M src/gmm/gmm_prim.c
M tests/gmm/gmm_prim_test.ok
5 files changed, 99 insertions(+), 4 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-gprs refs/changes/09/32909/1
diff --git a/include/osmocom/gprs/gmm/gmm_private.h
b/include/osmocom/gprs/gmm/gmm_private.h
index 339753b..0ae4df4 100644
--- a/include/osmocom/gprs/gmm/gmm_private.h
+++ b/include/osmocom/gprs/gmm/gmm_private.h
@@ -10,6 +10,7 @@
#include <osmocom/core/msgb.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/endian.h>
+#include <osmocom/core/tdef.h>
#include <osmocom/gsm/protocol/gsm_23_003.h>
#include <osmocom/gprs/llc/llc_prim.h>
@@ -83,6 +84,9 @@
unsigned long t3302;
unsigned long t3346;
+ /* READY timer, TS 24.008 4.7.2.1.1 */
+ struct osmo_timer_list t3314;
+ unsigned long t3314_assigned_sec; /* value assigned by the network */
};
/* gmm_prim.c: */
@@ -109,6 +113,9 @@
struct gprs_gmm_entity *gprs_gmm_find_gmme_by_tlli(uint32_t tlli);
struct gprs_gmm_entity *gprs_gmm_find_gmme_by_sess_id(uint32_t id);
uint32_t gprs_gmm_alloc_rand_tlli(void);
+void gprs_gmm_gmme_ready_timer_start(struct gprs_gmm_entity *gmme);
+void gprs_gmm_gmme_ready_timer_stop(struct gprs_gmm_entity *gmme);
+bool gprs_gmm_gmme_ready_timer_running(const struct gprs_gmm_entity *gmme);
int gprs_gmm_rx(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int len);
int gprs_gmm_tx_att_req(struct gprs_gmm_entity *gmme,
enum osmo_gprs_gmm_attach_type attach_type,
diff --git a/src/gmm/gmm.c b/src/gmm/gmm.c
index aef3571..5a3b0c0 100644
--- a/src/gmm/gmm.c
+++ b/src/gmm/gmm.c
@@ -78,6 +78,8 @@
{ 0 } /* empty item at the end */
};
+static void t3314_ready_timer_cb(void *data);
+
static void gprs_gmm_ctx_free(void)
{
struct gprs_gmm_entity *gmme;
@@ -173,6 +175,8 @@
gmme->t3302 = osmo_tdef_get(g_gmm_ctx->T_defs, 3302, OSMO_TDEF_S, -1);
gmme->t3346 = osmo_tdef_get(g_gmm_ctx->T_defs, 3346, OSMO_TDEF_S, -1);
+ osmo_timer_setup(&gmme->t3314, t3314_ready_timer_cb, gmme);
+
llist_add(&gmme->list, &g_gmm_ctx->gmme_list);
return gmme;
@@ -184,6 +188,8 @@
return;
LOGGMME(gmme, LOGL_DEBUG, "free()\n");
+ if (osmo_timer_pending(&gmme->t3314))
+ osmo_timer_del(&gmme->t3314);
gprs_gmm_ms_fsm_ctx_release(&gmme->ms_fsm);
llist_del(&gmme->list);
talloc_free(gmme);
@@ -280,6 +286,51 @@
return GPRS_GMM_TLLI_UNASSIGNED;
}
+/* TS 24.008 4.7.2.1.1 READY timer behaviour (A/Gb mode only) */
+/* Ready timer is started: */
+void gprs_gmm_gmme_ready_timer_start(struct gprs_gmm_entity *gmme)
+{
+ if (gmme->t3314_assigned_sec == 0)
+ return;
+ LOGGMME(gmme, LOGL_INFO, "READY timer started\n");
+ osmo_timer_schedule(&gmme->t3314, gmme->t3314_assigned_sec, 0);
+
+ /* TODO: "Timer T3312 is stopped and shall be set to its initial value
+ * for the next start when the READY timer is started." */
+}
+
+/* Ready timer is stopped: */
+void gprs_gmm_gmme_ready_timer_stop(struct gprs_gmm_entity *gmme)
+{
+ /* TODO: "In A/Gb mode, the timer T3312 is reset and started with its
+ * initial value, when the READY timer is stopped or expires."
+ */
+ if (!osmo_timer_pending(&gmme->t3314))
+ return;
+ LOGGMME(gmme, LOGL_INFO, "READY timer stopped\n");
+ osmo_timer_del(&gmme->t3314);
+}
+
+bool gprs_gmm_gmme_ready_timer_running(const struct gprs_gmm_entity *gmme)
+{
+ return osmo_timer_pending(&gmme->t3314);
+}
+
+/* READY timer expiration: */
+static void t3314_ready_timer_cb(void *data)
+{
+ /* "When the READY timer has expired the MS shall perform the routing
+ * area updating procedure when a routing area border is crossed"
+ */
+ struct gprs_gmm_entity *gmme = (struct gprs_gmm_entity *)data;
+ LOGGMME(gmme, LOGL_INFO, "READY timer expired\n");
+
+ /* TODO: "In A/Gb mode, the timer T3312 is reset and started with its
+ *initial value, when the READY timer is stopped or expires."
+ */
+
+}
+
int gprs_gmm_submit_gmmreg_attach_cnf(struct gprs_gmm_entity *gmme, bool accepted,
uint8_t cause)
{
struct osmo_gprs_gmm_prim *gmm_prim_tx;
@@ -572,6 +623,18 @@
gmme->ptmsi_sig = GSM_RESERVED_TMSI;
}
+ /* 10.5.7.3 Negotiated READY timer value */
+ if (TLVP_PRESENT(&tp, GSM48_IE_GMM_TIMER_READY)) {
+ int secs = gprs_gmm_gprs_tmr_to_secs(*TLVP_VAL(&tp, GSM48_IE_GMM_TIMER_READY));
+ gmme->t3314_assigned_sec = secs >= 0 ? secs : 0;
+ } else {
+ /* Apply the requested value: */
+ gmme->t3314_assigned_sec = osmo_tdef_get(g_gmm_ctx->T_defs, 3314, OSMO_TDEF_S,
-1);
+ }
+ /* "If the negotiated READY timer value is set to zero, the READY timer shall be
stopped immediately": */
+ if (gmme->t3314_assigned_sec == 0)
+ gprs_gmm_gmme_ready_timer_stop(gmme);
+
if (TLVP_PRESENT(&tp, GSM48_IE_GMM_ALLOC_PTMSI)) {
struct osmo_mobile_identity mi;
if (osmo_mobile_identity_decode(&mi, TLVP_VAL(&tp, GSM48_IE_GMM_ALLOC_PTMSI),
diff --git a/src/gmm/gmm_pdu.c b/src/gmm/gmm_pdu.c
index 28fd30f..c6c8118 100644
--- a/src/gmm/gmm_pdu.c
+++ b/src/gmm/gmm_pdu.c
@@ -181,6 +181,7 @@
uint8_t *l;
int rc;
struct gsm48_ra_id *raid_enc;
+ unsigned long t3314_sec;
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
gh->proto_discr = GSM48_PDISC_MM_GPRS;
@@ -236,6 +237,10 @@
msgb_tv_fixed_put(msg, GSM48_IE_GMM_PTMSI_SIG, sizeof(ptmsi_sig), ptmsi_sig);
}
+ /* 10.5.7.3 Requested READY timer value */
+ t3314_sec = osmo_tdef_get(g_gmm_ctx->T_defs, 3314, OSMO_TDEF_S, -1);
+ msgb_tv_put(msg, GSM48_IE_GMM_TIMER_READY, gprs_gmm_secs_to_gprs_tmr_floor(t3314_sec));
+
/* 9.4.1.13 P-TMSI type: The MS shall include this IE if the
* type of identity in the Mobile identity IE is set to
* "TMSI/P-TMSI/M-TMSI". */
diff --git a/src/gmm/gmm_prim.c b/src/gmm/gmm_prim.c
index 7ca6535..34c9fe9 100644
--- a/src/gmm/gmm_prim.c
+++ b/src/gmm/gmm_prim.c
@@ -603,6 +603,18 @@
return rc;
}
+static int gprs_gmm_prim_handle_gmmrr_llc_transmitted_ind(struct osmo_gprs_gmm_prim
*gmm_prim)
+{
+ struct gprs_gmm_entity *gmme = gprs_gmm_find_gmme_by_tlli(gmm_prim->gmmrr.tlli);
+ if (!gmme) {
+ LOGGMM(LOGL_NOTICE, "Rx %s: Unknown TLLI 0x%08x\n",
+ osmo_gprs_gmm_prim_name(gmm_prim), gmm_prim->gmmrr.tlli);
+ return -ENOENT;
+ }
+ gprs_gmm_gmme_ready_timer_start(gmme);
+ return 0;
+}
+
static int gprs_gmm_prim_handle_gmmrr(struct osmo_gprs_gmm_prim *gmm_prim)
{
int rc = 0;
@@ -612,8 +624,7 @@
rc = 1;
break;
case OSMO_PRIM(OSMO_GPRS_GMM_GMMRR_LLC_TRANSMITTED, PRIM_OP_INDICATION):
- rc = gprs_gmm_prim_handle_unsupported(gmm_prim);
- rc = 1;
+ rc = gprs_gmm_prim_handle_gmmrr_llc_transmitted_ind(gmm_prim);
break;
default:
rc = gprs_gmm_prim_handle_unsupported(gmm_prim);
diff --git a/tests/gmm/gmm_prim_test.ok b/tests/gmm/gmm_prim_test.ok
index cfebbfa..068876b 100644
--- a/tests/gmm/gmm_prim_test.ok
+++ b/tests/gmm/gmm_prim_test.ok
@@ -1,5 +1,5 @@
==== test_gmm_prim_ms_gmmreg() [start] ====
-test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 01 04
97 07 00 00 01 0a 00 05 f4 00 00 12 34 00 f0 00 00 00 00 00 19 55 66 77 e1 ]
+test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 01 04
97 07 00 00 01 0a 00 05 f4 00 00 12 34 00 f0 00 00 00 00 00 19 55 66 77 17 16 e1 ]
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 16 08
42 32 24 43 32 24 43 f2 ]
test_gmm_prim_up_cb(): Rx GMMREG-SIM_AUTH.indication ac_ref_nr=2 key_seq=0 rand=e2 a6 f3
f8 bb 9e a7 01 e0 ce 4f 33 64 a9 91 75
test_gmm_prim_llc_down_cb(): Rx LLGMM-ASSIGN.request old_TLLI=0xffffffff
new_TLLI=0x80001234
@@ -13,7 +13,7 @@
test_gmm_prim_up_cb(): Rx GMMREG-DETACH.confirm detach_type='GPRS detach'
==== test_gmm_prim_ms_gmmreg() [end] ====
==== test_gmm_prim_ms_gmmsm() [start] ====
-test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 01 04
97 07 00 00 01 0a 00 05 f4 00 00 12 34 00 f0 00 00 00 00 00 19 55 66 77 e1 ]
+test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 01 04
97 07 00 00 01 0a 00 05 f4 00 00 12 34 00 f0 00 00 00 00 00 19 55 66 77 17 16 e1 ]
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 16 08
42 32 24 43 32 24 43 f2 ]
test_gmm_prim_up_cb(): Rx GMMREG-SIM_AUTH.indication ac_ref_nr=2 key_seq=0 rand=e2 a6 f3
f8 bb 9e a7 01 e0 ce 4f 33 64 a9 91 75
test_gmm_prim_llc_down_cb(): Rx LLGMM-ASSIGN.request old_TLLI=0xffffffff
new_TLLI=0x80001234
--
To view, visit
https://gerrit.osmocom.org/c/libosmo-gprs/+/32909
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: libosmo-gprs
Gerrit-Branch: master
Gerrit-Change-Id: I451ce08d80fb247c28819de065136e2e4d49f3f5
Gerrit-Change-Number: 32909
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: newchange