aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/tests/sgsn/sgsn_test.c
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2015-01-08 16:23:25 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2015-01-20 16:12:33 +0100
commitf81cacc6814dde73f203d125b0065d1451a98317 (patch)
tree4cc0642f3b953433a5064d4992dbdad51a67c4ac /openbsc/tests/sgsn/sgsn_test.c
parent743dec4c0c80383556efac60f03d307287ecf024 (diff)
gprs: Block other GSUP procedures during PURGE_MS
GSM 09.02, 19.4.1.4 mandates that no other MAP procedures shall be started until the PURGE_MS procedure has been completed. This patch implements this by adding corresponding state and checks to gprs_subscr_purge, gprs_subscr_location_update, and gprs_subscr_update_auth_info. If an Update Location or a Send Auth Info Req procedure is not started because of blocking, the retry mechanism is aborted to shorten the blocking time. The outstanding Purge MS procedure itself is not aborted. Sponsored-by: On-Waves ehf
Diffstat (limited to 'openbsc/tests/sgsn/sgsn_test.c')
-rw-r--r--openbsc/tests/sgsn/sgsn_test.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c
index 818106190..d419f0a92 100644
--- a/openbsc/tests/sgsn/sgsn_test.c
+++ b/openbsc/tests/sgsn/sgsn_test.c
@@ -546,6 +546,97 @@ static void test_subscriber_gsup(void)
update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
}
+int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
+{
+ msgb_free(msg);
+ return 0;
+};
+
+
+static void test_subscriber_blocking(void)
+{
+ struct gsm_subscriber *s1;
+ const char *imsi1 = "1234567890";
+ struct sgsn_mm_ctx *ctx;
+ struct gprs_ra_id raid = { 0, };
+ uint32_t local_tlli = 0xffeeddcc;
+ struct gprs_llc_llme *llme;
+ int rc;
+
+ printf("Testing subcriber procedure blocking\n");
+
+ gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
+ sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
+
+ /* Check for emptiness */
+ OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
+
+ /* Create a context */
+ OSMO_ASSERT(count(gprs_llme_list()) == 0);
+ ctx = alloc_mm_ctx(local_tlli, &raid);
+ llme = ctx->llme;
+ strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
+
+ /* Allocate and attach a subscriber */
+ s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
+ assert_subscr(s1, imsi1);
+
+ /* Start SendAuthInfoRequest procedure */
+ rc = gprs_subscr_query_auth_info(s1);
+ /* Not blocking */
+ OSMO_ASSERT(rc == 0);
+
+ /* Start UpdateLocation procedure */
+ rc = gprs_subscr_location_update(s1);
+ /* Blocking */
+ OSMO_ASSERT(rc == 0);
+
+ /* Start PurgeMS procedure */
+ rc = gprs_subscr_purge(s1);
+ /* Not blocking */
+ OSMO_ASSERT(rc == 0);
+ OSMO_ASSERT(s1->sgsn_data->blocked_by == SGSN_SUBSCR_PROC_PURGE);
+
+ /* Start PurgeMS procedure (retry) */
+ rc = gprs_subscr_purge(s1);
+ /* Not blocking */
+ OSMO_ASSERT(rc == 0);
+
+ /* Start SendAuthInfoRequest procedure */
+ rc = gprs_subscr_query_auth_info(s1);
+ /* Blocking */
+ OSMO_ASSERT(rc == -EAGAIN);
+
+ /* Start UpdateLocation procedure */
+ rc = gprs_subscr_location_update(s1);
+ /* Blocking */
+ OSMO_ASSERT(rc == -EAGAIN);
+
+ /* Unblock manually (normally done by the caller of gprs_subscr_purge) */
+ s1->sgsn_data->blocked_by = SGSN_SUBSCR_PROC_NONE;
+
+ /* Start SendAuthInfoRequest procedure */
+ rc = gprs_subscr_query_auth_info(s1);
+ /* Not blocking */
+ OSMO_ASSERT(rc == 0);
+
+ /* Start UpdateLocation procedure */
+ rc = gprs_subscr_location_update(s1);
+ /* Blocking */
+ OSMO_ASSERT(rc == 0);
+
+ subscr_put(s1);
+ sgsn_mm_ctx_free(ctx);
+ gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
+
+ assert_no_subscrs();
+
+ gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
+ talloc_free(sgsn->gsup_client);
+ sgsn->gsup_client = NULL;
+}
+
+
/*
* Test that a GMM Detach will remove the MMCTX and the
* associated LLME.
@@ -1710,6 +1801,7 @@ int main(int argc, char **argv)
test_subscriber();
test_auth_triplets();
test_subscriber_gsup();
+ test_subscriber_blocking();
test_gmm_detach();
test_gmm_detach_power_off();
test_gmm_detach_no_mmctx();