diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-10-07 14:12:30 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2014-10-09 07:52:43 +0200 |
commit | 6ac70a41ee4cc9f3f286fb6b8f397215590fc2ac (patch) | |
tree | c8dbbb3a7a577178a663ada1e5c57225dea36e0e /src | |
parent | 0540d839ace7811257793c383275b929768175a5 (diff) |
gprs-ns: Fix reset state handling
Currently the NS-VC's state is updated from within gprs_ns_tx_reset,
which can lead to an inconsistent state when the RESET_ACK is lost.
In this state, the NSE_S_RESET bit is set but the Tns-reset timer is
not started.
This patch moves the state update into gprs_nsvc_reset. This way, the
state flags are consistent with the timer.
Addresses:
SGSN -> BSS NS_ALIVE
BSS -> SGSN NS_ALIVE_ACK
BSS -> SGSN BVC_RESET
SGSN -> BSS NS_STATUS, Cause: NS-VC blocked, NS VCI: 0x65
and there is no BSS->SGSN NS_ALIVE
Ticket: OW#1213
Sponsored-by: On-Waves ehf
Diffstat (limited to 'src')
-rw-r--r-- | src/gb/gprs_ns.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c index cf7adaf1..65d04947 100644 --- a/src/gb/gprs_ns.c +++ b/src/gb/gprs_ns.c @@ -348,8 +348,6 @@ int gprs_ns_tx_reset(struct gprs_nsvc *nsvc, uint8_t cause) LOGP(DNS, LOGL_INFO, "NSEI=%u Tx NS RESET (NSVCI=%u, cause=%s)\n", nsvc->nsei, nsvc->nsvci, gprs_ns_cause_str(cause)); - nsvc->state |= NSE_S_RESET; - msg->l2h = msgb_put(msg, sizeof(*nsh)); nsh = (struct gprs_ns_hdr *) msg->l2h; nsh->pdu_type = NS_PDUT_RESET; @@ -1250,8 +1248,8 @@ int gprs_ns_process_msg(struct gprs_ns_inst *nsi, struct msgb *msg, * and should send a NS-RESET to make sure everything recovers * fine. */ if ((*nsvc)->state == NSE_S_BLOCKED) - rc = gprs_ns_tx_reset((*nsvc), NS_CAUSE_PDU_INCOMP_PSTATE); - else + rc = gprs_nsvc_reset((*nsvc), NS_CAUSE_PDU_INCOMP_PSTATE); + else if (!((*nsvc)->state & NSE_S_RESET)) rc = gprs_ns_tx_alive_ack(*nsvc); break; case NS_PDUT_ALIVE_ACK: @@ -1503,7 +1501,8 @@ int gprs_nsvc_reset(struct gprs_nsvc *nsvc, uint8_t cause) nsvc->nsei); /* Mark NS-VC locally as blocked and dead */ - nsvc->state = NSE_S_BLOCKED; + nsvc->state = NSE_S_BLOCKED | NSE_S_RESET; + /* Send NS-RESET PDU */ rc = gprs_ns_tx_reset(nsvc, cause); if (rc < 0) { |