subscr: Add a VTY command to update the subscriber from the database.
diff --git a/openbsc/include/openbsc/db.h b/openbsc/include/openbsc/db.h
index 8bf361f..ba7c5a7 100644
--- a/openbsc/include/openbsc/db.h
+++ b/openbsc/include/openbsc/db.h
@@ -49,6 +49,7 @@
 int db_subscriber_alloc_token(struct gsm_subscriber *subscriber, u_int32_t* token);
 int db_subscriber_assoc_imei(struct gsm_subscriber *subscriber, char *imei);
 int db_sync_equipment(struct gsm_equipment *equip);
+int db_subscriber_update(struct gsm_subscriber *subscriber);
 
 /* auth info */
 int db_get_authinfo_for_subscr(struct gsm_auth_info *ainfo,
diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h
index b5e8fb6..29317e8 100644
--- a/openbsc/include/openbsc/gsm_subscriber.h
+++ b/openbsc/include/openbsc/gsm_subscriber.h
@@ -91,6 +91,7 @@
 char *subscr_name(struct gsm_subscriber *subscr);
 
 int subscr_purge_inactive(struct gsm_network *net);
+void subscr_update_from_db(struct gsm_subscriber *subscr);
 
 /* internal */
 struct gsm_subscriber *subscr_alloc(void);
diff --git a/openbsc/src/db.c b/openbsc/src/db.c
index d672081..ec1e72c 100644
--- a/openbsc/src/db.c
+++ b/openbsc/src/db.c
@@ -558,13 +558,35 @@
 	return 0;
 }
 
+static void db_set_from_query(struct gsm_subscriber *subscr, dbi_conn result)
+{
+	const char *string;
+	string = dbi_result_get_string(result, "imsi");
+	if (string)
+		strncpy(subscr->imsi, string, GSM_IMSI_LENGTH);
+
+	string = dbi_result_get_string(result, "tmsi");
+	if (string)
+		subscr->tmsi = tmsi_from_string(string);
+
+	string = dbi_result_get_string(result, "name");
+	if (string)
+		strncpy(subscr->name, string, GSM_NAME_LENGTH);
+
+	string = dbi_result_get_string(result, "extension");
+	if (string)
+		strncpy(subscr->extension, string, GSM_EXTENSION_LENGTH);
+
+	subscr->lac = dbi_result_get_uint(result, "lac");
+	subscr->authorized = dbi_result_get_uint(result, "authorized");
+}
+
 #define BASE_QUERY "SELECT * FROM Subscriber "
 struct gsm_subscriber *db_get_subscriber(struct gsm_network *net,
 					 enum gsm_subscriber_field field,
 					 const char *id)
 {
 	dbi_result result;
-	const char *string;
 	char *quoted;
 	struct gsm_subscriber *subscr;
 
@@ -621,24 +643,8 @@
 	subscr = subscr_alloc();
 	subscr->net = net;
 	subscr->id = dbi_result_get_ulonglong(result, "id");
-	string = dbi_result_get_string(result, "imsi");
-	if (string)
-		strncpy(subscr->imsi, string, GSM_IMSI_LENGTH);
 
-	string = dbi_result_get_string(result, "tmsi");
-	if (string)
-		subscr->tmsi = tmsi_from_string(string);
-
-	string = dbi_result_get_string(result, "name");
-	if (string)
-		strncpy(subscr->name, string, GSM_NAME_LENGTH);
-
-	string = dbi_result_get_string(result, "extension");
-	if (string)
-		strncpy(subscr->extension, string, GSM_EXTENSION_LENGTH);
-
-	subscr->lac = dbi_result_get_uint(result, "lac");
-	subscr->authorized = dbi_result_get_uint(result, "authorized");
+	db_set_from_query(subscr, result);
 	DEBUGP(DDB, "Found Subscriber: ID %llu, IMSI %s, NAME '%s', TMSI %u, EXTEN '%s', LAC %hu, AUTH %u\n",
 		subscr->id, subscr->imsi, subscr->name, subscr->tmsi, subscr->extension,
 		subscr->lac, subscr->authorized);
@@ -649,6 +655,36 @@
 	return subscr;
 }
 
+int db_subscriber_update(struct gsm_subscriber *subscr)
+{
+	char buf[32];
+	char *quoted;
+	dbi_result result;
+
+	/* Copy the id to a string as queryf with %llu is failing */
+	sprintf(buf, "%llu", subscr->id);
+	result = dbi_conn_queryf(conn,
+			BASE_QUERY
+			"WHERE id = %s", buf);
+
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR, "Failed to query Subscriber: %llu\n", subscr->id);
+		return -EIO;
+	}
+	if (!dbi_result_next_row(result)) {
+		DEBUGP(DDB, "Failed to find the Subscriber. %llu\n",
+			subscr->id);
+		dbi_result_free(result);
+		return -EIO;
+	}
+
+	db_set_from_query(subscr, result);
+	dbi_result_free(result);
+	get_equipment_by_subscr(subscr);
+
+	return 0;
+}
+
 int db_sync_subscriber(struct gsm_subscriber *subscriber)
 {
 	dbi_result result;
diff --git a/openbsc/src/gsm_subscriber.c b/openbsc/src/gsm_subscriber.c
index ed76e45..f066eca 100644
--- a/openbsc/src/gsm_subscriber.c
+++ b/openbsc/src/gsm_subscriber.c
@@ -318,4 +318,7 @@
 	return db_sync_subscriber(s);
 }
 
-
+void subscr_update_from_db(struct gsm_subscriber *sub)
+{
+	db_subscriber_update(sub);
+}
diff --git a/openbsc/src/vty_interface_layer3.c b/openbsc/src/vty_interface_layer3.c
index a49ca5e..0552653 100644
--- a/openbsc/src/vty_interface_layer3.c
+++ b/openbsc/src/vty_interface_layer3.c
@@ -549,6 +549,25 @@
 	return CMD_SUCCESS;
 }
 
+DEFUN(subscriber_update,
+      subscriber_update_cmd,
+      "subscriber " SUBSCR_TYPES " ID update",
+      SUBSCR_HELP "Update the subscriber data from the dabase.\n")
+{
+	struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+	struct gsm_subscriber *subscr = get_subscr_by_argv(gsmnet, argv[0], argv[1]);
+
+	if (!subscr) {
+		vty_out(vty, "%% No subscriber found for %s %s%s",
+			argv[0], argv[1], VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	subscr_update_from_db(subscr);
+	subscr_put(subscr);
+	return CMD_SUCCESS;
+}
+
 static int scall_cbfn(unsigned int subsys, unsigned int signal,
 			void *handler_data, void *signal_data)
 {
@@ -626,6 +645,7 @@
 	install_element_ve(&subscriber_silent_call_start_cmd);
 	install_element_ve(&subscriber_silent_call_stop_cmd);
 	install_element_ve(&subscriber_ussd_notify_cmd);
+	install_element_ve(&subscriber_update_cmd);
 	install_element_ve(&show_stats_cmd);
 
 	install_element(ENABLE_NODE, &ena_subscr_name_cmd);