OM2000: Add support for configuring the TF (Timing Function)
diff --git a/openbsc/configure.in b/openbsc/configure.in
index 8c0c728..1d2db88 100644
--- a/openbsc/configure.in
+++ b/openbsc/configure.in
@@ -43,7 +43,7 @@
     ])
 AM_CONDITIONAL(BUILD_BSC, test "x$osmo_ac_build_bsc" = "xyes")
 
-PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.1.27)
+PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.1.30)
 PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.1.28)
 
 dnl checks for header files
diff --git a/openbsc/include/openbsc/abis_om2000.h b/openbsc/include/openbsc/abis_om2000.h
index bb6563a..e4f19cf 100644
--- a/openbsc/include/openbsc/abis_om2000.h
+++ b/openbsc/include/openbsc/abis_om2000.h
@@ -65,6 +65,7 @@
 			 uint8_t operational);
 int abis_om2k_tx_is_conf_req(struct gsm_bts *bts, struct om2k_is_conn_grp *cg,
 			     unsigned int num_cg);
+int abis_om2k_tx_tf_conf_req(struct gsm_bts *bts);
 int abis_om2k_tx_rx_conf_req(struct gsm_bts_trx *trx);
 int abis_om2k_tx_tx_conf_req(struct gsm_bts_trx *trx);
 int abis_om2k_tx_ts_conf_req(struct gsm_bts_trx_ts *ts);
diff --git a/openbsc/src/libbsc/abis_om2000.c b/openbsc/src/libbsc/abis_om2000.c
index 760f15f..805b844 100644
--- a/openbsc/src/libbsc/abis_om2000.c
+++ b/openbsc/src/libbsc/abis_om2000.c
@@ -140,6 +140,12 @@
 	OM2K_MSGT_TEST_RES_NACK			= 0x0099,
 	OM2K_MSGT_TEST_RES			= 0x009a,
 
+	OM2K_MSGT_TF_CONF_REQ			= 0x00a0,
+	OM2K_MSGT_TF_CONF_REQ_ACK		= 0x00a2,
+	OM2K_MSGT_TF_CONF_REQ_REJ		= 0x00a3,
+	OM2K_MSGT_TF_CONF_RES_ACK		= 0x00a4,
+	OM2K_MSGT_TF_CONF_RES_NACK		= 0x00a5,
+	OM2K_MSGT_TF_CONF_RES			= 0x00a6,
 	OM2K_MSGT_TS_CONF_REQ			= 0x00a8,
 	OM2K_MSGT_TS_CONF_REQ_ACK		= 0x00aa,
 	OM2K_MSGT_TS_CONF_REQ_REJ		= 0x00ab,
@@ -177,10 +183,12 @@
 	OM2K_DEI_OP_INFO			= 0x2e,
 	OM2K_DEI_POWER				= 0x2f,
 	OM2K_DEI_RX_DIVERSITY			= 0x33,
+	OM2K_DEI_TF_MODE			= 0x3a,
 	OM2K_DEI_TS_NR				= 0x3c,
 	OM2K_DEI_EXT_RANGE			= 0x47,
 	OM2K_DEI_NEGOT_REC1			= 0x90,
 	OM2K_DEI_NEGOT_REC2			= 0x91,
+	OM2K_DEI_FS_OFFSET			= 0x98,
 };
 
 static const struct value_string om2k_msgcode_vals[] = {
@@ -569,6 +577,7 @@
 const struct abis_om2k_mo om2k_mo_cf = { OM2K_MO_CLS_CF, 0, 0xFF, 0 };
 const struct abis_om2k_mo om2k_mo_is = { OM2K_MO_CLS_IS, 0, 0xFF, 0 };
 const struct abis_om2k_mo om2k_mo_con = { OM2K_MO_CLS_CON, 0, 0xFF, 0 };
+const struct abis_om2k_mo om2k_mo_tf = { OM2K_MO_CLS_TF, 0, 0xFF, 0 };
 
 static int abis_om2k_cal_time_resp(struct gsm_bts *bts)
 {
@@ -761,6 +770,31 @@
 	return abis_om2k_sendmsg(trx->bts, msg);
 }
 
+enum abis_om2k_tf_mode {
+	OM2K_TF_MODE_MASTER	= 0x00,
+	OM2K_TF_MODE_STANDALONE	= 0x01,
+	OM2K_TF_MODE_SLAVE	= 0x02,
+	OM2K_TF_MODE_UNDEFINED	= 0xff,
+};
+
+static const uint8_t fs_offset_undef[5] = { 0xff, 0xff, 0xff, 0xff, 0xff };
+
+int abis_om2k_tx_tf_conf_req(struct gsm_bts *bts)
+{
+	struct msgb *msg = om2k_msgb_alloc();
+	struct abis_om2k_hdr *o2k;
+
+	o2k = (struct abis_om2k_hdr *) msgb_put(msg, sizeof(*o2k));
+	fill_om2k_hdr(o2k, &om2k_mo_tf, OM2K_MSGT_TF_CONF_REQ,
+			2+1+sizeof(fs_offset_undef));
+
+	msgb_tv_put(msg, OM2K_DEI_TF_MODE, OM2K_TF_MODE_STANDALONE);
+	msgb_tv_fixed_put(msg, OM2K_DEI_FS_OFFSET,
+			  sizeof(fs_offset_undef), fs_offset_undef);
+
+	return abis_om2k_sendmsg(bts, msg);
+}
+
 static uint8_t pchan2comb(enum gsm_phys_chan_config pchan)
 {
 	switch (pchan) {
@@ -1003,6 +1037,9 @@
 	case OM2K_MSGT_TS_CONF_RES:
 		rc = abis_om2k_tx_simple(bts, &o2h->mo, OM2K_MSGT_TS_CONF_RES_ACK);
 		break;
+	case OM2K_MSGT_TF_CONF_RES:
+		rc = abis_om2k_tx_simple(bts, &o2h->mo, OM2K_MSGT_TF_CONF_RES_ACK);
+		break;
 	case OM2K_MSGT_CONNECT_COMPL:
 		rc = abis_om2k_tx_simple(bts, &o2h->mo, OM2K_MSGT_RESET_CMD);
 		break;
@@ -1026,6 +1063,7 @@
 	case OM2K_MSGT_TX_CONF_REQ_ACK:
 	case OM2K_MSGT_RX_CONF_REQ_ACK:
 	case OM2K_MSGT_TS_CONF_REQ_ACK:
+	case OM2K_MSGT_TF_CONF_REQ_ACK:
 	case OM2K_MSGT_ENABLE_REQ_ACK:
 	case OM2K_MSGT_ALARM_STATUS_REQ_ACK:
 	case OM2K_MSGT_DISABLE_REQ_ACK:
diff --git a/openbsc/src/libbsc/abis_om2000_vty.c b/openbsc/src/libbsc/abis_om2000_vty.c
index 001c650..5ebb2a3 100644
--- a/openbsc/src/libbsc/abis_om2000_vty.c
+++ b/openbsc/src/libbsc/abis_om2000_vty.c
@@ -455,6 +455,9 @@
 			break;
 		}
 		break;
+	case OM2K_MO_CLS_TF:
+		abis_om2k_tx_tf_conf_req(bts);
+		break;
 	default:
 		vty_out(vty, "%% Don't know how to configure MO%s",
 			VTY_NEWLINE);