diff options
Diffstat (limited to 'src/sgsn/gprs_mm_state_gb_fsm.c')
-rw-r--r-- | src/sgsn/gprs_mm_state_gb_fsm.c | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/src/sgsn/gprs_mm_state_gb_fsm.c b/src/sgsn/gprs_mm_state_gb_fsm.c index 4e1ed48d5..dde7b770a 100644 --- a/src/sgsn/gprs_mm_state_gb_fsm.c +++ b/src/sgsn/gprs_mm_state_gb_fsm.c @@ -1,3 +1,25 @@ +/* TS 23.060 ยง 6.1.1 Mobility Management States (A/Gb mode) */ +/* + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * Author: Pau Espin Pedrol <pespin@sysmocom.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ #include <osmocom/core/tdef.h> #include <osmocom/sgsn/gprs_mm_state_gb_fsm.h> @@ -5,6 +27,7 @@ #include <osmocom/sgsn/debug.h> #include <osmocom/sgsn/sgsn.h> +#include <osmocom/sgsn/mmctx.h> #define X(s) (1 << (s)) @@ -20,6 +43,10 @@ static const struct osmo_tdef_state_timeout mm_state_gb_fsm_timeouts[32] = { static void st_mm_idle_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) { struct sgsn_mm_ctx *ctx = fi->priv; + /* FIXME: remove this timer when RAU has it's own fsm */ + if (ctx->T == 3350 && osmo_timer_pending(&ctx->timer)) + osmo_timer_del(&ctx->timer); + if (ctx->gb.llme) { gprs_llgmm_unassign(ctx->gb.llme); ctx->gb.llme = NULL; @@ -43,9 +70,11 @@ static void st_mm_ready(struct osmo_fsm_inst *fi, uint32_t event, void *data) switch(event) { case E_MM_READY_TIMER_EXPIRY: - case E_MM_IMPLICIT_DETACH: mm_state_gb_fsm_state_chg(fi, ST_MM_STANDBY); break; + case E_MM_GPRS_DETACH: + mm_state_gb_fsm_state_chg(fi, ST_MM_IDLE); + break; case E_MM_PDU_RECEPTION: /* RE-arm the READY timer upon receival of Gb PDUs */ t_secs = osmo_tdef_get(sgsn->cfg.T_defs, 3314, OSMO_TDEF_S, -1); @@ -62,6 +91,9 @@ static void st_mm_standby(struct osmo_fsm_inst *fi, uint32_t event, void *data) case E_MM_PDU_RECEPTION: mm_state_gb_fsm_state_chg(fi, ST_MM_READY); break; + case E_MM_GPRS_DETACH: + mm_state_gb_fsm_state_chg(fi, ST_MM_IDLE); + break; } } @@ -74,13 +106,13 @@ static struct osmo_fsm_state mm_state_gb_fsm_states[] = { .action = st_mm_idle, }, [ST_MM_READY] = { - .in_event_mask = X(E_MM_READY_TIMER_EXPIRY) | X(E_MM_RA_UPDATE) | X(E_MM_IMPLICIT_DETACH) | X(E_MM_PDU_RECEPTION), + .in_event_mask = X(E_MM_READY_TIMER_EXPIRY) | X(E_MM_RA_UPDATE) | X(E_MM_GPRS_DETACH) | X(E_MM_PDU_RECEPTION), .out_state_mask = X(ST_MM_IDLE) | X(ST_MM_STANDBY), .name = "Ready", .action = st_mm_ready, }, [ST_MM_STANDBY] = { - .in_event_mask = X(E_MM_PDU_RECEPTION), + .in_event_mask = X(E_MM_PDU_RECEPTION) | X(E_MM_GPRS_DETACH), .out_state_mask = X(ST_MM_IDLE) | X(ST_MM_READY), .name = "Standby", .action = st_mm_standby, @@ -90,7 +122,7 @@ static struct osmo_fsm_state mm_state_gb_fsm_states[] = { const struct value_string mm_state_gb_fsm_event_names[] = { OSMO_VALUE_STRING(E_MM_GPRS_ATTACH), OSMO_VALUE_STRING(E_MM_PDU_RECEPTION), - OSMO_VALUE_STRING(E_MM_IMPLICIT_DETACH), + OSMO_VALUE_STRING(E_MM_GPRS_DETACH), OSMO_VALUE_STRING(E_MM_READY_TIMER_EXPIRY), OSMO_VALUE_STRING(E_MM_RA_UPDATE), { 0, NULL } @@ -119,5 +151,5 @@ struct osmo_fsm mm_state_gb_fsm = { static __attribute__((constructor)) void mm_state_gb_fsm_init(void) { - osmo_fsm_register(&mm_state_gb_fsm); + OSMO_ASSERT(osmo_fsm_register(&mm_state_gb_fsm) == 0); } |