gprs: Pass GMM causes related to the MSC connection

Currently the error causes MSC_TEMP_NOTREACH, NET_FAIL, and
CONGESTION are silently dropped to force the MS to continue. On the
other hand, GSM 04.08/24.008, 4.7.3.1.4 in combination with 4.7.3.1.5,
require the MS to retry the attachment procedure for cause codes
above 15 instead of disabling GPRS. All of the mentioned GMM causes
have codes above 15, so using a REJECT message including the cause
code is a better choice. This way, the retry algorithm based on T3311
(15s, 5 times) and T3302 (default 12min) could be used.

This patch modifies gprs_subscr_handle_gsup_auth_err and
gprs_subscr_handle_gsup_upd_loc_err to proceed like when the access
has beed denied, except that the corresponding subscriber's
information fields are not cleared.

This has been successfully tested which an iphone which enters a
retry loop as it is being described in the specification.

Sponsored-by: On-Waves ehf
This commit is contained in:
Jacob Erlbeck
2015-01-05 16:20:47 +01:00
committed by Holger Hans Peter Freyther
parent bf34c67f3f
commit f06fe29f61

View File

@@ -227,7 +227,7 @@ static int check_cause(int cause)
return EACCES; return EACCES;
case GMM_CAUSE_MSC_TEMP_NOTREACH ... GMM_CAUSE_CONGESTION: case GMM_CAUSE_MSC_TEMP_NOTREACH ... GMM_CAUSE_CONGESTION:
return EAGAIN; return EHOSTUNREACH;
case GMM_CAUSE_SEM_INCORR_MSG ... GMM_CAUSE_PROTO_ERR_UNSPEC: case GMM_CAUSE_SEM_INCORR_MSG ... GMM_CAUSE_PROTO_ERR_UNSPEC:
default: default:
@@ -266,11 +266,14 @@ static int gprs_subscr_handle_gsup_auth_err(struct gsm_subscriber *subscr,
gprs_subscr_update_auth_info(subscr); gprs_subscr_update_auth_info(subscr);
break; break;
case EAGAIN: case EHOSTUNREACH:
LOGGSUBSCRP(LOGL_NOTICE, subscr, LOGGSUBSCRP(LOGL_NOTICE, subscr,
"GPRS send auth info req failed, GMM cause = '%s' (%d)\n", "GPRS send auth info req failed, GMM cause = '%s' (%d)\n",
get_value_string(gsm48_gmm_cause_names, gsup_msg->cause), get_value_string(gsm48_gmm_cause_names, gsup_msg->cause),
gsup_msg->cause); gsup_msg->cause);
sdata->error_cause = gsup_msg->cause;
gprs_subscr_update_auth_info(subscr);
break; break;
default: default:
@@ -309,11 +312,14 @@ static int gprs_subscr_handle_gsup_upd_loc_err(struct gsm_subscriber *subscr,
gprs_subscr_update_auth_info(subscr); gprs_subscr_update_auth_info(subscr);
break; break;
case EAGAIN: case EHOSTUNREACH:
LOGGSUBSCRP(LOGL_NOTICE, subscr, LOGGSUBSCRP(LOGL_NOTICE, subscr,
"GPRS update location failed, GMM cause = '%s' (%d)\n", "GPRS update location failed, GMM cause = '%s' (%d)\n",
get_value_string(gsm48_gmm_cause_names, gsup_msg->cause), get_value_string(gsm48_gmm_cause_names, gsup_msg->cause),
gsup_msg->cause); gsup_msg->cause);
subscr->sgsn_data->error_cause = gsup_msg->cause;
gprs_subscr_update_auth_info(subscr);
break; break;
default: default: