aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/gsm_04_08.h53
-rw-r--r--openbsc/src/gsm_04_08.c28
-rw-r--r--openbsc/src/mncc.c15
3 files changed, 83 insertions, 13 deletions
diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h
index d83d67bd5..2fe23d1fc 100644
--- a/openbsc/include/openbsc/gsm_04_08.h
+++ b/openbsc/include/openbsc/gsm_04_08.h
@@ -482,6 +482,59 @@ enum gsm48_rr_cause {
GSM48_RR_CAUSE_PROT_ERROR_UNSPC = 0x6f,
};
+/* Section 10.5.4.11 CC Cause / Table 10.5.123 */
+enum gsm48_cc_cause {
+ GSM48_CC_CAUSE_UNASSIGNED_NR = 1,
+ GSM48_CC_CAUSE_NO_ROUTE = 3,
+ GSM48_CC_CAUSE_CHAN_UNACCEPT = 6,
+ GSM48_CC_CAUSE_OP_DET_BARRING = 8,
+ GSM48_CC_CAUSE_NORM_CALL_CLEAR = 16,
+ GSM48_CC_CAUSE_USER_BUSY = 17,
+ GSM48_CC_CAUSE_USER_NOTRESPOND = 18,
+ GSM48_CC_CAUSE_USER_ALERTING_NA = 19,
+ GSM48_CC_CAUSE_CALL_REJECTED = 21,
+ GSM48_CC_CAUSE_NUMBER_CHANGED = 22,
+ GSM48_CC_CAUSE_PRE_EMPTION = 25,
+ GSM48_CC_CAUSE_NONSE_USER_CLR = 26,
+ GSM48_CC_CAUSE_DEST_OOO = 27,
+ GSM48_CC_CAUSE_INV_NR_FORMAT = 28,
+ GSM48_CC_CAUSE_FACILITY_REJ = 29,
+ GSM48_CC_CAUSE_RESP_STATUS_INQ = 30,
+ GSM48_CC_CAUSE_NORMAL_UNSPEC = 31,
+ GSM48_CC_CAUSE_NO_CIRCUIT_CHAN = 34,
+ GSM48_CC_CAUSE_NETWORK_OOO = 38,
+ GSM48_CC_CAUSE_TEMP_FAILURE = 41,
+ GSM48_CC_CAUSE_SWITCH_CONG = 42,
+ GSM48_CC_CAUSE_ACC_INF_DISCARD = 43,
+ GSM48_CC_CAUSE_REQ_CHAN_UNAVAIL = 44,
+ GSM48_CC_CAUSE_RESOURCE_UNAVAIL = 47,
+ GSM48_CC_CAUSE_QOS_UNAVAIL = 49,
+ GSM48_CC_CAUSE_REQ_FAC_NOT_SUBSC= 50,
+ GSM48_CC_CAUSE_INC_BARRED_CUG = 55,
+ GSM48_CC_CAUSE_BEARER_CAP_UNAUTH= 57,
+ GSM48_CC_CAUSE_BEARER_CA_UNAVAIL= 58,
+ GSM48_CC_CAUSE_SERV_OPT_UNAVAIL = 63,
+ GSM48_CC_CAUSE_BEARERSERV_UNIMPL= 65,
+ GSM48_CC_CAUSE_ACM_GE_ACM_MAX = 68,
+ GSM48_CC_CAUSE_REQ_FAC_NOTIMPL = 69,
+ GSM48_CC_CAUSE_RESTR_BCAP_AVAIL = 70,
+ GSM48_CC_CAUSE_SERV_OPT_UNIMPL = 79,
+ GSM48_CC_CAUSE_INVAL_TRANS_ID = 81,
+ GSM48_CC_CAUSE_USER_NOT_IN_CUG = 87,
+ GSM48_CC_CAUSE_INCOMPAT_DEST = 88,
+ GSM48_CC_CAUSE_INVAL_TRANS_NET = 91,
+ GSM48_CC_CAUSE_SEMANTIC_INCORR = 95,
+ GSM48_CC_CAUSE_INVAL_MAND_INF = 96,
+ GSM48_CC_CAUSE_MSGTYPE_NOTEXIST = 97,
+ GSM48_CC_CAUSE_MSGTYPE_INCOMPAT = 98,
+ GSM48_CC_CAUSE_IE_NOTEXIST = 99,
+ GSM48_CC_CAUSE_COND_IE_ERR = 100,
+ GSM48_CC_CAUSE_MSG_INCOMP_STATE = 101,
+ GSM48_CC_CAUSE_RECOVERY_TIMER = 102,
+ GSM48_CC_CAUSE_PROTO_ERR = 111,
+ GSM48_CC_CAUSE_INTERWORKING = 127,
+};
+
/* Annex G, GSM specific cause values for mobility management */
enum gsm48_reject_value {
GSM48_REJECT_IMSI_UNKNOWN_IN_HLR = 2,
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index 3aaa0f53c..367f7fa70 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -1867,7 +1867,8 @@ int mncc_release_ind(struct gsm_network *net, struct gsm_trans *trans,
memset(&rel, 0, sizeof(&rel));
rel.callref = callref;
- mncc_set_cause(&rel, 1, 1); /* Unknown subscriber */
+ mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU,
+ GSM48_CC_CAUSE_UNASSIGNED_NR);
return mncc_recvmsg(net, trans, MNCC_REL_IND, &rel);
}
@@ -2086,8 +2087,10 @@ static void gsm48_cc_timeout(void *arg)
{
struct gsm_trans *trans = arg;
int disconnect = 0, release = 0;
- int mo_cause = 102, mo_location = 0;
- int l4_cause = 31, l4_location = 1;
+ int mo_cause = GSM48_CC_CAUSE_RECOVERY_TIMER;
+ int mo_location = GSM48_CAUSE_LOC_USER;
+ int l4_cause = GSM48_CC_CAUSE_NORMAL_UNSPEC;
+ int l4_location = GSM48_CAUSE_LOC_PRN_S_LU;
struct gsm_mncc mo_rel, l4_rel;
memset(&mo_rel, 0, sizeof(struct gsm_mncc));
@@ -2098,11 +2101,11 @@ static void gsm48_cc_timeout(void *arg)
switch(trans->Tcurrent) {
case 0x303:
release = 1;
- l4_cause = 18;
+ l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
break;
case 0x310:
disconnect = 1;
- l4_cause = 18;
+ l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
break;
case 0x313:
disconnect = 1;
@@ -2110,7 +2113,7 @@ static void gsm48_cc_timeout(void *arg)
break;
case 0x301:
disconnect = 1;
- l4_cause = 19;
+ l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
break;
case 0x308:
if (!trans->T308_second) {
@@ -2628,7 +2631,15 @@ static int gsm48_cc_rx_disconnect(struct gsm_trans *trans, struct msgb *msg)
}
-static struct gsm_mncc_cause default_cause = { 1, 0, 0, 0, 31, 0, { 0 } };
+static struct gsm_mncc_cause default_cause = {
+ .location = GSM48_CAUSE_LOC_PRN_S_LU,
+ .coding = 0,
+ .rec = 0,
+ .rec_val = 0,
+ .value = GSM48_CC_CAUSE_NORMAL_UNSPEC,
+ .diag_len = 0,
+ .diag = { 0 },
+};
static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg)
{
@@ -3463,7 +3474,8 @@ int mncc_send(struct gsm_network *net, int msg_type, void *arg)
"Received '%s' from MNCC in paging state\n",
(trans->subscr)?(trans->subscr->extension):"-",
get_mncc_name(msg_type));
- mncc_set_cause(&rel, 1, 16); /* Normal call clearing */
+ mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU,
+ GSM48_CC_CAUSE_NORM_CALL_CLEAR);
if (msg_type == MNCC_REL_REQ)
rc = mncc_recvmsg(net, trans, MNCC_REL_CNF, &rel);
else
diff --git a/openbsc/src/mncc.c b/openbsc/src/mncc.c
index 8f93b3f68..4282aaf3c 100644
--- a/openbsc/src/mncc.c
+++ b/openbsc/src/mncc.c
@@ -140,7 +140,8 @@ static int mncc_setup_ind(struct gsm_call *call, int msg_type,
if (!(remote = calloc(1, sizeof(struct gsm_call)))) {
memset(&mncc, 0, sizeof(struct gsm_mncc));
mncc.callref = call->callref;
- mncc_set_cause(&mncc, 1, 47);
+ mncc_set_cause(&mncc, GSM48_CAUSE_LOC_PRN_S_LU,
+ GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
mncc_send(call->net, MNCC_REJ_REQ, &mncc);
free_call(call);
return 0;
@@ -304,7 +305,8 @@ int mncc_recv(struct gsm_network *net, int msg_type, void *arg)
memset(&rel, 0, sizeof(struct gsm_mncc));
rel.callref = callref;
- mncc_set_cause(&rel, 1, 47);
+ mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU,
+ GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
mncc_send(net, MNCC_REL_REQ, &rel);
return 0;
}
@@ -354,7 +356,8 @@ int mncc_recv(struct gsm_network *net, int msg_type, void *arg)
case MNCC_STOP_DTMF_IND:
break;
case MNCC_MODIFY_IND:
- mncc_set_cause(data, 1, 79);
+ mncc_set_cause(data, GSM48_CAUSE_LOC_PRN_S_LU,
+ GSM48_CC_CAUSE_SERV_OPT_UNIMPL);
DEBUGP(DMNCC, "(call %x) Rejecting MODIFY with cause %d\n",
call->callref, data->cause.value);
rc = mncc_send(net, MNCC_MODIFY_REJ, data);
@@ -362,13 +365,15 @@ int mncc_recv(struct gsm_network *net, int msg_type, void *arg)
case MNCC_MODIFY_CNF:
break;
case MNCC_HOLD_IND:
- mncc_set_cause(data, 1, 79);
+ mncc_set_cause(data, GSM48_CAUSE_LOC_PRN_S_LU,
+ GSM48_CC_CAUSE_SERV_OPT_UNIMPL);
DEBUGP(DMNCC, "(call %x) Rejecting HOLD with cause %d\n",
call->callref, data->cause.value);
rc = mncc_send(net, MNCC_HOLD_REJ, data);
break;
case MNCC_RETRIEVE_IND:
- mncc_set_cause(data, 1, 79);
+ mncc_set_cause(data, GSM48_CAUSE_LOC_PRN_S_LU,
+ GSM48_CC_CAUSE_SERV_OPT_UNIMPL);
DEBUGP(DMNCC, "(call %x) Rejecting RETRIEVE with cause %d\n",
call->callref, data->cause.value);
rc = mncc_send(net, MNCC_RETRIEVE_REJ, data);