[gsm48] Move parsing of the MI from to gsm_04_08_utils.c

The parsing of the IMSI is needed for the MSC part as well. Move
it to the gsm_04_08_utils.c so it can be used.
diff --git a/openbsc/src/gsm_04_08_utils.c b/openbsc/src/gsm_04_08_utils.c
index 50deb2b..e771ea3 100644
--- a/openbsc/src/gsm_04_08_utils.c
+++ b/openbsc/src/gsm_04_08_utils.c
@@ -156,6 +156,15 @@
 	val = val / 10;
 }
 
+static char bcd2char(u_int8_t bcd)
+{
+	if (bcd < 0xa)
+		return '0' + bcd;
+	else
+		return 'A' + (bcd - 0xa);
+}
+
+
 void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc,
 			 u_int16_t mnc, u_int16_t lac)
 {
@@ -308,3 +317,46 @@
 	return rsl_deact_sacch(lchan);
 }
 
+/* Convert Mobile Identity (10.5.1.4) to string */
+int gsm48_mi_to_string(char *string, const int str_len, const u_int8_t *mi, const int mi_len)
+{
+	int i;
+	u_int8_t mi_type;
+	char *str_cur = string;
+	u_int32_t tmsi;
+
+	mi_type = mi[0] & GSM_MI_TYPE_MASK;
+
+	switch (mi_type) {
+	case GSM_MI_TYPE_NONE:
+		break;
+	case GSM_MI_TYPE_TMSI:
+		/* Table 10.5.4.3, reverse generate_mid_from_tmsi */
+		if (mi_len == GSM48_TMSI_LEN && mi[0] == (0xf0 | GSM_MI_TYPE_TMSI)) {
+			memcpy(&tmsi, &mi[1], 4);
+			tmsi = ntohl(tmsi);
+			return snprintf(string, str_len, "%u", tmsi);
+		}
+		break;
+	case GSM_MI_TYPE_IMSI:
+	case GSM_MI_TYPE_IMEI:
+	case GSM_MI_TYPE_IMEISV:
+		*str_cur++ = bcd2char(mi[0] >> 4);
+
+                for (i = 1; i < mi_len; i++) {
+			if (str_cur + 2 >= string + str_len)
+				return str_cur - string;
+			*str_cur++ = bcd2char(mi[i] & 0xf);
+			/* skip last nibble in last input byte when GSM_EVEN */
+			if( (i != mi_len-1) || (mi[0] & GSM_MI_ODD))
+				*str_cur++ = bcd2char(mi[i] >> 4);
+		}
+		break;
+	default:
+		break;
+	}
+	*str_cur++ = '\0';
+
+	return str_cur - string;
+}
+