sgsn: Add various signals consumed by CDR or other client code
This commit is contained in:
parent
20de3ae17c
commit
b100895557
|
@ -1,5 +1,5 @@
|
|||
/* Generic signalling/notification infrastructure */
|
||||
/* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
/* (C) 2009-2010, 2015 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009 by Harald Welte <laforge@gnumonks.org>
|
||||
* (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
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include <openbsc/gprs_gmm.h>
|
||||
#include <openbsc/gprs_utils.h>
|
||||
#include <openbsc/sgsn.h>
|
||||
#include <openbsc/signal.h>
|
||||
|
||||
#include <pdp.h>
|
||||
|
||||
|
@ -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");
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <openbsc/gsm_04_08_gprs.h>
|
||||
#include <openbsc/gprs_gmm.h>
|
||||
#include <openbsc/gprs_utils.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include "openbsc/gprs_llc.h"
|
||||
|
||||
#include <time.h>
|
||||
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue