Change the subscriber and database backend

gsm_subscriber is now refcounted, the db backend is leaking
a lot less, db_get_subscriber will allocate the subscr record
now, subscr_* will look up a subscriber in the list of currently
active subscribers and add an ref to this one.

The db test cases pass, more testing will be when next to the bts
diff --git a/include/openbsc/db.h b/include/openbsc/db.h
index df703e0..bd30aab 100644
--- a/include/openbsc/db.h
+++ b/include/openbsc/db.h
@@ -1,4 +1,5 @@
 /* (C) 2008 by Jan Luebbe <jluebbe@debian.org>
+ * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
  * All Rights Reserved
  *
  * This program is free software; you can redistribute it and/or modify
@@ -24,14 +25,16 @@
 
 #include <openbsc/gsm_subscriber.h>
 
+/* one time initialisation */
 int db_init(const char *name);
 int db_prepare();
 int db_fini();
 
-struct gsm_subscriber* db_create_subscriber(char imsi[GSM_IMSI_LENGTH]);
-int db_get_subscriber(enum gsm_subscriber_field field, struct gsm_subscriber* subscriber);
-int db_set_subscriber(struct gsm_subscriber* subscriber);
+/* subscriber management */
+struct gsm_subscriber* db_create_subscriber(char *imsi);
+struct gsm_subscriber* db_get_subscriber(enum gsm_subscriber_field field, char *subscr);
+int db_sync_subscriber(struct gsm_subscriber* subscriber);
 int db_subscriber_alloc_tmsi(struct gsm_subscriber* subscriber);
-int db_subscriber_assoc_imei(struct gsm_subscriber* subscriber, char imei[GSM_IMEI_LENGTH]);
+int db_subscriber_assoc_imei(struct gsm_subscriber* subscriber, char *imei);
 
 #endif /* _DB_H */
diff --git a/include/openbsc/gsm_subscriber.h b/include/openbsc/gsm_subscriber.h
index 97c7665..90117d3 100644
--- a/include/openbsc/gsm_subscriber.h
+++ b/include/openbsc/gsm_subscriber.h
@@ -3,6 +3,7 @@
 
 #include <sys/types.h>
 #include "gsm_data.h"
+#include "linuxlist.h"
 
 #define GSM_IMEI_LENGTH 17
 #define GSM_IMSI_LENGTH 17
@@ -18,6 +19,10 @@
 	char name[GSM_NAME_LENGTH];
 	char extension[GSM_EXTENSION_LENGTH];
 	int authorized;
+
+	/* for internal management */ 
+	int use_count;
+	struct llist_head entry;
 };
 
 enum gsm_subscriber_field {
@@ -25,4 +30,8 @@
 	GSM_SUBSCRIBER_TMSI,
 };
 
+struct gsm_subscriber *subscr_alloc();
+struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr);
+struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr);
+
 #endif /* _GSM_SUBSCR_H */