From b100895557af0980d5910a3dc81903179dea615e Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 2 May 2015 19:55:38 +0200 Subject: [PATCH] sgsn: Add various signals consumed by CDR or other client code --- openbsc/include/openbsc/signal.h | 21 ++++++++++++++++++++- openbsc/src/gprs/gprs_gmm.c | 31 ++++++++++++++++++++++++++++++- openbsc/src/gprs/gprs_sgsn.c | 19 +++++++++++++++++++ openbsc/src/gprs/sgsn_libgtp.c | 11 +++++++++++ 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/openbsc/include/openbsc/signal.h b/openbsc/include/openbsc/signal.h index 39319f1c9..8f27b3831 100644 --- a/openbsc/include/openbsc/signal.h +++ b/openbsc/include/openbsc/signal.h @@ -1,5 +1,5 @@ /* Generic signalling/notification infrastructure */ -/* (C) 2009-2010 by Holger Hans Peter Freyther +/* (C) 2009-2010, 2015 by Holger Hans Peter Freyther * (C) 2009 by Harald Welte * (C) 2010 by On-Waves * All Rights Reserved @@ -46,6 +46,7 @@ enum signal_subsystems { SS_MSC, SS_HO, SS_CCCH, + SS_SGSN, }; /* SS_PAGING signals */ @@ -241,4 +242,22 @@ struct ccch_signal_data { uint16_t rach_access_count; }; +/* GPRS SGSN signals SS_SGSN */ +enum signal_sgsn { + S_SGSN_ATTACH, + S_SGSN_DETACH, + S_SGSN_UPDATE, + S_SGSN_PDP_ACT, + S_SGSN_PDP_DEACT, + S_SGSN_PDP_TERMINATE, + S_SGSN_PDP_FREE, + S_SGSN_MM_FREE, +}; + +struct sgsn_mm_ctx; +struct sgsn_signal_data { + struct sgsn_mm_ctx *mm; + struct sgsn_pdp_ctx *pdp; /* non-NULL for PDP_ACT, PDP_DEACT, PDP_FREE */ +}; + #endif diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 2a856a6cb..8ada3d41b 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -52,6 +52,7 @@ #include #include #include +#include #include @@ -580,6 +581,10 @@ static void extract_subscr_msisdn(struct sgsn_mm_ctx *ctx) /* Check if we can already authorize a subscriber */ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx) { +#ifndef PTMSI_ALLOC + struct sgsn_signal_data sig_data; +#endif + /* Request IMSI and IMEI from the MS if they are unknown */ if (!strlen(ctx->imei)) { ctx->t3370_id_type = GSM_MI_TYPE_IMEI; @@ -643,6 +648,9 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx) mmctx_timer_start(ctx, 3350, GSM0408_T3350_SECS); ctx->t3350_mode = GMM_T3350_MODE_ATT; #else + memset(&sig_data, 0, sizeof(sig_data)); + sig_data.mm = mmctx; + osmo_signal_dispatch(SS_SGSN, S_SGSN_ATTACH, &sig_data); ctx->mm_state = GMM_REGISTERED_NORMAL; #endif @@ -976,8 +984,13 @@ static int gsm48_rx_gmm_det_req(struct sgsn_mm_ctx *ctx, struct msgb *msg) rc = gsm48_tx_gmm_det_ack_oldmsg(msg, 0); } - if (ctx) + if (ctx) { + struct sgsn_signal_data sig_data; + memset(&sig_data, 0, sizeof(sig_data)); + sig_data.mm = ctx; + osmo_signal_dispatch(SS_SGSN, S_SGSN_DETACH, &sig_data); mm_ctx_cleanup_free(ctx, "GPRS DETACH REQUEST"); + } return rc; } @@ -1083,6 +1096,9 @@ static void process_ms_ctx_status(struct sgsn_mm_ctx *mmctx, static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, struct gprs_llc_llme *llme) { +#ifndef PTMSI_ALLOC + struct sgsn_signal_data sig_data; +#endif struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); uint8_t *cur = gh->data; uint8_t ms_ra_acc_cap_len; @@ -1168,6 +1184,10 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, #else /* Make sure we are NORMAL (i.e. not SUSPENDED anymore) */ mmctx->mm_state = GMM_REGISTERED_NORMAL; + + memset(&sig_data, 0, sizeof(sig_data)); + sig_data.mm = mmctx; + osmo_signal_dispatch(SS_SGSN, S_SGSN_UPDATE, &sig_data); #endif /* Even if there is no P-TMSI allocated, the MS will switch from * foreign TLLI to local TLLI */ @@ -1217,6 +1237,7 @@ static int gsm48_rx_gmm_status(struct sgsn_mm_ctx *mmctx, struct msgb *msg) static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg, struct gprs_llc_llme *llme) { + struct sgsn_signal_data sig_data; struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); int rc; @@ -1298,6 +1319,10 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg, GPRS_ALGO_GEA0, NULL); mmctx->mm_state = GMM_REGISTERED_NORMAL; rc = 0; + + memset(&sig_data, 0, sizeof(sig_data)); + sig_data.mm = mmctx; + osmo_signal_dispatch(SS_SGSN, S_SGSN_ATTACH, &sig_data); break; case GSM48_MT_GMM_RA_UPD_COMPL: /* only in case SGSN offered new P-TMSI */ @@ -1312,6 +1337,10 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg, GPRS_ALGO_GEA0, NULL); mmctx->mm_state = GMM_REGISTERED_NORMAL; rc = 0; + + memset(&sig_data, 0, sizeof(sig_data)); + sig_data.mm = mmctx; + osmo_signal_dispatch(SS_SGSN, S_SGSN_UPDATE, &sig_data); break; case GSM48_MT_GMM_PTMSI_REALL_COMPL: LOGMMCTXP(LOGL_INFO, mmctx, "-> PTMSI REALLLICATION COMPLETE\n"); diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index 2f5d39e83..5fe4e616e 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "openbsc/gprs_llc.h" #include @@ -204,6 +205,7 @@ void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm) struct gprs_llc_llme *llme = mm->llme; uint32_t tlli = mm->tlli; struct sgsn_pdp_ctx *pdp, *pdp2; + struct sgsn_signal_data sig_data; /* delete all existing PDP contexts for this MS */ llist_for_each_entry_safe(pdp, pdp2, &mm->pdp_list, list) { @@ -217,6 +219,11 @@ void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm) osmo_timer_del(&mm->timer); } + memset(&sig_data, 0, sizeof(sig_data)); + sig_data.mm = mm; + osmo_signal_dispatch(SS_SGSN, S_SGSN_MM_FREE, &sig_data); + + /* Detach from subscriber which is possibly freed then */ if (mm->subscr) { struct gsm_subscriber *subscr = subscr_get(mm->subscr); @@ -289,6 +296,8 @@ struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm, */ void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp) { + struct sgsn_signal_data sig_data; + OSMO_ASSERT(pdp->mm != NULL); /* There might still be pending callbacks in libgtp. So the parts of @@ -299,6 +308,10 @@ void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp) /* Force the deactivation of the SNDCP layer */ sndcp_sm_deactivate_ind(&pdp->mm->llme->lle[pdp->sapi], pdp->nsapi); + memset(&sig_data, 0, sizeof(sig_data)); + sig_data.pdp = pdp; + osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_TERMINATE, &sig_data); + /* Detach from MM context */ llist_del(&pdp->list); pdp->mm = NULL; @@ -313,6 +326,12 @@ void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp) */ void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp) { + struct sgsn_signal_data sig_data; + + memset(&sig_data, 0, sizeof(sig_data)); + sig_data.pdp = pdp; + osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_FREE, &sig_data); + rate_ctr_group_free(pdp->ctrg); if (pdp->mm) llist_del(&pdp->list); diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index eee3ef21c..af5c93de3 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -287,6 +287,7 @@ static const struct cause_map gtp2sm_cause_map[] = { /* The GGSN has confirmed the creation of a PDP Context */ static int create_pdp_conf(struct pdp_t *pdp, void *cbp, int cause) { + struct sgsn_signal_data sig_data; struct sgsn_pdp_ctx *pctx = cbp; uint8_t reject_cause; @@ -322,6 +323,11 @@ static int create_pdp_conf(struct pdp_t *pdp, void *cbp, int cause) /* Activate the SNDCP layer */ sndcp_sm_activate_ind(&pctx->mm->llme->lle[pctx->sapi], pctx->nsapi); + /* Inform others about it */ + memset(&sig_data, 0, sizeof(sig_data)); + sig_data.pdp = pctx; + osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_ACT, &sig_data); + /* Send PDP CTX ACT to MS */ return gsm48_tx_gsm_act_pdp_acc(pctx); @@ -349,12 +355,17 @@ reject: /* Confirmation of a PDP Context Delete */ static int delete_pdp_conf(struct pdp_t *pdp, void *cbp, int cause) { + struct sgsn_signal_data sig_data; struct sgsn_pdp_ctx *pctx = cbp; int rc = 0; LOGPDPCTXP(LOGL_INFO, pctx, "Received DELETE PDP CTX CONF, cause=%d(%s)\n", cause, get_value_string(gtp_cause_strs, cause)); + memset(&sig_data, 0, sizeof(sig_data)); + sig_data.pdp = pctx; + osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_DEACT, &sig_data); + if (pctx->mm) { /* Deactivate the SNDCP layer */ sndcp_sm_deactivate_ind(&pctx->mm->llme->lle[pctx->sapi], pctx->nsapi);