* add database handling
* fix IMSI handling

diff --git a/src/gsm_04_08.c b/src/gsm_04_08.c
index 447c263..83399d0 100644
--- a/src/gsm_04_08.c
+++ b/src/gsm_04_08.c
@@ -28,6 +28,7 @@
 #include <errno.h>
 #include <netinet/in.h>
 
+#include <openbsc/db.h>
 #include <openbsc/msgb.h>
 #include <openbsc/debug.h>
 #include <openbsc/gsm_data.h>
@@ -98,15 +99,12 @@
 #define TMSI_LEN	4
 #define MID_TMSI_LEN	(TMSI_LEN + 2)
 
-static void generate_mid_from_tmsi(u_int8_t *buf, u_int8_t *tmsi_bcd)
+static void generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi)
 {
 	buf[0] = GSM48_IE_MOBILE_ID;
 	buf[1] = MID_TMSI_LEN;
 	buf[2] = 0xf0 | GSM_MI_TYPE_TMSI;
-	buf[3] = tmsi_bcd[0];
-	buf[4] = tmsi_bcd[1];
-	buf[5] = tmsi_bcd[2];
-	buf[6] = tmsi_bcd[3];
+	*((u_int32_t *) &buf[3]) = htonl(tmsi);
 }
 
 static struct msgb *gsm48_msgb_alloc(void)
@@ -144,7 +142,7 @@
 }
 
 /* Chapter 9.2.13 : Send LOCATION UPDATE ACCEPT */
-int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int8_t *tmsi)
+int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int32_t tmsi)
 {
 	struct gsm_bts *bts = lchan->ts->trx->bts;
 	struct msgb *msg = gsm48_msgb_alloc();
@@ -241,14 +239,33 @@
 static int mm_rx_id_resp(struct msgb *msg)
 {
 	struct gsm48_hdr *gh = msgb_l3(msg);
+	struct gsm_lchan *lchan = msg->lchan;
 	u_int8_t mi_type = gh->data[1] & GSM_MI_TYPE_MASK;
 	char mi_string[MI_SIZE];
+	u_int32_t tmsi;
 
 	mi_to_string(mi_string, sizeof(mi_string), &gh->data[1], gh->data[0]);
 	DEBUGP(DMM, "IDENTITY RESPONSE: mi_type=0x%02x MI(%s)\n",
 		mi_type, mi_string);
 
-	/* FIXME: update subscribe <-> IMEI mapping */
+	switch (mi_type) {
+	case GSM_MI_TYPE_IMSI:
+		if (!lchan->subscr)
+			lchan->subscr = db_create_subscriber(mi_string);
+		if (lchan->subscr && lchan->subscr->authorized) {
+			/* FIXME: check if we've recently received UPDATE REQUEST */
+			db_subscriber_alloc_tmsi(lchan->subscr);
+			tmsi = strtoul(lchan->subscr->tmsi, NULL, 16);
+			return gsm0408_loc_upd_acc(msg->lchan, tmsi);
+		}
+		break;
+	case GSM_MI_TYPE_IMEI:
+		/* update subscribe <-> IMEI mapping */
+		if (lchan->subscr)
+			db_subscriber_assoc_imei(lchan->subscr, mi_string);
+		break;
+	}
+	return 0;
 }
 
 #define MI_SIZE 32
@@ -260,6 +277,7 @@
 	struct gsm48_loc_upd_req *lu;
 	struct gsm_subscriber *subscr;
 	u_int8_t mi_type;
+	u_int32_t tmsi;
 	char mi_string[MI_SIZE];
 	int rc;
 
@@ -275,7 +293,7 @@
 		/* we always want the IMEI, too */
 		rc = mm_tx_identity_req(msg->lchan, GSM_MI_TYPE_IMEISV);
 		/* look up subscriber based on IMSI */
-		subscr = subscr_get_by_imsi(lu->mi);
+		subscr = db_create_subscriber(mi_string);
 		break;
 	case GSM_MI_TYPE_TMSI:
 		/* we always want the IMEI, too */
@@ -297,17 +315,20 @@
 		break;
 	}
 
-	if (!subscr) {
+	if (!subscr || !subscr->authorized) {
 		/* 0x16 is congestion */
 		gsm0408_loc_upd_rej(msg->lchan, 0x16);
 		rsl_chan_release(msg->lchan);
 		return -EINVAL;
 	}
 
+	db_subscriber_alloc_tmsi(subscr);
+
 	msg->lchan->subscr = subscr;
 	subscr_update(subscr, bts);
+	tmsi = strtoul(subscr->tmsi, NULL, 16);
 
-	return gsm0408_loc_upd_acc(msg->lchan, subscr->tmsi);
+	return gsm0408_loc_upd_acc(msg->lchan, tmsi);
 }
 
 static int gsm48_tx_mm_serv_ack(struct gsm_lchan *lchan)