aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/gprs_sgsn.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2015-12-29 18:56:13 +0100
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2016-03-03 16:19:07 +0100
commit315abfd46b7de3923d8d111322f56aab88f7fd27 (patch)
treeb4b906a0ab4ce06c6420446f103283c57090cffb /openbsc/src/gprs/gprs_sgsn.c
parent648b9db47f191c905f3fa52ea67c564e322e7436 (diff)
WIP: Really ugly hacks to get up to (and including) PDP CTX ACT
Diffstat (limited to 'openbsc/src/gprs/gprs_sgsn.c')
-rw-r--r--openbsc/src/gprs/gprs_sgsn.c51
1 files changed, 46 insertions, 5 deletions
diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c
index 99477f4f4..1aa29be28 100644
--- a/openbsc/src/gprs/gprs_sgsn.c
+++ b/openbsc/src/gprs/gprs_sgsn.c
@@ -91,6 +91,20 @@ static const struct rate_ctr_group_desc pdpctx_ctrg_desc = {
};
/* look-up a SGSN MM context based on TLLI + RAI */
+struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx)
+{
+ struct sgsn_mm_ctx *ctx;
+
+ llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
+ if (ctx->ran_type == MM_CTX_T_UTRAN_Iu && uectx == ctx->iu.ue_ctx)
+ return ctx;
+ }
+
+ return NULL;
+}
+
+
+/* look-up a SGSN MM context based on TLLI + RAI */
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
const struct gprs_ra_id *raid)
{
@@ -165,6 +179,7 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
return NULL;
memcpy(&ctx->ra, raid, sizeof(ctx->ra));
+ ctx->ran_type = MM_CTX_T_GERAN_Gb;
ctx->gb.tlli = tlli;
ctx->mm_state = GMM_DEREGISTERED;
ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL;
@@ -176,6 +191,28 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
return ctx;
}
+/* Allocate a new SGSN MM context */
+struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx)
+{
+ struct sgsn_mm_ctx *ctx;
+
+ ctx = talloc_zero(tall_bsc_ctx, struct sgsn_mm_ctx);
+ if (!ctx)
+ return NULL;
+
+ ctx->ran_type = MM_CTX_T_UTRAN_Iu;
+ ctx->iu.ue_ctx = uectx;
+ ctx->mm_state = GMM_DEREGISTERED;
+ ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL;
+ ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, 0);
+ INIT_LLIST_HEAD(&ctx->pdp_list);
+
+ llist_add(&ctx->list, &sgsn_mm_ctxts);
+
+ return ctx;
+}
+
+
/* this is a hard _free_ function, it doesn't clean up the PDP contexts
* in libgtp! */
static void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm)
@@ -233,11 +270,13 @@ void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm)
subscr_put(subscr);
}
+ if (mm->ran_type == MM_CTX_T_GERAN_Gb) {
+ /* TLLI unassignment, must be called after sgsn_mm_ctx_free */
+ gprs_llgmm_assign(llme, tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
+ }
+
sgsn_mm_ctx_free(mm);
mm = NULL;
-
- /* TLLI unassignment, must be called after sgsn_mm_ctx_free */
- gprs_llgmm_assign(llme, tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
}
@@ -307,8 +346,10 @@ void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp)
LOGPDPCTXP(LOGL_INFO, pdp, "Forcing release of PDP context\n");
- /* Force the deactivation of the SNDCP layer */
- sndcp_sm_deactivate_ind(&pdp->mm->gb.llme->lle[pdp->sapi], pdp->nsapi);
+ if (pdp->mm->ran_type == MM_CTX_T_GERAN_Gb) {
+ /* Force the deactivation of the SNDCP layer */
+ sndcp_sm_deactivate_ind(&pdp->mm->gb.llme->lle[pdp->sapi], pdp->nsapi);
+ }
memset(&sig_data, 0, sizeof(sig_data));
sig_data.pdp = pdp;