gbproxy: Use pointer to PTMSI value instead of MI

Currently, ptmsi_enc and new_ptmsi_enc point to the beginning of the
mobile identity. Since all P-TMSI in 04.08 (MM) are encoded this way (1
byte header + 4 byte P-TMSI value). This is different to the P-TMSI
encoding in 08.18 (BSSGP), where the P-TMSI is encoded into 4 byte
without MI header.

This patch changes the code to use pointers to the P-TMSI value,
which is encoded in the same way in both specifications.

Sponsored-by: On-Waves ehf
diff --git a/openbsc/src/gprs/gb_proxy_patch.c b/openbsc/src/gprs/gb_proxy_patch.c
index 5cac8a5..b148094 100644
--- a/openbsc/src/gprs/gb_proxy_patch.c
+++ b/openbsc/src/gprs/gb_proxy_patch.c
@@ -172,7 +172,7 @@
 		to_bss ?
 		GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN :
 		GBPROX_PEER_CTR_PTMSI_PATCHED_BSS;
-	memcpy(&ptmsi_be, ptmsi_enc + 1, sizeof(ptmsi_be));
+	memcpy(&ptmsi_be, ptmsi_enc, sizeof(ptmsi_be));
 	ptmsi = ntohl(ptmsi_be);
 
 	if (ptmsi == new_ptmsi)
@@ -184,7 +184,7 @@
 	     log_text, ptmsi, new_ptmsi);
 
 	ptmsi_be = htonl(new_ptmsi);
-	memcpy(ptmsi_enc + 1, &ptmsi_be, sizeof(ptmsi_be));
+	memcpy(ptmsi_enc, &ptmsi_be, sizeof(ptmsi_be));
 
 	rate_ctr_inc(&peer->ctrg->ctr[counter]);
 
diff --git a/openbsc/src/gprs/gb_proxy_tlli.c b/openbsc/src/gprs/gb_proxy_tlli.c
index 9b337fe..138837e 100644
--- a/openbsc/src/gprs/gb_proxy_tlli.c
+++ b/openbsc/src/gprs/gb_proxy_tlli.c
@@ -481,13 +481,8 @@
 
 	if (!link_info && parse_ctx->ptmsi_enc && !parse_ctx->old_raid_is_foreign) {
 		uint32_t bss_ptmsi;
-		if (!gprs_parse_mi_tmsi(parse_ctx->ptmsi_enc, GSM48_TMSI_LEN,
-					&bss_ptmsi))
-			LOGP(DGPRS, LOGL_ERROR,
-			     "Failed to parse P-TMSI (TLLI is %08x)\n",
-			     parse_ctx->tlli);
-		else
-			link_info = gbproxy_link_info_by_ptmsi(peer, bss_ptmsi);
+		gprs_parse_tmsi(parse_ctx->ptmsi_enc, &bss_ptmsi);
+		link_info = gbproxy_link_info_by_ptmsi(peer, bss_ptmsi);
 	}
 
 	if (link_info)
@@ -563,13 +558,7 @@
 		 * register new TLLI */
 		uint32_t new_sgsn_ptmsi;
 		uint32_t new_bss_ptmsi;
-		if (!gprs_parse_mi_tmsi(parse_ctx->new_ptmsi_enc, GSM48_TMSI_LEN,
-					&new_sgsn_ptmsi)) {
-			LOGP(DGPRS, LOGL_ERROR,
-			     "Failed to parse new TLLI/PTMSI (current is %08x)\n",
-			     parse_ctx->tlli);
-			return link_info;
-		}
+		gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_sgsn_ptmsi);
 		new_bss_ptmsi = gbproxy_make_bss_ptmsi(peer, new_sgsn_ptmsi);
 
 		LOGP(DGPRS, LOGL_INFO,
@@ -584,13 +573,7 @@
 		 * TLLI, create a new link_info */
 		/* TODO: Add a test case for this branch */
 		uint32_t new_ptmsi;
-		if (!gprs_parse_mi_tmsi(parse_ctx->new_ptmsi_enc, GSM48_TMSI_LEN,
-					&new_ptmsi)) {
-			LOGP(DGPRS, LOGL_ERROR,
-			     "Failed to parse new PTMSI (TLLI is %08x)\n",
-			     parse_ctx->tlli);
-			return link_info;
-		}
+		gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi);
 
 		LOGP(DGPRS, LOGL_INFO,
 		     "Adding TLLI %08x to list (SGSN, new P-TMSI is %08x)\n",
@@ -620,13 +603,7 @@
 			return link_info;
 		/* A new P-TMSI has been signalled in the message */
 
-		if (!gprs_parse_mi_tmsi(parse_ctx->new_ptmsi_enc,
-					GSM48_TMSI_LEN, &new_ptmsi)) {
-			LOGP(DGPRS, LOGL_ERROR,
-			     "Failed to parse new PTMSI (TLLI is %08x)\n",
-			     parse_ctx->tlli);
-			return link_info;
-		}
+		gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi);
 		LOGP(DGPRS, LOGL_INFO,
 		     "Assigning new P-TMSI %08x\n", new_ptmsi);
 		/* Setup P-TMSIs */
diff --git a/openbsc/src/gprs/gprs_gb_parse.c b/openbsc/src/gprs/gprs_gb_parse.c
index 87cea1b..1978bd4 100644
--- a/openbsc/src/gprs/gprs_gb_parse.c
+++ b/openbsc/src/gprs/gprs_gb_parse.c
@@ -171,7 +171,7 @@
 		return 0;
 
 	if (gprs_is_mi_tmsi(value, value_len)) {
-		parse_ctx->ptmsi_enc = value;
+		parse_ctx->ptmsi_enc = value + 1;
 	} else if (gprs_is_mi_imsi(value, value_len)) {
 		parse_ctx->imsi = value;
 		parse_ctx->imsi_len = value_len;
@@ -215,7 +215,7 @@
 	if (tlv_match(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI,
 		      &value, &value_len) > 0 &&
 	    gprs_is_mi_tmsi(value, value_len))
-		parse_ctx->new_ptmsi_enc = value;
+		parse_ctx->new_ptmsi_enc = value + 1;
 	return 1;
 }
 
@@ -270,7 +270,7 @@
 			      GSM48_IE_GMM_ALLOC_PTMSI, &value, &value_len) > 0)
 		{
 			if (gprs_is_mi_tmsi(value, value_len))
-				parse_ctx->ptmsi_enc = value;
+				parse_ctx->ptmsi_enc = value + 1;
 		}
 	}
 
@@ -351,7 +351,7 @@
 	if (tlv_match(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI,
 		      &value, &value_len) > 0 &&
 	    gprs_is_mi_tmsi(value, value_len))
-		parse_ctx->new_ptmsi_enc = value;
+		parse_ctx->new_ptmsi_enc = value + 1;
 
 	return 1;
 }
@@ -370,7 +370,7 @@
 	/* Allocated P-TMSI */
 	if (lv_shift(&data, &data_len, &value, &value_len) > 0 &&
 	    gprs_is_mi_tmsi(value, value_len))
-		parse_ctx->new_ptmsi_enc = value;
+		parse_ctx->new_ptmsi_enc = value + 1;
 
 	if (v_fixed_shift(&data, &data_len, 6, &value) <= 0)
 		return 0;
@@ -395,7 +395,7 @@
 		return 0;
 
 	if (gprs_is_mi_tmsi(value, value_len)) {
-		parse_ctx->ptmsi_enc = value;
+		parse_ctx->ptmsi_enc = value + 1;
 	} else if (gprs_is_mi_imsi(value, value_len)) {
 		parse_ctx->imsi = value;
 		parse_ctx->imsi_len = value_len;
@@ -680,20 +680,15 @@
 
 	if (parse_ctx->ptmsi_enc) {
 		uint32_t ptmsi = GSM_RESERVED_TMSI;
-		int ok;
-		ok = gprs_parse_mi_tmsi(parse_ctx->ptmsi_enc, GSM48_TMSI_LEN, &ptmsi);
-		LOGPC(DGPRS, LOGL_DEBUG, "%s PTMSI %08x%s",
-		     sep, ptmsi, ok ? "" : " (parse error)");
+		gprs_parse_tmsi(parse_ctx->ptmsi_enc, &ptmsi);
+		LOGPC(DGPRS, LOGL_DEBUG, "%s PTMSI %08x", sep, ptmsi);
 		sep = ",";
 	}
 
 	if (parse_ctx->new_ptmsi_enc) {
 		uint32_t new_ptmsi = GSM_RESERVED_TMSI;
-		int ok;
-		ok = gprs_parse_mi_tmsi(parse_ctx->new_ptmsi_enc, GSM48_TMSI_LEN,
-					&new_ptmsi);
-		LOGPC(DGPRS, LOGL_DEBUG, "%s new PTMSI %08x%s",
-		     sep, new_ptmsi, ok ? "" : " (parse error)");
+		gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi);
+		LOGPC(DGPRS, LOGL_DEBUG, "%s new PTMSI %08x", sep, new_ptmsi);
 		sep = ",";
 	}
 
diff --git a/openbsc/src/gprs/gprs_utils.c b/openbsc/src/gprs/gprs_utils.c
index c620454..0cf8e4f 100644
--- a/openbsc/src/gprs/gprs_utils.c
+++ b/openbsc/src/gprs/gprs_utils.c
@@ -209,3 +209,11 @@
 	return 1;
 }
 
+void gprs_parse_tmsi(const uint8_t *value, uint32_t *tmsi)
+{
+	uint32_t tmsi_be;
+
+	memcpy(&tmsi_be, value, sizeof(tmsi_be));
+
+	*tmsi = ntohl(tmsi_be);
+}