Move UL allocation&assign functions to gprs_ms.c

Similar structure as what we have with DL-TBF.

Change-Id: I256aeede2a2678c9738539fb6ec4db9766fa85e4
diff --git a/src/bts.cpp b/src/bts.cpp
index 2389987..31c2b0a 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -981,7 +981,7 @@
 		bts_do_rate_ctr_inc(bts, CTR_IMMEDIATE_ASSIGN_UL_TBF_TWO_PHASE);
 	} else {
 		GprsMs *ms = bts_alloc_ms(bts, 0, chan_req.egprs_mslot_class);
-		tbf = tbf_alloc_ul_ccch(bts, ms);
+		tbf = ms_new_ul_tbf_assigned_agch(ms);
 		if (!tbf) {
 			/* Send RR Immediate Assignment Reject */
 			rc = -EBUSY;
diff --git a/src/gprs_ms.c b/src/gprs_ms.c
index 90e8289..bf4d08a 100644
--- a/src/gprs_ms.c
+++ b/src/gprs_ms.c
@@ -1056,6 +1056,46 @@
 
 }
 
+/* Alloc a UL TBF to be assigned over PACCH. Called when an MS requests to
+ * create a new UL TBF during the end of life of a previous UL TBF (or an SBA).
+ * In summary, this TBF is allocated as a consequence of receiving a "Pkt
+ * Resource Req" or "Pkt Ctrl Ack" from the MS.
+ * See TS 44.060 9.3.2.4.2 "Non-extended uplink TBF mode".
+ */
+struct gprs_rlcmac_ul_tbf *ms_new_ul_tbf_assigned_pacch(struct GprsMs *ms, int8_t use_trx)
+{
+	const bool single_slot = false;
+	struct gprs_rlcmac_ul_tbf *ul_tbf;
+
+	ul_tbf = tbf_alloc_ul_tbf(ms->bts, ms, use_trx, single_slot);
+	if (!ul_tbf) {
+		LOGPMS(ms, DTBF, LOGL_NOTICE, "No PDCH resource\n");
+		/* Caller will most probably send a Imm Ass Reject after return */
+		return NULL;
+	}
+	osmo_fsm_inst_dispatch(tbf_state_fi(ul_tbf_as_tbf(ul_tbf)), TBF_EV_ASSIGN_ADD_PACCH, NULL);
+	/* Contention resolution is considered to be done since TLLI is known in MS */
+	return ul_tbf;
+}
+
+/* Alloc a UL TBF to be assigned over AGCH. Used by request of a "One phase
+ * packet access", where MS requested only 1 PDCH TS (TS 44.018 Table 9.1.8.1). */
+struct gprs_rlcmac_ul_tbf *ms_new_ul_tbf_assigned_agch(struct GprsMs *ms)
+{
+	const int8_t trx_no = -1;
+	const bool single_slot = true;
+	struct gprs_rlcmac_ul_tbf *ul_tbf;
+
+	ul_tbf = tbf_alloc_ul_tbf(ms->bts, ms, trx_no, single_slot);
+	if (!ul_tbf) {
+		LOGP(DTBF, LOGL_NOTICE, "No PDCH resource for Uplink TBF\n");
+		/* Caller will most probably send a Imm Ass Reject after return */
+		return NULL;
+	}
+	osmo_fsm_inst_dispatch(tbf_state_fi(ul_tbf_as_tbf(ul_tbf)), TBF_EV_ASSIGN_ADD_CCCH, NULL);
+	return ul_tbf;
+}
+
 /* A new DL-TBF is allocated and assigned through PACCH using "tbf".
  * "tbf" may be either a UL-TBF or a DL-TBF.
  * Note: This should be called only when MS is reachable, see ms_is_reachable_for_dl_ass().
@@ -1088,7 +1128,6 @@
 	struct gprs_rlcmac_dl_tbf *dl_tbf;
 
 	dl_tbf = dl_tbf_alloc(ms->bts, ms, trx_no, single_slot);
-
 	if (!dl_tbf) {
 		LOGPMS(ms, DTBF, LOGL_NOTICE, "No PDCH resource\n");
 		return -EBUSY;
diff --git a/src/gprs_ms.h b/src/gprs_ms.h
index 8014f26..53b0cd6 100644
--- a/src/gprs_ms.h
+++ b/src/gprs_ms.h
@@ -144,6 +144,8 @@
 bool ms_nacc_rts(const struct GprsMs *ms);
 struct msgb *ms_nacc_create_rlcmac_msg(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf, uint32_t fn, uint8_t ts);
 
+struct gprs_rlcmac_ul_tbf *ms_new_ul_tbf_assigned_pacch(struct GprsMs *ms, int8_t use_trx);
+struct gprs_rlcmac_ul_tbf *ms_new_ul_tbf_assigned_agch(struct GprsMs *ms);
 int ms_new_dl_tbf_assigned_on_pacch(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf);
 int ms_new_dl_tbf_assigned_on_pch(struct GprsMs *ms);
 int ms_append_llc_dl_data(struct GprsMs *ms, uint16_t pdu_delay_csec, const uint8_t *data, uint16_t len);
diff --git a/src/pdch.cpp b/src/pdch.cpp
index ad521e3..8dd7597 100644
--- a/src/pdch.cpp
+++ b/src/pdch.cpp
@@ -119,7 +119,7 @@
 	bts_do_rate_ctr_inc(bts, CTR_CHANNEL_REQUEST_DESCRIPTION);
 
 	/* This call will register the new TBF with the MS on success */
-	gprs_rlcmac_ul_tbf *ul_tbf = tbf_alloc_ul_pacch(bts, tbf->ms(), tbf->trx->trx_no);
+	gprs_rlcmac_ul_tbf *ul_tbf = ms_new_ul_tbf_assigned_pacch(tbf->ms(), tbf->trx->trx_no);
 
 	/* schedule uplink assignment or reject */
 	if (ul_tbf) {
@@ -757,7 +757,7 @@
 		get_meas(meas, request);
 		ms_update_l1_meas(ms, meas);
 
-		ul_tbf = tbf_alloc_ul_pacch(bts, ms, trx_no());
+		ul_tbf = ms_new_ul_tbf_assigned_pacch(ms, trx_no());
 		if (!ul_tbf) {
 			handle_tbf_reject(bts, ms, trx_no(), ts_no);
 			goto return_unref;
diff --git a/src/tbf.cpp b/src/tbf.cpp
index d855083..58695d2 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -801,6 +801,11 @@
 	return (enum tbf_fsm_states)tbf->state_fsm.fi->state;
 }
 
+struct osmo_fsm_inst *tbf_state_fi(const struct gprs_rlcmac_tbf *tbf)
+{
+	return tbf->state_fsm.fi;
+}
+
 struct osmo_fsm_inst *tbf_ul_ass_fi(const struct gprs_rlcmac_tbf *tbf)
 {
 	return tbf->ul_ass_fsm.fi;
diff --git a/src/tbf.h b/src/tbf.h
index 65b131e..616c3e0 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -125,6 +125,7 @@
 enum tbf_fsm_states tbf_state(const struct gprs_rlcmac_tbf *tbf);
 struct osmo_fsm_inst *tbf_ul_ass_fi(const struct gprs_rlcmac_tbf *tbf);
 struct osmo_fsm_inst *tbf_dl_ass_fi(const struct gprs_rlcmac_tbf *tbf);
+struct osmo_fsm_inst *tbf_state_fi(const struct gprs_rlcmac_tbf *tbf);
 enum gprs_rlcmac_tbf_direction tbf_direction(const struct gprs_rlcmac_tbf *tbf);
 void tbf_set_ms(struct gprs_rlcmac_tbf *tbf, struct GprsMs *ms);
 struct llist_head *tbf_ms_list(struct gprs_rlcmac_tbf *tbf);
diff --git a/src/tbf_fsm.c b/src/tbf_fsm.c
index 9118fd7..a8e7886 100644
--- a/src/tbf_fsm.c
+++ b/src/tbf_fsm.c
@@ -99,8 +99,13 @@
 	switch (event) {
 	case TBF_EV_ASSIGN_ADD_CCCH:
 		mod_ass_type(ctx, GPRS_RLCMAC_FLAG_CCCH, true);
-		tbf_fsm_state_chg(fi, tbf_direction(ctx->tbf) == GPRS_RLCMAC_DL_TBF ?
-					TBF_ST_ASSIGN : TBF_ST_FLOW);
+		if (tbf_direction(ctx->tbf) == GPRS_RLCMAC_UL_TBF) {
+			struct gprs_rlcmac_ul_tbf *ul_tbf = tbf_as_ul_tbf(ctx->tbf);
+			tbf_fsm_state_chg(fi, TBF_ST_FLOW);
+			ul_tbf_contention_resolution_start(ul_tbf);
+		} else {
+			tbf_fsm_state_chg(fi, TBF_ST_ASSIGN);
+		}
 		break;
 	case TBF_EV_ASSIGN_ADD_PACCH:
 		mod_ass_type(ctx, GPRS_RLCMAC_FLAG_PACCH, true);
diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp
index 7189b6f..6edf8be 100644
--- a/src/tbf_ul.cpp
+++ b/src/tbf_ul.cpp
@@ -104,7 +104,7 @@
 }
 
 /* Generic function to alloc a UL TBF, later configured to be assigned either over CCCH or PACCH */
-struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms, int8_t use_trx, bool single_slot)
+struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, struct GprsMs *ms, int8_t use_trx, bool single_slot)
 {
 	struct gprs_rlcmac_ul_tbf *tbf;
 	int rc;
@@ -147,48 +147,6 @@
 	return tbf;
 }
 
-/* Alloc a UL TBF to be assigned over PACCH. Called when an MS requests to
- * create a new UL TBF during the end of life of a previous UL TBF (or an SBA).
- * In summary, this TBF is allocated as a consequence of receiving a "Pkt
- * Resource Req" or "Pkt Ctrl Ack" from the MS.
- * See TS 44.060 9.3.2.4.2 "Non-extended uplink TBF mode".
- */
-gprs_rlcmac_ul_tbf *tbf_alloc_ul_pacch(struct gprs_rlcmac_bts *bts, GprsMs *ms, int8_t use_trx)
-{
-	struct gprs_rlcmac_ul_tbf *tbf;
-
-	tbf = tbf_alloc_ul_tbf(bts, ms, use_trx, false);
-	if (!tbf) {
-		LOGPMS(ms, DTBF, LOGL_NOTICE, "No PDCH resource\n");
-		/* Caller will most probably send a Imm Ass Reject after return */
-		return NULL;
-	}
-	/* Contention resolution is considered to be done since TLLI is known in MS: */
-	tbf->m_contention_resolution_done = true;
-	osmo_fsm_inst_dispatch(tbf->state_fsm.fi, TBF_EV_ASSIGN_ADD_PACCH, NULL);
-
-	return tbf;
-}
-
-/* Alloc a UL TBF to be assigned over CCCH. Used by request of a "One phase
- * packet access", where MS requested only 1 PDCH TS (TS 44.018 Table 9.1.8.1). */
-struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_ccch(struct gprs_rlcmac_bts *bts, struct GprsMs *ms)
-{
-	struct gprs_rlcmac_ul_tbf *tbf;
-
-	tbf = tbf_alloc_ul_tbf(bts, ms, -1, true);
-	if (!tbf) {
-		LOGP(DTBF, LOGL_NOTICE, "No PDCH resource for Uplink TBF\n");
-		/* Caller will most probably send a Imm Ass Reject after return */
-		return NULL;
-	}
-	osmo_fsm_inst_dispatch(tbf->state_fsm.fi, TBF_EV_ASSIGN_ADD_CCCH, NULL);
-	tbf->contention_resolution_start();
-	OSMO_ASSERT(tbf->ms());
-
-	return tbf;
-}
-
 /* Create a temporary dummy TBF to Tx a ImmAssReject if allocating a new one during
  * packet resource Request failed. This is similar as tbf_alloc_ul() but without
  * calling tbf->setup() (in charge of TFI/USF allocation), and reusing resources
@@ -237,7 +195,7 @@
 gprs_rlcmac_ul_tbf::gprs_rlcmac_ul_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms) :
 	gprs_rlcmac_tbf(bts_, ms, GPRS_RLCMAC_UL_TBF),
 	m_rx_counter(0),
-	m_contention_resolution_done(false),
+	m_contention_resolution_done(true),
 	m_ul_gprs_ctrs(NULL),
 	m_ul_egprs_ctrs(NULL)
 {
@@ -311,6 +269,7 @@
 	 * timeout only for one-phase packet access, since two-phase is handled
 	 * through SBA structs, which are freed by the PDCH UL Controller if the
 	 * single allocated block is lost. */
+	m_contention_resolution_done = false;
 	T_START(this, T3141, 3141, "Contention resolution (UL-TBF, CCCH)", true);
 }
 void gprs_rlcmac_ul_tbf::contention_resolution_success()
@@ -782,6 +741,11 @@
 	return tbf->ul_ack_fsm.fi;
 }
 
+void ul_tbf_contention_resolution_start(struct gprs_rlcmac_ul_tbf *tbf)
+{
+	tbf->contention_resolution_start();
+}
+
 void ul_tbf_contention_resolution_success(struct gprs_rlcmac_ul_tbf *tbf)
 {
 	return tbf->contention_resolution_success();
diff --git a/src/tbf_ul.h b/src/tbf_ul.h
index 59e5d66..0812b9d 100644
--- a/src/tbf_ul.h
+++ b/src/tbf_ul.h
@@ -121,9 +121,6 @@
 	return m_window.ws();
 }
 
-struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms, int8_t use_trx, bool single_slot);
-struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_pacch(struct gprs_rlcmac_bts *bts, GprsMs *ms, int8_t use_trx);
-struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_ccch(struct gprs_rlcmac_bts *bts, struct GprsMs *ms);
 struct gprs_rlcmac_ul_tbf *handle_tbf_reject(struct gprs_rlcmac_bts *bts,
 	GprsMs *ms, uint8_t trx_no, uint8_t ts_no);
 
@@ -135,13 +132,15 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, struct GprsMs *ms, int8_t use_trx, bool single_slot);
 void update_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, int8_t ta_delta);
 void set_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, uint8_t ta);
 struct gprs_rlcmac_ul_tbf *tbf_as_ul_tbf(struct gprs_rlcmac_tbf *tbf);
 void tbf_usf_timeout(struct gprs_rlcmac_ul_tbf *tbf);
+void ul_tbf_contention_resolution_start(struct gprs_rlcmac_ul_tbf *tbf);
+void ul_tbf_contention_resolution_success(struct gprs_rlcmac_ul_tbf *tbf);
 bool ul_tbf_contention_resolution_done(const struct gprs_rlcmac_ul_tbf *tbf);
 struct osmo_fsm_inst *tbf_ul_ack_fi(const struct gprs_rlcmac_ul_tbf *tbf);
-void ul_tbf_contention_resolution_success(struct gprs_rlcmac_ul_tbf *tbf);
 
 static inline struct gprs_rlcmac_tbf *ul_tbf_as_tbf(struct gprs_rlcmac_ul_tbf *ul_tbf)
 {