store all APDU's received from the MS in the database

This helps us to analyze data such as RRLP location information for
later analysis.
diff --git a/openbsc/include/openbsc/db.h b/openbsc/include/openbsc/db.h
index 67436df..0713593 100644
--- a/openbsc/include/openbsc/db.h
+++ b/openbsc/include/openbsc/db.h
@@ -48,4 +48,9 @@
 struct gsm_sms *db_sms_get_unsent(struct gsm_network *net, int min_id);
 struct gsm_sms *db_sms_get_unsent_for_subscr(struct gsm_subscriber *subscr);
 int db_sms_mark_sent(struct gsm_sms *sms);
+
+/* APDU blob storage */
+int db_apdu_blob_store(struct gsm_subscriber *subscr, 
+			u_int8_t apdu_id_flags, u_int8_t len,
+			u_int8_t *apdu);
 #endif /* _DB_H */
diff --git a/openbsc/src/db.c b/openbsc/src/db.c
index d5e924d..16a7f6a 100644
--- a/openbsc/src/db.c
+++ b/openbsc/src/db.c
@@ -109,6 +109,13 @@
 		"subscriber_id NUMERIC UNIQUE NOT NULL, "
 		"last_bts NUMERIC NOT NULL "
 		")",
+	"CREATE TABLE IF NOT EXISTS ApduBlobs ("
+		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
+		"created TIMESTAMP NOT NULL, "
+		"apdu_id_flags INTEGER NOT NULL, "
+		"subscriber_id INTEGER NOT NULL, "
+		"apdu BLOB "
+		")",
 };
 
 void db_error_func(dbi_conn conn, void* data) {
@@ -771,3 +778,27 @@
 	dbi_result_free(result);
 	return 0;
 }
+
+int db_apdu_blob_store(struct gsm_subscriber *subscr, 
+			u_int8_t apdu_id_flags, u_int8_t len,
+			u_int8_t *apdu)
+{
+	dbi_result result;
+	char *q_apdu;
+
+	dbi_conn_quote_binary_copy(conn, apdu, len, &q_apdu);
+
+	result = dbi_conn_queryf(conn,
+		"INSERT INTO ApduBlobs "
+		"(created,subscriber_id,apdu_id_flags,apdu) VALUES "
+		"(datetime('now'),%llu,%u,%s)",
+		subscr->id, apdu_id_flags, q_apdu);
+
+	free(q_apdu);
+
+	if (!result)
+		return -EIO;
+
+	dbi_result_free(result);
+	return 0;
+}
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index 9d9cde7..b64d253 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -1839,7 +1839,7 @@
 	DEBUGP(DNM, "RX APPLICATION INFO id/flags=0x%02x apdu_len=%u apdu=%s",
 		apdu_id_flags, apdu_len, hexdump(apdu_data, apdu_len));
 
-	return 0;
+	return db_apdu_blob_store(msg->lchan->subscr, apdu_id_flags, apdu_len, apdu_data);
 }