blob: 1f98cc66c24fb6534a9a592228cc1d0a166e7681 [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{
Harald Welte7184bd02015-12-28 14:04:36 +010046 if (!subscr)
47 return "unknown";
48
Holger Hans Peter Freyther06109472010-06-30 12:56:41 +080049 if (strlen(subscr->name))
50 return subscr->name;
51
52 return subscr->imsi;
53}
54
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020055struct gsm_subscriber *subscr_alloc(void)
56{
57 struct gsm_subscriber *s;
58
Holger Hans Peter Freyther5ea73132009-10-29 02:29:45 +010059 s = talloc_zero(tall_subscr_ctx, struct gsm_subscriber);
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020060 if (!s)
61 return NULL;
62
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020063 llist_add_tail(&s->entry, &active_subscribers);
64 s->use_count = 1;
Holger Hans Peter Freyther22230252009-08-19 12:53:57 +020065 s->tmsi = GSM_RESERVED_TMSI;
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020066
67 INIT_LLIST_HEAD(&s->requests);
68
69 return s;
70}
71
72static void subscr_free(struct gsm_subscriber *subscr)
73{
74 llist_del(&subscr->entry);
75 talloc_free(subscr);
76}
77
Holger Hans Peter Freythere7cc9aa2014-03-07 18:17:22 +010078void subscr_direct_free(struct gsm_subscriber *subscr)
79{
80 OSMO_ASSERT(subscr->use_count == 1);
81 subscr_free(subscr);
82}
83
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020084struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr)
85{
86 subscr->use_count++;
Harald Welted0c19142009-12-24 11:46:44 +010087 DEBUGP(DREF, "subscr %s usage increases usage to: %d\n",
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020088 subscr->extension, subscr->use_count);
89 return subscr;
90}
91
92struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr)
93{
94 subscr->use_count--;
Harald Welted0c19142009-12-24 11:46:44 +010095 DEBUGP(DREF, "subscr %s usage decreased usage to: %d\n",
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020096 subscr->extension, subscr->use_count);
Jacob Erlbeck70d8e312014-12-03 11:08:23 +010097 if (subscr->use_count <= 0 &&
98 !((subscr->group && subscr->group->keep_subscr) ||
99 subscr->keep_in_ram))
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +0200100 subscr_free(subscr);
101 return NULL;
102}
103
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100104struct gsm_subscriber *subscr_get_or_create(struct gsm_subscriber_group *sgrp,
Holger Hans Peter Freytherd740b682010-11-15 09:15:01 +0100105 const char *imsi)
106{
107 struct gsm_subscriber *subscr;
108
Jan Luebbe6e300682012-12-25 18:58:34 +0100109 llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100110 if (strcmp(subscr->imsi, imsi) == 0 && subscr->group == sgrp)
Holger Hans Peter Freytherd740b682010-11-15 09:15:01 +0100111 return subscr_get(subscr);
112 }
113
114 subscr = subscr_alloc();
115 if (!subscr)
116 return NULL;
117
Harald Welted3fa84d2016-04-20 17:50:17 +0200118 strncpy(subscr->imsi, imsi, sizeof(subscr->imsi)-1);
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100119 subscr->group = sgrp;
Holger Hans Peter Freytherd740b682010-11-15 09:15:01 +0100120 return subscr;
121}
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100122
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100123struct gsm_subscriber *subscr_active_by_tmsi(struct gsm_subscriber_group *sgrp,
124 uint32_t tmsi)
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100125{
126 struct gsm_subscriber *subscr;
127
Jan Luebbe6e300682012-12-25 18:58:34 +0100128 llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100129 if (subscr->tmsi == tmsi && subscr->group == sgrp)
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100130 return subscr_get(subscr);
131 }
132
133 return NULL;
134}
135
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100136struct gsm_subscriber *subscr_active_by_imsi(struct gsm_subscriber_group *sgrp,
137 const char *imsi)
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100138{
139 struct gsm_subscriber *subscr;
140
Jan Luebbe6e300682012-12-25 18:58:34 +0100141 llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100142 if (strcmp(subscr->imsi, imsi) == 0 && subscr->group == sgrp)
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100143 return subscr_get(subscr);
144 }
145
146 return NULL;
147}
Holger Hans Peter Freytherf694d5f2010-12-22 14:31:34 +0100148
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100149int subscr_purge_inactive(struct gsm_subscriber_group *sgrp)
Holger Hans Peter Freytherf694d5f2010-12-22 14:31:34 +0100150{
151 struct gsm_subscriber *subscr, *tmp;
152 int purged = 0;
153
Jan Luebbe6e300682012-12-25 18:58:34 +0100154 llist_for_each_entry_safe(subscr, tmp, subscr_bsc_active_subscribers(), entry) {
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100155 if (subscr->group == sgrp && subscr->use_count <= 0) {
Holger Hans Peter Freytherf694d5f2010-12-22 14:31:34 +0100156 subscr_free(subscr);
157 purged += 1;
158 }
159 }
160
161 return purged;
162}