gmm: Initial implementation of READY timer
Change-Id: I451ce08d80fb247c28819de065136e2e4d49f3f5
This commit is contained in:
parent
c6e7a3bd88
commit
a2fe6f302a
|
@ -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 @@ struct gprs_gmm_entity {
|
|||
|
||||
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_imsi(const char *imsi);
|
|||
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,
|
||||
|
|
|
@ -78,6 +78,8 @@ static struct osmo_tdef T_defs_gmm[] = {
|
|||
{ 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 @@ struct gprs_gmm_entity *gprs_gmm_gmme_alloc(uint32_t ptmsi, const char *imsi)
|
|||
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 @@ void gprs_gmm_gmme_free(struct gprs_gmm_entity *gmme)
|
|||
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 @@ failed:
|
|||
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 @@ static int gprs_gmm_rx_att_ack(struct gprs_gmm_entity *gmme, struct gsm48_hdr *g
|
|||
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),
|
||||
|
|
|
@ -181,6 +181,7 @@ int gprs_gmm_build_attach_req(struct gprs_gmm_entity *gmme,
|
|||
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 @@ int gprs_gmm_build_attach_req(struct gprs_gmm_entity *gmme,
|
|||
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". */
|
||||
|
|
|
@ -603,6 +603,18 @@ int gprs_gmm_prim_call_down_cb(struct osmo_gprs_gmm_prim *gmm_prim)
|
|||
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 @@ static int gprs_gmm_prim_handle_gmmrr(struct osmo_gprs_gmm_prim *gmm_prim)
|
|||
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);
|
||||
|
|
|
@ -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_llc_down_cb(): Rx LLGMM-ASSIGN.request old_TLLI=0xea711b41 new_TLL
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue