mirror of https://gerrit.osmocom.org/libosmocore
ns: Handle procedure changes for UDP in TS 48.016 (TODO)
Sponsored-by: On-Waves ehf
This commit is contained in:
parent
91ff17c9ef
commit
ecb5e8ed25
|
@ -61,6 +61,11 @@ enum gprs_ns_cs {
|
|||
GPRS_NS_CS_ERROR, /*!< Failed to process message */
|
||||
};
|
||||
|
||||
enum gprs_ns_spec {
|
||||
GPRS_NS_TS_08_16 = 0,
|
||||
GPRS_NS_TS_48_016,
|
||||
};
|
||||
|
||||
struct gprs_nsvc;
|
||||
/*! \brief Osmocom GPRS callback function type */
|
||||
typedef int gprs_ns_cb_t(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
|
||||
|
@ -119,10 +124,13 @@ struct gprs_nsvc {
|
|||
struct osmo_timer_list timer;
|
||||
enum nsvc_timer_mode timer_mode;
|
||||
int alive_retries;
|
||||
enum gprs_ns_spec compliance;
|
||||
|
||||
unsigned int remote_end_is_sgsn:1;
|
||||
unsigned int persistent:1;
|
||||
unsigned int nsvci_is_valid:1;
|
||||
unsigned int static_config:1;
|
||||
unsigned int config_completed:1;
|
||||
|
||||
struct rate_ctr_group *ctrg;
|
||||
|
||||
|
|
|
@ -126,11 +126,28 @@ static const struct rate_ctr_group_desc nsvc_ctrg_desc = {
|
|||
.ctr_desc = nsvc_ctr_description,
|
||||
};
|
||||
|
||||
static void nsvc_start_timer(struct gprs_nsvc *nsvc, enum nsvc_timer_mode mode);
|
||||
|
||||
#define CHECK_TX_RC(rc, nsvc) \
|
||||
if (rc < 0) \
|
||||
LOGP(DNS, LOGL_ERROR, "TX failed (%d) to peer %s\n", \
|
||||
rc, gprs_ns_ll_str(nsvc));
|
||||
|
||||
static int enable_reset_block_proc(const struct gprs_nsvc *nsvc)
|
||||
{
|
||||
return nsvc->compliance != GPRS_NS_TS_48_016 ||
|
||||
!nsvc->static_config ||
|
||||
nsvc->ll != GPRS_NS_LL_UDP;
|
||||
}
|
||||
|
||||
static int continue_test_proc(const struct gprs_nsvc *nsvc)
|
||||
{
|
||||
return nsvc->compliance == GPRS_NS_TS_48_016 &&
|
||||
nsvc->static_config &&
|
||||
nsvc->ll == GPRS_NS_LL_UDP &&
|
||||
nsvc->remote_end_is_sgsn;
|
||||
}
|
||||
|
||||
struct msgb *gprs_ns_msgb_alloc(void)
|
||||
{
|
||||
struct msgb *msg = msgb_alloc_headroom(NS_ALLOC_SIZE, NS_ALLOC_HEADROOM,
|
||||
|
@ -552,16 +569,24 @@ static void gprs_ns_timer_cb(void *data)
|
|||
nsvc->alive_retries++;
|
||||
if (nsvc->alive_retries >
|
||||
nsvc->nsi->timeout[NS_TOUT_TNS_ALIVE_RETRIES]) {
|
||||
/* mark as dead and blocked */
|
||||
nsvc->state = NSE_S_BLOCKED;
|
||||
rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_BLOCKED]);
|
||||
rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_DEAD]);
|
||||
LOGP(DNS, LOGL_NOTICE,
|
||||
"NSEI=%u Tns-alive expired more then "
|
||||
"%u times, blocking NS-VC\n", nsvc->nsei,
|
||||
nsvc->nsi->timeout[NS_TOUT_TNS_ALIVE_RETRIES]);
|
||||
/* mark as dead */
|
||||
nsvc->state = nsvc->state & ~NSE_S_ALIVE;
|
||||
rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_DEAD]);
|
||||
ns_osmo_signal_dispatch(nsvc, S_NS_ALIVE_EXP, 0);
|
||||
ns_osmo_signal_dispatch(nsvc, S_NS_BLOCK, NS_CAUSE_NSVC_BLOCKED);
|
||||
|
||||
if (continue_test_proc(nsvc)) {
|
||||
nsvc_start_timer(nsvc, NSVC_TIMER_TNS_TEST);
|
||||
} else if (enable_reset_block_proc(nsvc)) {
|
||||
/* mark as blocked */
|
||||
nsvc->state = NSE_S_BLOCKED;
|
||||
rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_BLOCKED]);
|
||||
ns_osmo_signal_dispatch(nsvc, S_NS_BLOCK,
|
||||
NS_CAUSE_NSVC_BLOCKED);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* Tns-test case: send NS-ALIVE PDU */
|
||||
|
@ -1064,6 +1089,14 @@ int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
|
|||
return rc;
|
||||
|
||||
rc = 0;
|
||||
} else if (nsvc->static_config && !nsvc->config_completed) {
|
||||
|
||||
if (!enable_reset_block_proc(nsvc)) {
|
||||
nsvc->state = NSE_S_ALIVE;
|
||||
nsvc_start_timer(nsvc, NSVC_TIMER_TNS_TEST);
|
||||
}
|
||||
|
||||
nsvc->config_completed = 1;
|
||||
}
|
||||
|
||||
if (nsvc)
|
||||
|
@ -1266,10 +1299,18 @@ int gprs_ns_process_msg(struct gprs_ns_inst *nsi, struct msgb *msg,
|
|||
* NS-ALIVE out of the blue, we might have been re-started
|
||||
* and should send a NS-RESET to make sure everything recovers
|
||||
* fine. */
|
||||
if ((*nsvc)->state == NSE_S_BLOCKED)
|
||||
if ((*nsvc)->state == NSE_S_BLOCKED) {
|
||||
rc = gprs_nsvc_reset((*nsvc), NS_CAUSE_PDU_INCOMP_PSTATE);
|
||||
else if (!((*nsvc)->state & NSE_S_RESET))
|
||||
} else if (!((*nsvc)->state & NSE_S_RESET)) {
|
||||
rc = gprs_ns_tx_alive_ack(*nsvc);
|
||||
if (!enable_reset_block_proc(*nsvc) &&
|
||||
!((*nsvc)->state & NSE_S_ALIVE))
|
||||
{
|
||||
/* start the test procedure */
|
||||
gprs_ns_tx_simple((*nsvc), NS_PDUT_ALIVE);
|
||||
nsvc_start_timer((*nsvc), NSVC_TIMER_TNS_TEST);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NS_PDUT_ALIVE_ACK:
|
||||
/* stop Tns-alive and start Tns-test */
|
||||
|
@ -1557,7 +1598,12 @@ struct gprs_nsvc *gprs_ns_nsip_connect(struct gprs_ns_inst *nsi,
|
|||
nsvc->nsei = nsei;
|
||||
nsvc->remote_end_is_sgsn = 1;
|
||||
|
||||
gprs_nsvc_reset(nsvc, NS_CAUSE_OM_INTERVENTION);
|
||||
if (enable_reset_block_proc(nsvc)) {
|
||||
gprs_nsvc_reset(nsvc, NS_CAUSE_OM_INTERVENTION);
|
||||
} else if (continue_test_proc(nsvc)) {
|
||||
nsvc->state = NSE_S_ALIVE;
|
||||
nsvc_start_timer(nsvc, NSVC_TIMER_TNS_TEST);
|
||||
}
|
||||
return nsvc;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,6 +91,11 @@ static int config_write_ns(struct vty *vty)
|
|||
vty_out(vty, " nse %u remote-role %s%s",
|
||||
nsvc->nsei, nsvc->remote_end_is_sgsn ? "sgsn" : "bss",
|
||||
VTY_NEWLINE);
|
||||
vty_out(vty, " nse %u compliance %s%s",
|
||||
nsvc->nsei,
|
||||
nsvc->compliance == GPRS_NS_TS_08_16 ?
|
||||
"ts08.16" : "ts48.016",
|
||||
VTY_NEWLINE);
|
||||
switch (nsvc->ll) {
|
||||
case GPRS_NS_LL_UDP:
|
||||
vty_out(vty, " nse %u encapsulation udp%s", nsvc->nsei,
|
||||
|
@ -255,6 +260,7 @@ DEFUN(cfg_nse_nsvc, cfg_nse_nsvci_cmd,
|
|||
if (!nsvc) {
|
||||
nsvc = gprs_nsvc_create(vty_nsi, nsvci);
|
||||
nsvc->nsei = nsei;
|
||||
nsvc->static_config = 1;
|
||||
}
|
||||
nsvc->nsvci = nsvci;
|
||||
/* All NSVCs that are explicitly configured by VTY are
|
||||
|
@ -387,6 +393,30 @@ DEFUN(cfg_nse_remoterole, cfg_nse_remoterole_cmd,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_nse_compliance, cfg_nse_compliance_cmd,
|
||||
"nse <0-65535> compliance (ts08.16|ts48.016)",
|
||||
NSE_CMD_STR
|
||||
"Set protocol compliance\n"
|
||||
"Use 3GPP TS 08.16\n"
|
||||
"Use 3GPP TS 48.016\n")
|
||||
{
|
||||
uint16_t nsei = atoi(argv[0]);
|
||||
struct gprs_nsvc *nsvc;
|
||||
|
||||
nsvc = gprs_nsvc_by_nsei(vty_nsi, nsei);
|
||||
if (!nsvc) {
|
||||
vty_out(vty, "No such NSE (%u)%s", nsei, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "ts08.16"))
|
||||
nsvc->compliance = GPRS_NS_TS_08_16;
|
||||
else
|
||||
nsvc->compliance = GPRS_NS_TS_48_016;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_no_nse, cfg_no_nse_cmd,
|
||||
"no nse <0-65535>",
|
||||
"Delete Persistent NS Entity\n"
|
||||
|
@ -591,6 +621,7 @@ int gprs_ns_vty_init(struct gprs_ns_inst *nsi)
|
|||
install_element(L_NS_NODE, &cfg_nse_fr_dlci_cmd);
|
||||
install_element(L_NS_NODE, &cfg_nse_encaps_cmd);
|
||||
install_element(L_NS_NODE, &cfg_nse_remoterole_cmd);
|
||||
install_element(L_NS_NODE, &cfg_nse_compliance_cmd);
|
||||
install_element(L_NS_NODE, &cfg_no_nse_cmd);
|
||||
install_element(L_NS_NODE, &cfg_ns_timer_cmd);
|
||||
install_element(L_NS_NODE, &cfg_nsip_local_ip_cmd);
|
||||
|
|
Loading…
Reference in New Issue