Introduce FSM mm_state_gb_fsm
Implement TS 23.060 6.1.1 Mobility Management States (A/Gb mode) using osmocom FSM and drop old implementation. Most of the logic on each state is still kept in gprs_gmm.c, will be inserted into the FSM later. Change-Id: I04004423e993107374d5a3549b8a93ac169251dd
This commit is contained in:
parent
9119d50849
commit
02514bc592
|
@ -7,6 +7,7 @@ noinst_HEADERS = \
|
||||||
gprs_gb_parse.h \
|
gprs_gb_parse.h \
|
||||||
gprs_gmm.h \
|
gprs_gmm.h \
|
||||||
gprs_gmm_attach.h \
|
gprs_gmm_attach.h \
|
||||||
|
gprs_mm_state_gb_fsm.h \
|
||||||
gprs_llc.h \
|
gprs_llc.h \
|
||||||
gprs_llc_xid.h \
|
gprs_llc_xid.h \
|
||||||
gprs_ranap.h \
|
gprs_ranap.h \
|
||||||
|
|
|
@ -50,8 +50,6 @@ void extract_subscr_hlr(struct sgsn_mm_ctx *ctx);
|
||||||
void pdp_ctx_detach_mm_ctx(struct sgsn_pdp_ctx *pdp);
|
void pdp_ctx_detach_mm_ctx(struct sgsn_pdp_ctx *pdp);
|
||||||
|
|
||||||
void mmctx_set_pmm_state(struct sgsn_mm_ctx *ctx, enum gprs_mm_state_iu state);
|
void mmctx_set_pmm_state(struct sgsn_mm_ctx *ctx, enum gprs_mm_state_iu state);
|
||||||
void mmctx_state_timer_start(struct sgsn_mm_ctx *mm, unsigned int T);
|
|
||||||
void mmctx_set_mm_state(struct sgsn_mm_ctx *ctx, enum gprs_mm_state_gb state);
|
|
||||||
|
|
||||||
void msgid2mmctx(struct sgsn_mm_ctx *mm, const struct msgb *msg);
|
void msgid2mmctx(struct sgsn_mm_ctx *mm, const struct msgb *msg);
|
||||||
#endif /* _GPRS_GMM_H */
|
#endif /* _GPRS_GMM_H */
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <osmocom/core/fsm.h>
|
||||||
|
|
||||||
|
struct sgsn_mm_ctx;
|
||||||
|
|
||||||
|
|
||||||
|
/* TS 23.060 6.1.1 Mobility Management States (A/Gb mode) */
|
||||||
|
enum mm_state_gb_fsm_states {
|
||||||
|
ST_MM_IDLE,
|
||||||
|
ST_MM_READY,
|
||||||
|
ST_MM_STANDBY
|
||||||
|
};
|
||||||
|
|
||||||
|
enum mm_state_gb_fsm_events {
|
||||||
|
E_MM_GPRS_ATTACH,
|
||||||
|
/* E_GPRS_DETACH, TODO: not used */
|
||||||
|
E_MM_PDU_RECEPTION,
|
||||||
|
E_MM_IMPLICIT_DETACH, /* = E_MM_CANCEL_LOCATION */
|
||||||
|
E_MM_READY_TIMER_EXPIRY,
|
||||||
|
/* E_FORCE_TO_STANDBY, TODO: not used */
|
||||||
|
/* E_ABNSORMAL_RLC_CONDITION, TODO: not used */
|
||||||
|
E_MM_RA_UPDATE,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct osmo_fsm mm_state_gb_fsm;
|
|
@ -32,12 +32,6 @@ enum gprs_gmm_state {
|
||||||
GMM_DEREGISTERED_INIT, /* 4.1.3.3.1.4 */
|
GMM_DEREGISTERED_INIT, /* 4.1.3.3.1.4 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* TS 23.060 6.1.1 Mobility Management States (A/Gb mode) */
|
|
||||||
enum gprs_mm_state_gb {
|
|
||||||
MM_IDLE,
|
|
||||||
MM_READY,
|
|
||||||
MM_STANDBY
|
|
||||||
};
|
|
||||||
/* TS 23.060 6.1.2 Mobility Management States (Iu mode) */
|
/* TS 23.060 6.1.2 Mobility Management States (Iu mode) */
|
||||||
enum gprs_mm_state_iu {
|
enum gprs_mm_state_iu {
|
||||||
PMM_DETACHED,
|
PMM_DETACHED,
|
||||||
|
@ -161,10 +155,7 @@ struct sgsn_mm_ctx {
|
||||||
uint32_t tlli_new;
|
uint32_t tlli_new;
|
||||||
|
|
||||||
/* TS 23.060 6.1.1 Mobility Management States (A/Gb mode) */
|
/* TS 23.060 6.1.1 Mobility Management States (A/Gb mode) */
|
||||||
enum gprs_mm_state_gb mm_state;
|
struct osmo_fsm_inst *mm_state_fsm;
|
||||||
/* timer for mm state. state=READY: T3314 (aka TS 23.060 "READY timer") */
|
|
||||||
struct osmo_timer_list state_timer;
|
|
||||||
unsigned int state_T; /* Txxxx number but only used for mm_state */
|
|
||||||
} gb;
|
} gb;
|
||||||
struct {
|
struct {
|
||||||
int new_key;
|
int new_key;
|
||||||
|
|
|
@ -63,6 +63,7 @@ osmo_sgsn_SOURCES = \
|
||||||
gprs_gb.c \
|
gprs_gb.c \
|
||||||
gprs_gmm_attach.c \
|
gprs_gmm_attach.c \
|
||||||
gprs_gmm.c \
|
gprs_gmm.c \
|
||||||
|
gprs_mm_state_gb_fsm.c \
|
||||||
gprs_ranap.c \
|
gprs_ranap.c \
|
||||||
gprs_sgsn.c \
|
gprs_sgsn.c \
|
||||||
gprs_sndcp.c \
|
gprs_sndcp.c \
|
||||||
|
|
|
@ -28,25 +28,11 @@
|
||||||
|
|
||||||
#include "bscconfig.h"
|
#include "bscconfig.h"
|
||||||
|
|
||||||
|
#include <osmocom/sgsn/gprs_mm_state_gb_fsm.h>
|
||||||
#include <osmocom/sgsn/gprs_sgsn.h>
|
#include <osmocom/sgsn/gprs_sgsn.h>
|
||||||
#include <osmocom/sgsn/gprs_gmm.h>
|
#include <osmocom/sgsn/gprs_gmm.h>
|
||||||
#include <osmocom/sgsn/debug.h>
|
#include <osmocom/sgsn/debug.h>
|
||||||
|
|
||||||
/* Update the MM context state */
|
|
||||||
static void gsm0408_gprs_notify_pdu_gb(struct sgsn_mm_ctx *mmctx)
|
|
||||||
{
|
|
||||||
switch (mmctx->gb.mm_state) {
|
|
||||||
case MM_STANDBY:
|
|
||||||
mmctx_set_mm_state(mmctx, MM_READY);
|
|
||||||
break;
|
|
||||||
case MM_READY: /* RE-arm the timer upon receival of Gb PDUs */
|
|
||||||
mmctx_state_timer_start(mmctx, 3314);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Main entry point for incoming 04.08 GPRS messages from Gb */
|
/* Main entry point for incoming 04.08 GPRS messages from Gb */
|
||||||
int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
|
int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
|
||||||
bool drop_cipherable)
|
bool drop_cipherable)
|
||||||
|
@ -63,13 +49,11 @@ int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
|
||||||
msgid2mmctx(mmctx, msg);
|
msgid2mmctx(mmctx, msg);
|
||||||
rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]);
|
rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]);
|
||||||
mmctx->gb.llme = llme;
|
mmctx->gb.llme = llme;
|
||||||
|
osmo_fsm_inst_dispatch(mmctx->gb.mm_state_fsm, E_MM_PDU_RECEPTION, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MMCTX can be NULL */
|
/* MMCTX can be NULL */
|
||||||
|
|
||||||
if (mmctx)
|
|
||||||
gsm0408_gprs_notify_pdu_gb(mmctx);
|
|
||||||
|
|
||||||
switch (pdisc) {
|
switch (pdisc) {
|
||||||
case GSM48_PDISC_MM_GPRS:
|
case GSM48_PDISC_MM_GPRS:
|
||||||
rc = gsm0408_rcv_gmm(mmctx, msg, llme, drop_cipherable);
|
rc = gsm0408_rcv_gmm(mmctx, msg, llme, drop_cipherable);
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
#include <osmocom/sgsn/gprs_subscriber.h>
|
#include <osmocom/sgsn/gprs_subscriber.h>
|
||||||
#include <osmocom/sgsn/sgsn.h>
|
#include <osmocom/sgsn/sgsn.h>
|
||||||
#include <osmocom/sgsn/gprs_gmm_attach.h>
|
#include <osmocom/sgsn/gprs_gmm_attach.h>
|
||||||
|
#include <osmocom/sgsn/gprs_mm_state_gb_fsm.h>
|
||||||
#include <osmocom/sgsn/signal.h>
|
#include <osmocom/sgsn/signal.h>
|
||||||
#include <osmocom/sgsn/gprs_sndcp.h>
|
#include <osmocom/sgsn/gprs_sndcp.h>
|
||||||
#include <osmocom/sgsn/gprs_ranap.h>
|
#include <osmocom/sgsn/gprs_ranap.h>
|
||||||
|
@ -102,13 +103,6 @@ static const struct tlv_definition gsm48_sm_att_tlvdef = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct value_string gprs_mm_state_gb_names[] = {
|
|
||||||
OSMO_VALUE_STRING(MM_IDLE),
|
|
||||||
OSMO_VALUE_STRING(MM_READY),
|
|
||||||
OSMO_VALUE_STRING(MM_STANDBY),
|
|
||||||
{ 0, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct value_string gprs_mm_state_iu_names[] = {
|
static const struct value_string gprs_mm_state_iu_names[] = {
|
||||||
OSMO_VALUE_STRING(PMM_DETACHED),
|
OSMO_VALUE_STRING(PMM_DETACHED),
|
||||||
OSMO_VALUE_STRING(PMM_CONNECTED),
|
OSMO_VALUE_STRING(PMM_CONNECTED),
|
||||||
|
@ -130,56 +124,6 @@ static void mmctx_change_gtpu_endpoints_to_sgsn(struct sgsn_mm_ctx *mm_ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mmctx_state_timer_cb(void *_mm)
|
|
||||||
{
|
|
||||||
struct sgsn_mm_ctx *mm = _mm;
|
|
||||||
|
|
||||||
switch (mm->gb.state_T) {
|
|
||||||
case 3314:
|
|
||||||
switch (mm->gb.mm_state) {
|
|
||||||
case MM_READY:
|
|
||||||
LOGMMCTXP(LOGL_INFO, mm, "T3314 expired\n");
|
|
||||||
mmctx_set_mm_state(mm, MM_STANDBY);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOGMMCTXP(LOGL_ERROR, mm, "T3314 expired in state %s != MM_READY\n",
|
|
||||||
get_value_string(gprs_mm_state_gb_names, mm->gb.mm_state));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOGMMCTXP(LOGL_ERROR, mm, "state timer expired in unknown mode %u\n",
|
|
||||||
mm->gb.state_T);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void mmctx_state_timer_start(struct sgsn_mm_ctx *mm, unsigned int T)
|
|
||||||
{
|
|
||||||
unsigned long seconds;
|
|
||||||
|
|
||||||
if (mm->gb.state_T && mm->gb.state_T != T)
|
|
||||||
LOGMMCTXP(LOGL_ERROR, mm, "Attempting to start timer %u but %u is active!\n",
|
|
||||||
T, mm->gb.state_T);
|
|
||||||
|
|
||||||
mm->gb.state_T = T;
|
|
||||||
mm->gb.state_timer.data = mm;
|
|
||||||
mm->gb.state_timer.cb = &mmctx_state_timer_cb;
|
|
||||||
|
|
||||||
seconds = osmo_tdef_get(sgsn->cfg.T_defs, T, OSMO_TDEF_S, -1);
|
|
||||||
osmo_timer_schedule(&mm->gb.state_timer, seconds, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mmctx_state_timer_stop(struct sgsn_mm_ctx *mm, unsigned int T)
|
|
||||||
{
|
|
||||||
if (mm->gb.state_T == T)
|
|
||||||
osmo_timer_del(&mm->gb.state_timer);
|
|
||||||
else
|
|
||||||
LOGMMCTXP(LOGL_ERROR, mm, "Attempting to stop timer %u but %u is active!\n",
|
|
||||||
T, mm->gb.state_T);
|
|
||||||
mm->gb.state_T = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mmctx_set_pmm_state(struct sgsn_mm_ctx *ctx, enum gprs_mm_state_iu state)
|
void mmctx_set_pmm_state(struct sgsn_mm_ctx *ctx, enum gprs_mm_state_iu state)
|
||||||
{
|
{
|
||||||
OSMO_ASSERT(ctx->ran_type == MM_CTX_T_UTRAN_Iu);
|
OSMO_ASSERT(ctx->ran_type == MM_CTX_T_UTRAN_Iu);
|
||||||
|
@ -205,35 +149,6 @@ void mmctx_set_pmm_state(struct sgsn_mm_ctx *ctx, enum gprs_mm_state_iu state)
|
||||||
ctx->iu.mm_state = state;
|
ctx->iu.mm_state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mmctx_set_mm_state(struct sgsn_mm_ctx *ctx, enum gprs_mm_state_gb state)
|
|
||||||
{
|
|
||||||
OSMO_ASSERT(ctx->ran_type == MM_CTX_T_GERAN_Gb);
|
|
||||||
|
|
||||||
if (ctx->gb.mm_state == state)
|
|
||||||
return;
|
|
||||||
|
|
||||||
LOGMMCTXP(LOGL_INFO, ctx, "Changing MM state from %s to %s\n",
|
|
||||||
get_value_string(gprs_mm_state_gb_names, ctx->gb.mm_state),
|
|
||||||
get_value_string(gprs_mm_state_gb_names, state));
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
case MM_READY:
|
|
||||||
/* on expiration, T3314 moves mm state back to MM_STANDBY */
|
|
||||||
mmctx_state_timer_start(ctx, 3314);
|
|
||||||
break;
|
|
||||||
case MM_IDLE:
|
|
||||||
if (ctx->gb.mm_state == MM_READY)
|
|
||||||
mmctx_state_timer_stop(ctx, 3314);
|
|
||||||
break;
|
|
||||||
case MM_STANDBY:
|
|
||||||
if (ctx->gb.mm_state == MM_READY)
|
|
||||||
mmctx_state_timer_stop(ctx, 3314);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->gb.mm_state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Our implementation, should be kept in SGSN */
|
/* Our implementation, should be kept in SGSN */
|
||||||
|
|
||||||
static void mmctx_timer_cb(void *_mm);
|
static void mmctx_timer_cb(void *_mm);
|
||||||
|
@ -348,7 +263,7 @@ static void mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx, const char *log_text)
|
||||||
mmctx_set_pmm_state(ctx, PMM_DETACHED);
|
mmctx_set_pmm_state(ctx, PMM_DETACHED);
|
||||||
break;
|
break;
|
||||||
case MM_CTX_T_GERAN_Gb:
|
case MM_CTX_T_GERAN_Gb:
|
||||||
mmctx_set_mm_state(ctx, MM_IDLE);
|
osmo_fsm_inst_dispatch(ctx->gb.mm_state_fsm, E_MM_IMPLICIT_DETACH, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2107,7 +2022,7 @@ int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
|
||||||
gprs_llme_copy_key(mmctx, mmctx->gb.llme);
|
gprs_llme_copy_key(mmctx, mmctx->gb.llme);
|
||||||
gprs_llgmm_assign(mmctx->gb.llme, TLLI_UNASSIGNED,
|
gprs_llgmm_assign(mmctx->gb.llme, TLLI_UNASSIGNED,
|
||||||
mmctx->gb.tlli_new);
|
mmctx->gb.tlli_new);
|
||||||
mmctx_set_mm_state(mmctx, MM_READY);
|
osmo_fsm_inst_dispatch(mmctx->gb.mm_state_fsm, E_MM_GPRS_ATTACH, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
@ -2136,7 +2051,7 @@ int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
|
||||||
mmctx->gb.tlli = mmctx->gb.tlli_new;
|
mmctx->gb.tlli = mmctx->gb.tlli_new;
|
||||||
gprs_llgmm_assign(mmctx->gb.llme, TLLI_UNASSIGNED,
|
gprs_llgmm_assign(mmctx->gb.llme, TLLI_UNASSIGNED,
|
||||||
mmctx->gb.tlli_new);
|
mmctx->gb.tlli_new);
|
||||||
mmctx_set_mm_state(mmctx, MM_READY);
|
osmo_fsm_inst_dispatch(mmctx->gb.mm_state_fsm, E_MM_RA_UPDATE, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
#include <osmocom/core/tdef.h>
|
||||||
|
|
||||||
|
#include <osmocom/sgsn/gprs_mm_state_gb_fsm.h>
|
||||||
|
|
||||||
|
#include <osmocom/sgsn/debug.h>
|
||||||
|
#include <osmocom/sgsn/sgsn.h>
|
||||||
|
|
||||||
|
#define X(s) (1 << (s))
|
||||||
|
|
||||||
|
static const struct osmo_tdef_state_timeout mm_state_gb_fsm_timeouts[32] = {
|
||||||
|
[ST_MM_IDLE] = { },
|
||||||
|
[ST_MM_READY] = { .T=3314 },
|
||||||
|
[ST_MM_STANDBY] = { },
|
||||||
|
};
|
||||||
|
|
||||||
|
#define mm_state_gb_fsm_state_chg(fi, NEXT_STATE) \
|
||||||
|
osmo_tdef_fsm_inst_state_chg(fi, NEXT_STATE, mm_state_gb_fsm_timeouts, sgsn->cfg.T_defs, -1)
|
||||||
|
|
||||||
|
static void st_mm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
|
{
|
||||||
|
switch(event) {
|
||||||
|
case E_MM_GPRS_ATTACH:
|
||||||
|
mm_state_gb_fsm_state_chg(fi, ST_MM_READY);
|
||||||
|
break;
|
||||||
|
case E_MM_PDU_RECEPTION:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_mm_ready(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
|
{
|
||||||
|
unsigned long t_secs;
|
||||||
|
|
||||||
|
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_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);
|
||||||
|
osmo_timer_schedule(&fi->timer, t_secs, 0);
|
||||||
|
break;
|
||||||
|
case E_MM_RA_UPDATE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_mm_standby(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
|
{
|
||||||
|
switch(event) {
|
||||||
|
case E_MM_PDU_RECEPTION:
|
||||||
|
mm_state_gb_fsm_state_chg(fi, ST_MM_READY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct osmo_fsm_state mm_state_gb_fsm_states[] = {
|
||||||
|
[ST_MM_IDLE] = {
|
||||||
|
.in_event_mask = X(E_MM_GPRS_ATTACH) | X(E_MM_PDU_RECEPTION),
|
||||||
|
.out_state_mask = X(ST_MM_READY),
|
||||||
|
.name = "Idle",
|
||||||
|
.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),
|
||||||
|
.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),
|
||||||
|
.out_state_mask = X(ST_MM_IDLE) | X(ST_MM_READY),
|
||||||
|
.name = "Standby",
|
||||||
|
.action = st_mm_standby,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
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_READY_TIMER_EXPIRY),
|
||||||
|
OSMO_VALUE_STRING(E_MM_RA_UPDATE),
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
int mm_state_gb_fsm_timer_cb(struct osmo_fsm_inst *fi)
|
||||||
|
{
|
||||||
|
switch(fi->state) {
|
||||||
|
case ST_MM_READY:
|
||||||
|
/* timer for mm state. state=READY: T3314 (aka TS 23.060 "READY timer") */
|
||||||
|
osmo_fsm_inst_dispatch(fi, E_MM_READY_TIMER_EXPIRY, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct osmo_fsm mm_state_gb_fsm = {
|
||||||
|
.name = "MM_STATE_Gb",
|
||||||
|
.states = mm_state_gb_fsm_states,
|
||||||
|
.num_states = ARRAY_SIZE(mm_state_gb_fsm_states),
|
||||||
|
.event_names = mm_state_gb_fsm_event_names,
|
||||||
|
.log_subsys = DMM,
|
||||||
|
.timer_cb = mm_state_gb_fsm_timer_cb,
|
||||||
|
};
|
||||||
|
|
||||||
|
static __attribute__((constructor)) void mm_state_gb_fsm_init(void)
|
||||||
|
{
|
||||||
|
osmo_fsm_register(&mm_state_gb_fsm);
|
||||||
|
}
|
|
@ -42,6 +42,7 @@
|
||||||
#include <osmocom/sgsn/gprs_utils.h>
|
#include <osmocom/sgsn/gprs_utils.h>
|
||||||
#include <osmocom/sgsn/signal.h>
|
#include <osmocom/sgsn/signal.h>
|
||||||
#include <osmocom/sgsn/gprs_gmm_attach.h>
|
#include <osmocom/sgsn/gprs_gmm_attach.h>
|
||||||
|
#include <osmocom/sgsn/gprs_mm_state_gb_fsm.h>
|
||||||
#include <osmocom/sgsn/gprs_llc.h>
|
#include <osmocom/sgsn/gprs_llc.h>
|
||||||
|
|
||||||
#include <pdp.h>
|
#include <pdp.h>
|
||||||
|
@ -243,6 +244,7 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_gb(uint32_t tlli,
|
||||||
const struct gprs_ra_id *raid)
|
const struct gprs_ra_id *raid)
|
||||||
{
|
{
|
||||||
struct sgsn_mm_ctx *ctx;
|
struct sgsn_mm_ctx *ctx;
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
ctx = sgsn_mm_ctx_alloc(tlli);
|
ctx = sgsn_mm_ctx_alloc(tlli);
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
|
@ -251,8 +253,9 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_gb(uint32_t tlli,
|
||||||
memcpy(&ctx->ra, raid, sizeof(ctx->ra));
|
memcpy(&ctx->ra, raid, sizeof(ctx->ra));
|
||||||
ctx->ran_type = MM_CTX_T_GERAN_Gb;
|
ctx->ran_type = MM_CTX_T_GERAN_Gb;
|
||||||
ctx->gb.tlli = tlli;
|
ctx->gb.tlli = tlli;
|
||||||
ctx->gb.mm_state = MM_IDLE;
|
|
||||||
ctx->ciph_algo = sgsn->cfg.cipher;
|
ctx->ciph_algo = sgsn->cfg.cipher;
|
||||||
|
snprintf(buf, sizeof(buf), "%" PRIu32, tlli);
|
||||||
|
ctx->gb.mm_state_fsm = osmo_fsm_inst_alloc(&mm_state_gb_fsm, ctx, ctx, LOGL_DEBUG, buf);
|
||||||
|
|
||||||
LOGMMCTXP(LOGL_DEBUG, ctx, "Allocated with %s cipher.\n",
|
LOGMMCTXP(LOGL_DEBUG, ctx, "Allocated with %s cipher.\n",
|
||||||
get_value_string(gprs_cipher_names, ctx->ciph_algo));
|
get_value_string(gprs_cipher_names, ctx->ciph_algo));
|
||||||
|
@ -334,11 +337,6 @@ void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm)
|
||||||
osmo_timer_del(&mm->timer);
|
osmo_timer_del(&mm->timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (osmo_timer_pending(&mm->gb.state_timer)) {
|
|
||||||
LOGMMCTXP(LOGL_INFO, mm, "Cancelling MM state timer %u\n", mm->gb.state_T);
|
|
||||||
osmo_timer_del(&mm->gb.state_timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&sig_data, 0, sizeof(sig_data));
|
memset(&sig_data, 0, sizeof(sig_data));
|
||||||
sig_data.mm = mm;
|
sig_data.mm = mm;
|
||||||
osmo_signal_dispatch(SS_SGSN, S_SGSN_MM_FREE, &sig_data);
|
osmo_signal_dispatch(SS_SGSN, S_SGSN_MM_FREE, &sig_data);
|
||||||
|
@ -353,6 +351,8 @@ void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm)
|
||||||
|
|
||||||
if (mm->gmm_att_req.fsm)
|
if (mm->gmm_att_req.fsm)
|
||||||
gmm_att_req_free(mm);
|
gmm_att_req_free(mm);
|
||||||
|
if (mm->gb.mm_state_fsm)
|
||||||
|
osmo_fsm_inst_free(mm->gb.mm_state_fsm);
|
||||||
|
|
||||||
sgsn_mm_ctx_free(mm);
|
sgsn_mm_ctx_free(mm);
|
||||||
mm = NULL;
|
mm = NULL;
|
||||||
|
|
|
@ -50,6 +50,7 @@ sgsn_test_LDADD = \
|
||||||
$(top_builddir)/src/gprs/gprs_sndcp.o \
|
$(top_builddir)/src/gprs/gprs_sndcp.o \
|
||||||
$(top_builddir)/src/gprs/gprs_gmm_attach.o \
|
$(top_builddir)/src/gprs/gprs_gmm_attach.o \
|
||||||
$(top_builddir)/src/gprs/gprs_gmm.o \
|
$(top_builddir)/src/gprs/gprs_gmm.o \
|
||||||
|
$(top_builddir)/src/gprs/gprs_mm_state_gb_fsm.o \
|
||||||
$(top_builddir)/src/gprs/gprs_sgsn.o \
|
$(top_builddir)/src/gprs/gprs_sgsn.o \
|
||||||
$(top_builddir)/src/gprs/sgsn_vty.o \
|
$(top_builddir)/src/gprs/sgsn_vty.o \
|
||||||
$(top_builddir)/src/gprs/sgsn_libgtp.o \
|
$(top_builddir)/src/gprs/sgsn_libgtp.o \
|
||||||
|
|
Loading…
Reference in New Issue