From b93aa5caa58310f4bcbfbc4676fa9dd6b7a36927 Mon Sep 17 00:00:00 2001
From: Pau Espin Pedrol <pespin@sysmocom.de>
Date: Fri, 23 Nov 2018 17:51:38 +0100
Subject: [PATCH] WIP

We should not ACK PDCH DEACT until we get response from osmo-trx.

20181123044720655 DRLL <0002> rsl.c:2523 (bts=0,trx=0,ts=0,ss=0) Rx RLL DATA_REQ Abis -> LAPDm
20181123044720700 DRSL <0000> rsl.c:2805 (bts=0,trx=0,ts=6,pchan=TCH/F_PDCH as PDCH) ss=0 Rx RSL IPAC_PDCH_DEACT
20181123044720700 DRSL <0000> rsl.c:2205 (bts=0,trx=0,ts=6,pchan=TCH/F_PDCH as PDCH) Request to PDCH DEACT, but lchan is still active
20181123044720700 DRSL <0000> rsl.c:2131 (bts=0,trx=0,ts=6,ss=0) Tx PDCH DEACT NACK (cause = 0x0f)
20181123044720700 DPCU <0009> pcu_sock.c:124 Sending info
20181123044720700 DPCU <0009> pcu_sock.c:139 BTS is up
20181123044720700 DPCU <0009> pcu_sock.c:232 trx=0 ts=7: available (tsc=7 arfcn=868)
20181123044720703 DPCU <0009> pcu_sock.c:608 Deactivate request received: TRX=0 TX=6
20181123044720703 DL1C <0006> l1sap.c:1519 deactivating channel chan_nr=TCH/F on TS6 trx=0
20181123044720703 DTRX <000b> trx_if.c:242 Enqueuing TRX control command 'CMD NOHANDOVER 6 0'
20181123044720703 DL1C <0006> l1sap.c:648 deactivate confirm chan_nr=TCH/F on TS6 trx=0
20181123044720703 DRSL <0000> rsl.c:714 (bts=0,trx=0,ts=6,ss=0) not sending REL ACK
20181123044720703 DRSL <0000> rsl.c:2264 (bts=0,trx=0,ts=6,ss=0) PDCH DEACT operation: channel disconnected, will reconnect as TCH
20181123044720703 DL1C <0006> scheduler.c:593 Configuring multiframe with TCH/F+SACCH trx=0 ts=6
20181123044720703 DTRX <000b> trx_if.c:242 Enqueuing TRX control command 'CMD SETSLOT 6 1'
20181123044720703 DL1C <0006> l1_if.c:780 (bts=0,trx=0,ts=6) bts_model_ts_connect(as_pchan=TCH/F) success, calling cb_ts_connected()
20181123044720703 DRSL <0000> rsl.c:2339 (bts=0,trx=0,ts=6,ss=0) PDCH DEACT operation: timeslot connected as TCH/F
20181123044720703 DRSL <0000> rsl.c:2440 (bts=0,trx=0,ts=6,ss=0) TCH/F_PDCH switched to TCH/F mode (ts->flags == 0)
20181123044720703 DRSL <0000> rsl.c:2103 (bts=0,trx=0,ts=6,ss=0) Tx PDCH DEACT ACK
20181123044720704 DTRX <000b> trx_if.c:492 Response message: 'RSP NOHANDOVER 0 6'
20181123044720705 DTRX <000b> trx_if.c:492 Response message: 'RSP SETSLOT 0 6 1'

Change-Id: I63a8544b4ddbf20f0e7d3b359d9e5b75bc6967cc
---
 include/osmo-bts/bts_model.h   |  2 +-
 src/common/rsl.c               | 32 ++++++++++++++++++++++----------
 src/osmo-bts-trx/l1_if.c       |  2 +-
 src/osmo-bts-trx/trx_if.c      | 13 +++++++++++++
 tests/handover/handover_test.c |  2 +-
 tests/meas/meas_test.c         |  4 ++--
 tests/stubs.c                  |  4 ++--
 7 files changed, 42 insertions(+), 17 deletions(-)

diff --git a/include/osmo-bts/bts_model.h b/include/osmo-bts/bts_model.h
index f1f68307..be0480c1 100644
--- a/include/osmo-bts/bts_model.h
+++ b/include/osmo-bts/bts_model.h
@@ -60,6 +60,6 @@ void bts_model_phy_link_set_defaults(struct phy_link *plink);
 void bts_model_phy_instance_set_defaults(struct phy_instance *pinst);
 
 int bts_model_ts_disconnect(struct gsm_bts_trx_ts *ts);
-int bts_model_ts_connect(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config as_pchan);
+void bts_model_ts_connect(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config as_pchan);
 
 #endif
diff --git a/src/common/rsl.c b/src/common/rsl.c
index b4cea2cd..e8e3211e 100644
--- a/src/common/rsl.c
+++ b/src/common/rsl.c
@@ -2157,7 +2157,7 @@ static int rsl_tx_dyn_pdch_nack(struct gsm_lchan *lchan, bool pdch_act,
  * 1. call bts_model_ts_disconnect() to disconnect TCH/F;
  * 2. cb_ts_disconnected() is called when done;
  * 3. call bts_model_ts_connect() to connect as PDTCH;
- * 4. cb_ts_connected() is called when done;
+ * 4. cb_ts_connected(rc) is called when done;
  * 5. instruct the PCU to enable PDTCH;
  * 6. the PCU will call back with an activation request;
  * 7. l1sap_info_act_cnf() will call ipacc_dyn_pdch_complete() when SAPI
@@ -2171,7 +2171,7 @@ static int rsl_tx_dyn_pdch_nack(struct gsm_lchan *lchan, bool pdch_act,
  *    deactivations are done;
  * 4. cb_ts_disconnected() is called when done;
  * 5. call bts_model_ts_connect() to connect as TCH/F;
- * 6. cb_ts_connected() is called when done;
+ * 6. cb_ts_connected(rc) is called when done;
  * 7. directly call ipacc_dyn_pdch_complete(), since no further action required
  *    for TCH/F;
  * 8. send a PDCH DEACT ACK.
@@ -2276,7 +2276,8 @@ static void ipacc_dyn_pdch_ts_disconnected(struct gsm_bts_trx_ts *ts)
 	if (rc)
 		goto error_nack;
 
-	rc = bts_model_ts_connect(ts, as_pchan);
+	bts_model_ts_connect(ts, as_pchan);
+	return;
 
 error_nack:
 	/* Error? then NACK right now. */
@@ -2322,9 +2323,14 @@ void cb_ts_disconnected(struct gsm_bts_trx_ts *ts)
 	}
 }
 
-static void ipacc_dyn_pdch_ts_connected(struct gsm_bts_trx_ts *ts)
+static void ipacc_dyn_pdch_ts_connected(struct gsm_bts_trx_ts *ts, int rc)
 {
-	int rc;
+	if (rc) {
+		LOGP(DRSL, LOGL_NOTICE, "%s PDCH ACT IPA operation failed (%d) in bts model\n",
+		     gsm_lchan_name(ts->lchan), rc);
+		ipacc_dyn_pdch_complete(ts, rc);
+		return;
+	}
 
 	if (ts->flags & TS_F_PDCH_DEACT_PENDING) {
 		if (ts->lchan[0].type != GSM_LCHAN_TCH_F)
@@ -2373,12 +2379,18 @@ static void ipacc_dyn_pdch_ts_connected(struct gsm_bts_trx_ts *ts)
 	}
 }
 
-static void osmo_dyn_ts_connected(struct gsm_bts_trx_ts *ts)
+static void osmo_dyn_ts_connected(struct gsm_bts_trx_ts *ts, int rc)
 {
-	int rc;
 	struct msgb *msg = ts->dyn.pending_chan_activ;
 	ts->dyn.pending_chan_activ = NULL;
 
+	if (rc) {
+		LOGP(DRSL, LOGL_NOTICE, "%s PDCH ACT OSMO operation failed (%d) in bts model\n",
+		     gsm_lchan_name(ts->lchan), rc);
+		ipacc_dyn_pdch_complete(ts, rc);
+		return;
+	}
+
 	if (!msg) {
 		LOGP(DRSL, LOGL_ERROR,
 		     "%s TS re-connected, but no chan activ msg pending\n",
@@ -2395,15 +2407,15 @@ static void osmo_dyn_ts_connected(struct gsm_bts_trx_ts *ts)
 		msgb_free(msg);
 }
 
-void cb_ts_connected(struct gsm_bts_trx_ts *ts)
+void cb_ts_connected(struct gsm_bts_trx_ts *ts, int rc)
 {
 	OSMO_ASSERT(ts);
 
 	switch (ts->pchan) {
 	case GSM_PCHAN_TCH_F_PDCH:
-		return ipacc_dyn_pdch_ts_connected(ts);
+		return ipacc_dyn_pdch_ts_connected(ts, rc);
 	case GSM_PCHAN_TCH_F_TCH_H_PDCH:
-		return osmo_dyn_ts_connected(ts);
+		return osmo_dyn_ts_connected(ts, rc);
 	default:
 		return;
 	}
diff --git a/src/osmo-bts-trx/l1_if.c b/src/osmo-bts-trx/l1_if.c
index b4ca54f0..aeb77a6d 100644
--- a/src/osmo-bts-trx/l1_if.c
+++ b/src/osmo-bts-trx/l1_if.c
@@ -779,6 +779,6 @@ int bts_model_ts_connect(struct gsm_bts_trx_ts *ts,
 	     " calling cb_ts_connected()\n",
 	     gsm_ts_name(ts), gsm_pchan_name(as_pchan));
 
-	cb_ts_connected(ts);
+	/* cb_ts_connected will be called once we receive RSP SETSLOT */
 	return 0;
 }
diff --git a/src/osmo-bts-trx/trx_if.c b/src/osmo-bts-trx/trx_if.c
index abe6846d..e44a302d 100644
--- a/src/osmo-bts-trx/trx_if.c
+++ b/src/osmo-bts-trx/trx_if.c
@@ -437,6 +437,17 @@ static bool cmd_matches_rsp(struct trx_ctrl_msg *tcm, struct trx_ctrl_rsp *rsp)
 	return true;
 }
 
+static int trx_ctrl_rx_rsp_setslot(struct trx_l1h *l1h, struct trx_ctrl_rsp *rsp)
+{
+	/*TODO: parse TS num from rsp and get ts pointer, call a function in l1_if.c which in turn will: */
+		if (rsp->status) {
+			LOG("SETSLOT failed with status XYZ");
+		}
+		if (ts->flags | TS_F_PDCH_ACT_PENDING)
+			cb_ts_connected(ts, rsp->status)
+		return rsp->status == 0 ? 0 : -EINVAL;
+}
+
 /* -EINVAL: unrecoverable error, exit BTS
  * N > 0: try sending originating command again after N seconds
  * 0: Done with response, get originating command out from send queue
@@ -459,6 +470,8 @@ static int trx_ctrl_rx_rsp(struct trx_l1h *l1h, struct trx_ctrl_rsp *rsp, bool c
 				phy_link_state_set(pinst->phy_link, PHY_LINK_SHUTDOWN);
 			return 5;
 		}
+	} else if (strcmp(rsp->cmd, "SETSLOT") == 0) {
+		return trx_ctrl_rx_rsp_setslot(l1h, rsp);
 	}
 
 	if (rsp->status) {
diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c
index 407ed95d..a805554e 100644
--- a/tests/handover/handover_test.c
+++ b/tests/handover/handover_test.c
@@ -278,6 +278,6 @@ int bts_model_trx_close(struct gsm_bts_trx *trx) { return 0; }
 void trx_get_hlayer1(void) {}
 int bts_model_adjst_ms_pwr(struct gsm_lchan *lchan) { return 0; }
 int bts_model_ts_disconnect(struct gsm_bts_trx_ts *ts) { return 0; }
-int bts_model_ts_connect(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config as_pchan) { return 0; }
+void bts_model_ts_connect(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config as_pchan) { return; }
 int bts_model_lchan_deactivate(struct gsm_lchan *lchan) { return 0; }
 int bts_model_lchan_deactivate_sacch(struct gsm_lchan *lchan) { return 0; }
diff --git a/tests/meas/meas_test.c b/tests/meas/meas_test.c
index f5803743..b2bf80e2 100644
--- a/tests/meas/meas_test.c
+++ b/tests/meas/meas_test.c
@@ -659,9 +659,9 @@ int bts_model_ts_disconnect(struct gsm_bts_trx_ts *ts)
 	return 0;
 }
 
-int bts_model_ts_connect(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config as_pchan)
+void bts_model_ts_connect(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config as_pchan)
 {
-	return 0;
+	return;
 }
 
 int bts_model_lchan_deactivate(struct gsm_lchan *lchan)
diff --git a/tests/stubs.c b/tests/stubs.c
index d6f4d3d8..7c64034b 100644
--- a/tests/stubs.c
+++ b/tests/stubs.c
@@ -54,6 +54,6 @@ void bts_model_abis_close(struct gsm_bts *bts)
 int bts_model_ts_disconnect(struct gsm_bts_trx_ts *ts)
 { return 0; }
 
-int bts_model_ts_connect(struct gsm_bts_trx_ts *ts,
+void bts_model_ts_connect(struct gsm_bts_trx_ts *ts,
 			 enum gsm_phys_chan_config as_pchan)
-{ return 0; }
+{ return; }
-- 
2.19.1

