* give Siemens ObjClass reasonable names rather than A3/A5/A6
* add nm_state objects for RACK and CCLK
* add obj_class human-readable printing for all vendor obj_classes
* add human-readable printing of administrative state
* add enum for cell_alloc numbers

diff --git a/include/openbsc/abis_nm.h b/include/openbsc/abis_nm.h
index 6f0e041..3aac31f 100644
--- a/include/openbsc/abis_nm.h
+++ b/include/openbsc/abis_nm.h
@@ -223,6 +223,11 @@
 	NM_MT_IPACC_GET_NVATTR_NACK,
 };
 
+enum abis_nm_bs11_cell_alloc {
+	NM_BS11_CANR_GSM	= 0x00,
+	NM_BS11_CANR_DCS1800	= 0x01,
+};
+
 /* Section 9.2: Object Class */
 enum abis_nm_obj_class {
 	NM_OC_SITE_MANAGER		= 0x00,
@@ -231,13 +236,13 @@
 	NM_OC_CHANNEL,
 	NM_OC_BASEB_TRANSC,
 	/* RFU: 05-FE */
-	NM_OC_BS11_A0			= 0xa0,
+	NM_OC_BS11_ADJC			= 0xa0,
 	NM_OC_BS11_HANDOVER		= 0xa1,
 	NM_OC_BS11_PWR_CTRL		= 0xa2,
-	NM_OC_BS11_A3			= 0xa3,
-	NM_OC_BS11_A4			= 0xa4,
-	NM_OC_BS11			= 0xa5,
-	NM_OC_BS11_A6			= 0xa6,
+	NM_OC_BS11_BTSE			= 0xa3,		/* LMT? */
+	NM_OC_BS11_RACK			= 0xa4,
+	NM_OC_BS11			= 0xa5,		/* 01: ALCO */
+	NM_OC_BS11_TEST			= 0xa6,
 	NM_OC_BS11_ENVABTSE		= 0xa8,
 	NM_OC_BS11_BPORT		= 0xa9,
 
@@ -495,7 +500,7 @@
 	u_int8_t	subslot;
 } __attribute__ ((packed));
 
-/* Siemens BS-11 specific */
+/* Siemens BS-11 specific objects in the SienemsHW (0xA5) object class */
 enum abis_bs11_objtype {
 	BS11_OBJ_ALCO		= 0x01,
 	BS11_OBJ_BBSIG		= 0x02,	/* obj_class: 0,1 */
diff --git a/include/openbsc/gsm_data.h b/include/openbsc/gsm_data.h
index 2c05260..145e406 100644
--- a/include/openbsc/gsm_data.h
+++ b/include/openbsc/gsm_data.h
@@ -303,10 +303,21 @@
 	} site_mgr;
 
 	/* ip.accesss Unit ID's have Site/BTS/TRX layout */
-	struct {
-		u_int16_t site_id;
-		u_int16_t bts_id;
-	} ip_access;
+	union {
+		struct {
+			u_int16_t site_id;
+			u_int16_t bts_id;
+		} ip_access;
+		struct {
+			struct {
+				struct gsm_nm_state nm_state;
+			} cclk;
+			struct {
+				struct gsm_nm_state nm_state;
+			} rack;
+
+		} bs11;
+	};
 	
 	/* transceivers */
 	int num_trx;
diff --git a/src/abis_nm.c b/src/abis_nm.c
index 0107c29..57d4159 100644
--- a/src/abis_nm.c
+++ b/src/abis_nm.c
@@ -435,19 +435,46 @@
 
 static int abis_nm_rcvmsg_sw(struct msgb *mb);
 
-const char *oc_names[] = {
-	[NM_OC_SITE_MANAGER]	= "SITE MANAGER",
-	[NM_OC_BTS]		= "BTS",
-	[NM_OC_RADIO_CARRIER]	= "RADIO CARRIER",
-	[NM_OC_BASEB_TRANSC]	= "BASEBAND TRANSCEIVER",
-	[NM_OC_CHANNEL]		= "CHANNEL",
-};
-
 static const char *obj_class_name(u_int8_t oc)
 {
-	if (oc >= ARRAY_SIZE(oc_names))
-		return "UNKNOWN";
-	return oc_names[oc];
+	switch (oc) {
+	case NM_OC_SITE_MANAGER:
+		return "SITE MANAGER";
+	case NM_OC_BTS:
+		return "BTS";
+	case NM_OC_RADIO_CARRIER:
+		return "RADIO CARRIER";
+	case NM_OC_BASEB_TRANSC:
+		return "BASEBAND TRANSCEIVER";
+	case NM_OC_CHANNEL:
+		return "CHANNL";
+	case NM_OC_BS11_ADJC:
+		return "ADJC";
+	case NM_OC_BS11_HANDOVER:
+		return "HANDOVER";
+	case NM_OC_BS11_PWR_CTRL:
+		return "POWER CONTROL";
+	case NM_OC_BS11_BTSE:
+		return "BTSE";
+	case NM_OC_BS11_RACK:
+		return "RACK";
+	case NM_OC_BS11_TEST:
+		return "TEST";
+	case NM_OC_BS11_ENVABTSE:
+		return "ENVABTSE";
+	case NM_OC_BS11_BPORT:
+		return "BPORT";
+	case NM_OC_GPRS_NSE:
+		return "GPRS NSE";
+	case NM_OC_GPRS_CELL:
+		return "GPRS CELL";
+	case NM_OC_GPRS_NSVC0:
+		return "GPRS NSVC0";
+	case NM_OC_GPRS_NSVC1:
+		return "GPRS NSVC1";
+	}
+
+	return "UNKNOWN";
 }
 
 const char *nm_opstate_name(u_int8_t os)
@@ -484,7 +511,20 @@
 		return "UNKNOWN";
 	return avail_names[avail];
 }
-	
+
+const char *nm_adm_name(u_int8_t adm)
+{
+	switch (adm) {
+	case 1:
+		return "Locked";
+	case 2:
+		return "Unlocked";
+	case 3:
+		return "Shutdown";
+	default:
+		return "<not used>";
+	}
+}
 
 /* obtain the gsm_nm_state data structure for a given object instance */
 static struct gsm_nm_state *
@@ -521,6 +561,17 @@
 	case NM_OC_SITE_MANAGER:
 		nm_state = &bts->site_mgr.nm_state;
 		break;
+	case NM_OC_BS11:
+		switch (obj_inst->bts_nr) {
+		case BS11_OBJ_CCLK:
+			nm_state = &bts->bs11.cclk.nm_state;
+			break;
+		default:
+			return NULL;
+		}
+	case NM_OC_BS11_RACK:
+		nm_state = &bts->bs11.rack.nm_state;
+		break;
 	}
 	return nm_state;
 }
@@ -622,7 +673,7 @@
 	}
 	if (TLVP_PRESENT(&tp, NM_ATT_ADM_STATE)) {
 		new_state.administrative = *TLVP_VAL(&tp, NM_ATT_ADM_STATE);
-		DEBUGPC(DNM, "ADM=%02x ", new_state.administrative);
+		DEBUGPC(DNM, "ADM=%02x ", nm_adm_name(new_state.administrative));
 	}
 	DEBUGPC(DNM, "\n");
 
@@ -1872,7 +1923,7 @@
 		u_int8_t len = 3*2 + sizeof(bdt)
 				+ sizeof(bs11_logon_c8) + sizeof(bs11_logon_c9);
 		fill_om_fom_hdr(oh, len, NM_MT_BS11_LMT_LOGON,
-				NM_OC_BS11_A3, 0xff, 0xff, 0xff);
+				NM_OC_BS11_BTSE, 0xff, 0xff, 0xff);
 		msgb_tlv_put(msg, NM_ATT_BS11_LMT_LOGIN_TIME,
 			     sizeof(bdt), (u_int8_t *) &bdt);
 		msgb_tlv_put(msg, NM_ATT_BS11_LMT_USER_ACC_LEV,
@@ -1881,7 +1932,7 @@
 			     sizeof(bs11_logon_c9), bs11_logon_c9);
 	} else {
 		fill_om_fom_hdr(oh, 0, NM_MT_BS11_LMT_LOGOFF,
-				NM_OC_BS11_A3, 0xff, 0xff, 0xff);
+				NM_OC_BS11_BTSE, 0xff, 0xff, 0xff);
 	}
 	
 	return abis_nm_sendmsg(bts, msg);
diff --git a/src/bs11_config.c b/src/bs11_config.c
index ceb23a8..656feb4 100644
--- a/src/bs11_config.c
+++ b/src/bs11_config.c
@@ -310,8 +310,10 @@
 {
 	switch (acc) {
 	case 0:
+		/* Out of the demanded +/- 0.05ppm */
 		return "Medium";
 	case 1:
+		/* Synchronized with Abis, within demanded tolerance +/- 0.05ppm */
 		return "High";
 	default:
 		return "unknown";
diff --git a/src/bsc_hack.c b/src/bsc_hack.c
index 7ac65c5..a8fd537 100644
--- a/src/bsc_hack.c
+++ b/src/bsc_hack.c
@@ -157,8 +157,8 @@
 		NM_ATT_BS11_BTSLS_HOPPING, 0x00,
 		NM_ATT_CCCH_L_I_P, 0x01,
 		NM_ATT_CCCH_L_T, 0x00,
-		NM_ATT_BS11_CELL_ALLOC_NR, 0x00,
-		NM_ATT_BS11_ENA_INTERF_CLASS, 0x00,
+		NM_ATT_BS11_CELL_ALLOC_NR, NM_BS11_CANR_GSM,
+		NM_ATT_BS11_ENA_INTERF_CLASS, 0x01,
 		NM_ATT_BS11_FACCH_QUAL, 0x06,
 		/* interference avg. period in numbers of SACCH multifr */
 		NM_ATT_INTAVE_PARAM, 0x1F,