blob: 50f4118886a470da650d7599b74975b77075e09d [file] [log] [blame]
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +02001/* The concept of a subscriber as seen by the BSC */
2
3/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
Holger Hans Peter Freyther66efcbc2010-06-30 09:22:31 +08004 * (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
Holger Hans Peter Freyther85531cc2010-10-06 20:37:09 +08005 * (C) 2010 by On-Waves
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +02006 *
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +010010 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020012 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte9af6ddf2011-01-01 15:25:50 +010017 * GNU Affero General Public License for more details.
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020018 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010019 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020021 *
22 */
23
24#include <unistd.h>
25#include <stdlib.h>
26#include <stdio.h>
27#include <string.h>
28#include <assert.h>
29
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010030#include <osmocom/core/talloc.h>
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020031#include <openbsc/gsm_subscriber.h>
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020032#include <openbsc/debug.h>
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020033
34LLIST_HEAD(active_subscribers);
35void *tall_subscr_ctx;
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020036
37/* for the gsm_subscriber.c */
Jan Luebbe6e300682012-12-25 18:58:34 +010038struct llist_head *subscr_bsc_active_subscribers(void)
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020039{
40 return &active_subscribers;
41}
42
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020043
Holger Hans Peter Freyther06109472010-06-30 12:56:41 +080044char *subscr_name(struct gsm_subscriber *subscr)
45{
46 if (strlen(subscr->name))
47 return subscr->name;
48
49 return subscr->imsi;
50}
51
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020052struct gsm_subscriber *subscr_alloc(void)
53{
54 struct gsm_subscriber *s;
55
Holger Hans Peter Freyther5ea73132009-10-29 02:29:45 +010056 s = talloc_zero(tall_subscr_ctx, struct gsm_subscriber);
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020057 if (!s)
58 return NULL;
59
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020060 llist_add_tail(&s->entry, &active_subscribers);
61 s->use_count = 1;
Holger Hans Peter Freyther22230252009-08-19 12:53:57 +020062 s->tmsi = GSM_RESERVED_TMSI;
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020063
64 INIT_LLIST_HEAD(&s->requests);
65
66 return s;
67}
68
69static void subscr_free(struct gsm_subscriber *subscr)
70{
71 llist_del(&subscr->entry);
72 talloc_free(subscr);
73}
74
Holger Hans Peter Freythere7cc9aa2014-03-07 18:17:22 +010075void subscr_direct_free(struct gsm_subscriber *subscr)
76{
77 OSMO_ASSERT(subscr->use_count == 1);
78 subscr_free(subscr);
79}
80
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020081struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr)
82{
83 subscr->use_count++;
Harald Welted0c19142009-12-24 11:46:44 +010084 DEBUGP(DREF, "subscr %s usage increases usage to: %d\n",
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020085 subscr->extension, subscr->use_count);
86 return subscr;
87}
88
89struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr)
90{
91 subscr->use_count--;
Harald Welted0c19142009-12-24 11:46:44 +010092 DEBUGP(DREF, "subscr %s usage decreased usage to: %d\n",
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020093 subscr->extension, subscr->use_count);
Jacob Erlbeck70d8e312014-12-03 11:08:23 +010094 if (subscr->use_count <= 0 &&
95 !((subscr->group && subscr->group->keep_subscr) ||
96 subscr->keep_in_ram))
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020097 subscr_free(subscr);
98 return NULL;
99}
100
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100101struct gsm_subscriber *subscr_get_or_create(struct gsm_subscriber_group *sgrp,
Holger Hans Peter Freytherd740b682010-11-15 09:15:01 +0100102 const char *imsi)
103{
104 struct gsm_subscriber *subscr;
105
Jan Luebbe6e300682012-12-25 18:58:34 +0100106 llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100107 if (strcmp(subscr->imsi, imsi) == 0 && subscr->group == sgrp)
Holger Hans Peter Freytherd740b682010-11-15 09:15:01 +0100108 return subscr_get(subscr);
109 }
110
111 subscr = subscr_alloc();
112 if (!subscr)
113 return NULL;
114
Harald Welted3fa84d2016-04-20 17:50:17 +0200115 strncpy(subscr->imsi, imsi, sizeof(subscr->imsi)-1);
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100116 subscr->group = sgrp;
Holger Hans Peter Freytherd740b682010-11-15 09:15:01 +0100117 return subscr;
118}
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100119
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100120struct gsm_subscriber *subscr_active_by_tmsi(struct gsm_subscriber_group *sgrp,
121 uint32_t tmsi)
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100122{
123 struct gsm_subscriber *subscr;
124
Jan Luebbe6e300682012-12-25 18:58:34 +0100125 llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100126 if (subscr->tmsi == tmsi && subscr->group == sgrp)
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100127 return subscr_get(subscr);
128 }
129
130 return NULL;
131}
132
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100133struct gsm_subscriber *subscr_active_by_imsi(struct gsm_subscriber_group *sgrp,
134 const char *imsi)
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100135{
136 struct gsm_subscriber *subscr;
137
Jan Luebbe6e300682012-12-25 18:58:34 +0100138 llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100139 if (strcmp(subscr->imsi, imsi) == 0 && subscr->group == sgrp)
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100140 return subscr_get(subscr);
141 }
142
143 return NULL;
144}
Holger Hans Peter Freytherf694d5f2010-12-22 14:31:34 +0100145
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100146int subscr_purge_inactive(struct gsm_subscriber_group *sgrp)
Holger Hans Peter Freytherf694d5f2010-12-22 14:31:34 +0100147{
148 struct gsm_subscriber *subscr, *tmp;
149 int purged = 0;
150
Jan Luebbe6e300682012-12-25 18:58:34 +0100151 llist_for_each_entry_safe(subscr, tmp, subscr_bsc_active_subscribers(), entry) {
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100152 if (subscr->group == sgrp && subscr->use_count <= 0) {
Holger Hans Peter Freytherf694d5f2010-12-22 14:31:34 +0100153 subscr_free(subscr);
154 purged += 1;
155 }
156 }
157
158 return purged;
159}