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
diff --git a/openbsc/src/gprs/gprs_subscriber.c b/openbsc/src/gprs/gprs_subscriber.c
index ab1aa4b..9fe6ad2 100644
--- a/openbsc/src/gprs/gprs_subscriber.c
+++ b/openbsc/src/gprs/gprs_subscriber.c
@@ -227,7 +227,7 @@
 		return EACCES;
 
 	case GMM_CAUSE_MSC_TEMP_NOTREACH ... GMM_CAUSE_CONGESTION:
-		return EAGAIN;
+		return EHOSTUNREACH;
 
 	case GMM_CAUSE_SEM_INCORR_MSG ... GMM_CAUSE_PROTO_ERR_UNSPEC:
 	default:
@@ -266,11 +266,14 @@
 		gprs_subscr_update_auth_info(subscr);
 		break;
 
-	case EAGAIN:
+	case EHOSTUNREACH:
 		LOGGSUBSCRP(LOGL_NOTICE, subscr,
 			"GPRS send auth info req failed, GMM cause = '%s' (%d)\n",
 			get_value_string(gsm48_gmm_cause_names, gsup_msg->cause),
 			gsup_msg->cause);
+
+		sdata->error_cause = gsup_msg->cause;
+		gprs_subscr_update_auth_info(subscr);
 		break;
 
 	default:
@@ -309,11 +312,14 @@
 		gprs_subscr_update_auth_info(subscr);
 		break;
 
-	case EAGAIN:
+	case EHOSTUNREACH:
 		LOGGSUBSCRP(LOGL_NOTICE, subscr,
 			"GPRS update location failed, GMM cause = '%s' (%d)\n",
 			get_value_string(gsm48_gmm_cause_names, gsup_msg->cause),
 			gsup_msg->cause);
+
+		subscr->sgsn_data->error_cause = gsup_msg->cause;
+		gprs_subscr_update_auth_info(subscr);
 		break;
 
 	default: