blob: cf0af908395a8d886937e393c79a995a9dccad77 [file] [log] [blame]
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001/* MS subscriber data handling */
2
3/* (C) 2014 by sysmocom s.f.m.c. GmbH
4 *
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#include <openbsc/gsm_subscriber.h>
23
24#include <openbsc/sgsn.h>
25#include <openbsc/gprs_sgsn.h>
26#include <openbsc/gprs_gmm.h>
27
28#include <openbsc/debug.h>
29
30extern void *tall_bsc_ctx;
31
32void gprs_subscr_init(struct sgsn_instance *sgi)
33{
34}
35
Jacob Erlbecka1e03732014-12-02 11:28:38 +010036static struct sgsn_subscriber_data *sgsn_subscriber_data_alloc(void *ctx)
37{
38 struct sgsn_subscriber_data *sdata;
39
40 sdata = talloc_zero(ctx, struct sgsn_subscriber_data);
41
42 return sdata;
43}
44
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010045struct gsm_subscriber *gprs_subscr_get_or_create(const char *imsi)
46{
47 struct gsm_subscriber *subscr;
48
49 subscr = subscr_get_or_create(NULL, imsi);
50 if (!subscr)
51 return NULL;
52
Jacob Erlbecka1e03732014-12-02 11:28:38 +010053 if (!subscr->sgsn_data)
54 subscr->sgsn_data = sgsn_subscriber_data_alloc(subscr);
55
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010056 subscr->keep_in_ram = 1;
57
58 return subscr;
59}
60
61struct gsm_subscriber *gprs_subscr_get_by_imsi(const char *imsi)
62{
63 return subscr_active_by_imsi(NULL, imsi);
64}
65
66void gprs_subscr_delete(struct gsm_subscriber *subscr)
67{
Jacob Erlbecka1e03732014-12-02 11:28:38 +010068 if (subscr->sgsn_data->mm) {
69 subscr_put(subscr->sgsn_data->mm->subscr);
70 subscr->sgsn_data->mm->subscr = NULL;
71 subscr->sgsn_data->mm = NULL;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010072 }
73
74 if ((subscr->flags & GPRS_SUBSCRIBER_CANCELLED) ||
75 (subscr->flags & GSM_SUBSCRIBER_FIRST_CONTACT))
76 subscr->keep_in_ram = 0;
77
78 subscr_put(subscr);
79}
80
81void gprs_subscr_put_and_cancel(struct gsm_subscriber *subscr)
82{
83 subscr->authorized = 0;
84 subscr->flags |= GPRS_SUBSCRIBER_CANCELLED;
85
86 gprs_subscr_update(subscr);
87
88 gprs_subscr_delete(subscr);
89}
90
91int gprs_subscr_query(struct gsm_subscriber *subscr)
92{
93 /* TODO: Implement remote query to MSC, ... */
94
Jacob Erlbecka1e03732014-12-02 11:28:38 +010095 LOGMMCTXP(LOGL_INFO, subscr->sgsn_data->mm,
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010096 "subscriber data is not available (remote query NYI)\n");
97 return -ENOTSUP;
98}
99
100void gprs_subscr_update(struct gsm_subscriber *subscr)
101{
Jacob Erlbecka1e03732014-12-02 11:28:38 +0100102 LOGMMCTXP(LOGL_DEBUG, subscr->sgsn_data->mm, "Updating subscriber data\n");
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100103
104 subscr->flags &= ~GPRS_SUBSCRIBER_UPDATE_PENDING;
105 subscr->flags &= ~GSM_SUBSCRIBER_FIRST_CONTACT;
106
Jacob Erlbecka1e03732014-12-02 11:28:38 +0100107 sgsn_update_subscriber_data(subscr->sgsn_data->mm, subscr);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100108}
109
110int gprs_subscr_request_update(struct sgsn_mm_ctx *mmctx)
111{
112 struct gsm_subscriber *subscr = NULL;
113 int need_update = 0;
114 int rc;
115
116 LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber data update\n");
117
118 if (mmctx->subscr) {
119 subscr = subscr_get(mmctx->subscr);
120 } else if (mmctx->imsi[0]) {
121 subscr = gprs_subscr_get_by_imsi(mmctx->imsi);
122 need_update = 1;
123 }
124
125 if (!subscr) {
126 subscr = gprs_subscr_get_or_create(mmctx->imsi);
127 subscr->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
128 need_update = 1;
129 }
130
131 if (strcpy(subscr->equipment.imei, mmctx->imei) != 0) {
132 strncpy(subscr->equipment.imei, mmctx->imei, GSM_IMEI_LENGTH-1);
133 subscr->equipment.imei[GSM_IMEI_LENGTH-1] = 0;
134 need_update = 1;
135 }
136
137 if (subscr->lac != mmctx->ra.lac) {
138 subscr->lac = mmctx->ra.lac;
139 need_update = 1;
140 }
141
142 if (need_update) {
143 subscr->flags |= GPRS_SUBSCRIBER_UPDATE_PENDING;
144 if (!mmctx->subscr) {
Jacob Erlbecka1e03732014-12-02 11:28:38 +0100145 subscr->sgsn_data->mm = mmctx;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100146 mmctx->subscr = subscr_get(subscr);
147 }
148
149 rc = gprs_subscr_query(subscr);
150 subscr_put(subscr);
151 return rc;
152 }
153 gprs_subscr_update(subscr);
154 subscr_put(subscr);
155 return 0;
156}