Move FLOW tbf_state transition to tbf_fsm.

Related: OS#2709
Change-Id: Ia8c7de759c195d09263fb1f083fbf6cfa3087f8d
diff --git a/src/pdch.cpp b/src/pdch.cpp
index f53e155..b5622b4 100644
--- a/src/pdch.cpp
+++ b/src/pdch.cpp
@@ -368,15 +368,7 @@
 				tbf->direction == new_tbf->direction)
 			tbf_free(tbf);
 
-		if (new_tbf->state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)) {
-			/* We now know that the PACCH really existed */
-			LOGPTBF(new_tbf, LOGL_INFO,
-				"The TBF has been confirmed on the PACCH, "
-				"changed type from CCCH to PACCH\n");
-			osmo_fsm_inst_dispatch(new_tbf->state_fsm.fi, TBF_EV_ASSIGN_DEL_CCCH, NULL);
-			osmo_fsm_inst_dispatch(new_tbf->state_fsm.fi, TBF_EV_ASSIGN_ADD_PACCH, NULL);
-		}
-		TBF_SET_STATE(new_tbf, TBF_ST_FLOW);
+		osmo_fsm_inst_dispatch(new_tbf->state_fsm.fi, TBF_EV_ASSIGN_ACK_PACCH, NULL);
 		/* stop pending assignment timer */
 		new_tbf->t_stop(T0, "control acked (DL-TBF)");
 		if (new_tbf->check_n_clear(GPRS_RLCMAC_FLAG_TO_DL_ASS))
@@ -401,7 +393,7 @@
 				tbf->direction == new_tbf->direction)
 			tbf_free(tbf);
 
-		TBF_SET_STATE(new_tbf, TBF_ST_FLOW);
+		osmo_fsm_inst_dispatch(new_tbf->state_fsm.fi, TBF_EV_ASSIGN_ACK_PACCH, NULL);
 		if (new_tbf->check_n_clear(GPRS_RLCMAC_FLAG_TO_UL_ASS))
 			LOGPTBF(new_tbf, LOGL_NOTICE, "Recovered uplink assignment for UL\n");
 
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 8b17059..7b5fce2 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -808,7 +808,7 @@
 			if (!dl_tbf->upgrade_to_multislot) {
 				/* change state to FLOW, so scheduler
 				 * will start transmission */
-				TBF_SET_STATE(dl_tbf, TBF_ST_FLOW);
+				osmo_fsm_inst_dispatch(dl_tbf->state_fsm.fi, TBF_EV_ASSIGN_READY_CCCH, NULL);
 				return;
 			}
 
diff --git a/src/tbf_fsm.c b/src/tbf_fsm.c
index 9301931..5799d90 100644
--- a/src/tbf_fsm.c
+++ b/src/tbf_fsm.c
@@ -44,6 +44,8 @@
 	{ TBF_EV_ASSIGN_ADD_CCCH, "ASSIGN_ADD_CCCH" },
 	{ TBF_EV_ASSIGN_ADD_PACCH, "ASSIGN_ADD_PACCH" },
 	{ TBF_EV_ASSIGN_DEL_CCCH, "ASSIGN_DEL_CCCH" },
+	{ TBF_EV_ASSIGN_ACK_PACCH, "ASSIGN_ACK_PACCH" },
+	{ TBF_EV_ASSIGN_READY_CCCH, "ASSIGN_READY_CCCH" },
 	{ 0, NULL }
 };
 
@@ -115,6 +117,21 @@
 	case TBF_EV_ASSIGN_ADD_PACCH:
 		mod_ass_type(ctx, GPRS_RLCMAC_FLAG_PACCH, true);
 		break;
+	case TBF_EV_ASSIGN_ACK_PACCH:
+		if (ctx->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)) {
+			/* We now know that the PACCH really existed */
+			LOGPTBF(ctx->tbf, LOGL_INFO,
+				"The TBF has been confirmed on the PACCH, "
+				"changed type from CCCH to PACCH\n");
+			mod_ass_type(ctx, GPRS_RLCMAC_FLAG_CCCH, false);
+			mod_ass_type(ctx, GPRS_RLCMAC_FLAG_PACCH, true);
+		}
+		tbf_fsm_state_chg(fi, TBF_ST_FLOW);
+		break;
+	case TBF_EV_ASSIGN_READY_CCCH:
+		/* change state to FLOW, so scheduler will start transmission */
+		tbf_fsm_state_chg(fi, TBF_ST_FLOW);
+		break;
 	default:
 		OSMO_ASSERT(0);
 	}
@@ -151,7 +168,9 @@
 	[TBF_ST_ASSIGN] = {
 		.in_event_mask =
 			X(TBF_EV_ASSIGN_ADD_CCCH) |
-			X(TBF_EV_ASSIGN_ADD_PACCH),
+			X(TBF_EV_ASSIGN_ADD_PACCH) |
+			X(TBF_EV_ASSIGN_ACK_PACCH) |
+			X(TBF_EV_ASSIGN_READY_CCCH),
 		.out_state_mask =
 			X(TBF_ST_FLOW) |
 			X(TBF_ST_FINISHED) |
diff --git a/src/tbf_fsm.h b/src/tbf_fsm.h
index ed025ca..a3050c0 100644
--- a/src/tbf_fsm.h
+++ b/src/tbf_fsm.h
@@ -30,6 +30,8 @@
 	TBF_EV_ASSIGN_ADD_CCCH, /* An assignment is sent over CCCH and confirmation from MS is pending */
 	TBF_EV_ASSIGN_ADD_PACCH, /* An assignment is sent over PACCH and confirmation from MS is pending */
 	TBF_EV_ASSIGN_DEL_CCCH, /* An assignment previously sent over CCCH has been confirmed by MS */
+	TBF_EV_ASSIGN_ACK_PACCH, /*  We received a CTRL ACK confirming assignment started on PACCH */
+	TBF_EV_ASSIGN_READY_CCCH, /* TBF Start Time timer triggered */
 };
 
 enum tbf_fsm_states {