blob: 3d01ca20d342c117fe60b22e75d911945a3de682 [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 Erlbeck1e30a282014-12-03 09:28:24 +010094 if (subscr->use_count <= 0 && !subscr->group->keep_subscr)
Holger Hans Peter Freyther857e5e62009-06-12 07:08:13 +020095 subscr_free(subscr);
96 return NULL;
97}
98
Jacob Erlbeck1e30a282014-12-03 09:28:24 +010099struct gsm_subscriber *subscr_get_or_create(struct gsm_subscriber_group *sgrp,
Holger Hans Peter Freytherd740b682010-11-15 09:15:01 +0100100 const char *imsi)
101{
102 struct gsm_subscriber *subscr;
103
Jan Luebbe6e300682012-12-25 18:58:34 +0100104 llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100105 if (strcmp(subscr->imsi, imsi) == 0 && subscr->group == sgrp)
Holger Hans Peter Freytherd740b682010-11-15 09:15:01 +0100106 return subscr_get(subscr);
107 }
108
109 subscr = subscr_alloc();
110 if (!subscr)
111 return NULL;
112
Holger Hans Peter Freythera5ddf482013-12-12 15:28:43 +0100113 strncpy(subscr->imsi, imsi, GSM_IMSI_LENGTH);
114 subscr->imsi[GSM_IMSI_LENGTH - 1] = '\0';
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100115 subscr->group = sgrp;
Holger Hans Peter Freytherd740b682010-11-15 09:15:01 +0100116 return subscr;
117}
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100118
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100119struct gsm_subscriber *subscr_active_by_tmsi(struct gsm_subscriber_group *sgrp,
120 uint32_t tmsi)
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100121{
122 struct gsm_subscriber *subscr;
123
Jan Luebbe6e300682012-12-25 18:58:34 +0100124 llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100125 if (subscr->tmsi == tmsi && subscr->group == sgrp)
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100126 return subscr_get(subscr);
127 }
128
129 return NULL;
130}
131
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100132struct gsm_subscriber *subscr_active_by_imsi(struct gsm_subscriber_group *sgrp,
133 const char *imsi)
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100134{
135 struct gsm_subscriber *subscr;
136
Jan Luebbe6e300682012-12-25 18:58:34 +0100137 llist_for_each_entry(subscr, subscr_bsc_active_subscribers(), entry) {
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100138 if (strcmp(subscr->imsi, imsi) == 0 && subscr->group == sgrp)
Holger Hans Peter Freyther8dfd2412010-11-15 13:32:33 +0100139 return subscr_get(subscr);
140 }
141
142 return NULL;
143}
Holger Hans Peter Freytherf694d5f2010-12-22 14:31:34 +0100144
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100145int subscr_purge_inactive(struct gsm_subscriber_group *sgrp)
Holger Hans Peter Freytherf694d5f2010-12-22 14:31:34 +0100146{
147 struct gsm_subscriber *subscr, *tmp;
148 int purged = 0;
149
Jan Luebbe6e300682012-12-25 18:58:34 +0100150 llist_for_each_entry_safe(subscr, tmp, subscr_bsc_active_subscribers(), entry) {
Jacob Erlbeck1e30a282014-12-03 09:28:24 +0100151 if (subscr->group == sgrp && subscr->use_count <= 0) {
Holger Hans Peter Freytherf694d5f2010-12-22 14:31:34 +0100152 subscr_free(subscr);
153 purged += 1;
154 }
155 }
156
157 return purged;
158}