diff options
Diffstat (limited to 'openbsc/src/gprs/gprs_sgsn.c')
-rw-r--r-- | openbsc/src/gprs/gprs_sgsn.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c new file mode 100644 index 000000000..ba4671955 --- /dev/null +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -0,0 +1,96 @@ +/* GPRS SGSN functionality */ + +/* (C) 2009 by Harald Welte <laforge@gnumonks.org> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include <stdint.h> + +#include <osmocore/linuxlist.h> +#include <osmocore/talloc.h> +#include <osmocore/timer.h> +#include <openbsc/gsm_subscriber.h> +#include <openbsc/debug.h> +#include <openbsc/gprs_sgsn.h> +#include <openbsc/gprs_ns.h> +#include <openbsc/gprs_bssgp.h> + +static LLIST_HEAD(sgsn_mm_ctxts); + +static int ra_id_equals(const struct gprs_ra_id *id1, + const struct gprs_ra_id *id2) +{ + return (id1->mcc == id2->mcc && id1->mnc == id2->mnc && + id1->lac == id2->lac && id1->rac == id2->rac); +} + +/* look-up a SGSN MM context based on TLLI + RAI */ +struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli, + const struct gprs_ra_id *raid) +{ + struct sgsn_mm_ctx *ctx; + + llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) { + if (tlli == ctx->tlli && + ra_id_equals(raid, &ctx->ra)) + return ctx; + } + return NULL; +} + +struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t p_tmsi) +{ + struct sgsn_mm_ctx *ctx; + + llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) { + if (p_tmsi == ctx->p_tmsi) + return ctx; + } + return NULL; +} + +struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi) +{ + struct sgsn_mm_ctx *ctx; + + llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) { + if (!strcmp(imsi, ctx->imsi)) + return ctx; + } + return NULL; + +} + +/* Allocate a new SGSN MM context */ +struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli, + const struct gprs_ra_id *raid) +{ + struct sgsn_mm_ctx *ctx = talloc_zero(NULL, struct sgsn_mm_ctx); + + if (!ctx) + return NULL; + + memcpy(&ctx->ra, raid, sizeof(ctx->ra)); + ctx->tlli = tlli; + ctx->mm_state = GMM_DEREGISTERED; + + llist_add(&ctx->list, &sgsn_mm_ctxts); + + return ctx; +} |