* add more detailed status printout to bs11_config
* add support for real LMT logon time
* add support for abis external time
* move 'create_trx1_objects' to separate function

diff --git a/src/abis_nm.c b/src/abis_nm.c
index 2591320..c9bea25 100644
--- a/src/abis_nm.c
+++ b/src/abis_nm.c
@@ -28,6 +28,7 @@
 #include <fcntl.h>
 #include <malloc.h>
 #include <libgen.h>
+#include <time.h>
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -836,6 +837,31 @@
 
 /* Siemens (or BS-11) specific commands */
 
+struct bs11_date_time {
+	u_int16_t	year;
+	u_int8_t	month;
+	u_int8_t	day;
+	u_int8_t	hour;
+	u_int8_t	min;
+	u_int8_t	sec;
+} __attribute__((packed));
+
+
+void get_bs11_date_time(struct bs11_date_time *aet)
+{
+	time_t t;
+	struct tm *tm;
+
+	t = time(NULL);
+	tm = localtime(&t);
+	aet->sec = tm->tm_sec;
+	aet->min = tm->tm_min;
+	aet->hour = tm->tm_hour;
+	aet->day = tm->tm_mday;
+	aet->month = tm->tm_mon;
+	aet->year = htons(1900 + tm->tm_year);
+}
+
 int abis_nm_bs11_reset_resource(struct gsm_bts *bts)
 {
 	return __simple_cmd(bts, NM_MT_BS11_RESET_RESOURCE);
@@ -859,7 +885,7 @@
 
 	oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
 	fill_om_fom_hdr(oh, attr_len, NM_MT_BS11_CREATE_OBJ,
-			NM_OC_BS11, type, idx, 0);
+			NM_OC_BS11, type, 0, idx);
 	cur = msgb_put(msg, attr_len);
 	memcpy(cur, attr, attr_len);
 
@@ -936,8 +962,7 @@
 	return abis_nm_sendmsg(trx->bts, msg);
 }
 
-static const u_int8_t bs11_logon_c7[] = 
-	{ 0x07, 0xd9, 0x01, 0x11, 0x0d, 0x10, 0x20 };
+//static const u_int8_t bs11_logon_c7[] = { 0x07, 0xd9, 0x01, 0x11, 0x0d, 0x10, 0x20 };
 static const u_int8_t bs11_logon_c8[] = { 0x02 };
 static const u_int8_t bs11_logon_c9[] = "FACTORY";
 
@@ -945,15 +970,18 @@
 {
 	struct abis_om_hdr *oh;
 	struct msgb *msg = nm_msgb_alloc();
+	struct bs11_date_time bdt;
+
+	get_bs11_date_time(&bdt);
 
 	oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
 	if (on) {
-		u_int8_t len = 3*2 + sizeof(bs11_logon_c7)
+		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);
 		msgb_tlv_put(msg, NM_ATT_BS11_LMT_LOGIN_TIME,
-			     sizeof(bs11_logon_c7), bs11_logon_c7);
+			     sizeof(bdt), &bdt);
 		msgb_tlv_put(msg, NM_ATT_BS11_LMT_USER_ACC_LEV,
 			     sizeof(bs11_logon_c8), bs11_logon_c8);
 		msgb_tlv_put(msg, NM_ATT_BS11_LMT_USER_NAME,
@@ -1182,3 +1210,19 @@
 
 	return abis_nm_sendmsg(bts, msg);
 }
+
+int abis_nm_bs11_set_ext_time(struct gsm_bts *bts)
+{
+	struct abis_om_hdr *oh;
+	struct msgb *msg = nm_msgb_alloc();
+	struct bs11_date_time aet;
+
+	get_bs11_date_time(&aet);
+	oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
+	/* SiemensHW CCTRL object */
+	fill_om_fom_hdr(oh, 2+sizeof(aet), NM_MT_BS11_SET_ATTR, NM_OC_SITE_MANAGER,
+			0xff, 0xff, 0xff);
+	msgb_tlv_put(msg, NM_ATT_BS11_ABIS_EXT_TIME, sizeof(aet), &aet);
+
+	return abis_nm_sendmsg(bts, msg);
+}
diff --git a/src/bs11_config.c b/src/bs11_config.c
index 6166c84..af73d23 100644
--- a/src/bs11_config.c
+++ b/src/bs11_config.c
@@ -81,6 +81,27 @@
 
 static int handle_serial_msg(struct msgb *rx_msg);
 
+static int create_trx1_objects(struct gsm_bts *bts)
+{
+	u_int8_t bbsig1_attr[sizeof(obj_bbsig0_attr)+12];
+	u_int8_t *cur = bbsig1_attr;
+	
+	abis_nm_bs11_set_trx1_pw(bts, trx1_password);
+
+	cur = tlv_put(cur, NM_ATT_BS11_PASSWORD, 10,
+		      (u_int8_t *)trx1_password);
+	memcpy(cur, obj_bbsig0_attr, sizeof(obj_bbsig0_attr));
+	abis_nm_bs11_create_object(bts, BS11_OBJ_BBSIG, 1,
+				   sizeof(bbsig1_attr), bbsig1_attr);
+
+	abis_nm_bs11_create_object(bts, BS11_OBJ_PA, 1,
+				   sizeof(obj_pa0_attr), obj_pa0_attr);
+
+	abis_nm_bs11_set_trx_power(&bts->trx[1], BS11_TRX_POWER_GSM_30mW);
+
+	return 0;
+}
+
 /* create all objects for an initial configuration */
 static int create_objects(struct gsm_bts *bts, int trx1)
 {
@@ -94,22 +115,6 @@
 				   sizeof(obj_bbsig0_attr), obj_bbsig0_attr);
 	abis_nm_bs11_create_object(bts, BS11_OBJ_PA, 0,
 				   sizeof(obj_pa0_attr), obj_pa0_attr);
-	if (trx1) {
-		u_int8_t bbsig1_attr[sizeof(obj_bbsig0_attr)+12];
-		u_int8_t *cur = bbsig1_attr;
-		
-		abis_nm_bs11_set_trx1_pw(bts, trx1_password);
-
-		cur = tlv_put(cur, NM_ATT_BS11_PASSWORD, 10,
-			      (u_int8_t *)trx1_password);
-		memcpy(cur, obj_bbsig0_attr, sizeof(obj_bbsig0_attr));
-		abis_nm_bs11_create_object(bts, BS11_OBJ_BBSIG, 1,
-					   sizeof(bbsig1_attr), bbsig1_attr);
-
-		abis_nm_bs11_create_object(bts, BS11_OBJ_PA, 1,
-					   sizeof(obj_pa0_attr), obj_pa0_attr);
-	}
-
 	abis_nm_bs11_create_envaBTSE(bts, 0);
 	abis_nm_bs11_create_envaBTSE(bts, 1);
 	abis_nm_bs11_create_envaBTSE(bts, 2);
@@ -119,10 +124,6 @@
 	abis_nm_bs11_set_oml_tei(bts, TEI_OML);
 
 	abis_nm_bs11_set_trx_power(&bts->trx[0], BS11_TRX_POWER_GSM_30mW);
-
-	if (trx1)
-		abis_nm_bs11_set_trx_power(&bts->trx[1], BS11_TRX_POWER_GSM_30mW);
-
 	//abis_nm_bs11_factory_logon(bts, 0);
 	
 	return 0;
@@ -336,24 +337,99 @@
 	return 0;
 }
 
-/* handle a response from the BTS to a GET STATE command */
-static int handle_state_resp(u_int8_t state)
+static const char *bs11_link_state[] = {
+	[0x00]	= "Down",
+	[0x01]	= "Up",
+	[0x02]	= "Restoring",
+};
+
+static const char *linkstate_name(u_int8_t linkstate)
 {
-	int rc = 0;
+	if (linkstate > ARRAY_SIZE(bs11_link_state))
+		return "Unknown";
 
-	printf("STATE: ");
+	return bs11_link_state[linkstate];
+}
 
-	switch (state) {
+static const char *mbccu_load[] = {
+	[0]	= "No Load",
+	[1]	= "Load BTSCAC",
+	[2]	= "Load BTSDRX",
+	[3]	= "Load BTSBBX",
+	[4]	= "Load BTSARC",
+	[5]	= "Load",
+};
+
+static const char *mbccu_load_name(u_int8_t linkstate)
+{
+	if (linkstate > ARRAY_SIZE(mbccu_load))
+		return "Unknown";
+
+	return mbccu_load[linkstate];
+}
+
+
+static void print_state(struct abis_nm_bs11_state *st)
+{
+	enum abis_bs11_phase phase = st->phase;
+
+	printf("T-Link: %-9s Abis-link: %-9s MBCCU0: %-11s MBCCU1: %-11s PHASE: %u SUBPHASE: ",
+		linkstate_name(st->t_link), linkstate_name(st->abis_link),
+		mbccu_load_name(st->mbccu >> 4), mbccu_load_name(st->mbccu & 0xf),
+		phase & 0xf);
+
+	switch (phase) {
 	case BS11_STATE_WARM_UP:
 		printf("Warm Up...\n");
-		sleep(5);
 		break;
 	case BS11_STATE_LOAD_SMU_SAFETY:
 		printf("Load SMU Safety...\n");
-		sleep(5);
+		break;
+	case BS11_STATE_LOAD_SMU_INTENDED:
+		printf("Load SMU Intended...\n");
+		break;
+	case BS11_STATE_LOAD_MBCCU:
+		printf("Load MBCCU...\n");
 		break;
 	case BS11_STATE_SOFTWARE_RQD:
 		printf("Software required...\n");
+		break;
+	case BS11_STATE_WAIT_MIN_CFG:
+	case BS11_STATE_WAIT_MIN_CFG_2:
+		printf("Wait minimal config...\n");
+		break;
+	case BS11_STATE_MAINTENANCE:
+		printf("Maintenance...\n");
+		break;
+	case BS11_STATE_NORMAL:
+		printf("Normal...\n");
+		break;
+	default:
+		printf("Unknown phase 0x%02x\n", phase);
+		break;
+	}
+}
+
+/* handle a response from the BTS to a GET STATE command */
+static int handle_state_resp(enum abis_bs11_phase state)
+{
+	int rc = 0;
+
+	printf("PHASE: %u STATE: ", state & 0xf);
+
+	switch (state) {
+	case BS11_STATE_WARM_UP:
+		sleep(5);
+		break;
+	case BS11_STATE_LOAD_SMU_SAFETY:
+		sleep(5);
+		break;
+	case BS11_STATE_LOAD_SMU_INTENDED:
+		sleep(5);
+		break;
+	case BS11_STATE_LOAD_MBCCU:
+		break;
+	case BS11_STATE_SOFTWARE_RQD:
 		bs11cfg_state = STATE_SWLOAD;
 		/* send safety load. Use g_bts as private 'param'
 		 * argument, so our swload_cbfn can distinguish
@@ -368,12 +444,10 @@
 		break;
 	case BS11_STATE_WAIT_MIN_CFG:
 	case BS11_STATE_WAIT_MIN_CFG_2:
-		printf("Wait minimal config...\n");
 		bs11cfg_state = STATE_SWLOAD;
 		rc = create_objects(g_bts, have_trx1);
 		break;
 	case BS11_STATE_MAINTENANCE:
-		printf("Maintenance...\n");
 		bs11cfg_state = STATE_SWLOAD;
 		/* send software (FIXME: over A-bis?) */
 		if (file_is_readable(fname_software))
@@ -384,10 +458,10 @@
 				fname_software);
 		break;
 	case BS11_STATE_NORMAL:
-		printf("Normal...\n");
+		if (have_trx1)
+			create_trx1_objects(g_bts);
 		return 1;
 	default:
-		printf("Unknown state 0x%02u\n", state);
 		sleep(5);
 		break;
 	}
@@ -399,6 +473,7 @@
 {
 	struct abis_om_hdr *oh;
 	struct abis_om_fom_hdr *foh;
+	struct abis_nm_bs11_state *st;
 	int rc = -1;
 
 	if (rx_msg->len < LAPD_HDR_LEN
@@ -427,7 +502,9 @@
 		exit(0);
 		break;
 	case NM_MT_BS11_GET_STATE_ACK:
-		rc = handle_state_resp(foh->data[2]);
+		st = (struct abis_nm_bs11_state *) &foh->data[0];
+		print_state(st);
+		rc = handle_state_resp(st->phase);
 		break;
 	default:
 		rc = abis_nm_rcvmsg(rx_msg);