aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/gprs_sgsn.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2010-05-17 22:58:03 +0200
committerHarald Welte <laforge@gnumonks.org>2010-05-17 22:58:03 +0200
commitd193cb327a145b5d69953f12c5638eb46997f791 (patch)
tree644a58f5a7adcfa89e611c7fa1fbee09be9096cc /openbsc/src/gprs/gprs_sgsn.c
parent8fc1a46f2868d71ba271aa34d1758a6c6bb8bd92 (diff)
[GPRS] More work on a real SGSN
Diffstat (limited to 'openbsc/src/gprs/gprs_sgsn.c')
-rw-r--r--openbsc/src/gprs/gprs_sgsn.c120
1 files changed, 119 insertions, 1 deletions
diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c
index 90ede7651..4e5fb016a 100644
--- a/openbsc/src/gprs/gprs_sgsn.c
+++ b/openbsc/src/gprs/gprs_sgsn.c
@@ -31,7 +31,10 @@
#include <openbsc/gprs_ns.h>
#include <openbsc/gprs_bssgp.h>
-static LLIST_HEAD(sgsn_mm_ctxts);
+LLIST_HEAD(sgsn_mm_ctxts);
+LLIST_HEAD(sgsn_ggsn_ctxts);
+LLIST_HEAD(sgsn_apn_ctxts);
+LLIST_HEAD(sgsn_pdp_ctxts);
static int ra_id_equals(const struct gprs_ra_id *id1,
const struct gprs_ra_id *id2)
@@ -95,3 +98,118 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
return ctx;
}
+
+struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_nsapi(const struct sgsn_mm_ctx *mm,
+ uint8_t nsapi)
+{
+ struct sgsn_pdp_ctx *pdp;
+
+ llist_for_each_entry(pdp, &mm->pdp_list, list) {
+ if (pdp->nsapi == nsapi)
+ return pdp;
+ }
+ return NULL;
+}
+
+struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm,
+ uint8_t nsapi)
+{
+ struct sgsn_pdp_ctx *pdp;
+
+ pdp = sgsn_pdp_ctx_by_nsapi(mm, nsapi);
+ if (pdp)
+ return NULL;
+
+ pdp = talloc_zero(tall_bsc_ctx, struct sgsn_pdp_ctx);
+ if (!pdp)
+ return NULL;
+
+ pdp->mm = mm;
+ pdp->nsapi = nsapi;
+ llist_add(&pdp->list, &mm->pdp_list);
+ llist_add(&pdp->g_list, &sgsn_pdp_ctxts);
+
+ return pdp;
+}
+
+void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp)
+{
+ llist_del(&pdp->list);
+ llist_del(&pdp->g_list);
+ talloc_free(pdp);
+}
+
+/* GGSN contexts */
+
+struct ggsn_ctx *ggsn_ctx_alloc(uint32_t id)
+{
+ struct ggsn_ctx *ggc;
+
+ ggc = talloc_zero(tall_bsc_ctx, struct ggsn_ctx);
+ if (!ggc)
+ return NULL;
+
+ ggc->id = id;
+ ggc->gtp_version = 1;
+
+ return ggc;
+}
+
+struct ggsn_ctx *ggsn_ctx_by_id(uint32_t id)
+{
+ struct ggsn_ctx *ggc;
+
+ llist_for_each_entry(ggc, &sgsn_ggsn_ctxts, list) {
+ if (id == ggc->id)
+ return ggc;
+ }
+ return NULL;
+}
+
+struct ggsn_ctx *ggsn_ctx_find_alloc(uint32_t id)
+{
+ struct ggsn_ctx *ggc;
+
+ ggc = ggsn_ctx_by_id(id);
+ if (!ggc)
+ ggc = ggsn_ctx_alloc(id);
+ return ggc;
+}
+
+/* APN contexts */
+
+#if 0
+struct apn_ctx *apn_ctx_alloc(const char *ap_name)
+{
+ struct apn_ctx *actx;
+
+ actx = talloc_zero(talloc_bsc_ctx, struct apn_ctx);
+ if (!actx)
+ return NULL;
+ actx->name = talloc_strdup(actx, ap_name);
+
+ return actx;
+}
+
+struct apn_ctx *apn_ctx_by_name(const char *name)
+{
+ struct apn_ctx *actx;
+
+ llist_for_each_entry(actx, &sgsn_apn_ctxts, list) {
+ if (!strcmp(name, actx->name))
+ return actx;
+ }
+ return NULL;
+}
+
+struct apn_ctx *apn_ctx_find_alloc(const char *name)
+{
+ struct apn_ctx *actx;
+
+ actx = apn_ctx_by_name(name);
+ if (!actx)
+ actx = apn_ctx_alloc(name);
+
+ return actx;
+}
+#endif