GPRS/GMM: Correctly look up MM Context in RA Update

If a MS changes RA, the RA will arrive in the new cell using the old
TLLI (masked as foreign TLLI).  So we need to look-up the TLLI
in a special way, using the old RA as indicated in the 04.08 GMM
message.

There is still another bug remaining: As we somehow create a new LLC,
the sequence numbers of our responses start from 0 again, which is not
what the MS expects.  This needs to be fixed in a follow-up patch.
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index 817092e..82a4ca8 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -899,6 +899,7 @@
 	}
 
 	/* Look-up the MM context based on old RA-ID and TLLI */
+	mmctx = sgsn_mm_ctx_by_tlli(msgb_tlli(msg), &old_ra_id);
 	if (!mmctx || mmctx->mm_state == GMM_DEREGISTERED) {
 		/* The MS has to perform GPRS attach */
 		DEBUGPC(DMM, " REJECT\n");
diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c
index ae18ea0..48a00b8 100644
--- a/openbsc/src/gprs/gprs_sgsn.c
+++ b/openbsc/src/gprs/gprs_sgsn.c
@@ -82,6 +82,12 @@
 		id1->lac == id2->lac && id1->rac == id2->rac);
 }
 
+/* See 03.02 Chapter 2.6 */
+static inline uint32_t tlli_foreign(uint32_t tlli)
+{
+	return ((tlli | 0x80000000) & ~0x40000000);	
+}
+
 /* 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)
@@ -96,7 +102,8 @@
 	}
 
 	tlli_type = gprs_tlli_type(tlli);
-	if (tlli_type == TLLI_LOCAL) {
+	switch (tlli_type) {
+	case TLLI_LOCAL:
 		llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
 			if ((ctx->p_tmsi | 0xC0000000) == tlli ||
 			     (ctx->p_tmsi_old && (ctx->p_tmsi_old | 0xC0000000) == tlli)) {
@@ -104,6 +111,16 @@
 				return ctx;
 			}
 		}
+		break;
+	case TLLI_FOREIGN:
+		llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
+			if (tlli == tlli_foreign(ctx->tlli) &&
+			    ra_id_equals(raid, &ctx->ra))
+				return ctx;
+		}
+		break;
+	default:
+		break;
 	}
 
 	return NULL;