blob: 1ecdee5a518301c0ee22fc29871a0809479915af [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>
Neels Hofmeyr93bafb62017-01-13 03:12:08 +010031#include <osmocom/core/utils.h>
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020032#include <openbsc/gsm_subscriber.h>
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020033#include <openbsc/debug.h>
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020034
35LLIST_HEAD(active_subscribers);
36void *tall_subscr_ctx;
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020037
38/* for the gsm_subscriber.c */
Jan Luebbe6e300682012-12-25 18:58:34 +010039struct llist_head *subscr_bsc_active_subscribers(void)
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020040{
41 return &active_subscribers;
42}
43
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020044
Holger Hans Peter Freyther06109472010-06-30 12:56:41 +080045char *subscr_name(struct gsm_subscriber *subscr)
46{
Harald Welte7184bd02015-12-28 14:04:36 +010047 if (!subscr)
48 return "unknown";
49
Holger Hans Peter Freyther06109472010-06-30 12:56:41 +080050 if (strlen(subscr->name))
51 return subscr->name;
52
53 return subscr->imsi;
54}
55
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020056struct gsm_subscriber *subscr_alloc(void)
57{
58 struct gsm_subscriber *s;
59
Holger Hans Peter Freyther5ea73132009-10-29 02:29:45 +010060 s = talloc_zero(tall_subscr_ctx, struct gsm_subscriber);
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020061 if (!s)
62 return NULL;
63
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020064 llist_add_tail(&s->entry, &active_subscribers);
65 s->use_count = 1;
Holger Hans Peter Freyther22230252009-08-19 12:53:57 +020066 s->tmsi = GSM_RESERVED_TMSI;
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020067
68 INIT_LLIST_HEAD(&s->requests);
69
70 return s;
71}
72
73static void subscr_free(struct gsm_subscriber *subscr)
74{
75 llist_del(&subscr->entry);
76 talloc_free(subscr);
77}
78
Holger Hans Peter Freythere7cc9aa2014-03-07 18:17:22 +010079void subscr_direct_free(struct gsm_subscriber *subscr)
80{
81 OSMO_ASSERT(subscr->use_count == 1);
82 subscr_free(subscr);
83}
84
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020085struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr)
86{
87 subscr->use_count++;
Harald Welted0c19142009-12-24 11:46:44 +010088 DEBUGP(DREF, "subscr %s usage increases usage to: %d\n",
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020089 subscr->extension, subscr->use_count);
90 return subscr;
91}
92
93struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr)
94{
95 subscr->use_count--;
Harald Welted0c19142009-12-24 11:46:44 +010096 DEBUGP(DREF, "subscr %s usage decreased usage to: %d\n",
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020097 subscr->extension, subscr->use_count);
Jacob Erlbeck70d8e312014-12-03 11:08:23 +010098 if (subscr->use_count <= 0 &&
99 !((subscr->group && subscr->group->keep_subscr) ||
100 subscr->keep_in_ram))
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +0200101 subscr_free(subscr);
102 return NULL;
103}
104
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100105struct gsm_subscriber *subscr_get_or_create(struct gsm_subscriber_group *sgrp,
Holger Hans Peter Freytherd740b682010-11-15 09:15:01 +0100106 const char *imsi)
107{
108 struct gsm_subscriber *subscr;
109
Jan Luebbe6e300682012-12-25 18:58:34 +0100110 llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100111 if (strcmp(subscr->imsi, imsi) == 0 && subscr->group == sgrp)
Holger Hans Peter Freytherd740b682010-11-15 09:15:01 +0100112 return subscr_get(subscr);
113 }
114
115 subscr = subscr_alloc();
116 if (!subscr)
117 return NULL;
118
Neels Hofmeyr93bafb62017-01-13 03:12:08 +0100119 osmo_strlcpy(subscr->imsi, imsi, sizeof(subscr->imsi));
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100120 subscr->group = sgrp;
Holger Hans Peter Freytherd740b682010-11-15 09:15:01 +0100121 return subscr;
122}
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100123
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100124struct gsm_subscriber *subscr_active_by_tmsi(struct gsm_subscriber_group *sgrp,
125 uint32_t tmsi)
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100126{
127 struct gsm_subscriber *subscr;
128
Jan Luebbe6e300682012-12-25 18:58:34 +0100129 llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100130 if (subscr->tmsi == tmsi && subscr->group == sgrp)
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100131 return subscr_get(subscr);
132 }
133
134 return NULL;
135}
136
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100137struct gsm_subscriber *subscr_active_by_imsi(struct gsm_subscriber_group *sgrp,
138 const char *imsi)
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100139{
140 struct gsm_subscriber *subscr;
141
Jan Luebbe6e300682012-12-25 18:58:34 +0100142 llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100143 if (strcmp(subscr->imsi, imsi) == 0 && subscr->group == sgrp)
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100144 return subscr_get(subscr);
145 }
146
147 return NULL;
148}
Holger Hans Peter Freytherf694d5f2010-12-22 14:31:34 +0100149
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100150int subscr_purge_inactive(struct gsm_subscriber_group *sgrp)
Holger Hans Peter Freytherf694d5f2010-12-22 14:31:34 +0100151{
152 struct gsm_subscriber *subscr, *tmp;
153 int purged = 0;
154
Jan Luebbe6e300682012-12-25 18:58:34 +0100155 llist_for_each_entry_safe(subscr, tmp, subscr_bsc_active_subscribers(), entry) {
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100156 if (subscr->group == sgrp && subscr->use_count <= 0) {
Holger Hans Peter Freytherf694d5f2010-12-22 14:31:34 +0100157 subscr_free(subscr);
158 purged += 1;
159 }
160 }
161
162 return purged;
163}