VTY: dynamically create BTS "type" command syntax
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index e2ba9b6..572f8f5 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -365,4 +365,7 @@
 /* generic E1 line operations for all ISDN-based BTS. */
 extern struct e1inp_line_ops bts_isdn_e1inp_line_ops;
 
+extern const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE+1];
+extern const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1];
+
 #endif /* _GSM_DATA_H */
diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h
index 3ba7a4b..5d4c516 100644
--- a/openbsc/include/openbsc/gsm_data_shared.h
+++ b/openbsc/include/openbsc/gsm_data_shared.h
@@ -363,6 +363,7 @@
 	GSM_BTS_TYPE_HSL_FEMTO,
 	GSM_BTS_TYPE_NOKIA_SITE,
 	GSM_BTS_TYPE_OSMO_SYSMO,
+	_NUM_GSM_BTS_TYPE
 };
 
 struct vty;
diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c
index e3d31a1..d7cdee6 100644
--- a/openbsc/src/libbsc/bsc_vty.c
+++ b/openbsc/src/libbsc/bsc_vty.c
@@ -1434,7 +1434,7 @@
 
 DEFUN(cfg_bts_type,
       cfg_bts_type_cmd,
-      "type TYPE",
+      "type TYPE", /* dynamically created */
       "Set the BTS type\n" "Type\n")
 {
 	struct gsm_bts *bts = vty->index;
@@ -2854,6 +2854,18 @@
 					   "Physical Channel Combination\n",
 					   "\n", "", 0);
 
+	cfg_bts_type_cmd.string =
+		vty_cmd_string_from_valstr(tall_bsc_ctx,
+					   bts_type_names,
+					   "type (", "|", ")",
+					   VTY_DO_LOWER);
+	cfg_bts_type_cmd.doc =
+		vty_cmd_string_from_valstr(tall_bsc_ctx,
+					   bts_type_descs,
+					   "BTS Vendor/Type\n",
+					   "\n", "", 0);
+
+
 	install_element_ve(&show_net_cmd);
 	install_element_ve(&show_bts_cmd);
 	install_element_ve(&show_trx_cmd);
diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c
index 5c58bf3..e3a6ba3 100644
--- a/openbsc/src/libcommon/gsm_data.c
+++ b/openbsc/src/libcommon/gsm_data.c
@@ -182,7 +182,7 @@
 	return NULL;
 }
 
-static const struct value_string bts_types[] = {
+const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE+1] = {
 	{ GSM_BTS_TYPE_UNKNOWN,	"unknown" },
 	{ GSM_BTS_TYPE_BS11,	"bs11" },
 	{ GSM_BTS_TYPE_NANOBTS,	"nanobts" },
@@ -193,14 +193,25 @@
 	{ 0,			NULL }
 };
 
+const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1] = {
+	{ GSM_BTS_TYPE_UNKNOWN,		"Unknown BTS Type" },
+	{ GSM_BTS_TYPE_BS11,		"Siemens BTS (BS-11 or compatible)" },
+	{ GSM_BTS_TYPE_NANOBTS,		"ip.access nanoBTS or compatible" },
+	{ GSM_BTS_TYPE_RBS2000,		"Ericsson RBS2000 Series" },
+	{ GSM_BTS_TYPE_HSL_FEMTO,	"HSL 2.75G femto" },
+	{ GSM_BTS_TYPE_NOKIA_SITE,	"Nokia {Metro,Ultra,In}Site" },
+	{ GSM_BTS_TYPE_OSMO_SYSMO,	"sysmocom sysmoBTS" },
+	{ 0,				NULL }
+};
+
 enum gsm_bts_type parse_btstype(const char *arg)
 {
-	return get_string_value(bts_types, arg);
+	return get_string_value(bts_type_names, arg);
 }
 
 const char *btstype2str(enum gsm_bts_type type)
 {
-	return get_value_string(bts_types, type);
+	return get_value_string(bts_type_names, type);
 }
 
 struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr)