From 33b6dadc884ec1060e401ba097523086ac34b552 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 12 Nov 2014 10:12:11 +0100 Subject: sgsn: Add gprs_subscriber.c This patch adds GPRS specific functions for gsm_subscriber objects (allocation, retrieval, deletion) and subscriber data requests/updates. The sgsn_update_subscriber_data callback is used to notify the sgsn about updates and is extended by a parameter that passes a reference to a gsm_subscriber. Sponsored-by: On-Waves ehf --- openbsc/src/gprs/Makefile.am | 2 +- openbsc/src/gprs/gprs_sgsn.c | 3 +- openbsc/src/gprs/gprs_subscriber.c | 144 +++++++++++++++++++++++++++++++++++++ openbsc/src/gprs/sgsn_main.c | 3 - 4 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 openbsc/src/gprs/gprs_subscriber.c (limited to 'openbsc/src') diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 75eafddd3..f937362a4 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -22,7 +22,7 @@ osmo_gbproxy_LDADD = $(top_builddir)/src/libcommon/libcommon.a \ osmo_sgsn_SOURCES = gprs_gmm.c gprs_sgsn.c gprs_sndcp.c gprs_sndcp_vty.c \ sgsn_main.c sgsn_vty.c sgsn_libgtp.c \ gprs_llc.c gprs_llc_parse.c gprs_llc_vty.c crc24.c \ - sgsn_ctrl.c sgsn_auth.c + sgsn_ctrl.c sgsn_auth.c gprs_subscriber.c osmo_sgsn_LDADD = \ $(top_builddir)/src/libcommon/libcommon.a \ -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index 39bfa84bc..71cd742df 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -452,7 +452,8 @@ int sgsn_force_reattach_oldmsg(struct msgb *oldmsg) return gsm0408_gprs_force_reattach_oldmsg(oldmsg); } -void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx) +void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx, + struct gsm_subscriber *subscr) { OSMO_ASSERT(mmctx); diff --git a/openbsc/src/gprs/gprs_subscriber.c b/openbsc/src/gprs/gprs_subscriber.c new file mode 100644 index 000000000..78fa3e1e8 --- /dev/null +++ b/openbsc/src/gprs/gprs_subscriber.c @@ -0,0 +1,144 @@ +/* MS subscriber data handling */ + +/* (C) 2014 by sysmocom s.f.m.c. GmbH + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include + +#include +#include +#include + +#include + +extern void *tall_bsc_ctx; + +void gprs_subscr_init(struct sgsn_instance *sgi) +{ +} + +struct gsm_subscriber *gprs_subscr_get_or_create(const char *imsi) +{ + struct gsm_subscriber *subscr; + + subscr = subscr_get_or_create(NULL, imsi); + if (!subscr) + return NULL; + + subscr->keep_in_ram = 1; + + return subscr; +} + +struct gsm_subscriber *gprs_subscr_get_by_imsi(const char *imsi) +{ + return subscr_active_by_imsi(NULL, imsi); +} + +void gprs_subscr_delete(struct gsm_subscriber *subscr) +{ + if (subscr->mm) { + subscr_put(subscr->mm->subscr); + subscr->mm->subscr = NULL; + subscr->mm = NULL; + } + + if ((subscr->flags & GPRS_SUBSCRIBER_CANCELLED) || + (subscr->flags & GSM_SUBSCRIBER_FIRST_CONTACT)) + subscr->keep_in_ram = 0; + + subscr_put(subscr); +} + +void gprs_subscr_put_and_cancel(struct gsm_subscriber *subscr) +{ + subscr->authorized = 0; + subscr->flags |= GPRS_SUBSCRIBER_CANCELLED; + + gprs_subscr_update(subscr); + + gprs_subscr_delete(subscr); +} + +int gprs_subscr_query(struct gsm_subscriber *subscr) +{ + /* TODO: Implement remote query to MSC, ... */ + + LOGMMCTXP(LOGL_INFO, subscr->mm, + "subscriber data is not available (remote query NYI)\n"); + return -ENOTSUP; +} + +void gprs_subscr_update(struct gsm_subscriber *subscr) +{ + LOGMMCTXP(LOGL_DEBUG, subscr->mm, "Updating subscriber data\n"); + + subscr->flags &= ~GPRS_SUBSCRIBER_UPDATE_PENDING; + subscr->flags &= ~GSM_SUBSCRIBER_FIRST_CONTACT; + + sgsn_update_subscriber_data(subscr->mm, subscr); +} + +int gprs_subscr_request_update(struct sgsn_mm_ctx *mmctx) +{ + struct gsm_subscriber *subscr = NULL; + int need_update = 0; + int rc; + + LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber data update\n"); + + if (mmctx->subscr) { + subscr = subscr_get(mmctx->subscr); + } else if (mmctx->imsi[0]) { + subscr = gprs_subscr_get_by_imsi(mmctx->imsi); + need_update = 1; + } + + if (!subscr) { + subscr = gprs_subscr_get_or_create(mmctx->imsi); + subscr->flags |= GSM_SUBSCRIBER_FIRST_CONTACT; + need_update = 1; + } + + if (strcpy(subscr->equipment.imei, mmctx->imei) != 0) { + strncpy(subscr->equipment.imei, mmctx->imei, GSM_IMEI_LENGTH-1); + subscr->equipment.imei[GSM_IMEI_LENGTH-1] = 0; + need_update = 1; + } + + if (subscr->lac != mmctx->ra.lac) { + subscr->lac = mmctx->ra.lac; + need_update = 1; + } + + if (need_update) { + subscr->flags |= GPRS_SUBSCRIBER_UPDATE_PENDING; + if (!mmctx->subscr) { + subscr->mm = mmctx; + mmctx->subscr = subscr_get(subscr); + } + + rc = gprs_subscr_query(subscr); + subscr_put(subscr); + return rc; + } + gprs_subscr_update(subscr); + subscr_put(subscr); + return 0; +} diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 0310cb2b2..141eacf94 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -58,9 +58,6 @@ #include "../../bscconfig.h" -/* this is here for the vty... it will never be called */ -void subscr_put() { abort(); } - #define _GNU_SOURCE #include -- cgit v1.2.3