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.
---
 openbsc/include/openbsc/transaction.h |  1 +
 openbsc/src/libbsc/bsc_api.c          |  2 +-
 openbsc/src/libmsc/gsm_04_08.c        | 14 ++++++++++----
 openbsc/src/libmsc/transaction.c      |  9 +++++++--
 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 504f044..54083f3 100644
--- a/openbsc/src/libbsc/bsc_api.c
+++ b/openbsc/src/libbsc/bsc_api.c
@@ -830,7 +830,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 5dd9247..94d186d 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -58,6 +58,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>
@@ -410,7 +411,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;
                }
        }
@@ -1399,16 +1400,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);
-- 
1.9.1

Reply via email to