aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/sgsn_libgtp.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2010-05-18 10:35:06 +0200
committerHarald Welte <laforge@gnumonks.org>2010-05-18 10:35:06 +0200
commit6abf94e4206fa97c7dfd72f481c278d9e2873958 (patch)
treeb18b638e78d561a77fa0957b56a889559d7a475d /openbsc/src/gprs/sgsn_libgtp.c
parentd2a9ed22859dfc4b99bfac7c0010539db3e12a0d (diff)
[GPRS] Properly connect GPRS SM with LIBGTP for PDP context activation
* store LLC SAPI as part of PDP ctx * store NSEI + BVCI as part of MM ctx * export gsm48_tx_gsm_act_pdp_acc() and call it from sgsn_libgtp.c * create and use gsm48_tx_gsm_act_pdp_rej for error cases * print SAPI as part of VTY show pdp
Diffstat (limited to 'openbsc/src/gprs/sgsn_libgtp.c')
-rw-r--r--openbsc/src/gprs/sgsn_libgtp.c73
1 files changed, 63 insertions, 10 deletions
diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c
index f6331b9f0..78bb57a5a 100644
--- a/openbsc/src/gprs/sgsn_libgtp.c
+++ b/openbsc/src/gprs/sgsn_libgtp.c
@@ -37,14 +37,13 @@
#include <osmocore/talloc.h>
#include <osmocore/select.h>
#include <osmocore/rate_ctr.h>
+#include <openbsc/gsm_04_08_gprs.h>
#include <openbsc/signal.h>
#include <openbsc/debug.h>
#include <openbsc/sgsn.h>
-//#include <openbsc/gprs_ns.h>
-//#include <openbsc/gprs_bssgp.h>
#include <openbsc/gprs_sgsn.h>
-#include <openbsc/gsm_04_08_gprs.h>
+#include <openbsc/gprs_gmm.h>
#include <gtp.h>
#include <pdp.h>
@@ -170,7 +169,8 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct ggsn_ctx *ggsn,
memcpy(pdp->gsnlu.v, &sgsn->cfg.gtp_listenaddr,
sizeof(sgsn->cfg.gtp_listenaddr));
- /* FIXME: change pdp state to 'requested' */
+ /* change pdp state to 'requested' */
+ pctx->state = PDP_STATE_CR_REQ;
rc = gtp_create_context_req(ggsn->gsn, pdp, pctx);
/* FIXME */
@@ -178,10 +178,51 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct ggsn_ctx *ggsn,
return pctx;
}
+
+struct cause_map {
+ uint8_t cause_in;
+ uint8_t cause_out;
+};
+
+static uint8_t cause_map(const struct cause_map *map, uint8_t in, uint8_t deflt)
+{
+ const struct cause_map *m;
+
+ for (m = map; m->cause_in && m->cause_out; m++) {
+ if (m->cause_in == in)
+ return m->cause_out;
+ }
+ return deflt;
+}
+
+/* how do we map from gtp cause to SM cause */
+static const struct cause_map gtp2sm_cause_map[] = {
+ { GTPCAUSE_NO_RESOURCES, GSM_CAUSE_INSUFF_RSRC },
+ { GTPCAUSE_NOT_SUPPORTED, GSM_CAUSE_SERV_OPT_NOTSUPP },
+ { GTPCAUSE_MAN_IE_INCORRECT, GSM_CAUSE_INV_MAND_INFO },
+ { GTPCAUSE_MAN_IE_MISSING, GSM_CAUSE_INV_MAND_INFO },
+ { GTPCAUSE_OPT_IE_INCORRECT, GSM_CAUSE_PROTO_ERR_UNSPEC },
+ { GTPCAUSE_SYS_FAIL, GSM_CAUSE_NET_FAIL },
+ { GTPCAUSE_ROAMING_REST, GSM_CAUSE_REQ_SERV_OPT_NOTSUB },
+ { GTPCAUSE_PTIMSI_MISMATCH, GSM_CAUSE_PROTO_ERR_UNSPEC },
+ { GTPCAUSE_CONN_SUSP, GSM_CAUSE_PROTO_ERR_UNSPEC },
+ { GTPCAUSE_AUTH_FAIL, GSM_CAUSE_AUTH_FAILED },
+ { GTPCAUSE_USER_AUTH_FAIL, GSM_CAUSE_ACT_REJ_GGSN },
+ { GTPCAUSE_CONTEXT_NOT_FOUND, GSM_CAUSE_PROTO_ERR_UNSPEC },
+ { GTPCAUSE_ADDR_OCCUPIED, GSM_CAUSE_INSUFF_RSRC },
+ { GTPCAUSE_NO_MEMORY, GSM_CAUSE_INSUFF_RSRC },
+ { GTPCAUSE_RELOC_FAIL, GSM_CAUSE_PROTO_ERR_UNSPEC },
+ { GTPCAUSE_UNKNOWN_MAN_EXTHEADER, GSM_CAUSE_PROTO_ERR_UNSPEC },
+ { GTPCAUSE_MISSING_APN, GSM_CAUSE_MISSING_APN },
+ { GTPCAUSE_UNKNOWN_PDP, GSM_CAUSE_UNKNOWN_PDP },
+ { 0, 0 }
+};
+
/* 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_pdp_ctx *pctx = cbp;
+ uint8_t reject_cause;
DEBUGP(DGPRS, "Received CREATE PDP CTX CONF, cause=%d(%s)\n",
cause, get_value_string(gtp_cause_strs, cause));
@@ -194,19 +235,30 @@ static int create_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
gtp_create_context_req(sgsn->gsn, pdp, cbp);
return 0;
} else {
- pdp_freepdp(pdp);
- return EOF;
+ reject_cause = GSM_CAUSE_NET_FAIL;
+ goto reject;
}
}
/* Check for cause value if it was really successful */
if (cause != GTPCAUSE_ACC_REQ) {
- pdp_freepdp(pdp);
- return EOF;
+ reject_cause = cause_map(gtp2sm_cause_map, cause,
+ GSM_CAUSE_ACT_REJ_GGSN);
+ goto reject;
}
- /* FIXME: Send PDP CTX ACT ACK/REJ to MS */
- return 0;
+ /* Send PDP CTX ACT to MS */
+ return gsm48_tx_gsm_act_pdp_acc(pctx);
+
+reject:
+ pctx->state = PDP_STATE_NONE;
+ pdp_freepdp(pdp);
+ sgsn_pdp_ctx_free(pctx);
+ /* Send PDP CTX ACT REJ to MS */
+ return gsm48_tx_gsm_act_pdp_rej(pctx->mm, pdp->ti, reject_cause,
+ 0, NULL);
+
+ return EOF;
}
/* If we receive a 04.08 DEACT PDP CTX REQ or GPRS DETACH, we need to
@@ -289,6 +341,7 @@ static int cb_extheader_ind(struct sockaddr_in *peer)
static int cb_data_ind(struct pdp_t *pdp, void *packet, unsigned int len)
{
DEBUGP(DGPRS, "GTP DATA IND from GGSN, length=%u\n", len);
+ /* FIXME: resolve PDP/MM context, forward to SNDCP layer */
return 0;
}