summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Chemeris <Alexander.Chemeris@gmail.com>2015-09-12 20:25:09 -0400
committerAlexander Chemeris <Alexander.Chemeris@gmail.com>2015-09-12 20:36:00 -0400
commit45450b9214a01351ad88710430b43884fa161243 (patch)
tree4932f96e3396a9ff3b49238d63ce6eb2d7b668c0
parente98086dad536f6415da387db5de32b1c146be9f2 (diff)
mncc: Send "Dest OOO" cause in case of a link radio failure.achemeris/mncc_cause_fixes_master
Previously we were sending a generic "Resource unavailable" cause code making it impossible to distinguish real error cases from a regular radio link failure. This was the reason for many "unknown" call errors we've seen at Rhizomatica installations. Now they are properly classified as non-erroneous call failures.
-rw-r--r--openbsc/include/openbsc/transaction.h1
-rw-r--r--openbsc/src/libbsc/bsc_api.c2
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c14
-rw-r--r--openbsc/src/libmsc/transaction.c9
4 files changed, 19 insertions, 7 deletions
diff --git a/openbsc/include/openbsc/transaction.h b/openbsc/include/openbsc/transaction.h
index 6ef1612..303ef6e 100644
--- a/openbsc/include/openbsc/transaction.h
+++ b/openbsc/include/openbsc/transaction.h
@@ -70,6 +70,7 @@ struct gsm_trans *trans_alloc(struct gsm_network *net,
struct gsm_subscriber *subscr,
uint8_t protocol, uint8_t trans_id,
uint32_t callref);
+void trans_free_cause(struct gsm_trans *trans, int gsm0808_cause);
void trans_free(struct gsm_trans *trans);
int trans_assign_trans_id(struct gsm_network *net, struct gsm_subscriber *subscr,
diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c
index 76ceb2d..0afce2f 100644
--- a/openbsc/src/libbsc/bsc_api.c
+++ b/openbsc/src/libbsc/bsc_api.c
@@ -816,7 +816,7 @@ static void handle_release(struct gsm_subscriber_connection *conn,
/* clear the connection now */
if (bsc->clear_request)
- destruct = bsc->clear_request(conn, 0);
+ destruct = bsc->clear_request(conn, GSM0808_CAUSE_RADIO_INTERFACE_FAILURE);
/* now give up all channels */
if (conn->lchan == lchan)
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 01f1391..13e4297 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -57,6 +57,7 @@
#include <osmocom/gsm/gsm48.h>
#include <osmocom/gsm/gsm0480.h>
+#include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/talloc.h>
@@ -407,7 +408,7 @@ void gsm0408_clear_request(struct gsm_subscriber_connection *conn, uint32_t caus
restart:
llist_for_each_entry_safe(trans, temp, &conn->bts->network->trans_list, entry) {
if (trans->conn == conn) {
- trans_free(trans);
+ trans_free_cause(trans, cause);
goto restart;
}
}
@@ -1396,16 +1397,21 @@ int mncc_release_ind(struct gsm_network *net, struct gsm_trans *trans,
/* Call Control Specific transaction release.
* gets called by trans_free, DO NOT CALL YOURSELF! */
-void _gsm48_cc_trans_free(struct gsm_trans *trans)
+void _gsm48_cc_trans_free(struct gsm_trans *trans, int gsm0808_cause)
{
gsm48_stop_cc_timer(trans);
/* send release to L4, if callref still exists */
if (trans->callref) {
- /* Ressource unavailable */
+ /* Release CC connection */
+ int cc_cause = GSM48_CC_CAUSE_RESOURCE_UNAVAIL;
+ if (gsm0808_cause == GSM0808_CAUSE_RADIO_INTERFACE_FAILURE)
+ {
+ cc_cause = GSM48_CC_CAUSE_DEST_OOO;
+ }
mncc_release_ind(trans->net, trans, trans->callref,
GSM48_CAUSE_LOC_PRN_S_LU,
- GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
+ cc_cause);
}
if (trans->cc.state != GSM_CSTATE_NULL)
new_cc_state(trans, GSM_CSTATE_NULL);
diff --git a/openbsc/src/libmsc/transaction.c b/openbsc/src/libmsc/transaction.c
index a750362..95939d3 100644
--- a/openbsc/src/libmsc/transaction.c
+++ b/openbsc/src/libmsc/transaction.c
@@ -31,7 +31,7 @@
void *tall_trans_ctx;
-void _gsm48_cc_trans_free(struct gsm_trans *trans);
+void _gsm48_cc_trans_free(struct gsm_trans *trans, int gsm0808_cause);
struct gsm_trans *trans_find_by_id(struct gsm_subscriber_connection *conn,
uint8_t proto, uint8_t trans_id)
@@ -89,9 +89,14 @@ struct gsm_trans *trans_alloc(struct gsm_network *net,
void trans_free(struct gsm_trans *trans)
{
+ trans_free_cause(trans, -1);
+}
+
+void trans_free_cause(struct gsm_trans *trans, int gsm0808_cause)
+{
switch (trans->protocol) {
case GSM48_PDISC_CC:
- _gsm48_cc_trans_free(trans);
+ _gsm48_cc_trans_free(trans, gsm0808_cause);
break;
case GSM48_PDISC_SMS:
_gsm411_sms_trans_free(trans);