blob: 78fa3e1e802cbe80f4420a407f70730525904ad2 [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
36struct gsm_subscriber *gprs_subscr_get_or_create(const char *imsi)
37{
38 struct gsm_subscriber *subscr;
39
40 subscr = subscr_get_or_create(NULL, imsi);
41 if (!subscr)
42 return NULL;
43
44 subscr->keep_in_ram = 1;
45
46 return subscr;
47}
48
49struct gsm_subscriber *gprs_subscr_get_by_imsi(const char *imsi)
50{
51 return subscr_active_by_imsi(NULL, imsi);
52}
53
54void gprs_subscr_delete(struct gsm_subscriber *subscr)
55{
56 if (subscr->mm) {
57 subscr_put(subscr->mm->subscr);
58 subscr->mm->subscr = NULL;
59 subscr->mm = NULL;
60 }
61
62 if ((subscr->flags & GPRS_SUBSCRIBER_CANCELLED) ||
63 (subscr->flags & GSM_SUBSCRIBER_FIRST_CONTACT))
64 subscr->keep_in_ram = 0;
65
66 subscr_put(subscr);
67}
68
69void gprs_subscr_put_and_cancel(struct gsm_subscriber *subscr)
70{
71 subscr->authorized = 0;
72 subscr->flags |= GPRS_SUBSCRIBER_CANCELLED;
73
74 gprs_subscr_update(subscr);
75
76 gprs_subscr_delete(subscr);
77}
78
79int gprs_subscr_query(struct gsm_subscriber *subscr)
80{
81 /* TODO: Implement remote query to MSC, ... */
82
83 LOGMMCTXP(LOGL_INFO, subscr->mm,
84 "subscriber data is not available (remote query NYI)\n");
85 return -ENOTSUP;
86}
87
88void gprs_subscr_update(struct gsm_subscriber *subscr)
89{
90 LOGMMCTXP(LOGL_DEBUG, subscr->mm, "Updating subscriber data\n");
91
92 subscr->flags &= ~GPRS_SUBSCRIBER_UPDATE_PENDING;
93 subscr->flags &= ~GSM_SUBSCRIBER_FIRST_CONTACT;
94
95 sgsn_update_subscriber_data(subscr->mm, subscr);
96}
97
98int gprs_subscr_request_update(struct sgsn_mm_ctx *mmctx)
99{
100 struct gsm_subscriber *subscr = NULL;
101 int need_update = 0;
102 int rc;
103
104 LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber data update\n");
105
106 if (mmctx->subscr) {
107 subscr = subscr_get(mmctx->subscr);
108 } else if (mmctx->imsi[0]) {
109 subscr = gprs_subscr_get_by_imsi(mmctx->imsi);
110 need_update = 1;
111 }
112
113 if (!subscr) {
114 subscr = gprs_subscr_get_or_create(mmctx->imsi);
115 subscr->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
116 need_update = 1;
117 }
118
119 if (strcpy(subscr->equipment.imei, mmctx->imei) != 0) {
120 strncpy(subscr->equipment.imei, mmctx->imei, GSM_IMEI_LENGTH-1);
121 subscr->equipment.imei[GSM_IMEI_LENGTH-1] = 0;
122 need_update = 1;
123 }
124
125 if (subscr->lac != mmctx->ra.lac) {
126 subscr->lac = mmctx->ra.lac;
127 need_update = 1;
128 }
129
130 if (need_update) {
131 subscr->flags |= GPRS_SUBSCRIBER_UPDATE_PENDING;
132 if (!mmctx->subscr) {
133 subscr->mm = mmctx;
134 mmctx->subscr = subscr_get(subscr);
135 }
136
137 rc = gprs_subscr_query(subscr);
138 subscr_put(subscr);
139 return rc;
140 }
141 gprs_subscr_update(subscr);
142 subscr_put(subscr);
143 return 0;
144}