aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2010-05-14 11:53:08 +0000
committerHarald Welte <laforge@gnumonks.org>2010-05-14 11:53:08 +0000
commit1ccbf44d79544689e47b704f1f714a7bff63c1cf (patch)
treeadf4dec2ec07fa7e580b1b30d395d42413d27ec9
parent768f2871a5b1c6639b480816557618ee22ee2e3b (diff)
[GPRS] gb_proxy: Initiate RESET procedure on persistent NS-VC at startup
Some BSS that connect to the proxy do not continue to perform the RESET procedure after a timeout. In order to resurrect them, we simply start a RESET procedure.
-rw-r--r--openbsc/include/openbsc/gb_proxy.h4
-rw-r--r--openbsc/include/openbsc/gprs_ns.h3
-rw-r--r--openbsc/src/gprs/gb_proxy.c12
-rw-r--r--openbsc/src/gprs/gb_proxy_main.c4
-rw-r--r--openbsc/src/gprs/gprs_ns.c33
5 files changed, 41 insertions, 15 deletions
diff --git a/openbsc/include/openbsc/gb_proxy.h b/openbsc/include/openbsc/gb_proxy.h
index db236b5d0..8979aac84 100644
--- a/openbsc/include/openbsc/gb_proxy.h
+++ b/openbsc/include/openbsc/gb_proxy.h
@@ -39,4 +39,8 @@ int gbprox_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci);
int gbprox_signal(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data);
+
+/* Reset all persistent NS-VC's */
+int gbprox_reset_persistent_nsvcs(struct gprs_ns_inst *nsi);
+
#endif
diff --git a/openbsc/include/openbsc/gprs_ns.h b/openbsc/include/openbsc/gprs_ns.h
index 4ccf4c7b9..24a797450 100644
--- a/openbsc/include/openbsc/gprs_ns.h
+++ b/openbsc/include/openbsc/gprs_ns.h
@@ -209,6 +209,9 @@ struct gprs_nsvc *nsvc_create(struct gprs_ns_inst *nsi, uint16_t nsvci);
void nsvc_delete(struct gprs_nsvc *nsvc);
struct gprs_nsvc *nsvc_by_nsei(struct gprs_ns_inst *nsi, uint16_t nsei);
+/* Initiate a RESET procedure (including timer start, ...)*/
+int gprs_nsvc_reset(struct gprs_nsvc *nsvc, uint8_t cause);
+
/* Add NS-specific VTY stuff */
int gprs_ns_vty_init(struct gprs_ns_inst *nsi);
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index 5fbf9bfcc..1fe9e9662 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -507,6 +507,18 @@ int gbprox_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci)
return rc;
}
+int gbprox_reset_persistent_nsvcs(struct gprs_ns_inst *nsi)
+{
+ struct gprs_nsvc *nsvc;
+
+ llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
+ if (!nsvc->persistent)
+ continue;
+ gprs_nsvc_reset(nsvc, NS_CAUSE_OM_INTERVENTION);
+ }
+ return 0;
+}
+
/* Signal handler for signals from NS layer */
int gbprox_signal(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
diff --git a/openbsc/src/gprs/gb_proxy_main.c b/openbsc/src/gprs/gb_proxy_main.c
index f6260bf2d..de83186f3 100644
--- a/openbsc/src/gprs/gb_proxy_main.c
+++ b/openbsc/src/gprs/gb_proxy_main.c
@@ -237,6 +237,10 @@ int main(int argc, char **argv)
nsip_connect(bssgp_nsi, &sin, gbcfg.nsip_sgsn_nsei,
gbcfg.nsip_sgsn_nsvci);
+
+ /* Reset all the persistent NS-VCs that we've read from the config */
+ gbprox_reset_persistent_nsvcs(bssgp_nsi);
+
while (1) {
rc = bsc_select_main(0);
if (rc < 0)
diff --git a/openbsc/src/gprs/gprs_ns.c b/openbsc/src/gprs/gprs_ns.c
index dc12953e0..6a6cfe154 100644
--- a/openbsc/src/gprs/gprs_ns.c
+++ b/openbsc/src/gprs/gprs_ns.c
@@ -720,7 +720,7 @@ int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
nsvc->state = NSE_S_BLOCKED | NSE_S_ALIVE;
nsvc->remote_state = NSE_S_BLOCKED | NSE_S_ALIVE;
rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_BLOCKED]);
- if (nsvc->remote_end_is_sgsn) {
+ if (nsvc->persistent || nsvc->remote_end_is_sgsn) {
/* stop RESET timer */
bsc_del_timer(&nsvc->timer);
/* Initiate TEST proc.: Send ALIVE and start timer */
@@ -894,6 +894,22 @@ int nsip_listen(struct gprs_ns_inst *nsi, uint16_t udp_port)
return ret;
}
+/* Initiate a RESET procedure */
+int gprs_nsvc_reset(struct gprs_nsvc *nsvc, uint8_t cause)
+{
+ /* Mark NS-VC locally as blocked and dead */
+ nsvc->state = NSE_S_BLOCKED;
+ /* Send NS-RESET PDU */
+ if (gprs_ns_tx_reset(nsvc, cause) < 0) {
+ LOGP(DNS, LOGL_ERROR, "NSEI=%u, error resetting NS-VC\n",
+ nsvc->nsei);
+ }
+ /* Start Tns-reset */
+ nsvc_start_timer(nsvc, NSVC_TIMER_TNS_RESET);
+
+ return nsvc;
+}
+
/* Establish a connection (from the BSS) to the SGSN */
struct gprs_nsvc *nsip_connect(struct gprs_ns_inst *nsi,
struct sockaddr_in *dest, uint16_t nsei,
@@ -909,18 +925,5 @@ struct gprs_nsvc *nsip_connect(struct gprs_ns_inst *nsi,
nsvc->nsvci = nsvci;
nsvc->remote_end_is_sgsn = 1;
- /* Initiate a RESET procedure */
- /* Mark NS-VC locally as blocked and dead */
- nsvc->state = NSE_S_BLOCKED;
- /* Send NS-RESET PDU */
- if (gprs_ns_tx_reset(nsvc, NS_CAUSE_OM_INTERVENTION) < 0) {
- LOGP(DNS, LOGL_ERROR, "NSEI=%u, error resetting NS-VC\n",
- nsei);
- }
- /* Start Tns-reset */
- nsvc_start_timer(nsvc, NSVC_TIMER_TNS_RESET);
-
- return nsvc;
+ return gprs_nsvc_reset(nsvc, NS_CAUSE_OM_INTERVENTION);
}
-
-