blob: 477e448bea98d0e5f33727bccee61632350e45bd [file] [log] [blame]
Harald Welte75bb8202010-03-14 15:45:01 +08001/* GPRS SGSN functionality */
2
3/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
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 General Public License as published by
9 * the Free Software Foundation; either version 2 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 General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
22
23#include <sys/types.h>
24
25#include <osmocore/linuxlist.h>
26#include <osmocore/talloc.h>
27#include <osmocore/timer.h>
28#include <openbsc/gsm_subscriber.h>
29#include <openbsc/gprs_sgsn.h>
30
31static LLIST_HEAD(sgsn_mm_ctxts);
32
33static int ra_id_equals(const struct gprs_ra_id *id1,
34 const struct gprs_ra_id *id2)
35{
36 return (id1->mcc == id2->mcc && id1->mnc == id2->mnc &&
37 id1->lac == id2->lac && id1->rac == id2->rac);
38}
39
40/* look-up a SGSN MM context based on TLLI + RAI */
41struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(u_int32_t tlli,
42 const struct gprs_ra_id *raid)
43{
44 struct sgsn_mm_ctx *ctx;
45
46 llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
47 if (tlli == ctx->tlli &&
48 ra_id_equals(raid, &ctx->ra))
49 return ctx;
50 }
51 return NULL;
52}
53
54struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(u_int32_t p_tmsi)
55{
56 struct sgsn_mm_ctx *ctx;
57
58 llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
59 if (p_tmsi == ctx->p_tmsi)
60 return ctx;
61 }
62 return NULL;
63}
64
65struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi)
66{
67 struct sgsn_mm_ctx *ctx;
68
69 llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
70 if (!strcmp(imsi, ctx->imsi))
71 return ctx;
72 }
73 return NULL;
74
75}
76
77/* Allocate a new SGSN MM context */
78struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(u_int32_t tlli,
79 const struct gprs_ra_id *raid)
80{
81 struct sgsn_mm_ctx *ctx = talloc_zero(NULL, struct sgsn_mm_ctx);
82
83 if (!ctx)
84 return NULL;
85
86 memcpy(&ctx->ra, raid, sizeof(ctx->ra));
87 ctx->tlli = tlli;
88 ctx->mm_state = GMM_DEREGISTERED;
89
90 llist_add(&ctx->list, &sgsn_mm_ctxts);
91
92 return ctx;
93}