blob: 90ede7651abf487093cfb60e758fd4c3332a001b [file] [log] [blame]
Harald Welte9b455bf2010-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
Harald Welteeaa614c2010-05-02 11:26:34 +020023#include <stdint.h>
Harald Welte9b455bf2010-03-14 15:45:01 +080024
25#include <osmocore/linuxlist.h>
26#include <osmocore/talloc.h>
27#include <osmocore/timer.h>
28#include <openbsc/gsm_subscriber.h>
Harald Weltecb991632010-04-26 19:18:54 +020029#include <openbsc/debug.h>
Harald Welte9b455bf2010-03-14 15:45:01 +080030#include <openbsc/gprs_sgsn.h>
Harald Weltecb991632010-04-26 19:18:54 +020031#include <openbsc/gprs_ns.h>
32#include <openbsc/gprs_bssgp.h>
Harald Welte9b455bf2010-03-14 15:45:01 +080033
34static LLIST_HEAD(sgsn_mm_ctxts);
35
36static int ra_id_equals(const struct gprs_ra_id *id1,
37 const struct gprs_ra_id *id2)
38{
39 return (id1->mcc == id2->mcc && id1->mnc == id2->mnc &&
40 id1->lac == id2->lac && id1->rac == id2->rac);
41}
42
43/* look-up a SGSN MM context based on TLLI + RAI */
Harald Welteeaa614c2010-05-02 11:26:34 +020044struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
Harald Welte9b455bf2010-03-14 15:45:01 +080045 const struct gprs_ra_id *raid)
46{
47 struct sgsn_mm_ctx *ctx;
48
49 llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
50 if (tlli == ctx->tlli &&
51 ra_id_equals(raid, &ctx->ra))
52 return ctx;
53 }
54 return NULL;
55}
56
Harald Welteeaa614c2010-05-02 11:26:34 +020057struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t p_tmsi)
Harald Welte9b455bf2010-03-14 15:45:01 +080058{
59 struct sgsn_mm_ctx *ctx;
60
61 llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
62 if (p_tmsi == ctx->p_tmsi)
63 return ctx;
64 }
65 return NULL;
66}
67
68struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi)
69{
70 struct sgsn_mm_ctx *ctx;
71
72 llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
73 if (!strcmp(imsi, ctx->imsi))
74 return ctx;
75 }
76 return NULL;
77
78}
79
80/* Allocate a new SGSN MM context */
Harald Welteeaa614c2010-05-02 11:26:34 +020081struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
Harald Welte9b455bf2010-03-14 15:45:01 +080082 const struct gprs_ra_id *raid)
83{
Harald Welte2720e732010-05-17 00:44:57 +020084 struct sgsn_mm_ctx *ctx;
Harald Welte9b455bf2010-03-14 15:45:01 +080085
Harald Welte2720e732010-05-17 00:44:57 +020086 ctx = talloc_zero(tall_bsc_ctx, struct sgsn_mm_ctx);
Harald Welte9b455bf2010-03-14 15:45:01 +080087 if (!ctx)
88 return NULL;
89
90 memcpy(&ctx->ra, raid, sizeof(ctx->ra));
91 ctx->tlli = tlli;
92 ctx->mm_state = GMM_DEREGISTERED;
93
94 llist_add(&ctx->list, &sgsn_mm_ctxts);
95
96 return ctx;
97}