diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/sgsn/Makefile.am | 1 | ||||
-rw-r--r-- | src/sgsn/gprs_gmm.c | 44 | ||||
-rw-r--r-- | src/sgsn/gprs_gmm_fsm.c | 187 | ||||
-rw-r--r-- | src/sgsn/gprs_sgsn.c | 7 | ||||
-rw-r--r-- | src/sgsn/sgsn_libgtp.c | 9 | ||||
-rw-r--r-- | src/sgsn/sgsn_vty.c | 11 |
6 files changed, 220 insertions, 39 deletions
diff --git a/src/sgsn/Makefile.am b/src/sgsn/Makefile.am index a8da94308..4402c9c6c 100644 --- a/src/sgsn/Makefile.am +++ b/src/sgsn/Makefile.am @@ -43,6 +43,7 @@ osmo_sgsn_SOURCES = \ gprs_gb.c \ gprs_gmm_attach.c \ gprs_gmm.c \ + gprs_gmm_fsm.c \ gprs_mm_state_gb_fsm.c \ gprs_mm_state_iu_fsm.c \ gprs_ranap.c \ diff --git a/src/sgsn/gprs_gmm.c b/src/sgsn/gprs_gmm.c index 399f7bf89..3317a0929 100644 --- a/src/sgsn/gprs_gmm.c +++ b/src/sgsn/gprs_gmm.c @@ -57,6 +57,7 @@ #include <osmocom/sgsn/gprs_gmm_attach.h> #include <osmocom/sgsn/gprs_mm_state_gb_fsm.h> #include <osmocom/sgsn/gprs_mm_state_iu_fsm.h> +#include <osmocom/sgsn/gprs_gmm_fsm.h> #include <osmocom/sgsn/signal.h> #include <osmocom/sgsn/gprs_sndcp.h> #include <osmocom/sgsn/gprs_ranap.h> @@ -211,7 +212,7 @@ static void mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx, const char *log_text) LOGMMCTXP(LOGL_INFO, ctx, "Cleaning MM context due to %s\n", log_text); /* Mark MM state as deregistered */ - ctx->gmm_state = GMM_DEREGISTERED; + osmo_fsm_inst_dispatch(ctx->gmm_fsm, E_GMM_CLEANUP, NULL); switch(ctx->ran_type) { case MM_CTX_T_UTRAN_Iu: @@ -967,7 +968,7 @@ int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx) memset(&sig_data, 0, sizeof(sig_data)); sig_data.mm = mmctx; osmo_signal_dispatch(SS_SGSN, S_SGSN_ATTACH, &sig_data); - ctx->gmm_state = GMM_REGISTERED_NORMAL; + osmo_fsm_inst_dispatch(mm->gmm_fsm, E_GMM_ATTACH_SUCCESS, NULL); #endif return gsm48_tx_gmm_att_ack(ctx); @@ -1009,8 +1010,8 @@ void gsm0408_gprs_authenticate(struct sgsn_mm_ctx *ctx) void gsm0408_gprs_access_granted(struct sgsn_mm_ctx *ctx) { - switch (ctx->gmm_state) { - case GMM_COMMON_PROC_INIT: + switch (ctx->gmm_fsm->state) { + case ST_GMM_COMMON_PROC_INIT: LOGMMCTXP(LOGL_NOTICE, ctx, "Authorized, continuing procedure, IMSI=%s\n", ctx->imsi); @@ -1030,8 +1031,8 @@ void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *ctx, int gmm_cause) if (gmm_cause == SGSN_ERROR_CAUSE_NONE) gmm_cause = GMM_CAUSE_GPRS_NOTALLOWED; - switch (ctx->gmm_state) { - case GMM_COMMON_PROC_INIT: + switch (ctx->gmm_fsm->state) { + case ST_GMM_COMMON_PROC_INIT: LOGMMCTXP(LOGL_NOTICE, ctx, "Not authorized, rejecting ATTACH REQUEST " "with cause '%s' (%d)\n", @@ -1040,8 +1041,8 @@ void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *ctx, int gmm_cause) if (ctx->gmm_att_req.fsm->state != ST_INIT) osmo_fsm_inst_dispatch(ctx->gmm_att_req.fsm, E_REJECT, (void *) (long) gmm_cause); break; - case GMM_REGISTERED_NORMAL: - case GMM_REGISTERED_SUSPENDED: + case ST_GMM_REGISTERED_NORMAL: + case ST_GMM_REGISTERED_SUSPENDED: LOGMMCTXP(LOGL_NOTICE, ctx, "Authorization lost, detaching " "with cause '%s' (%d)\n", @@ -1142,7 +1143,7 @@ static inline void ptmsi_update(struct sgsn_mm_ctx *ctx) { uint32_t ptmsi; /* Don't change the P-TMSI if a P-TMSI re-assignment is under way */ - if (ctx->gmm_state != GMM_COMMON_PROC_INIT) { + if (ctx->gmm_fsm->state != ST_GMM_COMMON_PROC_INIT) { ptmsi = sgsn_alloc_ptmsi(); if (ptmsi != GSM_RESERVED_TMSI) { ctx->p_tmsi_old = ctx->p_tmsi; @@ -1150,7 +1151,7 @@ static inline void ptmsi_update(struct sgsn_mm_ctx *ctx) } else LOGMMCTXP(LOGL_ERROR, ctx, "P-TMSI allocation failure: using old one.\n"); } - ctx->gmm_state = GMM_COMMON_PROC_INIT; + osmo_fsm_inst_dispatch(ctx->gmm_fsm, E_GMM_COMMON_PROC_INIT_REQ, NULL); } /* 3GPP TS 24.008 ยง 9.4.1 Attach request */ @@ -1360,7 +1361,7 @@ static int gsm48_rx_gmm_att_compl(struct sgsn_mm_ctx *mmctx) mmctx->t3350_mode = GMM_T3350_MODE_NONE; mmctx->p_tmsi_old = 0; mmctx->pending_req = 0; - mmctx->gmm_state = GMM_REGISTERED_NORMAL; + osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_ATTACH_SUCCESS, NULL); switch(mmctx->ran_type) { case MM_CTX_T_UTRAN_Iu: osmo_fsm_inst_dispatch(mmctx->iu.mm_state_fsm, E_PMM_PS_ATTACH, NULL); @@ -1658,11 +1659,10 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, mmctx->p_tmsi, mmctx->p_tmsi_old, mmctx->gb.tlli, mmctx->gb.tlli_new, osmo_rai_name(&mmctx->ra)); - - mmctx->gmm_state = GMM_COMMON_PROC_INIT; + osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_COMMON_PROC_INIT_REQ, NULL); } } else if (!gprs_ra_id_equals(&mmctx->ra, &old_ra_id) || - mmctx->gmm_state == GMM_DEREGISTERED) + mmctx->gmm_fsm->state == ST_GMM_DEREGISTERED) { /* We cannot use the mmctx */ LOGMMCTXP(LOGL_INFO, mmctx, @@ -1715,7 +1715,7 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, mmctx_timer_start(mmctx, 3350); #else /* Make sure we are NORMAL (i.e. not SUSPENDED anymore) */ - mmctx->gmm_state = GMM_REGISTERED_NORMAL; + osmo_fsm_inst_dispatch(mm->gmm_fsm, E_GMM_ATTACH_SUCCESS, NULL); memset(&sig_data, 0, sizeof(sig_data)); sig_data.mm = mmctx; @@ -1768,7 +1768,7 @@ static int gsm48_rx_gmm_ra_upd_compl(struct sgsn_mm_ctx *mmctx) mmctx->t3350_mode = GMM_T3350_MODE_NONE; mmctx->p_tmsi_old = 0; mmctx->pending_req = 0; - mmctx->gmm_state = GMM_REGISTERED_NORMAL; + osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_COMMON_PROC_SUCCESS, NULL); switch(mmctx->ran_type) { case MM_CTX_T_UTRAN_Iu: osmo_fsm_inst_dispatch(mmctx->iu.mm_state_fsm, E_PMM_RA_UPDATE, NULL); @@ -1883,7 +1883,7 @@ static int gsm48_rx_gmm_service_req(struct sgsn_mm_ctx *ctx, struct msgb *msg) goto rejected; } - ctx->gmm_state = GMM_COMMON_PROC_INIT; + osmo_fsm_inst_dispatch(ctx->gmm_fsm, E_GMM_COMMON_PROC_INIT_REQ, NULL); ctx->iu.service.type = service_type; @@ -2832,15 +2832,14 @@ int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli) return -EINVAL; } - if (mmctx->gmm_state != GMM_REGISTERED_NORMAL && - mmctx->gmm_state != GMM_REGISTERED_SUSPENDED) { + if (!gmm_fsm_is_registered(mmctx->gmm_fsm)) { LOGMMCTXP(LOGL_NOTICE, mmctx, "SUSPEND request while state " "!= REGISTERED (TLLI=%08x)\n", tlli); return -EINVAL; } /* Transition from REGISTERED_NORMAL to REGISTERED_SUSPENDED */ - mmctx->gmm_state = GMM_REGISTERED_SUSPENDED; + osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_SUSPEND, NULL); return 0; } @@ -2858,8 +2857,7 @@ int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli, return -EINVAL; } - if (mmctx->gmm_state != GMM_REGISTERED_NORMAL && - mmctx->gmm_state != GMM_REGISTERED_SUSPENDED) { + if (!gmm_fsm_is_registered(mmctx->gmm_fsm)) { LOGMMCTXP(LOGL_NOTICE, mmctx, "RESUME request while state " "!= SUSPENDED (TLLI=%08x)\n", tlli); /* FIXME: should we not simply ignore it? */ @@ -2867,6 +2865,6 @@ int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli, } /* Transition from SUSPENDED to NORMAL */ - mmctx->gmm_state = GMM_REGISTERED_NORMAL; + osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_RESUME, NULL); return 0; } diff --git a/src/sgsn/gprs_gmm_fsm.c b/src/sgsn/gprs_gmm_fsm.c new file mode 100644 index 000000000..fac06f27e --- /dev/null +++ b/src/sgsn/gprs_gmm_fsm.c @@ -0,0 +1,187 @@ +#include <osmocom/core/tdef.h> + +#include <osmocom/sgsn/gprs_gmm_fsm.h> + +#include <osmocom/sgsn/debug.h> +#include <osmocom/sgsn/sgsn.h> + +#define X(s) (1 << (s)) + +static const struct osmo_tdef_state_timeout gmm_fsm_timeouts[32] = { + [ST_GMM_DEREGISTERED] = { }, + [ST_GMM_COMMON_PROC_INIT] = { }, + [ST_GMM_REGISTERED_NORMAL] = { }, + [ST_GMM_REGISTERED_SUSPENDED] = { }, + [ST_GMM_DEREGISTERED_INIT] = { }, +}; + +#define gmm_fsm_state_chg(fi, NEXT_STATE) \ + osmo_tdef_fsm_inst_state_chg(fi, NEXT_STATE, gmm_fsm_timeouts, sgsn->cfg.T_defs, -1) + +static void st_gmm_deregistered(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch(event) { + case E_GMM_COMMON_PROC_INIT_REQ: + gmm_fsm_state_chg(fi, ST_GMM_COMMON_PROC_INIT); + break; + case E_GMM_ATTACH_SUCCESS: + gmm_fsm_state_chg(fi, ST_GMM_REGISTERED_NORMAL); + break; + } +} + +static void st_gmm_common_proc_init(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch(event) { + /* TODO: events not used + case E_GMM_LOWER_LAYER_FAILED: + case E_GMM_COMMON_PROC_FAILED: + gmm_fsm_state_chg(fi, ST_GMM_DEREGISTERED); + break; + */ + case E_GMM_COMMON_PROC_SUCCESS: + case E_GMM_ATTACH_SUCCESS: + gmm_fsm_state_chg(fi, ST_GMM_REGISTERED_NORMAL); + break; + } +} + +static void st_gmm_registered_normal(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch(event) { + case E_GMM_COMMON_PROC_INIT_REQ: + gmm_fsm_state_chg(fi, ST_GMM_COMMON_PROC_INIT); + break; + /* case E_GMM_NET_INIT_DETACH_REQ: + gmm_fsm_state_chg(fi, ST_GMM_DEREGISTERED_INIT); + break; */ + /* case E_GMM_MS_INIT_DETACH_REQ: + gmm_fsm_state_chg(fi, ST_GMM_DEREGISTERED); + break; */ + case E_GMM_SUSPEND: + gmm_fsm_state_chg(fi, ST_GMM_REGISTERED_SUSPENDED); + break; + } +} + +static void st_gmm_registered_suspended(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch(event) { + case E_GMM_RESUME: + gmm_fsm_state_chg(fi, ST_GMM_REGISTERED_NORMAL); + break; + } +} + +static void st_gmm_deregistered_init(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch(event) { + /* TODO: events not used in osmo-sgsn code + case E_GMM_DETACH_ACCEPTED: + case E_GMM_LOWER_LAYER_FAILED: + gmm_fsm_state_chg(fi, ST_GMM_DEREGISTERED); + break; + */ + } +} + +static struct osmo_fsm_state gmm_fsm_states[] = { + [ST_GMM_DEREGISTERED] = { + .in_event_mask = + X(E_GMM_COMMON_PROC_INIT_REQ) | + X(E_GMM_ATTACH_SUCCESS), + .out_state_mask = X(ST_GMM_COMMON_PROC_INIT), + .name = "Deregistered", + .action = st_gmm_deregistered, + }, + [ST_GMM_COMMON_PROC_INIT] = { + .in_event_mask = + /* X(E_GMM_LOWER_LAYER_FAILED) | */ + /* X(E_GMM_COMMON_PROC_FAILED) | */ + X(E_GMM_COMMON_PROC_SUCCESS) | + X(E_GMM_ATTACH_SUCCESS), + .out_state_mask = + X(ST_GMM_DEREGISTERED) | + X(ST_GMM_REGISTERED_NORMAL), + .name = "CommonProcedureInitiated", + .action = st_gmm_common_proc_init, + }, + [ST_GMM_REGISTERED_NORMAL] = { + .in_event_mask = + X(E_GMM_COMMON_PROC_INIT_REQ) | + /* X(E_GMM_NET_INIT_DETACH_REQ) | */ + /* X(E_GMM_MS_INIT_DETACH_REQ) | */ + X(E_GMM_SUSPEND), + .out_state_mask = + X(ST_GMM_DEREGISTERED) | + X(ST_GMM_COMMON_PROC_INIT) | + X(ST_GMM_DEREGISTERED_INIT) | + X(ST_GMM_REGISTERED_SUSPENDED), + .name = "Registered.NORMAL", + .action = st_gmm_registered_normal, + }, + [ST_GMM_REGISTERED_SUSPENDED] = { + .in_event_mask = X(E_GMM_RESUME), + .out_state_mask = + X(ST_GMM_DEREGISTERED) | + X(ST_GMM_REGISTERED_NORMAL), + .name = "Registered.SUSPENDED", + .action = st_gmm_registered_suspended, + }, + [ST_GMM_DEREGISTERED_INIT] = { + .in_event_mask = 0 + /* X(E_GMM_DETACH_ACCEPTED) | */ + /* X(E_GMM_LOWER_LAYER_FAILED) */, + .out_state_mask = X(ST_GMM_DEREGISTERED), + .name = "DeregisteredInitiated", + .action = st_gmm_deregistered_init, + }, +}; + +const struct value_string gmm_fsm_event_names[] = { + OSMO_VALUE_STRING(E_GMM_COMMON_PROC_INIT_REQ), + /* OSMO_VALUE_STRING(E_GMM_COMMON_PROC_FAILED), */ + /* OSMO_VALUE_STRING(E_GMM_LOWER_LAYER_FAILED), */ + OSMO_VALUE_STRING(E_GMM_COMMON_PROC_SUCCESS), + OSMO_VALUE_STRING(E_GMM_ATTACH_SUCCESS), + /* OSMO_VALUE_STRING(E_GMM_NET_INIT_DETACH_REQ), */ + /* OSMO_VALUE_STRING(E_GMM_MS_INIT_DETACH_REQ), */ + /* OSMO_VALUE_STRING(E_GMM_DETACH_ACCEPTED), */ + OSMO_VALUE_STRING(E_GMM_SUSPEND), + OSMO_VALUE_STRING(E_GMM_CLEANUP), + { 0, NULL } +}; + +void gmm_fsm_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + switch (event) { + case E_GMM_CLEANUP: + switch (fi->state) { + case ST_GMM_DEREGISTERED: + break; + default: + gmm_fsm_state_chg(fi, ST_GMM_DEREGISTERED); + break; + } + } +} + +int gmm_fsm_timer_cb(struct osmo_fsm_inst *fi) +{ + return 0; +} + +struct osmo_fsm gmm_fsm = { + .name = "GMM", + .states = gmm_fsm_states, + .num_states = ARRAY_SIZE(gmm_fsm_states), + .event_names = gmm_fsm_event_names, + .allstate_event_mask = X(E_GMM_CLEANUP), + .allstate_action = gmm_fsm_allstate_action, + .log_subsys = DMM, + .timer_cb = gmm_fsm_timer_cb, +}; + +static __attribute__((constructor)) void gmm_fsm_init(void) +{ + osmo_fsm_register(&gmm_fsm); +} diff --git a/src/sgsn/gprs_sgsn.c b/src/sgsn/gprs_sgsn.c index 387c0d5a1..1c23d06a4 100644 --- a/src/sgsn/gprs_sgsn.c +++ b/src/sgsn/gprs_sgsn.c @@ -44,6 +44,7 @@ #include <osmocom/sgsn/gprs_gmm_attach.h> #include <osmocom/sgsn/gprs_mm_state_gb_fsm.h> #include <osmocom/sgsn/gprs_mm_state_iu_fsm.h> +#include <osmocom/sgsn/gprs_gmm_fsm.h> #include <osmocom/sgsn/gprs_llc.h> #include <pdp.h> @@ -234,7 +235,6 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t rate_ctr_id) if (!ctx) return NULL; - ctx->gmm_state = GMM_DEREGISTERED; ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL; ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, rate_ctr_id); if (!ctx->ctrg) { @@ -242,6 +242,7 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t rate_ctr_id) talloc_free(ctx); return NULL; } + ctx->gmm_fsm = osmo_fsm_inst_alloc(&gmm_fsm, ctx, ctx, LOGL_DEBUG, "gmm_fsm"); ctx->gmm_att_req.fsm = osmo_fsm_inst_alloc(&gmm_attach_req_fsm, ctx, ctx, LOGL_DEBUG, "gb_gmm_req"); INIT_LLIST_HEAD(&ctx->pdp_list); @@ -368,6 +369,8 @@ void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm) osmo_fsm_inst_free(mm->gb.mm_state_fsm); if (mm->iu.mm_state_fsm) osmo_fsm_inst_free(mm->iu.mm_state_fsm); + if (mm->gmm_fsm) + osmo_fsm_inst_free(mm->gmm_fsm); sgsn_mm_ctx_free(mm); mm = NULL; @@ -736,7 +739,7 @@ void sgsn_ggsn_ctx_drop_pdp(struct sgsn_pdp_ctx *pctx) { /* the MM context can be deleted while the GGSN is not reachable or * if has been crashed. */ - if (pctx->mm && pctx->mm->gmm_state == GMM_REGISTERED_NORMAL) { + if (pctx->mm && pctx->mm->gmm_fsm->state == ST_GMM_REGISTERED_NORMAL) { gsm48_tx_gsm_deact_pdp_req(pctx, GSM_CAUSE_NET_FAIL, true); sgsn_ggsn_ctx_remove_pdp(pctx->ggsn, pctx); } else { diff --git a/src/sgsn/sgsn_libgtp.c b/src/sgsn/sgsn_libgtp.c index 5e3f48f3f..f6d7a690f 100644 --- a/src/sgsn/sgsn_libgtp.c +++ b/src/sgsn/sgsn_libgtp.c @@ -51,6 +51,7 @@ #include <osmocom/sgsn/gprs_subscriber.h> #include <osmocom/sgsn/gprs_sndcp.h> #include <osmocom/sgsn/gprs_ranap.h> +#include <osmocom/sgsn/gprs_gmm_fsm.h> #include <gtp.h> #include <pdp.h> @@ -655,8 +656,8 @@ static int cb_data_ind(struct pdp_t *lib, void *packet, unsigned int len) msgb_bvci(msg) = mm->gb.bvci; msgb_nsei(msg) = mm->gb.nsei; - switch (mm->gmm_state) { - case GMM_REGISTERED_SUSPENDED: + switch (mm->gmm_fsm->state) { + case ST_GMM_REGISTERED_SUSPENDED: /* initiate PS PAGING procedure */ memset(&pinfo, 0, sizeof(pinfo)); pinfo.mode = BSSGP_PAGING_PS; @@ -670,11 +671,11 @@ static int cb_data_ind(struct pdp_t *lib, void *packet, unsigned int len) rate_ctr_inc(&mm->ctrg->ctr[GMM_CTR_PAGING_PS]); /* FIXME: queue the packet we received from GTP */ break; - case GMM_REGISTERED_NORMAL: + case ST_GMM_REGISTERED_NORMAL: break; default: LOGP(DGPRS, LOGL_ERROR, "GTP DATA IND for TLLI %08X in state " - "%u\n", mm->gb.tlli, mm->gmm_state); + "%s\n", mm->gb.tlli, osmo_fsm_inst_state_name(mm->gmm_fsm)); msgb_free(msg); return -1; } diff --git a/src/sgsn/sgsn_vty.c b/src/sgsn/sgsn_vty.c index 184ece761..9200822e3 100644 --- a/src/sgsn/sgsn_vty.c +++ b/src/sgsn/sgsn_vty.c @@ -476,15 +476,6 @@ DEFUN(cfg_apn_imsi_ggsn, cfg_apn_imsi_ggsn_cmd, return add_apn_ggsn_mapping(vty, argv[0], argv[1], atoi(argv[2])); } -const struct value_string gprs_mm_st_strs[] = { - { GMM_DEREGISTERED, "DEREGISTERED" }, - { GMM_COMMON_PROC_INIT, "COMMON PROCEDURE (INIT)" }, - { GMM_REGISTERED_NORMAL, "REGISTERED (NORMAL)" }, - { GMM_REGISTERED_SUSPENDED, "REGISTERED (SUSPENDED)" }, - { GMM_DEREGISTERED_INIT, "DEREGISTERED (INIT)" }, - { 0, NULL } -}; - char *sgsn_gtp_ntoa(struct ul16_t *ul) { struct in_addr ia; @@ -546,7 +537,7 @@ static void vty_dump_mmctx(struct vty *vty, const char *pfx, vty_out(vty, "%s MSISDN: %s, TLLI: %08x%s HLR: %s", pfx, mm->msisdn, id, mm->hlr, VTY_NEWLINE); vty_out(vty, "%s GMM State: %s, Routeing Area: %s, Cell ID: %u%s", - pfx, get_value_string(gprs_mm_st_strs, mm->gmm_state), + pfx, osmo_fsm_inst_state_name(mm->gmm_fsm), osmo_rai_name(&mm->ra), mm->gb.cell_id, VTY_NEWLINE); vty_out(vty, "%s MM State: %s, RAN Type: %s%s", pfx, mm_state_name, get_value_string(sgsn_ran_type_names, mm->ran_type), VTY_NEWLINE); |