sgsn: make all SGSN timers configurable via the VTY
This commit is contained in:
parent
39ba248608
commit
9450882901
|
@ -45,6 +45,21 @@ struct sgsn_config {
|
|||
/* CDR configuration */
|
||||
struct sgsn_cdr cdr;
|
||||
|
||||
struct {
|
||||
int T3312;
|
||||
int T3322;
|
||||
int T3350;
|
||||
int T3360;
|
||||
int T3370;
|
||||
int T3313;
|
||||
int T3314;
|
||||
int T3316;
|
||||
int T3385;
|
||||
int T3386;
|
||||
int T3395;
|
||||
int T3397;
|
||||
} timers;
|
||||
|
||||
int dynamic_lookup;
|
||||
};
|
||||
|
||||
|
|
|
@ -60,27 +60,6 @@
|
|||
|
||||
#define PTMSI_ALLOC
|
||||
|
||||
/* Section 11.2.2 / Table 11.3a GPRS Mobility management timers – MS side */
|
||||
#define GSM0408_T3312_SECS (10*60) /* periodic RAU interval, default 54min */
|
||||
|
||||
/* Section 11.2.2 / Table 11.4 MM timers netwokr side */
|
||||
#define GSM0408_T3322_SECS 6 /* DETACH_REQ -> DETACH_ACC */
|
||||
#define GSM0408_T3350_SECS 6 /* waiting for ATT/RAU/TMSI COMPL */
|
||||
#define GSM0408_T3360_SECS 6 /* waiting for AUTH/CIPH RESP */
|
||||
#define GSM0408_T3370_SECS 6 /* waiting for ID RESP */
|
||||
|
||||
/* Section 11.2.2 / Table 11.4a MM timers netwokr side */
|
||||
#define GSM0408_T3313_SECS 30 /* waiting for paging response */
|
||||
#define GSM0408_T3314_SECS 44 /* force to STBY on expiry, Ready timer */
|
||||
#define GSM0408_T3316_SECS 44
|
||||
#define GSM0408_MOBILE_REACHABLE_SECS (GSM0408_T3312_SECS + 4 * 60)
|
||||
|
||||
/* Section 11.3 / Table 11.2d Timers of Session Management - network side */
|
||||
#define GSM0408_T3385_SECS 8 /* wait for ACT PDP CTX REQ */
|
||||
#define GSM0408_T3386_SECS 8 /* wait for MODIFY PDP CTX ACK */
|
||||
#define GSM0408_T3395_SECS 8 /* wait for DEACT PDP CTX ACK */
|
||||
#define GSM0408_T3397_SECS 8 /* wait for DEACT AA PDP CTX ACK */
|
||||
|
||||
extern struct sgsn_instance *sgsn;
|
||||
|
||||
static const struct tlv_definition gsm48_gmm_att_tlvdef = {
|
||||
|
@ -146,7 +125,7 @@ static void mmctx_timer_stop(struct sgsn_mm_ctx *mm, unsigned int T)
|
|||
|
||||
time_t gprs_max_time_to_idle(void)
|
||||
{
|
||||
return GSM0408_T3314_SECS + GSM0408_MOBILE_REACHABLE_SECS;
|
||||
return sgsn->cfg.timers.T3314 + (sgsn->cfg.timers.T3312 + 4 * 60);
|
||||
}
|
||||
|
||||
/* Send a message through the underlying layer */
|
||||
|
@ -319,7 +298,7 @@ static int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm)
|
|||
aa = (struct gsm48_attach_ack *) msgb_put(msg, sizeof(*aa));
|
||||
aa->force_stby = 0; /* not indicated */
|
||||
aa->att_result = 1; /* GPRS only */
|
||||
aa->ra_upd_timer = gprs_secs_to_tmr_floor(GSM0408_T3312_SECS);
|
||||
aa->ra_upd_timer = gprs_secs_to_tmr_floor(sgsn->cfg.timers.T3312);
|
||||
aa->radio_prio = 4; /* lowest */
|
||||
gsm48_construct_ra(aa->ra_id.digits, &mm->ra);
|
||||
|
||||
|
@ -337,7 +316,7 @@ static int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm)
|
|||
* the inactivity time READY->STANDBY.
|
||||
*/
|
||||
msgb_tv_put(msg, GSM48_IE_GMM_TIMER_READY,
|
||||
gprs_secs_to_tmr_floor(GSM0408_T3314_SECS));
|
||||
gprs_secs_to_tmr_floor(sgsn->cfg.timers.T3314));
|
||||
|
||||
#ifdef PTMSI_ALLOC
|
||||
/* Optional: Allocated P-TMSI */
|
||||
|
@ -627,12 +606,12 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx)
|
|||
/* Request IMSI and IMEI from the MS if they are unknown */
|
||||
if (!strlen(ctx->imei)) {
|
||||
ctx->t3370_id_type = GSM_MI_TYPE_IMEI;
|
||||
mmctx_timer_start(ctx, 3370, GSM0408_T3370_SECS);
|
||||
mmctx_timer_start(ctx, 3370, sgsn->cfg.timers.T3370);
|
||||
return gsm48_tx_gmm_id_req(ctx, GSM_MI_TYPE_IMEI);
|
||||
}
|
||||
if (!strlen(ctx->imsi)) {
|
||||
ctx->t3370_id_type = GSM_MI_TYPE_IMSI;
|
||||
mmctx_timer_start(ctx, 3370, GSM0408_T3370_SECS);
|
||||
mmctx_timer_start(ctx, 3370, sgsn->cfg.timers.T3370);
|
||||
return gsm48_tx_gmm_id_req(ctx, GSM_MI_TYPE_IMSI);
|
||||
}
|
||||
|
||||
|
@ -654,7 +633,7 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx)
|
|||
if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && !ctx->is_authenticated) {
|
||||
struct gsm_auth_tuple *at = &ctx->auth_triplet;
|
||||
|
||||
mmctx_timer_start(ctx, 3360, GSM0408_T3360_SECS);
|
||||
mmctx_timer_start(ctx, 3360, sgsn->cfg.timers.T3360);
|
||||
return gsm48_tx_gmm_auth_ciph_req(ctx, at->rand, at->key_seq,
|
||||
GPRS_ALGO_GEA0);
|
||||
}
|
||||
|
@ -685,7 +664,7 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx)
|
|||
extract_subscr_hlr(ctx);
|
||||
#ifdef PTMSI_ALLOC
|
||||
/* Start T3350 and re-transmit up to 5 times until ATTACH COMPLETE */
|
||||
mmctx_timer_start(ctx, 3350, GSM0408_T3350_SECS);
|
||||
mmctx_timer_start(ctx, 3350, sgsn->cfg.timers.T3350);
|
||||
ctx->t3350_mode = GMM_T3350_MODE_ATT;
|
||||
#else
|
||||
memset(&sig_data, 0, sizeof(sig_data));
|
||||
|
@ -1054,7 +1033,7 @@ static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm)
|
|||
rua = (struct gsm48_ra_upd_ack *) msgb_put(msg, sizeof(*rua));
|
||||
rua->force_stby = 0; /* not indicated */
|
||||
rua->upd_result = 0; /* RA updated */
|
||||
rua->ra_upd_timer = gprs_secs_to_tmr_floor(GSM0408_T3312_SECS);
|
||||
rua->ra_upd_timer = gprs_secs_to_tmr_floor(sgsn->cfg.timers.T3312);
|
||||
|
||||
gsm48_construct_ra(rua->ra_id.digits, &mm->ra);
|
||||
|
||||
|
@ -1076,7 +1055,7 @@ static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm)
|
|||
|
||||
/* Optional: Negotiated READY timer value */
|
||||
msgb_tv_put(msg, GSM48_IE_GMM_TIMER_READY,
|
||||
gprs_secs_to_tmr_floor(GSM0408_T3314_SECS));
|
||||
gprs_secs_to_tmr_floor(sgsn->cfg.timers.T3314));
|
||||
|
||||
/* Option: MS ID, ... */
|
||||
return gsm48_gmm_sendmsg(msg, 0, mm);
|
||||
|
@ -1218,7 +1197,7 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
|
|||
}
|
||||
/* Start T3350 and re-transmit up to 5 times until ATTACH COMPLETE */
|
||||
mmctx->t3350_mode = GMM_T3350_MODE_RAU;
|
||||
mmctx_timer_start(mmctx, 3350, GSM0408_T3350_SECS);
|
||||
mmctx_timer_start(mmctx, 3350, sgsn->cfg.timers.T3350);
|
||||
|
||||
mmctx->mm_state = GMM_COMMON_PROC_INIT;
|
||||
#else
|
||||
|
@ -1437,7 +1416,7 @@ static void mmctx_timer_cb(void *_mm)
|
|||
"T3350 mode wasn't set, ignoring timeout\n");
|
||||
break;
|
||||
}
|
||||
osmo_timer_schedule(&mm->timer, GSM0408_T3350_SECS, 0);
|
||||
osmo_timer_schedule(&mm->timer, sgsn->cfg.timers.T3350, 0);
|
||||
break;
|
||||
case 3360: /* waiting for AUTH AND CIPH RESP */
|
||||
if (mm->num_T_exp >= 5) {
|
||||
|
@ -1455,7 +1434,7 @@ static void mmctx_timer_cb(void *_mm)
|
|||
at = &mm->auth_triplet;
|
||||
|
||||
gsm48_tx_gmm_auth_ciph_req(mm, at->rand, at->key_seq, GPRS_ALGO_GEA0);
|
||||
osmo_timer_schedule(&mm->timer, GSM0408_T3360_SECS, 0);
|
||||
osmo_timer_schedule(&mm->timer, sgsn->cfg.timers.T3360, 0);
|
||||
break;
|
||||
case 3370: /* waiting for IDENTITY RESPONSE */
|
||||
if (mm->num_T_exp >= 5) {
|
||||
|
@ -1466,7 +1445,7 @@ static void mmctx_timer_cb(void *_mm)
|
|||
}
|
||||
/* re-tranmit IDENTITY REQUEST and re-start timer */
|
||||
gsm48_tx_gmm_id_req(mm, mm->t3370_id_type);
|
||||
osmo_timer_schedule(&mm->timer, GSM0408_T3370_SECS, 0);
|
||||
osmo_timer_schedule(&mm->timer, sgsn->cfg.timers.T3370, 0);
|
||||
break;
|
||||
default:
|
||||
LOGMMCTXP(LOGL_ERROR, mm, "timer expired in unknown mode %u\n",
|
||||
|
@ -1605,7 +1584,7 @@ static int _gsm48_tx_gsm_deact_pdp_req(struct sgsn_mm_ctx *mm, uint8_t tid,
|
|||
}
|
||||
int gsm48_tx_gsm_deact_pdp_req(struct sgsn_pdp_ctx *pdp, uint8_t sm_cause)
|
||||
{
|
||||
pdpctx_timer_start(pdp, 3395, GSM0408_T3395_SECS);
|
||||
pdpctx_timer_start(pdp, 3395, sgsn->cfg.timers.T3395);
|
||||
|
||||
return _gsm48_tx_gsm_deact_pdp_req(pdp->mm, pdp->ti, sm_cause);
|
||||
}
|
||||
|
@ -1989,7 +1968,7 @@ static void pdpctx_timer_cb(void *_pdp)
|
|||
break;
|
||||
}
|
||||
gsm48_tx_gsm_deact_pdp_req(pdp, GSM_CAUSE_NET_FAIL);
|
||||
osmo_timer_schedule(&pdp->timer, GSM0408_T3395_SECS, 0);
|
||||
osmo_timer_schedule(&pdp->timer, sgsn->cfg.timers.T3395, 0);
|
||||
break;
|
||||
default:
|
||||
LOGPDPCTXP(LOGL_ERROR, pdp, "timer expired in unknown mode %u\n",
|
||||
|
|
|
@ -54,6 +54,60 @@ const struct value_string sgsn_auth_pol_strs[] = {
|
|||
{ 0, NULL }
|
||||
};
|
||||
|
||||
/* Section 11.2.2 / Table 11.3a GPRS Mobility management timers – MS side */
|
||||
#define GSM0408_T3312_SECS (10*60) /* periodic RAU interval, default 54min */
|
||||
|
||||
/* Section 11.2.2 / Table 11.4 MM timers netwokr side */
|
||||
#define GSM0408_T3322_SECS 6 /* DETACH_REQ -> DETACH_ACC */
|
||||
#define GSM0408_T3350_SECS 6 /* waiting for ATT/RAU/TMSI COMPL */
|
||||
#define GSM0408_T3360_SECS 6 /* waiting for AUTH/CIPH RESP */
|
||||
#define GSM0408_T3370_SECS 6 /* waiting for ID RESP */
|
||||
|
||||
/* Section 11.2.2 / Table 11.4a MM timers netwokr side */
|
||||
#define GSM0408_T3313_SECS 30 /* waiting for paging response */
|
||||
#define GSM0408_T3314_SECS 44 /* force to STBY on expiry, Ready timer */
|
||||
#define GSM0408_T3316_SECS 44
|
||||
|
||||
/* Section 11.3 / Table 11.2d Timers of Session Management - network side */
|
||||
#define GSM0408_T3385_SECS 8 /* wait for ACT PDP CTX REQ */
|
||||
#define GSM0408_T3386_SECS 8 /* wait for MODIFY PDP CTX ACK */
|
||||
#define GSM0408_T3395_SECS 8 /* wait for DEACT PDP CTX ACK */
|
||||
#define GSM0408_T3397_SECS 8 /* wait for DEACT AA PDP CTX ACK */
|
||||
|
||||
#define DECLARE_TIMER(number, doc) \
|
||||
DEFUN(cfg_sgsn_T##number, \
|
||||
cfg_sgsn_T##number##_cmd, \
|
||||
"timer t" #number " <0-65535>", \
|
||||
"Configure GPRS Timers\n" \
|
||||
doc "Timer Value in seconds\n") \
|
||||
{ \
|
||||
int value = atoi(argv[0]); \
|
||||
\
|
||||
if (value < 0 || value > 65535) { \
|
||||
vty_out(vty, "Timer value %s out of range.%s", \
|
||||
argv[0], VTY_NEWLINE); \
|
||||
return CMD_WARNING; \
|
||||
} \
|
||||
\
|
||||
g_cfg->timers.T##number = value; \
|
||||
return CMD_SUCCESS; \
|
||||
}
|
||||
|
||||
DECLARE_TIMER(3312, "Periodic RA Update timer (s)")
|
||||
DECLARE_TIMER(3322, "Detach reqest -> accept timer (s)")
|
||||
DECLARE_TIMER(3350, "Waiting for ATT/RAU/TMSI_COMPL timer (s)")
|
||||
DECLARE_TIMER(3360, "Waiting for AUTH/CIPH response timer (s)")
|
||||
DECLARE_TIMER(3370, "Waiting for IDENTITY response timer (s)")
|
||||
|
||||
DECLARE_TIMER(3313, "Waiting for paging response timer (s)")
|
||||
DECLARE_TIMER(3314, "Force to STANDBY on expiry timer (s)")
|
||||
DECLARE_TIMER(3316, "")
|
||||
|
||||
DECLARE_TIMER(3385, "Wait for ACT PDP CTX REQ timer (s)")
|
||||
DECLARE_TIMER(3386, "Wait for MODIFY PDP CTX ACK timer (s)")
|
||||
DECLARE_TIMER(3395, "Wait for DEACT PDP CTX ACK timer (s)")
|
||||
DECLARE_TIMER(3397, "Wait for DEACT AA PDP CTX ACK timer (s)")
|
||||
|
||||
|
||||
#define GSM48_MAX_APN_LEN 102 /* 10.5.6.1 */
|
||||
static char *gprs_apn2str(uint8_t *apn, unsigned int len)
|
||||
|
@ -181,6 +235,19 @@ static int config_write_sgsn(struct vty *vty)
|
|||
vty_out(vty, " no cdr filename%s", VTY_NEWLINE);
|
||||
vty_out(vty, " cdr interval %d%s", g_cfg->cdr.interval, VTY_NEWLINE);
|
||||
|
||||
vty_out(vty, " timer t3312 %d%s", g_cfg->timers.T3312, VTY_NEWLINE);
|
||||
vty_out(vty, " timer t3322 %d%s", g_cfg->timers.T3322, VTY_NEWLINE);
|
||||
vty_out(vty, " timer t3350 %d%s", g_cfg->timers.T3350, VTY_NEWLINE);
|
||||
vty_out(vty, " timer t3360 %d%s", g_cfg->timers.T3360, VTY_NEWLINE);
|
||||
vty_out(vty, " timer t3370 %d%s", g_cfg->timers.T3370, VTY_NEWLINE);
|
||||
vty_out(vty, " timer t3313 %d%s", g_cfg->timers.T3313, VTY_NEWLINE);
|
||||
vty_out(vty, " timer t3314 %d%s", g_cfg->timers.T3314, VTY_NEWLINE);
|
||||
vty_out(vty, " timer t3316 %d%s", g_cfg->timers.T3316, VTY_NEWLINE);
|
||||
vty_out(vty, " timer t3385 %d%s", g_cfg->timers.T3385, VTY_NEWLINE);
|
||||
vty_out(vty, " timer t3386 %d%s", g_cfg->timers.T3386, VTY_NEWLINE);
|
||||
vty_out(vty, " timer t3395 %d%s", g_cfg->timers.T3395, VTY_NEWLINE);
|
||||
vty_out(vty, " timer t3397 %d%s", g_cfg->timers.T3397, VTY_NEWLINE);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -912,6 +979,19 @@ int sgsn_vty_init(void)
|
|||
install_element(SGSN_NODE, &cfg_ggsn_dynamic_lookup_cmd);
|
||||
install_element(SGSN_NODE, &cfg_grx_ggsn_cmd);
|
||||
|
||||
install_element(SGSN_NODE, &cfg_sgsn_T3312_cmd);
|
||||
install_element(SGSN_NODE, &cfg_sgsn_T3322_cmd);
|
||||
install_element(SGSN_NODE, &cfg_sgsn_T3350_cmd);
|
||||
install_element(SGSN_NODE, &cfg_sgsn_T3360_cmd);
|
||||
install_element(SGSN_NODE, &cfg_sgsn_T3370_cmd);
|
||||
install_element(SGSN_NODE, &cfg_sgsn_T3313_cmd);
|
||||
install_element(SGSN_NODE, &cfg_sgsn_T3314_cmd);
|
||||
install_element(SGSN_NODE, &cfg_sgsn_T3316_cmd);
|
||||
install_element(SGSN_NODE, &cfg_sgsn_T3385_cmd);
|
||||
install_element(SGSN_NODE, &cfg_sgsn_T3386_cmd);
|
||||
install_element(SGSN_NODE, &cfg_sgsn_T3395_cmd);
|
||||
install_element(SGSN_NODE, &cfg_sgsn_T3397_cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -921,6 +1001,19 @@ int sgsn_parse_config(const char *config_file, struct sgsn_config *cfg)
|
|||
|
||||
g_cfg = cfg;
|
||||
|
||||
g_cfg->timers.T3312 = GSM0408_T3312_SECS;
|
||||
g_cfg->timers.T3322 = GSM0408_T3322_SECS;
|
||||
g_cfg->timers.T3350 = GSM0408_T3350_SECS;
|
||||
g_cfg->timers.T3360 = GSM0408_T3360_SECS;
|
||||
g_cfg->timers.T3370 = GSM0408_T3370_SECS;
|
||||
g_cfg->timers.T3313 = GSM0408_T3313_SECS;
|
||||
g_cfg->timers.T3314 = GSM0408_T3314_SECS;
|
||||
g_cfg->timers.T3316 = GSM0408_T3316_SECS;
|
||||
g_cfg->timers.T3385 = GSM0408_T3385_SECS;
|
||||
g_cfg->timers.T3386 = GSM0408_T3386_SECS;
|
||||
g_cfg->timers.T3395 = GSM0408_T3395_SECS;
|
||||
g_cfg->timers.T3397 = GSM0408_T3397_SECS;
|
||||
|
||||
rc = vty_read_config_file(config_file, NULL);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
|
||||
|
|
Loading…
Reference in New Issue