[GPRS] SGSN: use GGSN IP address from config file, disable TMSI allocation
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index 35c850c..609f141 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -54,7 +54,6 @@
 #include <pdp.h>
 
 extern struct sgsn_instance *sgsn;
-extern struct sgsn_ggsn_ctx *dummy_ggsn;
 
 /* Protocol related stuff, should go into libosmocore */
 
@@ -218,6 +217,7 @@
 	aa->radio_prio = 4;	/* lowest */
 	gsm48_construct_ra(aa->ra_id.digits, &mm->ra);
 
+#if 0
 	/* Optional: P-TMSI signature */
 	msgb_v_put(msg, GSM48_IE_GMM_PTMSI_SIG);
 	ptsig = msgb_put(msg, 3);
@@ -228,10 +228,10 @@
 	/* Optional: Negotiated Ready timer value */
 
 	/* Optional: Allocated P-TMSI */
-	msgb_v_put(msg, GSM48_IE_GMM_ALLOC_PTMSI);
 	mid = msgb_put(msg, GSM48_MID_TMSI_LEN);
 	gsm48_generate_mid_from_tmsi(mid, mm->p_tmsi);
-
+	mid[0] = GSM48_IE_GMM_ALLOC_PTMSI;
+#endif
 	/* Optional: MS-identity (combined attach) */
 	/* Optional: GMM cause (partial attach result for combined attach) */
 
@@ -449,7 +449,8 @@
 		msgid2mmctx(ctx, msg);
 		break;
 	case GSM_MI_TYPE_TMSI:
-		tmsi = strtoul(mi_string, NULL, 10);
+		memcpy(&tmsi, mi+1, 4);
+		tmsi = ntohl(tmsi);
 		/* Try to find MM context based on P-TMSI */
 		ctx = sgsn_mm_ctx_by_ptmsi(tmsi);
 		if (!ctx) {
@@ -467,10 +468,10 @@
 	/* Update MM Context with currient RA and Cell ID */
 	ctx->ra = ra_id;
 	ctx->cell_id = cid;
-
+#if 0
 	/* Allocate a new P-TMSI (+ P-TMSI signature) */
 	ctx->p_tmsi = sgsn_alloc_ptmsi();
-
+#endif
 	/* FIXME: update the TLLI with the new local TLLI based on the P-TMSI */
 
 	DEBUGPC(DMM, "\n");
@@ -622,7 +623,9 @@
 
 	if (!mmctx &&
 	    gh->msg_type != GSM48_MT_GMM_ATTACH_REQ &&
-	    gh->msg_type != GSM48_MT_GMM_RA_UPD_REQ) {
+	    gh->msg_type != GSM48_MT_GMM_RA_UPD_REQ &&
+	    gh->msg_type != GSM48_MT_GMM_ATTACH_COMPL &&
+	    gh->msg_type != GSM48_MT_GMM_RA_UPD_COMPL) {
 		LOGP(DMM, LOGL_NOTICE, "Cannot handle GMM for unknown MM CTX\n");
 		/* FIXME: Send GMM_CAUSE_IMPL_DETACHED */
 		return -EINVAL;
@@ -645,10 +648,10 @@
 	case GSM48_MT_GMM_DETACH_REQ:
 		rc = gsm48_rx_gmm_det_req(mmctx, msg);
 		break;
-	case GSM48_MT_GMM_RA_UPD_COMPL:
-		/* only in case SGSN offered new P-TMSI */
 	case GSM48_MT_GMM_ATTACH_COMPL:
 		/* only in case SGSN offered new P-TMSI */
+	case GSM48_MT_GMM_RA_UPD_COMPL:
+		/* only in case SGSN offered new P-TMSI */
 	case GSM48_MT_GMM_PTMSI_REALL_COMPL:
 	case GSM48_MT_GMM_AUTH_CIPH_RESP:
 		DEBUGP(DMM, "Unimplemented GSM 04.08 GMM msg type 0x%02x\n",
@@ -782,6 +785,8 @@
 	uint8_t transaction_id = (gh->proto_discr >> 4);
 	struct sgsn_pdp_ctx *pdp;
 
+	memset(&tp, 0, sizeof(tp));
+
 	DEBUGP(DMM, "-> ACTIVATE PDP CONTEXT REQ: SAPI=%u NSAPI=%u ",
 		act_req->req_llc_sapi, act_req->req_nsapi);
 
@@ -854,7 +859,13 @@
 
 #if 1
 	{
-		pdp = sgsn_create_pdp_ctx(dummy_ggsn, mmctx, act_req->req_nsapi, &tp);
+		struct sgsn_ggsn_ctx *ggsn = sgsn_ggsn_ctx_by_id(0);
+		if (!ggsn) {
+			LOGP(DGPRS, LOGL_ERROR, "No GGSN context 0 found!\n");
+			return -EIO;
+		}
+		ggsn->gsn = sgsn->gsn;
+		pdp = sgsn_create_pdp_ctx(ggsn, mmctx, act_req->req_nsapi, &tp);
 		if (!pdp)
 			return -1;
 		pdp->sapi = act_req->req_llc_sapi;
diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c
index dfc0565..0e87e62 100644
--- a/openbsc/src/gprs/gprs_sgsn.c
+++ b/openbsc/src/gprs/gprs_sgsn.c
@@ -31,6 +31,9 @@
 #include <openbsc/gprs_sgsn.h>
 #include <openbsc/gprs_ns.h>
 #include <openbsc/gprs_bssgp.h>
+#include <openbsc/sgsn.h>
+
+extern struct sgsn_instance *sgsn;
 
 LLIST_HEAD(sgsn_mm_ctxts);
 LLIST_HEAD(sgsn_ggsn_ctxts);
@@ -70,12 +73,24 @@
 					const struct gprs_ra_id *raid)
 {
 	struct sgsn_mm_ctx *ctx;
+	int tlli_type;
 
 	llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
 		if (tlli == ctx->tlli &&
 		    ra_id_equals(raid, &ctx->ra))
 			return ctx;
 	}
+
+	tlli_type = gprs_tlli_type(tlli);
+	if (tlli_type == TLLI_LOCAL) {
+		llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
+			if ((ctx->p_tmsi | 0xC0000000) == tlli) {
+				ctx->tlli = tlli;
+				return ctx;
+			}
+		}
+	}
+
 	return NULL;
 }
 
@@ -189,6 +204,8 @@
 
 	ggc->id = id;
 	ggc->gtp_version = 1;
+	/* if we are called from config file parse, this gsn doesn't exist yet */
+	ggc->gsn = sgsn->gsn;
 	llist_add(&ggc->list, &sgsn_ggsn_ctxts);
 
 	return ggc;
diff --git a/openbsc/src/gprs/osmo_sgsn.cfg b/openbsc/src/gprs/osmo_sgsn.cfg
index f9a340a..6db912a 100644
--- a/openbsc/src/gprs/osmo_sgsn.cfg
+++ b/openbsc/src/gprs/osmo_sgsn.cfg
@@ -1,5 +1,5 @@
 !
-! Osmocom SGSN (0.9.0.384-d9a55-dirty) configuration saved from vty
+! Osmocom SGSN (0.9.0.404-6463) configuration saved from vty
 !!
 !
 line vty
@@ -7,6 +7,8 @@
 !
 sgsn
   nsip local port 23000
+  ggsn 0 remote-ip 192.168.100.239
+  ggsn 0 gtp-version 1
 ns
  timer tns-block 3
  timer tns-block-retries 3
diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c
index 47b6c51..550f2bf 100644
--- a/openbsc/src/gprs/sgsn_main.c
+++ b/openbsc/src/gprs/sgsn_main.c
@@ -123,8 +123,6 @@
 /* NSI that BSSGP uses when transmitting on NS */
 extern struct gprs_ns_inst *bssgp_nsi;
 extern void *tall_msgb_ctx;
-static struct sgsn_ggsn_ctx _ggsn;
-struct sgsn_ggsn_ctx *dummy_ggsn = &_ggsn;
 
 int main(int argc, char **argv)
 {
@@ -179,10 +177,6 @@
 
 	nsip_listen(sgsn_nsi, sgsn_inst.cfg.nsip_listen_port);
 
-	_ggsn.gtp_version = 1;
-	inet_aton("192.168.100.239", &_ggsn.remote_addr);
-	_ggsn.gsn = sgsn_inst.gsn;
-
 	while (1) {
 		rc = bsc_select_main(0);
 		if (rc < 0)