diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 5cd5afc4d..30c1191d7 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -31,6 +31,7 @@ noinst_HEADERS = \ gprs_sndcp_dcomp.h \ gprs_sndcp_pcomp.h \ gprs_sndcp_xid.h \ + gprs_subscriber.h \ gprs_utils.h \ gsm_04_08.h \ gsm_04_11.h \ diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index 2cc5b0c7e..c3cac7f2a 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -18,7 +18,7 @@ struct gprs_llc_lle; struct ctrl_handle; -struct gsm_subscriber; +struct gprs_subscr; enum gsm48_gsm_cause; @@ -225,7 +225,7 @@ struct sgsn_mm_ctx { /* the current GGSN look-up operation */ struct sgsn_ggsn_lookup *ggsn_lookup; - struct gsm_subscriber *subscr; + struct gprs_subscr *subscr; }; #define LOGMMCTXP(level, mm, fmt, args...) \ @@ -433,6 +433,7 @@ struct gsm_auth_tuple *sgsn_auth_get_tuple(struct sgsn_mm_ctx *mmctx, /* * GPRS subscriber data */ +#define GPRS_SUBSCRIBER_FIRST_CONTACT 0x00000001 #define GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING (1 << 16) #define GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING (1 << 17) #define GPRS_SUBSCRIBER_CANCELLED (1 << 18) @@ -446,13 +447,13 @@ struct gsm_auth_tuple *sgsn_auth_get_tuple(struct sgsn_mm_ctx *mmctx, int gprs_subscr_init(struct sgsn_instance *sgi); int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx); int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx); -void gprs_subscr_cleanup(struct gsm_subscriber *subscr); -struct gsm_subscriber *gprs_subscr_get_or_create(const char *imsi); -struct gsm_subscriber *gprs_subscr_get_or_create_by_mmctx( struct sgsn_mm_ctx *mmctx); -struct gsm_subscriber *gprs_subscr_get_by_imsi(const char *imsi); -void gprs_subscr_cancel(struct gsm_subscriber *subscr); -void gprs_subscr_update(struct gsm_subscriber *subscr); -void gprs_subscr_update_auth_info(struct gsm_subscriber *subscr); +void gprs_subscr_cleanup(struct gprs_subscr *subscr); +struct gprs_subscr *gprs_subscr_get_or_create(const char *imsi); +struct gprs_subscr *gprs_subscr_get_or_create_by_mmctx( struct sgsn_mm_ctx *mmctx); +struct gprs_subscr *gprs_subscr_get_by_imsi(const char *imsi); +void gprs_subscr_cancel(struct gprs_subscr *subscr); +void gprs_subscr_update(struct gprs_subscr *subscr); +void gprs_subscr_update_auth_info(struct gprs_subscr *subscr); int gprs_subscr_rx_gsup_message(struct msgb *msg); /* Called on subscriber data updates */ diff --git a/openbsc/include/openbsc/gprs_subscriber.h b/openbsc/include/openbsc/gprs_subscriber.h new file mode 100644 index 000000000..be78febff --- /dev/null +++ b/openbsc/include/openbsc/gprs_subscriber.h @@ -0,0 +1,31 @@ +/* GPRS subscriber details for use in SGSN land */ +#pragma once + +#include + +#include +#include + +extern struct llist_head * const gprs_subscribers; + +struct gprs_subscr { + struct llist_head entry; + int use_count; + + char imsi[GSM23003_IMSI_MAX_DIGITS+1]; + uint32_t tmsi; + char imei[GSM23003_IMEISV_NUM_DIGITS+1]; + bool authorized; + bool keep_in_ram; + uint32_t flags; + uint16_t lac; + + struct sgsn_subscriber_data *sgsn_data; +}; + +struct gprs_subscr *_gprs_subscr_get(struct gprs_subscr *gsub, + const char *file, int line); +struct gprs_subscr *_gprs_subscr_put(struct gprs_subscr *gsub, + const char *file, int line); +#define gprs_subscr_get(gsub) _gprs_subscr_get(gsub, __BASE_FILE__, __LINE__) +#define gprs_subscr_put(gsub) _gprs_subscr_put(gsub, __BASE_FILE__, __LINE__) diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 4425a1029..a14e59f7c 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -26,6 +26,8 @@ struct gsm_subscriber_group; #define OBSC_LINKID_CB(__msgb) (__msgb)->cb[3] +#define tmsi_from_string(str) strtoul(str, NULL, 10) + enum gsm_security_event { GSM_SECURITY_NOAVAIL, GSM_SECURITY_AUTH_FAILED, diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h index 314d61923..7e656145a 100644 --- a/openbsc/include/openbsc/gsm_subscriber.h +++ b/openbsc/include/openbsc/gsm_subscriber.h @@ -16,7 +16,6 @@ #define GSM_SUBSCRIBER_FIRST_CONTACT 0x00000001 /* gprs_sgsn.h defines additional flags including and above bit 16 (0x10000) */ -#define tmsi_from_string(str) strtoul(str, NULL, 10) #define GSM_SUBSCRIBER_NO_EXPIRATION 0x0 diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 1026474a1..9efe4026c 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index 260e032a8..727524ee6 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include #include @@ -321,9 +321,9 @@ void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm) /* Detach from subscriber which is possibly freed then */ if (mm->subscr) { - struct gsm_subscriber *subscr = subscr_get(mm->subscr); + struct gprs_subscr *subscr = gprs_subscr_get(mm->subscr); gprs_subscr_cleanup(subscr); - subscr_put(subscr); + gprs_subscr_put(subscr); } sgsn_mm_ctx_free(mm); diff --git a/openbsc/src/gprs/gprs_subscriber.c b/openbsc/src/gprs/gprs_subscriber.c index 57f73c5da..5f426f80c 100644 --- a/openbsc/src/gprs/gprs_subscriber.c +++ b/openbsc/src/gprs/gprs_subscriber.c @@ -23,7 +23,8 @@ #include #include #include -#include +#include +#include #include #include @@ -35,6 +36,7 @@ #include #include +#include #define SGSN_SUBSCR_MAX_RETRIES 3 #define SGSN_SUBSCR_RETRY_INTERVAL 10 @@ -46,6 +48,9 @@ extern void *tall_bsc_ctx; +LLIST_HEAD(_gprs_subscribers); +struct llist_head * const gprs_subscribers = &_gprs_subscribers; + static int gsup_read_cb(struct gsup_client *gsupc, struct msgb *msg); /* TODO: Some functions are specific to the SGSN, but this file is more general @@ -86,7 +91,7 @@ static int gsup_read_cb(struct gsup_client *gsupc, struct msgb *msg) return rc; } -int gprs_subscr_purge(struct gsm_subscriber *subscr); +int gprs_subscr_purge(struct gprs_subscr *subscr); static struct sgsn_subscriber_data *sgsn_subscriber_data_alloc(void *ctx) { @@ -117,28 +122,53 @@ struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc( return pdata; } -struct gsm_subscriber *gprs_subscr_get_or_create(const char *imsi) +struct gprs_subscr *gprs_subscr_get_by_imsi(const char *imsi) { - struct gsm_subscriber *subscr; + struct gprs_subscr *gsub; - subscr = subscr_get_or_create(NULL, imsi); - if (!subscr) + if (!imsi || !*imsi) return NULL; - if (!subscr->sgsn_data) - subscr->sgsn_data = sgsn_subscriber_data_alloc(subscr); - return subscr; + llist_for_each_entry(gsub, gprs_subscribers, entry) { + if (!strcmp(gsub->imsi, imsi)) + return gprs_subscr_get(gsub); + } + return NULL; } -struct gsm_subscriber *gprs_subscr_get_by_imsi(const char *imsi) +static struct gprs_subscr *gprs_subscr_alloc(void) { - return subscr_active_by_imsi(NULL, imsi); + struct gprs_subscr *gsub; + gsub = talloc_zero(tall_bsc_ctx, struct gprs_subscr); + if (!gsub) + return NULL; + llist_add_tail(&gsub->entry, gprs_subscribers); + gsub->use_count = 1; + gsub->tmsi = GSM_RESERVED_TMSI; + return gsub; } -void gprs_subscr_cleanup(struct gsm_subscriber *subscr) +struct gprs_subscr *gprs_subscr_get_or_create(const char *imsi) +{ + struct gprs_subscr *gsub; + + gsub = gprs_subscr_get_by_imsi(imsi); + if (!gsub) { + gsub = gprs_subscr_alloc(); + if (!gsub) + return NULL; + strncpy(gsub->imsi, imsi, sizeof(gsub->imsi)); + } + + if (!gsub->sgsn_data) + gsub->sgsn_data = sgsn_subscriber_data_alloc(gsub); + return gsub; +} + +void gprs_subscr_cleanup(struct gprs_subscr *subscr) { if (subscr->sgsn_data->mm) { - subscr_put(subscr->sgsn_data->mm->subscr); + gprs_subscr_put(subscr->sgsn_data->mm->subscr); subscr->sgsn_data->mm->subscr = NULL; subscr->sgsn_data->mm = NULL; } @@ -149,7 +179,7 @@ void gprs_subscr_cleanup(struct gsm_subscriber *subscr) } } -void gprs_subscr_cancel(struct gsm_subscriber *subscr) +void gprs_subscr_cancel(struct gprs_subscr *subscr) { subscr->authorized = 0; subscr->flags |= GPRS_SUBSCRIBER_CANCELLED; @@ -159,7 +189,7 @@ void gprs_subscr_cancel(struct gsm_subscriber *subscr) gprs_subscr_cleanup(subscr); } -static int gprs_subscr_tx_gsup_message(struct gsm_subscriber *subscr, +static int gprs_subscr_tx_gsup_message(struct gprs_subscr *subscr, struct osmo_gsup_message *gsup_msg) { struct msgb *msg = gsup_client_msgb_alloc(); @@ -181,7 +211,7 @@ static int gprs_subscr_tx_gsup_message(struct gsm_subscriber *subscr, return gsup_client_send(sgsn->gsup_client, msg); } -static int gprs_subscr_tx_gsup_error_reply(struct gsm_subscriber *subscr, +static int gprs_subscr_tx_gsup_error_reply(struct gprs_subscr *subscr, struct osmo_gsup_message *gsup_orig, enum gsm48_gmm_cause cause) { @@ -196,7 +226,7 @@ static int gprs_subscr_tx_gsup_error_reply(struct gsm_subscriber *subscr, return gprs_subscr_tx_gsup_message(subscr, &gsup_reply); } -static int gprs_subscr_handle_gsup_auth_res(struct gsm_subscriber *subscr, +static int gprs_subscr_handle_gsup_auth_res(struct gprs_subscr *subscr, struct osmo_gsup_message *gsup_msg) { unsigned idx; @@ -235,7 +265,7 @@ static int gprs_subscr_handle_gsup_auth_res(struct gsm_subscriber *subscr, return 0; } -static int gprs_subscr_pdp_data_clear(struct gsm_subscriber *subscr) +static int gprs_subscr_pdp_data_clear(struct gprs_subscr *subscr) { struct sgsn_subscriber_pdp_data *pdp, *pdp2; int count = 0; @@ -250,7 +280,7 @@ static int gprs_subscr_pdp_data_clear(struct gsm_subscriber *subscr) } static struct sgsn_subscriber_pdp_data *gprs_subscr_pdp_data_get_by_id( - struct gsm_subscriber *subscr, unsigned context_id) + struct gprs_subscr *subscr, unsigned context_id) { struct sgsn_subscriber_pdp_data *pdp; @@ -263,7 +293,7 @@ static struct sgsn_subscriber_pdp_data *gprs_subscr_pdp_data_get_by_id( } -static void gprs_subscr_gsup_insert_data(struct gsm_subscriber *subscr, +static void gprs_subscr_gsup_insert_data(struct gprs_subscr *subscr, struct osmo_gsup_message *gsup_msg) { struct sgsn_subscriber_data *sdata = subscr->sgsn_data; @@ -340,7 +370,7 @@ static void gprs_subscr_gsup_insert_data(struct gsm_subscriber *subscr, } } -static int gprs_subscr_handle_gsup_upd_loc_res(struct gsm_subscriber *subscr, +static int gprs_subscr_handle_gsup_upd_loc_res(struct gprs_subscr *subscr, struct osmo_gsup_message *gsup_msg) { /* contrary to MAP, we allow piggy-backing subscriber data onto @@ -357,7 +387,7 @@ static int gprs_subscr_handle_gsup_upd_loc_res(struct gsm_subscriber *subscr, return 0; } -static int gprs_subscr_handle_gsup_dsd_req(struct gsm_subscriber *subscr, +static int gprs_subscr_handle_gsup_dsd_req(struct gprs_subscr *subscr, struct osmo_gsup_message *gsup_msg) { struct osmo_gsup_message gsup_reply = {0}; @@ -377,7 +407,7 @@ static int gprs_subscr_handle_gsup_dsd_req(struct gsm_subscriber *subscr, return gprs_subscr_tx_gsup_message(subscr, &gsup_reply); } -static int gprs_subscr_handle_gsup_isd_req(struct gsm_subscriber *subscr, +static int gprs_subscr_handle_gsup_isd_req(struct gprs_subscr *subscr, struct osmo_gsup_message *gsup_msg) { struct osmo_gsup_message gsup_reply = {0}; @@ -409,7 +439,7 @@ static int check_cause(int cause) } } -static int gprs_subscr_handle_gsup_auth_err(struct gsm_subscriber *subscr, +static int gprs_subscr_handle_gsup_auth_err(struct gprs_subscr *subscr, struct osmo_gsup_message *gsup_msg) { unsigned idx; @@ -462,7 +492,7 @@ static int gprs_subscr_handle_gsup_auth_err(struct gsm_subscriber *subscr, return -gsup_msg->cause; } -static int gprs_subscr_handle_gsup_upd_loc_err(struct gsm_subscriber *subscr, +static int gprs_subscr_handle_gsup_upd_loc_err(struct gprs_subscr *subscr, struct osmo_gsup_message *gsup_msg) { int cause_err; @@ -523,7 +553,7 @@ static int gprs_subscr_handle_gsup_purge_no_subscr( return 0; } -static int gprs_subscr_handle_gsup_purge_res(struct gsm_subscriber *subscr, +static int gprs_subscr_handle_gsup_purge_res(struct gprs_subscr *subscr, struct osmo_gsup_message *gsup_msg) { LOGGSUBSCRP(LOGL_INFO, subscr, "Completing purge MS\n"); @@ -535,7 +565,7 @@ static int gprs_subscr_handle_gsup_purge_res(struct gsm_subscriber *subscr, return 0; } -static int gprs_subscr_handle_gsup_purge_err(struct gsm_subscriber *subscr, +static int gprs_subscr_handle_gsup_purge_err(struct gprs_subscr *subscr, struct osmo_gsup_message *gsup_msg) { LOGGSUBSCRP(LOGL_NOTICE, subscr, @@ -568,7 +598,7 @@ static int gprs_subscr_handle_gsup_purge_err(struct gsm_subscriber *subscr, return -gsup_msg->cause; } -static int gprs_subscr_handle_loc_cancel_req(struct gsm_subscriber *subscr, +static int gprs_subscr_handle_loc_cancel_req(struct gprs_subscr *subscr, struct osmo_gsup_message *gsup_msg) { struct osmo_gsup_message gsup_reply = {0}; @@ -629,7 +659,7 @@ int gprs_subscr_rx_gsup_message(struct msgb *msg) int rc = 0; struct osmo_gsup_message gsup_msg = {0}; - struct gsm_subscriber *subscr; + struct gprs_subscr *subscr; rc = osmo_gsup_decode(data, data_len, &gsup_msg); if (rc < 0) { @@ -715,12 +745,12 @@ int gprs_subscr_rx_gsup_message(struct msgb *msg) break; }; - subscr_put(subscr); + gprs_subscr_put(subscr); return rc; } -int gprs_subscr_purge(struct gsm_subscriber *subscr) +int gprs_subscr_purge(struct gprs_subscr *subscr) { struct sgsn_subscriber_data *sdata = subscr->sgsn_data; struct osmo_gsup_message gsup_msg = {0}; @@ -736,7 +766,7 @@ int gprs_subscr_purge(struct gsm_subscriber *subscr) return gprs_subscr_tx_gsup_message(subscr, &gsup_msg); } -int gprs_subscr_query_auth_info(struct gsm_subscriber *subscr) +int gprs_subscr_query_auth_info(struct gprs_subscr *subscr) { struct osmo_gsup_message gsup_msg = {0}; @@ -747,7 +777,7 @@ int gprs_subscr_query_auth_info(struct gsm_subscriber *subscr) return gprs_subscr_tx_gsup_message(subscr, &gsup_msg); } -int gprs_subscr_location_update(struct gsm_subscriber *subscr) +int gprs_subscr_location_update(struct gprs_subscr *subscr) { struct osmo_gsup_message gsup_msg = {0}; @@ -758,60 +788,59 @@ int gprs_subscr_location_update(struct gsm_subscriber *subscr) return gprs_subscr_tx_gsup_message(subscr, &gsup_msg); } -void gprs_subscr_update(struct gsm_subscriber *subscr) +void gprs_subscr_update(struct gprs_subscr *subscr) { LOGGSUBSCRP(LOGL_DEBUG, subscr, "Updating subscriber data\n"); subscr->flags &= ~GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING; - subscr->flags &= ~GSM_SUBSCRIBER_FIRST_CONTACT; + subscr->flags &= ~GPRS_SUBSCRIBER_FIRST_CONTACT; if (subscr->sgsn_data->mm) sgsn_update_subscriber_data(subscr->sgsn_data->mm); } -void gprs_subscr_update_auth_info(struct gsm_subscriber *subscr) +void gprs_subscr_update_auth_info(struct gprs_subscr *subscr) { LOGGSUBSCRP(LOGL_DEBUG, subscr, "Updating subscriber authentication info\n"); subscr->flags &= ~GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING; - subscr->flags &= ~GSM_SUBSCRIBER_FIRST_CONTACT; + subscr->flags &= ~GPRS_SUBSCRIBER_FIRST_CONTACT; if (subscr->sgsn_data->mm) sgsn_update_subscriber_data(subscr->sgsn_data->mm); } -struct gsm_subscriber *gprs_subscr_get_or_create_by_mmctx(struct sgsn_mm_ctx *mmctx) +struct gprs_subscr *gprs_subscr_get_or_create_by_mmctx(struct sgsn_mm_ctx *mmctx) { - struct gsm_subscriber *subscr = NULL; + struct gprs_subscr *subscr = NULL; if (mmctx->subscr) - return subscr_get(mmctx->subscr); + return gprs_subscr_get(mmctx->subscr); if (mmctx->imsi[0]) subscr = gprs_subscr_get_by_imsi(mmctx->imsi); if (!subscr) { subscr = gprs_subscr_get_or_create(mmctx->imsi); - subscr->flags |= GSM_SUBSCRIBER_FIRST_CONTACT; + subscr->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT; subscr->flags &= ~GPRS_SUBSCRIBER_ENABLE_PURGE; } - osmo_strlcpy(subscr->equipment.imei, mmctx->imei, - sizeof(subscr->equipment.imei)); + osmo_strlcpy(subscr->imei, mmctx->imei, sizeof(subscr->imei)); if (subscr->lac != mmctx->ra.lac) subscr->lac = mmctx->ra.lac; subscr->sgsn_data->mm = mmctx; - mmctx->subscr = subscr_get(subscr); + mmctx->subscr = gprs_subscr_get(subscr); return subscr; } int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) { - struct gsm_subscriber *subscr = NULL; + struct gprs_subscr *subscr = NULL; int rc; LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber data update\n"); @@ -821,13 +850,13 @@ int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) subscr->flags |= GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING; rc = gprs_subscr_location_update(subscr); - subscr_put(subscr); + gprs_subscr_put(subscr); return rc; } int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) { - struct gsm_subscriber *subscr = NULL; + struct gprs_subscr *subscr = NULL; int rc; LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber authentication info\n"); @@ -837,6 +866,40 @@ int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) subscr->flags |= GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING; rc = gprs_subscr_query_auth_info(subscr); - subscr_put(subscr); + gprs_subscr_put(subscr); return rc; } + +static void gprs_subscr_free(struct gprs_subscr *gsub) +{ + llist_del(&gsub->entry); + talloc_free(gsub); +} + +struct gprs_subscr *_gprs_subscr_get(struct gprs_subscr *gsub, + const char *file, int line) +{ + OSMO_ASSERT(gsub->use_count < INT_MAX); + gsub->use_count++; + LOGPSRC(DREF, LOGL_DEBUG, file, line, + "subscr %s usage increases to: %d\n", + gsub->imsi, gsub->use_count); + return gsub; +} + +struct gprs_subscr *_gprs_subscr_put(struct gprs_subscr *gsub, + const char *file, int line) +{ + gsub->use_count--; + LOGPSRC(DREF, gsub->use_count >= 0? LOGL_DEBUG : LOGL_ERROR, + file, line, + "subscr %s usage decreases to: %d%s\n", + gsub->imsi, gsub->use_count, + gsub->keep_in_ram? ", keep-in-ram flag is set" : ""); + if (gsub->use_count > 0) + return gsub; + if (gsub->keep_in_ram) + return gsub; + gprs_subscr_free(gsub); + return NULL; +} diff --git a/openbsc/src/gprs/sgsn_auth.c b/openbsc/src/gprs/sgsn_auth.c index 1fa7fc4ae..df7ee37b9 100644 --- a/openbsc/src/gprs/sgsn_auth.c +++ b/openbsc/src/gprs/sgsn_auth.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include const struct value_string auth_state_names[] = { @@ -151,7 +151,7 @@ enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mmctx) */ int sgsn_auth_request(struct sgsn_mm_ctx *mmctx) { - struct gsm_subscriber *subscr; + struct gprs_subscr *subscr; struct gsm_auth_tuple *at; int need_update_location; int rc; @@ -169,7 +169,7 @@ int sgsn_auth_request(struct sgsn_mm_ctx *mmctx) /* This has the side effect of registering the subscr with the mmctx */ subscr = gprs_subscr_get_or_create_by_mmctx(mmctx); - subscr_put(subscr); + gprs_subscr_put(subscr); OSMO_ASSERT(mmctx->subscr != NULL); @@ -207,7 +207,7 @@ int sgsn_auth_request(struct sgsn_mm_ctx *mmctx) void sgsn_auth_update(struct sgsn_mm_ctx *mmctx) { enum sgsn_auth_state auth_state; - struct gsm_subscriber *subscr = mmctx->subscr; + struct gprs_subscr *subscr = mmctx->subscr; struct gsm_auth_tuple *at; int gmm_cause; diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 062de444d..dde1e5e30 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include #ifdef BUILD_IU diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index 3ce054f97..a730635d9 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -657,40 +657,37 @@ DEFUN(cfg_auth_policy, cfg_auth_policy_cmd, } /* Subscriber */ -#include +#include -static void subscr_dump_full_vty(struct vty *vty, struct gsm_subscriber *subscr, int pending) +static void subscr_dump_full_vty(struct vty *vty, struct gprs_subscr *gsub, int pending) { +#if 0 char expire_time[200]; +#endif struct gsm_auth_tuple *at; int at_idx; struct sgsn_subscriber_pdp_data *pdp; - vty_out(vty, " ID: %llu, Authorized: %d%s", subscr->id, - subscr->authorized, VTY_NEWLINE); - if (strlen(subscr->name)) - vty_out(vty, " Name: '%s'%s", subscr->name, VTY_NEWLINE); - if (strlen(subscr->extension)) - vty_out(vty, " Extension: %s%s", subscr->extension, - VTY_NEWLINE); + vty_out(vty, " Authorized: %d%s", + gsub->authorized, VTY_NEWLINE); vty_out(vty, " LAC: %d/0x%x%s", - subscr->lac, subscr->lac, VTY_NEWLINE); - vty_out(vty, " IMSI: %s%s", subscr->imsi, VTY_NEWLINE); - if (subscr->tmsi != GSM_RESERVED_TMSI) - vty_out(vty, " TMSI: %08X%s", subscr->tmsi, + gsub->lac, gsub->lac, VTY_NEWLINE); + vty_out(vty, " IMSI: %s%s", gsub->imsi, VTY_NEWLINE); + if (gsub->tmsi != GSM_RESERVED_TMSI) + vty_out(vty, " TMSI: %08X%s", gsub->tmsi, VTY_NEWLINE); - if (subscr->sgsn_data->msisdn_len > 0) + if (gsub->sgsn_data->msisdn_len > 0) vty_out(vty, " MSISDN (BCD): %s%s", - osmo_hexdump(subscr->sgsn_data->msisdn, - subscr->sgsn_data->msisdn_len), + osmo_hexdump(gsub->sgsn_data->msisdn, + gsub->sgsn_data->msisdn_len), VTY_NEWLINE); - if (strlen(subscr->equipment.imei) > 0) - vty_out(vty, " IMEI: %s%s", subscr->equipment.imei, VTY_NEWLINE); + if (strlen(gsub->imei) > 0) + vty_out(vty, " IMEI: %s%s", gsub->imei, VTY_NEWLINE); - for (at_idx = 0; at_idx < ARRAY_SIZE(subscr->sgsn_data->auth_triplets); + for (at_idx = 0; at_idx < ARRAY_SIZE(gsub->sgsn_data->auth_triplets); at_idx++) { - at = &subscr->sgsn_data->auth_triplets[at_idx]; + at = &gsub->sgsn_data->auth_triplets[at_idx]; if (at->key_seq == GSM_KEY_SEQ_INVAL) continue; @@ -722,36 +719,38 @@ static void subscr_dump_full_vty(struct vty *vty, struct gsm_subscriber *subscr, } } - llist_for_each_entry(pdp, &subscr->sgsn_data->pdp_list, list) { + llist_for_each_entry(pdp, &gsub->sgsn_data->pdp_list, list) { vty_out(vty, " PDP info: Id: %d, Type: 0x%04x, APN: '%s' QoS: %s%s", pdp->context_id, pdp->pdp_type, pdp->apn_str, osmo_hexdump(pdp->qos_subscribed, pdp->qos_subscribed_len), VTY_NEWLINE); } +#if 0 /* print the expiration time of a subscriber */ - if (subscr->expire_lu) { + if (gsub->expire_lu) { strftime(expire_time, sizeof(expire_time), - "%a, %d %b %Y %T %z", localtime(&subscr->expire_lu)); + "%a, %d %b %Y %T %z", localtime(&gsub->expire_lu)); expire_time[sizeof(expire_time) - 1] = '\0'; vty_out(vty, " Expiration Time: %s%s", expire_time, VTY_NEWLINE); } +#endif - if (subscr->flags) + if (gsub->flags) vty_out(vty, " Flags: %s%s%s%s%s%s", - subscr->flags & GSM_SUBSCRIBER_FIRST_CONTACT ? + gsub->flags & GPRS_SUBSCRIBER_FIRST_CONTACT ? "FIRST_CONTACT " : "", - subscr->flags & GPRS_SUBSCRIBER_CANCELLED ? + gsub->flags & GPRS_SUBSCRIBER_CANCELLED ? "CANCELLED " : "", - subscr->flags & GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING ? + gsub->flags & GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING ? "UPDATE_LOCATION_PENDING " : "", - subscr->flags & GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING ? + gsub->flags & GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING ? "AUTH_INFO_PENDING " : "", - subscr->flags & GPRS_SUBSCRIBER_ENABLE_PURGE ? + gsub->flags & GPRS_SUBSCRIBER_ENABLE_PURGE ? "ENABLE_PURGE " : "", VTY_NEWLINE); - vty_out(vty, " Use count: %u%s", subscr->use_count, VTY_NEWLINE); + vty_out(vty, " Use count: %u%s", gsub->use_count, VTY_NEWLINE); } DEFUN(show_subscr_cache, @@ -760,9 +759,9 @@ DEFUN(show_subscr_cache, SHOW_STR "Show information about subscribers\n" "Display contents of subscriber cache\n") { - struct gsm_subscriber *subscr; + struct gprs_subscr *subscr; - llist_for_each_entry(subscr, &active_subscribers, entry) { + llist_for_each_entry(subscr, gprs_subscribers, entry) { vty_out(vty, " Subscriber:%s", VTY_NEWLINE); subscr_dump_full_vty(vty, subscr, 0); } @@ -794,7 +793,7 @@ DEFUN(update_subscr_insert_auth_triplet, update_subscr_insert_auth_triplet_cmd, const char *kc_str = argv[4]; struct gsm_auth_tuple at = {0,}; - struct gsm_subscriber *subscr; + struct gprs_subscr *subscr; subscr = gprs_subscr_get_by_imsi(imsi); if (!subscr) { @@ -825,12 +824,12 @@ DEFUN(update_subscr_insert_auth_triplet, update_subscr_insert_auth_triplet_cmd, subscr->sgsn_data->auth_triplets[cksn] = at; subscr->sgsn_data->auth_triplets_updated = 1; - subscr_put(subscr); + gprs_subscr_put(subscr); return CMD_SUCCESS; failed: - subscr_put(subscr); + gprs_subscr_put(subscr); return CMD_SUCCESS; } @@ -844,7 +843,7 @@ DEFUN(update_subscr_cancel, update_subscr_cancel_cmd, const char *imsi = argv[0]; const char *cancel_type = argv[1]; - struct gsm_subscriber *subscr; + struct gprs_subscr *subscr; subscr = gprs_subscr_get_by_imsi(imsi); if (!subscr) { @@ -859,7 +858,7 @@ DEFUN(update_subscr_cancel, update_subscr_cancel_cmd, subscr->sgsn_data->error_cause = GMM_CAUSE_IMPL_DETACHED; gprs_subscr_cancel(subscr); - subscr_put(subscr); + gprs_subscr_put(subscr); return CMD_SUCCESS; } @@ -871,7 +870,7 @@ DEFUN(update_subscr_create, update_subscr_create_cmd, { const char *imsi = argv[0]; - struct gsm_subscriber *subscr; + struct gprs_subscr *subscr; subscr = gprs_subscr_get_by_imsi(imsi); if (subscr) { @@ -882,7 +881,7 @@ DEFUN(update_subscr_create, update_subscr_create_cmd, subscr = gprs_subscr_get_or_create(imsi); subscr->keep_in_ram = 1; - subscr_put(subscr); + gprs_subscr_put(subscr); return CMD_SUCCESS; } @@ -894,7 +893,7 @@ DEFUN(update_subscr_destroy, update_subscr_destroy_cmd, { const char *imsi = argv[0]; - struct gsm_subscriber *subscr; + struct gprs_subscr *subscr; subscr = gprs_subscr_get_by_imsi(imsi); if (!subscr) { @@ -909,7 +908,7 @@ DEFUN(update_subscr_destroy, update_subscr_destroy_cmd, if (subscr->use_count > 1) vty_out(vty, "%% subscriber is still in use%s", VTY_NEWLINE); - subscr_put(subscr); + gprs_subscr_put(subscr); return CMD_SUCCESS; } @@ -934,7 +933,7 @@ DEFUN(update_subscr_update_location_result, update_subscr_update_location_result const char *imsi = argv[0]; const char *ret_code_str = argv[1]; - struct gsm_subscriber *subscr; + struct gprs_subscr *subscr; const struct value_string cause_mapping[] = { { GMM_CAUSE_NET_FAIL, "system-failure" }, @@ -963,7 +962,7 @@ DEFUN(update_subscr_update_location_result, update_subscr_update_location_result gprs_subscr_update(subscr); - subscr_put(subscr); + gprs_subscr_put(subscr); return CMD_SUCCESS; } @@ -975,7 +974,7 @@ DEFUN(update_subscr_update_auth_info, update_subscr_update_auth_info_cmd, { const char *imsi = argv[0]; - struct gsm_subscriber *subscr; + struct gprs_subscr *subscr; subscr = gprs_subscr_get_by_imsi(imsi); if (!subscr) { @@ -986,7 +985,7 @@ DEFUN(update_subscr_update_auth_info, update_subscr_update_auth_info_cmd, gprs_subscr_update_auth_info(subscr); - subscr_put(subscr); + gprs_subscr_put(subscr); return CMD_SUCCESS; } diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index ff07978c0..6eabddefd 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -248,7 +248,7 @@ static void test_llme(void) cleanup_test(); } -struct gsm_subscriber *last_updated_subscr = NULL; +struct gprs_subscr *last_updated_subscr = NULL; void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx) { OSMO_ASSERT(mmctx); @@ -257,23 +257,23 @@ void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx) last_updated_subscr = mmctx->subscr; } -static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi) +static void assert_subscr(const struct gprs_subscr *subscr, const char *imsi) { - struct gsm_subscriber *sfound; + struct gprs_subscr *sfound; OSMO_ASSERT(subscr); OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0); sfound = gprs_subscr_get_by_imsi(imsi); OSMO_ASSERT(sfound == subscr); - subscr_put(sfound); + gprs_subscr_put(sfound); } static void show_subscrs(FILE *out) { - struct gsm_subscriber *subscr; + struct gprs_subscr *subscr; - llist_for_each_entry(subscr, &active_subscribers, entry) { + llist_for_each_entry(subscr, gprs_subscribers, entry) { fprintf(out, " Subscriber: %s, " "use count: %d\n", subscr->imsi, subscr->use_count); @@ -284,12 +284,18 @@ static void assert_no_subscrs() { show_subscrs(stdout); fflush(stdout); - OSMO_ASSERT(llist_empty(&active_subscribers)); + OSMO_ASSERT(llist_empty(gprs_subscribers)); } +#define VERBOSE_ASSERT(val, expect_op, fmt) \ + do { \ + printf(#val " == " fmt "\n", (val)); \ + OSMO_ASSERT((val) expect_op); \ + } while (0); + static void test_subscriber(void) { - struct gsm_subscriber *s1, *s2, *s3, *sfound; + struct gprs_subscr *s1, *s2, *s3; const char *imsi1 = "1234567890"; const char *imsi2 = "9876543210"; const char *imsi3 = "5656565656"; @@ -302,19 +308,24 @@ static void test_subscriber(void) OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL); OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL); OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL); + VERBOSE_ASSERT(llist_count(gprs_subscribers), == 0, "%d"); /* Allocate entry 1 */ s1 = gprs_subscr_get_or_create(imsi1); - s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT; + VERBOSE_ASSERT(llist_count(gprs_subscribers), == 1, "%d"); + s1->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT; assert_subscr(s1, imsi1); + VERBOSE_ASSERT(llist_count(gprs_subscribers), == 1, "%d"); OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL); /* Allocate entry 2 */ s2 = gprs_subscr_get_or_create(imsi2); - s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT; + VERBOSE_ASSERT(llist_count(gprs_subscribers), == 2, "%d"); + s2->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT; /* Allocate entry 3 */ s3 = gprs_subscr_get_or_create(imsi3); + VERBOSE_ASSERT(llist_count(gprs_subscribers), == 3, "%d"); /* Check entries */ assert_subscr(s1, imsi1); @@ -326,33 +337,35 @@ static void test_subscriber(void) gprs_subscr_update(s1); OSMO_ASSERT(last_updated_subscr == NULL); OSMO_ASSERT(s1->sgsn_data->mm == NULL); - OSMO_ASSERT((s1->flags & GSM_SUBSCRIBER_FIRST_CONTACT) == 0); + OSMO_ASSERT((s1->flags & GPRS_SUBSCRIBER_FIRST_CONTACT) == 0); /* There is no subscriber cache. Verify it */ gprs_subscr_cleanup(s1); - subscr_put(s1); + gprs_subscr_put(s1); s1 = NULL; - sfound = gprs_subscr_get_by_imsi(imsi1); - OSMO_ASSERT(sfound == NULL); + VERBOSE_ASSERT(llist_count(gprs_subscribers), == 2, "%d"); + OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL); assert_subscr(s2, imsi2); assert_subscr(s3, imsi3); - /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */ + /* Free entry 2 (GPRS_SUBSCRIBER_FIRST_CONTACT is set) */ gprs_subscr_cleanup(s2); - subscr_put(s2); + gprs_subscr_put(s2); s2 = NULL; + VERBOSE_ASSERT(llist_count(gprs_subscribers), == 1, "%d"); OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL); OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL); assert_subscr(s3, imsi3); /* Try to delete entry 3 */ gprs_subscr_cleanup(s3); - subscr_put(s3); + gprs_subscr_put(s3); s3 = NULL; + VERBOSE_ASSERT(llist_count(gprs_subscribers), == 0, "%d"); OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL); - OSMO_ASSERT(llist_empty(&active_subscribers)); + OSMO_ASSERT(llist_empty(gprs_subscribers)); update_subscriber_data_cb = __real_sgsn_update_subscriber_data; @@ -361,7 +374,7 @@ static void test_subscriber(void) static void test_auth_triplets(void) { - struct gsm_subscriber *s1, *s1found; + struct gprs_subscr *s1, *s1found; const char *imsi1 = "1234567890"; struct gsm_auth_tuple *at; struct sgsn_mm_ctx *ctx; @@ -375,17 +388,17 @@ static void test_auth_triplets(void) /* Allocate entry 1 */ s1 = gprs_subscr_get_or_create(imsi1); - s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT; + s1->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT; s1found = gprs_subscr_get_by_imsi(imsi1); OSMO_ASSERT(s1found == s1); - subscr_put(s1found); + gprs_subscr_put(s1found); /* Create a context */ OSMO_ASSERT(count(gprs_llme_list()) == 0); ctx = alloc_mm_ctx(local_tlli, &raid); /* Attach s1 to ctx */ - ctx->subscr = subscr_get(s1); + ctx->subscr = gprs_subscr_get(s1); ctx->subscr->sgsn_data->mm = ctx; /* Try to get auth tuple */ @@ -414,7 +427,7 @@ static void test_auth_triplets(void) OSMO_ASSERT(at == NULL); /* Free MM context and subscriber */ - subscr_put(s1); + gprs_subscr_put(s1); sgsn_mm_ctx_cleanup_free(ctx); s1found = gprs_subscr_get_by_imsi(imsi1); OSMO_ASSERT(s1found == NULL); @@ -441,7 +454,7 @@ static int rx_gsup_message(const uint8_t *data, size_t data_len) static void test_subscriber_gsup(void) { - struct gsm_subscriber *s1, *s1found; + struct gprs_subscr *s1, *s1found; const char *imsi1 = "1234567890"; struct sgsn_mm_ctx *ctx; struct gprs_ra_id raid = { 0, }; @@ -563,17 +576,17 @@ static void test_subscriber_gsup(void) /* Allocate entry 1 */ s1 = gprs_subscr_get_or_create(imsi1); - s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT; + s1->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT; s1found = gprs_subscr_get_by_imsi(imsi1); OSMO_ASSERT(s1found == s1); - subscr_put(s1found); + gprs_subscr_put(s1found); /* Create a context */ OSMO_ASSERT(count(gprs_llme_list()) == 0); ctx = alloc_mm_ctx(local_tlli, &raid); /* Attach s1 to ctx */ - ctx->subscr = subscr_get(s1); + ctx->subscr = gprs_subscr_get(s1); ctx->subscr->sgsn_data->mm = ctx; /* Inject SendAuthInfoReq GSUP message */ @@ -675,7 +688,7 @@ static void test_subscriber_gsup(void) /* Free MM context and subscriber */ OSMO_ASSERT(ctx->subscr == NULL); sgsn_mm_ctx_cleanup_free(ctx); - subscr_put(s1); + gprs_subscr_put(s1); s1found = gprs_subscr_get_by_imsi(imsi1); OSMO_ASSERT(s1found == NULL); @@ -1090,7 +1103,7 @@ int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) { static void test_gmm_attach_subscr(void) { const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; - struct gsm_subscriber *subscr; + struct gprs_subscr *subscr; sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE; subscr_request_update_location_cb = my_subscr_request_update_location; @@ -1101,7 +1114,7 @@ static void test_gmm_attach_subscr(void) printf("Auth policy 'remote': "); test_gmm_attach(0); - subscr_put(subscr); + gprs_subscr_put(subscr); assert_no_subscrs(); sgsn->cfg.auth_policy = saved_auth_policy; @@ -1124,7 +1137,7 @@ int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx) static void test_gmm_attach_subscr_fake_auth(void) { const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; - struct gsm_subscriber *subscr; + struct gprs_subscr *subscr; sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE; subscr_request_update_location_cb = my_subscr_request_update_location; @@ -1137,7 +1150,7 @@ static void test_gmm_attach_subscr_fake_auth(void) printf("Auth policy 'remote', auth faked: "); test_gmm_attach(0); - subscr_put(subscr); + gprs_subscr_put(subscr); assert_no_subscrs(); sgsn->cfg.auth_policy = saved_auth_policy; @@ -1166,7 +1179,7 @@ int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx) static void test_gmm_attach_subscr_real_auth(void) { const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; - struct gsm_subscriber *subscr; + struct gprs_subscr *subscr; sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE; subscr_request_update_location_cb = my_subscr_request_update_location; @@ -1180,7 +1193,7 @@ static void test_gmm_attach_subscr_real_auth(void) printf("Auth policy 'remote', triplet based auth: "); test_gmm_attach(0); - subscr_put(subscr); + gprs_subscr_put(subscr); assert_no_subscrs(); sgsn->cfg.auth_policy = saved_auth_policy; @@ -1254,7 +1267,7 @@ int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) { static void test_gmm_attach_subscr_gsup_auth(int retry) { const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; - struct gsm_subscriber *subscr; + struct gprs_subscr *subscr; sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE; subscr_request_update_location_cb = my_subscr_request_update_gsup_auth; @@ -1268,7 +1281,7 @@ static void test_gmm_attach_subscr_gsup_auth(int retry) subscr->authorized = 1; sgsn->cfg.require_authentication = 1; sgsn->cfg.require_update_location = 1; - subscr_put(subscr); + gprs_subscr_put(subscr); printf("Auth policy 'remote', GSUP based auth: "); test_gmm_attach(retry); @@ -1337,7 +1350,7 @@ int my_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg) static void test_gmm_attach_subscr_real_gsup_auth(int retry) { const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; - struct gsm_subscriber *subscr; + struct gprs_subscr *subscr; sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE; gsup_client_send_cb = my_gsup_client_send; @@ -2228,7 +2241,7 @@ static void test_ggsn_selection(void) { struct apn_ctx *actxs[4]; struct sgsn_ggsn_ctx *ggc, *ggcs[3]; - struct gsm_subscriber *s1; + struct gprs_subscr *s1; const char *imsi1 = "1234567890"; struct sgsn_mm_ctx *ctx; struct gprs_ra_id raid = { 0, }; @@ -2347,7 +2360,7 @@ static void test_ggsn_selection(void) /* Cleanup */ - subscr_put(s1); + gprs_subscr_put(s1); sgsn_mm_ctx_cleanup_free(ctx); assert_no_subscrs(); diff --git a/openbsc/tests/sgsn/sgsn_test.ok b/openbsc/tests/sgsn/sgsn_test.ok index c7a53b9e5..f38d7309d 100644 --- a/openbsc/tests/sgsn/sgsn_test.ok +++ b/openbsc/tests/sgsn/sgsn_test.ok @@ -1,5 +1,13 @@ Testing LLME allocations Testing core subscriber data API +llist_count(gprs_subscribers) == 0 +llist_count(gprs_subscribers) == 1 +llist_count(gprs_subscribers) == 1 +llist_count(gprs_subscribers) == 2 +llist_count(gprs_subscribers) == 3 +llist_count(gprs_subscribers) == 2 +llist_count(gprs_subscribers) == 1 +llist_count(gprs_subscribers) == 0 Testing authentication triplet handling Testing subscriber GSUP handling Testing GMM detach