add struct gprs_subscr, separating gprs from gsm_subscriber

Prepare for replacing gsm_subscriber with vlr_subscriber. vlr_subscriber will
not make sense to be used in gprs, so have a dedicated GPRS subscriber struct.
(Could change if the gprs code were to use libvlr; is currently independent).

Related: OS#1592
Change-Id: Ia8b391ee009c8545763cba04505be3947835120e
This commit is contained in:
Neels Hofmeyr 2017-01-10 00:49:56 +01:00
parent a369e24cb9
commit 0e5d807297
13 changed files with 269 additions and 151 deletions

View File

@ -31,6 +31,7 @@ noinst_HEADERS = \
gprs_sndcp_dcomp.h \ gprs_sndcp_dcomp.h \
gprs_sndcp_pcomp.h \ gprs_sndcp_pcomp.h \
gprs_sndcp_xid.h \ gprs_sndcp_xid.h \
gprs_subscriber.h \
gprs_utils.h \ gprs_utils.h \
gsm_04_08.h \ gsm_04_08.h \
gsm_04_11.h \ gsm_04_11.h \

View File

@ -18,7 +18,7 @@
struct gprs_llc_lle; struct gprs_llc_lle;
struct ctrl_handle; struct ctrl_handle;
struct gsm_subscriber; struct gprs_subscr;
enum gsm48_gsm_cause; enum gsm48_gsm_cause;
@ -225,7 +225,7 @@ struct sgsn_mm_ctx {
/* the current GGSN look-up operation */ /* the current GGSN look-up operation */
struct sgsn_ggsn_lookup *ggsn_lookup; struct sgsn_ggsn_lookup *ggsn_lookup;
struct gsm_subscriber *subscr; struct gprs_subscr *subscr;
}; };
#define LOGMMCTXP(level, mm, fmt, args...) \ #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 * GPRS subscriber data
*/ */
#define GPRS_SUBSCRIBER_FIRST_CONTACT 0x00000001
#define GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING (1 << 16) #define GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING (1 << 16)
#define GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING (1 << 17) #define GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING (1 << 17)
#define GPRS_SUBSCRIBER_CANCELLED (1 << 18) #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_init(struct sgsn_instance *sgi);
int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx); int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx); int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
void gprs_subscr_cleanup(struct gsm_subscriber *subscr); void gprs_subscr_cleanup(struct gprs_subscr *subscr);
struct gsm_subscriber *gprs_subscr_get_or_create(const char *imsi); struct gprs_subscr *gprs_subscr_get_or_create(const char *imsi);
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 *gprs_subscr_get_by_imsi(const char *imsi); struct gprs_subscr *gprs_subscr_get_by_imsi(const char *imsi);
void gprs_subscr_cancel(struct gsm_subscriber *subscr); void gprs_subscr_cancel(struct gprs_subscr *subscr);
void gprs_subscr_update(struct gsm_subscriber *subscr); void gprs_subscr_update(struct gprs_subscr *subscr);
void gprs_subscr_update_auth_info(struct gsm_subscriber *subscr); void gprs_subscr_update_auth_info(struct gprs_subscr *subscr);
int gprs_subscr_rx_gsup_message(struct msgb *msg); int gprs_subscr_rx_gsup_message(struct msgb *msg);
/* Called on subscriber data updates */ /* Called on subscriber data updates */

View File

@ -0,0 +1,31 @@
/* GPRS subscriber details for use in SGSN land */
#pragma once
#include <stdint.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/gsm/protocol/gsm_23_003.h>
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__)

View File

@ -26,6 +26,8 @@ struct gsm_subscriber_group;
#define OBSC_LINKID_CB(__msgb) (__msgb)->cb[3] #define OBSC_LINKID_CB(__msgb) (__msgb)->cb[3]
#define tmsi_from_string(str) strtoul(str, NULL, 10)
enum gsm_security_event { enum gsm_security_event {
GSM_SECURITY_NOAVAIL, GSM_SECURITY_NOAVAIL,
GSM_SECURITY_AUTH_FAILED, GSM_SECURITY_AUTH_FAILED,

View File

@ -16,7 +16,6 @@
#define GSM_SUBSCRIBER_FIRST_CONTACT 0x00000001 #define GSM_SUBSCRIBER_FIRST_CONTACT 0x00000001
/* gprs_sgsn.h defines additional flags including and above bit 16 (0x10000) */ /* 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 #define GSM_SUBSCRIBER_NO_EXPIRATION 0x0

View File

@ -64,6 +64,7 @@
#include <openbsc/gprs_sgsn.h> #include <openbsc/gprs_sgsn.h>
#include <openbsc/gprs_gmm.h> #include <openbsc/gprs_gmm.h>
#include <openbsc/gprs_utils.h> #include <openbsc/gprs_utils.h>
#include <openbsc/gprs_subscriber.h>
#include <openbsc/sgsn.h> #include <openbsc/sgsn.h>
#include <openbsc/signal.h> #include <openbsc/signal.h>
#include <openbsc/iu.h> #include <openbsc/iu.h>

View File

@ -31,7 +31,7 @@
#include <osmocom/gprs/gprs_bssgp.h> #include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h> #include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <openbsc/gsm_subscriber.h> #include <openbsc/gprs_subscriber.h>
#include <openbsc/debug.h> #include <openbsc/debug.h>
#include <openbsc/gprs_sgsn.h> #include <openbsc/gprs_sgsn.h>
#include <openbsc/sgsn.h> #include <openbsc/sgsn.h>
@ -321,9 +321,9 @@ void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm)
/* Detach from subscriber which is possibly freed then */ /* Detach from subscriber which is possibly freed then */
if (mm->subscr) { if (mm->subscr) {
struct gsm_subscriber *subscr = subscr_get(mm->subscr); struct gprs_subscr *subscr = gprs_subscr_get(mm->subscr);
gprs_subscr_cleanup(subscr); gprs_subscr_cleanup(subscr);
subscr_put(subscr); gprs_subscr_put(subscr);
} }
sgsn_mm_ctx_free(mm); sgsn_mm_ctx_free(mm);

View File

@ -23,7 +23,8 @@
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h> #include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <osmocom/gsm/gsup.h> #include <osmocom/gsm/gsup.h>
#include <osmocom/core/utils.h> #include <osmocom/core/utils.h>
#include <openbsc/gsm_subscriber.h> #include <osmocom/core/logging.h>
#include <openbsc/gprs_subscriber.h>
#include <openbsc/gsup_client.h> #include <openbsc/gsup_client.h>
#include <openbsc/sgsn.h> #include <openbsc/sgsn.h>
@ -35,6 +36,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <limits.h>
#define SGSN_SUBSCR_MAX_RETRIES 3 #define SGSN_SUBSCR_MAX_RETRIES 3
#define SGSN_SUBSCR_RETRY_INTERVAL 10 #define SGSN_SUBSCR_RETRY_INTERVAL 10
@ -46,6 +48,9 @@
extern void *tall_bsc_ctx; 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); 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 /* 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; 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) 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; 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 (!imsi || !*imsi)
if (!subscr)
return NULL; return NULL;
if (!subscr->sgsn_data) llist_for_each_entry(gsub, gprs_subscribers, entry) {
subscr->sgsn_data = sgsn_subscriber_data_alloc(subscr); if (!strcmp(gsub->imsi, imsi))
return subscr; 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) { 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->subscr = NULL;
subscr->sgsn_data->mm = 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->authorized = 0;
subscr->flags |= GPRS_SUBSCRIBER_CANCELLED; subscr->flags |= GPRS_SUBSCRIBER_CANCELLED;
@ -159,7 +189,7 @@ void gprs_subscr_cancel(struct gsm_subscriber *subscr)
gprs_subscr_cleanup(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 osmo_gsup_message *gsup_msg)
{ {
struct msgb *msg = gsup_client_msgb_alloc(); 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); 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, struct osmo_gsup_message *gsup_orig,
enum gsm48_gmm_cause cause) 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); 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) struct osmo_gsup_message *gsup_msg)
{ {
unsigned idx; unsigned idx;
@ -235,7 +265,7 @@ static int gprs_subscr_handle_gsup_auth_res(struct gsm_subscriber *subscr,
return 0; 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; struct sgsn_subscriber_pdp_data *pdp, *pdp2;
int count = 0; 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( 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; 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 osmo_gsup_message *gsup_msg)
{ {
struct sgsn_subscriber_data *sdata = subscr->sgsn_data; 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) struct osmo_gsup_message *gsup_msg)
{ {
/* contrary to MAP, we allow piggy-backing subscriber data onto /* 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; 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_msg)
{ {
struct osmo_gsup_message gsup_reply = {0}; 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); 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_msg)
{ {
struct osmo_gsup_message gsup_reply = {0}; 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) struct osmo_gsup_message *gsup_msg)
{ {
unsigned idx; unsigned idx;
@ -462,7 +492,7 @@ static int gprs_subscr_handle_gsup_auth_err(struct gsm_subscriber *subscr,
return -gsup_msg->cause; 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) struct osmo_gsup_message *gsup_msg)
{ {
int cause_err; int cause_err;
@ -523,7 +553,7 @@ static int gprs_subscr_handle_gsup_purge_no_subscr(
return 0; 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) struct osmo_gsup_message *gsup_msg)
{ {
LOGGSUBSCRP(LOGL_INFO, subscr, "Completing purge MS\n"); 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; 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) struct osmo_gsup_message *gsup_msg)
{ {
LOGGSUBSCRP(LOGL_NOTICE, subscr, LOGGSUBSCRP(LOGL_NOTICE, subscr,
@ -568,7 +598,7 @@ static int gprs_subscr_handle_gsup_purge_err(struct gsm_subscriber *subscr,
return -gsup_msg->cause; 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_msg)
{ {
struct osmo_gsup_message gsup_reply = {0}; struct osmo_gsup_message gsup_reply = {0};
@ -629,7 +659,7 @@ int gprs_subscr_rx_gsup_message(struct msgb *msg)
int rc = 0; int rc = 0;
struct osmo_gsup_message gsup_msg = {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); rc = osmo_gsup_decode(data, data_len, &gsup_msg);
if (rc < 0) { if (rc < 0) {
@ -715,12 +745,12 @@ int gprs_subscr_rx_gsup_message(struct msgb *msg)
break; break;
}; };
subscr_put(subscr); gprs_subscr_put(subscr);
return rc; 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 sgsn_subscriber_data *sdata = subscr->sgsn_data;
struct osmo_gsup_message gsup_msg = {0}; 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); 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}; 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); 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}; 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); 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"); LOGGSUBSCRP(LOGL_DEBUG, subscr, "Updating subscriber data\n");
subscr->flags &= ~GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING; subscr->flags &= ~GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING;
subscr->flags &= ~GSM_SUBSCRIBER_FIRST_CONTACT; subscr->flags &= ~GPRS_SUBSCRIBER_FIRST_CONTACT;
if (subscr->sgsn_data->mm) if (subscr->sgsn_data->mm)
sgsn_update_subscriber_data(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, LOGGSUBSCRP(LOGL_DEBUG, subscr,
"Updating subscriber authentication info\n"); "Updating subscriber authentication info\n");
subscr->flags &= ~GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING; 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) if (subscr->sgsn_data->mm)
sgsn_update_subscriber_data(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) if (mmctx->subscr)
return subscr_get(mmctx->subscr); return gprs_subscr_get(mmctx->subscr);
if (mmctx->imsi[0]) if (mmctx->imsi[0])
subscr = gprs_subscr_get_by_imsi(mmctx->imsi); subscr = gprs_subscr_get_by_imsi(mmctx->imsi);
if (!subscr) { if (!subscr) {
subscr = gprs_subscr_get_or_create(mmctx->imsi); 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; subscr->flags &= ~GPRS_SUBSCRIBER_ENABLE_PURGE;
} }
osmo_strlcpy(subscr->equipment.imei, mmctx->imei, osmo_strlcpy(subscr->imei, mmctx->imei, sizeof(subscr->imei));
sizeof(subscr->equipment.imei));
if (subscr->lac != mmctx->ra.lac) if (subscr->lac != mmctx->ra.lac)
subscr->lac = mmctx->ra.lac; subscr->lac = mmctx->ra.lac;
subscr->sgsn_data->mm = mmctx; subscr->sgsn_data->mm = mmctx;
mmctx->subscr = subscr_get(subscr); mmctx->subscr = gprs_subscr_get(subscr);
return subscr; return subscr;
} }
int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx)
{ {
struct gsm_subscriber *subscr = NULL; struct gprs_subscr *subscr = NULL;
int rc; int rc;
LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber data update\n"); 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; subscr->flags |= GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING;
rc = gprs_subscr_location_update(subscr); rc = gprs_subscr_location_update(subscr);
subscr_put(subscr); gprs_subscr_put(subscr);
return rc; return rc;
} }
int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx)
{ {
struct gsm_subscriber *subscr = NULL; struct gprs_subscr *subscr = NULL;
int rc; int rc;
LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber authentication info\n"); 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; subscr->flags |= GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING;
rc = gprs_subscr_query_auth_info(subscr); rc = gprs_subscr_query_auth_info(subscr);
subscr_put(subscr); gprs_subscr_put(subscr);
return rc; 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;
}

View File

@ -24,7 +24,7 @@
#include <openbsc/sgsn.h> #include <openbsc/sgsn.h>
#include <openbsc/gprs_sgsn.h> #include <openbsc/gprs_sgsn.h>
#include <openbsc/gprs_gmm.h> #include <openbsc/gprs_gmm.h>
#include <openbsc/gsm_subscriber.h> #include <openbsc/gprs_subscriber.h>
#include <openbsc/debug.h> #include <openbsc/debug.h>
const struct value_string auth_state_names[] = { 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) int sgsn_auth_request(struct sgsn_mm_ctx *mmctx)
{ {
struct gsm_subscriber *subscr; struct gprs_subscr *subscr;
struct gsm_auth_tuple *at; struct gsm_auth_tuple *at;
int need_update_location; int need_update_location;
int rc; 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 */ /* This has the side effect of registering the subscr with the mmctx */
subscr = gprs_subscr_get_or_create_by_mmctx(mmctx); subscr = gprs_subscr_get_or_create_by_mmctx(mmctx);
subscr_put(subscr); gprs_subscr_put(subscr);
OSMO_ASSERT(mmctx->subscr != NULL); 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) void sgsn_auth_update(struct sgsn_mm_ctx *mmctx)
{ {
enum sgsn_auth_state auth_state; enum sgsn_auth_state auth_state;
struct gsm_subscriber *subscr = mmctx->subscr; struct gprs_subscr *subscr = mmctx->subscr;
struct gsm_auth_tuple *at; struct gsm_auth_tuple *at;
int gmm_cause; int gmm_cause;

View File

@ -48,7 +48,7 @@
#include <openbsc/gprs_llc.h> #include <openbsc/gprs_llc.h>
#include <openbsc/gprs_sgsn.h> #include <openbsc/gprs_sgsn.h>
#include <openbsc/gprs_gmm.h> #include <openbsc/gprs_gmm.h>
#include <openbsc/gsm_subscriber.h> #include <openbsc/gprs_subscriber.h>
#include <openbsc/gprs_sndcp.h> #include <openbsc/gprs_sndcp.h>
#ifdef BUILD_IU #ifdef BUILD_IU

View File

@ -657,40 +657,37 @@ DEFUN(cfg_auth_policy, cfg_auth_policy_cmd,
} }
/* Subscriber */ /* Subscriber */
#include <openbsc/gsm_subscriber.h> #include <openbsc/gprs_subscriber.h>
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]; char expire_time[200];
#endif
struct gsm_auth_tuple *at; struct gsm_auth_tuple *at;
int at_idx; int at_idx;
struct sgsn_subscriber_pdp_data *pdp; struct sgsn_subscriber_pdp_data *pdp;
vty_out(vty, " ID: %llu, Authorized: %d%s", subscr->id, vty_out(vty, " Authorized: %d%s",
subscr->authorized, VTY_NEWLINE); gsub->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, " LAC: %d/0x%x%s", vty_out(vty, " LAC: %d/0x%x%s",
subscr->lac, subscr->lac, VTY_NEWLINE); gsub->lac, gsub->lac, VTY_NEWLINE);
vty_out(vty, " IMSI: %s%s", subscr->imsi, VTY_NEWLINE); vty_out(vty, " IMSI: %s%s", gsub->imsi, VTY_NEWLINE);
if (subscr->tmsi != GSM_RESERVED_TMSI) if (gsub->tmsi != GSM_RESERVED_TMSI)
vty_out(vty, " TMSI: %08X%s", subscr->tmsi, vty_out(vty, " TMSI: %08X%s", gsub->tmsi,
VTY_NEWLINE); VTY_NEWLINE);
if (subscr->sgsn_data->msisdn_len > 0) if (gsub->sgsn_data->msisdn_len > 0)
vty_out(vty, " MSISDN (BCD): %s%s", vty_out(vty, " MSISDN (BCD): %s%s",
osmo_hexdump(subscr->sgsn_data->msisdn, osmo_hexdump(gsub->sgsn_data->msisdn,
subscr->sgsn_data->msisdn_len), gsub->sgsn_data->msisdn_len),
VTY_NEWLINE); VTY_NEWLINE);
if (strlen(subscr->equipment.imei) > 0) if (strlen(gsub->imei) > 0)
vty_out(vty, " IMEI: %s%s", subscr->equipment.imei, VTY_NEWLINE); 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_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) if (at->key_seq == GSM_KEY_SEQ_INVAL)
continue; 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", vty_out(vty, " PDP info: Id: %d, Type: 0x%04x, APN: '%s' QoS: %s%s",
pdp->context_id, pdp->pdp_type, pdp->apn_str, pdp->context_id, pdp->pdp_type, pdp->apn_str,
osmo_hexdump(pdp->qos_subscribed, pdp->qos_subscribed_len), osmo_hexdump(pdp->qos_subscribed, pdp->qos_subscribed_len),
VTY_NEWLINE); VTY_NEWLINE);
} }
#if 0
/* print the expiration time of a subscriber */ /* print the expiration time of a subscriber */
if (subscr->expire_lu) { if (gsub->expire_lu) {
strftime(expire_time, sizeof(expire_time), 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'; expire_time[sizeof(expire_time) - 1] = '\0';
vty_out(vty, " Expiration Time: %s%s", expire_time, VTY_NEWLINE); 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", vty_out(vty, " Flags: %s%s%s%s%s%s",
subscr->flags & GSM_SUBSCRIBER_FIRST_CONTACT ? gsub->flags & GPRS_SUBSCRIBER_FIRST_CONTACT ?
"FIRST_CONTACT " : "", "FIRST_CONTACT " : "",
subscr->flags & GPRS_SUBSCRIBER_CANCELLED ? gsub->flags & GPRS_SUBSCRIBER_CANCELLED ?
"CANCELLED " : "", "CANCELLED " : "",
subscr->flags & GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING ? gsub->flags & GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING ?
"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 " : "", "AUTH_INFO_PENDING " : "",
subscr->flags & GPRS_SUBSCRIBER_ENABLE_PURGE ? gsub->flags & GPRS_SUBSCRIBER_ENABLE_PURGE ?
"ENABLE_PURGE " : "", "ENABLE_PURGE " : "",
VTY_NEWLINE); 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, DEFUN(show_subscr_cache,
@ -760,9 +759,9 @@ DEFUN(show_subscr_cache,
SHOW_STR "Show information about subscribers\n" SHOW_STR "Show information about subscribers\n"
"Display contents of subscriber cache\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); vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
subscr_dump_full_vty(vty, subscr, 0); 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]; const char *kc_str = argv[4];
struct gsm_auth_tuple at = {0,}; struct gsm_auth_tuple at = {0,};
struct gsm_subscriber *subscr; struct gprs_subscr *subscr;
subscr = gprs_subscr_get_by_imsi(imsi); subscr = gprs_subscr_get_by_imsi(imsi);
if (!subscr) { 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[cksn] = at;
subscr->sgsn_data->auth_triplets_updated = 1; subscr->sgsn_data->auth_triplets_updated = 1;
subscr_put(subscr); gprs_subscr_put(subscr);
return CMD_SUCCESS; return CMD_SUCCESS;
failed: failed:
subscr_put(subscr); gprs_subscr_put(subscr);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -844,7 +843,7 @@ DEFUN(update_subscr_cancel, update_subscr_cancel_cmd,
const char *imsi = argv[0]; const char *imsi = argv[0];
const char *cancel_type = argv[1]; const char *cancel_type = argv[1];
struct gsm_subscriber *subscr; struct gprs_subscr *subscr;
subscr = gprs_subscr_get_by_imsi(imsi); subscr = gprs_subscr_get_by_imsi(imsi);
if (!subscr) { if (!subscr) {
@ -859,7 +858,7 @@ DEFUN(update_subscr_cancel, update_subscr_cancel_cmd,
subscr->sgsn_data->error_cause = GMM_CAUSE_IMPL_DETACHED; subscr->sgsn_data->error_cause = GMM_CAUSE_IMPL_DETACHED;
gprs_subscr_cancel(subscr); gprs_subscr_cancel(subscr);
subscr_put(subscr); gprs_subscr_put(subscr);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -871,7 +870,7 @@ DEFUN(update_subscr_create, update_subscr_create_cmd,
{ {
const char *imsi = argv[0]; const char *imsi = argv[0];
struct gsm_subscriber *subscr; struct gprs_subscr *subscr;
subscr = gprs_subscr_get_by_imsi(imsi); subscr = gprs_subscr_get_by_imsi(imsi);
if (subscr) { if (subscr) {
@ -882,7 +881,7 @@ DEFUN(update_subscr_create, update_subscr_create_cmd,
subscr = gprs_subscr_get_or_create(imsi); subscr = gprs_subscr_get_or_create(imsi);
subscr->keep_in_ram = 1; subscr->keep_in_ram = 1;
subscr_put(subscr); gprs_subscr_put(subscr);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -894,7 +893,7 @@ DEFUN(update_subscr_destroy, update_subscr_destroy_cmd,
{ {
const char *imsi = argv[0]; const char *imsi = argv[0];
struct gsm_subscriber *subscr; struct gprs_subscr *subscr;
subscr = gprs_subscr_get_by_imsi(imsi); subscr = gprs_subscr_get_by_imsi(imsi);
if (!subscr) { if (!subscr) {
@ -909,7 +908,7 @@ DEFUN(update_subscr_destroy, update_subscr_destroy_cmd,
if (subscr->use_count > 1) if (subscr->use_count > 1)
vty_out(vty, "%% subscriber is still in use%s", vty_out(vty, "%% subscriber is still in use%s",
VTY_NEWLINE); VTY_NEWLINE);
subscr_put(subscr); gprs_subscr_put(subscr);
return CMD_SUCCESS; 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 *imsi = argv[0];
const char *ret_code_str = argv[1]; const char *ret_code_str = argv[1];
struct gsm_subscriber *subscr; struct gprs_subscr *subscr;
const struct value_string cause_mapping[] = { const struct value_string cause_mapping[] = {
{ GMM_CAUSE_NET_FAIL, "system-failure" }, { 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); gprs_subscr_update(subscr);
subscr_put(subscr); gprs_subscr_put(subscr);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -975,7 +974,7 @@ DEFUN(update_subscr_update_auth_info, update_subscr_update_auth_info_cmd,
{ {
const char *imsi = argv[0]; const char *imsi = argv[0];
struct gsm_subscriber *subscr; struct gprs_subscr *subscr;
subscr = gprs_subscr_get_by_imsi(imsi); subscr = gprs_subscr_get_by_imsi(imsi);
if (!subscr) { if (!subscr) {
@ -986,7 +985,7 @@ DEFUN(update_subscr_update_auth_info, update_subscr_update_auth_info_cmd,
gprs_subscr_update_auth_info(subscr); gprs_subscr_update_auth_info(subscr);
subscr_put(subscr); gprs_subscr_put(subscr);
return CMD_SUCCESS; return CMD_SUCCESS;
} }

View File

@ -23,7 +23,7 @@
#include <openbsc/sgsn.h> #include <openbsc/sgsn.h>
#include <openbsc/gprs_gmm.h> #include <openbsc/gprs_gmm.h>
#include <openbsc/debug.h> #include <openbsc/debug.h>
#include <openbsc/gsm_subscriber.h> #include <openbsc/gprs_subscriber.h>
#include <osmocom/gsm/gsup.h> #include <osmocom/gsm/gsup.h>
#include <openbsc/gsup_client.h> #include <openbsc/gsup_client.h>
#include <openbsc/gprs_utils.h> #include <openbsc/gprs_utils.h>
@ -248,7 +248,7 @@ static void test_llme(void)
cleanup_test(); 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) void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
{ {
OSMO_ASSERT(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; 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(subscr);
OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0); OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
sfound = gprs_subscr_get_by_imsi(imsi); sfound = gprs_subscr_get_by_imsi(imsi);
OSMO_ASSERT(sfound == subscr); OSMO_ASSERT(sfound == subscr);
subscr_put(sfound); gprs_subscr_put(sfound);
} }
static void show_subscrs(FILE *out) 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, " fprintf(out, " Subscriber: %s, "
"use count: %d\n", "use count: %d\n",
subscr->imsi, subscr->use_count); subscr->imsi, subscr->use_count);
@ -284,12 +284,18 @@ static void assert_no_subscrs()
{ {
show_subscrs(stdout); show_subscrs(stdout);
fflush(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) static void test_subscriber(void)
{ {
struct gsm_subscriber *s1, *s2, *s3, *sfound; struct gprs_subscr *s1, *s2, *s3;
const char *imsi1 = "1234567890"; const char *imsi1 = "1234567890";
const char *imsi2 = "9876543210"; const char *imsi2 = "9876543210";
const char *imsi3 = "5656565656"; 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(imsi1) == NULL);
OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL); OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL); OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
VERBOSE_ASSERT(llist_count(gprs_subscribers), == 0, "%d");
/* Allocate entry 1 */ /* Allocate entry 1 */
s1 = gprs_subscr_get_or_create(imsi1); 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); assert_subscr(s1, imsi1);
VERBOSE_ASSERT(llist_count(gprs_subscribers), == 1, "%d");
OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL); OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
/* Allocate entry 2 */ /* Allocate entry 2 */
s2 = gprs_subscr_get_or_create(imsi2); 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 */ /* Allocate entry 3 */
s3 = gprs_subscr_get_or_create(imsi3); s3 = gprs_subscr_get_or_create(imsi3);
VERBOSE_ASSERT(llist_count(gprs_subscribers), == 3, "%d");
/* Check entries */ /* Check entries */
assert_subscr(s1, imsi1); assert_subscr(s1, imsi1);
@ -326,33 +337,35 @@ static void test_subscriber(void)
gprs_subscr_update(s1); gprs_subscr_update(s1);
OSMO_ASSERT(last_updated_subscr == NULL); OSMO_ASSERT(last_updated_subscr == NULL);
OSMO_ASSERT(s1->sgsn_data->mm == 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 */ /* There is no subscriber cache. Verify it */
gprs_subscr_cleanup(s1); gprs_subscr_cleanup(s1);
subscr_put(s1); gprs_subscr_put(s1);
s1 = NULL; s1 = NULL;
sfound = gprs_subscr_get_by_imsi(imsi1); VERBOSE_ASSERT(llist_count(gprs_subscribers), == 2, "%d");
OSMO_ASSERT(sfound == NULL); OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
assert_subscr(s2, imsi2); assert_subscr(s2, imsi2);
assert_subscr(s3, imsi3); 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); gprs_subscr_cleanup(s2);
subscr_put(s2); gprs_subscr_put(s2);
s2 = NULL; 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(imsi1) == NULL);
OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL); OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
assert_subscr(s3, imsi3); assert_subscr(s3, imsi3);
/* Try to delete entry 3 */ /* Try to delete entry 3 */
gprs_subscr_cleanup(s3); gprs_subscr_cleanup(s3);
subscr_put(s3); gprs_subscr_put(s3);
s3 = NULL; s3 = NULL;
VERBOSE_ASSERT(llist_count(gprs_subscribers), == 0, "%d");
OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL); 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; update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
@ -361,7 +374,7 @@ static void test_subscriber(void)
static void test_auth_triplets(void) static void test_auth_triplets(void)
{ {
struct gsm_subscriber *s1, *s1found; struct gprs_subscr *s1, *s1found;
const char *imsi1 = "1234567890"; const char *imsi1 = "1234567890";
struct gsm_auth_tuple *at; struct gsm_auth_tuple *at;
struct sgsn_mm_ctx *ctx; struct sgsn_mm_ctx *ctx;
@ -375,17 +388,17 @@ static void test_auth_triplets(void)
/* Allocate entry 1 */ /* Allocate entry 1 */
s1 = gprs_subscr_get_or_create(imsi1); 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); s1found = gprs_subscr_get_by_imsi(imsi1);
OSMO_ASSERT(s1found == s1); OSMO_ASSERT(s1found == s1);
subscr_put(s1found); gprs_subscr_put(s1found);
/* Create a context */ /* Create a context */
OSMO_ASSERT(count(gprs_llme_list()) == 0); OSMO_ASSERT(count(gprs_llme_list()) == 0);
ctx = alloc_mm_ctx(local_tlli, &raid); ctx = alloc_mm_ctx(local_tlli, &raid);
/* Attach s1 to ctx */ /* Attach s1 to ctx */
ctx->subscr = subscr_get(s1); ctx->subscr = gprs_subscr_get(s1);
ctx->subscr->sgsn_data->mm = ctx; ctx->subscr->sgsn_data->mm = ctx;
/* Try to get auth tuple */ /* Try to get auth tuple */
@ -414,7 +427,7 @@ static void test_auth_triplets(void)
OSMO_ASSERT(at == NULL); OSMO_ASSERT(at == NULL);
/* Free MM context and subscriber */ /* Free MM context and subscriber */
subscr_put(s1); gprs_subscr_put(s1);
sgsn_mm_ctx_cleanup_free(ctx); sgsn_mm_ctx_cleanup_free(ctx);
s1found = gprs_subscr_get_by_imsi(imsi1); s1found = gprs_subscr_get_by_imsi(imsi1);
OSMO_ASSERT(s1found == NULL); 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) static void test_subscriber_gsup(void)
{ {
struct gsm_subscriber *s1, *s1found; struct gprs_subscr *s1, *s1found;
const char *imsi1 = "1234567890"; const char *imsi1 = "1234567890";
struct sgsn_mm_ctx *ctx; struct sgsn_mm_ctx *ctx;
struct gprs_ra_id raid = { 0, }; struct gprs_ra_id raid = { 0, };
@ -563,17 +576,17 @@ static void test_subscriber_gsup(void)
/* Allocate entry 1 */ /* Allocate entry 1 */
s1 = gprs_subscr_get_or_create(imsi1); 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); s1found = gprs_subscr_get_by_imsi(imsi1);
OSMO_ASSERT(s1found == s1); OSMO_ASSERT(s1found == s1);
subscr_put(s1found); gprs_subscr_put(s1found);
/* Create a context */ /* Create a context */
OSMO_ASSERT(count(gprs_llme_list()) == 0); OSMO_ASSERT(count(gprs_llme_list()) == 0);
ctx = alloc_mm_ctx(local_tlli, &raid); ctx = alloc_mm_ctx(local_tlli, &raid);
/* Attach s1 to ctx */ /* Attach s1 to ctx */
ctx->subscr = subscr_get(s1); ctx->subscr = gprs_subscr_get(s1);
ctx->subscr->sgsn_data->mm = ctx; ctx->subscr->sgsn_data->mm = ctx;
/* Inject SendAuthInfoReq GSUP message */ /* Inject SendAuthInfoReq GSUP message */
@ -675,7 +688,7 @@ static void test_subscriber_gsup(void)
/* Free MM context and subscriber */ /* Free MM context and subscriber */
OSMO_ASSERT(ctx->subscr == NULL); OSMO_ASSERT(ctx->subscr == NULL);
sgsn_mm_ctx_cleanup_free(ctx); sgsn_mm_ctx_cleanup_free(ctx);
subscr_put(s1); gprs_subscr_put(s1);
s1found = gprs_subscr_get_by_imsi(imsi1); s1found = gprs_subscr_get_by_imsi(imsi1);
OSMO_ASSERT(s1found == NULL); 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) static void test_gmm_attach_subscr(void)
{ {
const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; 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; sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
subscr_request_update_location_cb = my_subscr_request_update_location; 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': "); printf("Auth policy 'remote': ");
test_gmm_attach(0); test_gmm_attach(0);
subscr_put(subscr); gprs_subscr_put(subscr);
assert_no_subscrs(); assert_no_subscrs();
sgsn->cfg.auth_policy = saved_auth_policy; 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) static void test_gmm_attach_subscr_fake_auth(void)
{ {
const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; 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; sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
subscr_request_update_location_cb = my_subscr_request_update_location; 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: "); printf("Auth policy 'remote', auth faked: ");
test_gmm_attach(0); test_gmm_attach(0);
subscr_put(subscr); gprs_subscr_put(subscr);
assert_no_subscrs(); assert_no_subscrs();
sgsn->cfg.auth_policy = saved_auth_policy; 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) static void test_gmm_attach_subscr_real_auth(void)
{ {
const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; 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; sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
subscr_request_update_location_cb = my_subscr_request_update_location; 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: "); printf("Auth policy 'remote', triplet based auth: ");
test_gmm_attach(0); test_gmm_attach(0);
subscr_put(subscr); gprs_subscr_put(subscr);
assert_no_subscrs(); assert_no_subscrs();
sgsn->cfg.auth_policy = saved_auth_policy; 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) static void test_gmm_attach_subscr_gsup_auth(int retry)
{ {
const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; 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; sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
subscr_request_update_location_cb = my_subscr_request_update_gsup_auth; 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; subscr->authorized = 1;
sgsn->cfg.require_authentication = 1; sgsn->cfg.require_authentication = 1;
sgsn->cfg.require_update_location = 1; sgsn->cfg.require_update_location = 1;
subscr_put(subscr); gprs_subscr_put(subscr);
printf("Auth policy 'remote', GSUP based auth: "); printf("Auth policy 'remote', GSUP based auth: ");
test_gmm_attach(retry); 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) static void test_gmm_attach_subscr_real_gsup_auth(int retry)
{ {
const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy; 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; sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
gsup_client_send_cb = my_gsup_client_send; gsup_client_send_cb = my_gsup_client_send;
@ -2228,7 +2241,7 @@ static void test_ggsn_selection(void)
{ {
struct apn_ctx *actxs[4]; struct apn_ctx *actxs[4];
struct sgsn_ggsn_ctx *ggc, *ggcs[3]; struct sgsn_ggsn_ctx *ggc, *ggcs[3];
struct gsm_subscriber *s1; struct gprs_subscr *s1;
const char *imsi1 = "1234567890"; const char *imsi1 = "1234567890";
struct sgsn_mm_ctx *ctx; struct sgsn_mm_ctx *ctx;
struct gprs_ra_id raid = { 0, }; struct gprs_ra_id raid = { 0, };
@ -2347,7 +2360,7 @@ static void test_ggsn_selection(void)
/* Cleanup */ /* Cleanup */
subscr_put(s1); gprs_subscr_put(s1);
sgsn_mm_ctx_cleanup_free(ctx); sgsn_mm_ctx_cleanup_free(ctx);
assert_no_subscrs(); assert_no_subscrs();

View File

@ -1,5 +1,13 @@
Testing LLME allocations Testing LLME allocations
Testing core subscriber data API 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 authentication triplet handling
Testing subscriber GSUP handling Testing subscriber GSUP handling
Testing GMM detach Testing GMM detach