aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/src/gprs/gprs_subscriber.c110
1 files changed, 94 insertions, 16 deletions
diff --git a/openbsc/src/gprs/gprs_subscriber.c b/openbsc/src/gprs/gprs_subscriber.c
index 2f3ae96de..fd16fa3ef 100644
--- a/openbsc/src/gprs/gprs_subscriber.c
+++ b/openbsc/src/gprs/gprs_subscriber.c
@@ -182,6 +182,7 @@ static int gprs_subscr_handle_gsup_auth_res(struct gsm_subscriber *subscr,
}
sdata->auth_triplets_updated = 1;
+ sdata->error_cause = 0;
gprs_subscr_update_auth_info(subscr);
@@ -211,43 +212,119 @@ static int gprs_subscr_handle_gsup_upd_loc_res(struct gsm_subscriber *subscr,
}
subscr->authorized = 1;
+ subscr->sgsn_data->error_cause = 0;
gprs_subscr_update(subscr);
return 0;
}
+static int check_cause(int cause)
+{
+ switch (cause) {
+ case GMM_CAUSE_IMSI_UNKNOWN ... GMM_CAUSE_ILLEGAL_ME:
+ case GMM_CAUSE_GPRS_NOTALLOWED ... GMM_CAUSE_NO_GPRS_PLMN:
+ return EACCES;
+
+ case GMM_CAUSE_MSC_TEMP_NOTREACH ... GMM_CAUSE_CONGESTION:
+ return EAGAIN;
+
+ case GMM_CAUSE_SEM_INCORR_MSG ... GMM_CAUSE_PROTO_ERR_UNSPEC:
+ default:
+ return EINVAL;
+ }
+}
+
static int gprs_subscr_handle_gsup_auth_err(struct gsm_subscriber *subscr,
struct gprs_gsup_message *gsup_msg)
{
unsigned idx;
struct sgsn_subscriber_data *sdata = subscr->sgsn_data;
+ int cause_err;
- LOGP(DGPRS, LOGL_INFO,
- "Send authentication info has failed for IMSI %s with cause %d\n",
- gsup_msg->imsi, gsup_msg->cause);
+ cause_err = check_cause(gsup_msg->cause);
- /* Clear auth tuples */
- memset(sdata->auth_triplets, 0, sizeof(sdata->auth_triplets));
- for (idx = 0; idx < ARRAY_SIZE(sdata->auth_triplets); idx++)
- sdata->auth_triplets[idx].key_seq = GSM_KEY_SEQ_INVAL;
+ LOGMMCTXP(LOGL_DEBUG, subscr->sgsn_data->mm,
+ "Send authentication info has failed with cause %d, "
+ "handled as: %s\n",
+ gsup_msg->cause, strerror(cause_err));
+
+ switch (cause_err) {
+ case EACCES:
+ LOGMMCTXP(LOGL_NOTICE, subscr->sgsn_data->mm,
+ "GPRS send auth info req failed, access denied, "
+ "GMM cause = '%s' (%d)\n",
+ get_value_string(gsm48_gmm_cause_names, gsup_msg->cause),
+ gsup_msg->cause);
+ /* Clear auth tuples */
+ memset(sdata->auth_triplets, 0, sizeof(sdata->auth_triplets));
+ for (idx = 0; idx < ARRAY_SIZE(sdata->auth_triplets); idx++)
+ sdata->auth_triplets[idx].key_seq = GSM_KEY_SEQ_INVAL;
- subscr->authorized = 0;
+ subscr->authorized = 0;
+ sdata->error_cause = gsup_msg->cause;
+ gprs_subscr_update_auth_info(subscr);
+ break;
- gprs_subscr_update_auth_info(subscr);
- return 0;
+ case EAGAIN:
+ LOGMMCTXP(LOGL_NOTICE, subscr->sgsn_data->mm,
+ "GPRS send auth info req failed, GMM cause = '%s' (%d)\n",
+ get_value_string(gsm48_gmm_cause_names, gsup_msg->cause),
+ gsup_msg->cause);
+ break;
+
+ default:
+ case EINVAL:
+ LOGMMCTXP(LOGL_ERROR, subscr->sgsn_data->mm,
+ "GSUP protocol remote error, GMM cause = '%s' (%d)\n",
+ get_value_string(gsm48_gmm_cause_names, gsup_msg->cause),
+ gsup_msg->cause);
+ break;
+ }
+
+ return -gsup_msg->cause;
}
static int gprs_subscr_handle_gsup_upd_loc_err(struct gsm_subscriber *subscr,
struct gprs_gsup_message *gsup_msg)
{
- LOGP(DGPRS, LOGL_INFO,
- "Update location has failed for IMSI %s with cause %d\n",
- gsup_msg->imsi, gsup_msg->cause);
+ int cause_err;
- subscr->authorized = 0;
+ cause_err = check_cause(gsup_msg->cause);
- gprs_subscr_update(subscr);
- return 0;
+ LOGMMCTXP(LOGL_DEBUG, subscr->sgsn_data->mm,
+ "Update location has failed with cause %d, handled as: %s\n",
+ gsup_msg->cause, strerror(cause_err));
+
+ switch (cause_err) {
+ case EACCES:
+ LOGMMCTXP(LOGL_NOTICE, subscr->sgsn_data->mm,
+ "GPRS update location failed, access denied, "
+ "GMM cause = '%s' (%d)\n",
+ get_value_string(gsm48_gmm_cause_names, gsup_msg->cause),
+ gsup_msg->cause);
+
+ subscr->authorized = 0;
+ subscr->sgsn_data->error_cause = gsup_msg->cause;
+ gprs_subscr_update_auth_info(subscr);
+ break;
+
+ case EAGAIN:
+ LOGMMCTXP(LOGL_NOTICE, subscr->sgsn_data->mm,
+ "GPRS update location failed, GMM cause = '%s' (%d)\n",
+ get_value_string(gsm48_gmm_cause_names, gsup_msg->cause),
+ gsup_msg->cause);
+ break;
+
+ default:
+ case EINVAL:
+ LOGMMCTXP(LOGL_ERROR, subscr->sgsn_data->mm,
+ "GSUP protocol remote error, GMM cause = '%s' (%d)\n",
+ get_value_string(gsm48_gmm_cause_names, gsup_msg->cause),
+ gsup_msg->cause);
+ break;
+ }
+
+ return -gsup_msg->cause;
}
int gprs_subscr_rx_gsup_message(struct msgb *msg)
@@ -286,6 +363,7 @@ int gprs_subscr_rx_gsup_message(struct msgb *msg)
switch (gsup_msg.message_type) {
case GPRS_GSUP_MSGT_LOCATION_CANCEL_REQUEST:
+ subscr->sgsn_data->error_cause = 0;
gprs_subscr_put_and_cancel(subscr);
subscr = NULL;
break;