rf: Verify that the requested mode is entered and drop OML in error

Verify that the BTS is following our orders, if we think there was
an error we will drop the OML connection.
diff --git a/openbsc/src/bsc/osmo_bsc_rf.c b/openbsc/src/bsc/osmo_bsc_rf.c
index 6d2a174..627915a 100644
--- a/openbsc/src/bsc/osmo_bsc_rf.c
+++ b/openbsc/src/bsc/osmo_bsc_rf.c
@@ -106,6 +106,30 @@
 	send_resp(conn, send);
 }
 
+static void rf_check_cb(void *_data)
+{
+	struct gsm_bts *bts;
+	struct osmo_bsc_rf *rf = _data;
+
+	llist_for_each_entry(bts, &rf->gsm_network->bts_list, list) {
+		struct gsm_bts_trx *trx;
+
+		/* don't bother to check a booting or missing BTS */
+		if (!bts->oml_link || !is_ipaccess_bts(bts))
+			continue;
+
+		llist_for_each_entry(trx, &bts->trx_list, list) {
+			if (trx->nm_state.availability != NM_AVSTATE_OK ||
+			    trx->nm_state.operational != NM_OPSTATE_ENABLED ||
+			    trx->nm_state.administrative != NM_STATE_UNLOCKED) {
+				LOGP(DNM, LOGL_ERROR, "RF activation failed. Starting again.\n");
+				ipaccess_drop_oml(bts);
+				break;
+			}
+		}
+	}
+}
+
 static void send_signal(struct osmo_bsc_rf *rf, int val)
 {
 	struct rf_signal_data sig;
@@ -167,6 +191,7 @@
 		break;
 	case RF_CMD_D_OFF:
 		conn->rf->last_state_command = "RF Direct Off";
+		bsc_del_timer(&conn->rf->rf_check);
 		bsc_del_timer(&conn->rf->grace_timeout);
 		switch_rf_off(conn->rf);
 		break;
@@ -175,9 +200,11 @@
 		bsc_del_timer(&conn->rf->grace_timeout);
 		lock_each_trx(conn->rf->gsm_network, 0);
 		send_signal(conn->rf, S_RF_ON);
+		bsc_schedule_timer(&conn->rf->rf_check, 3, 0);
 		break;
 	case RF_CMD_OFF:
 		conn->rf->last_state_command = "RF Scheduled Off";
+		bsc_del_timer(&conn->rf->rf_check);
 		enter_grace(conn);
 		break;
 	default:
@@ -311,6 +338,10 @@
 	rf->policy = S_RF_ON;
 	rf->last_state_command = "";
 
+	/* check the rf state */
+	rf->rf_check.data = rf;
+	rf->rf_check.cb = rf_check_cb;
+
 	return rf;
 }