Fix mess with struct tbf types passed to LOGPTBF macro

It is quite common in all osmo-pcu code to have to convert between
parent class "tbf" and children "dl_tbf"/"ul_tbf", or other way around.
This commit adds new helper static inline functions to cast between
those while doing type checks.
This is used by new LOGPTBFDL and LOGPTBFUL macros to now expect the
proper subclass and cast securely inside the macro itself, hence sparing
all code calling those macros to have to cast explicitly the pointer to
the parent "tbf" class.

Change-Id: I7e4489ad4b93c9c8442213947e53c10b61fdc5e9
diff --git a/src/gprs_ms.c b/src/gprs_ms.c
index f552d93..df1c9be 100644
--- a/src/gprs_ms.c
+++ b/src/gprs_ms.c
@@ -96,7 +96,7 @@
 	if (tbf_state((const struct gprs_rlcmac_tbf *)dl_tbf) != TBF_ST_FLOW)
 		return;
 
-	LOGPTBFDL((const struct gprs_rlcmac_tbf *)dl_tbf, LOGL_DEBUG, "LLC receive timeout, requesting DL ACK\n");
+	LOGPTBFDL(dl_tbf, LOGL_DEBUG, "LLC receive timeout, requesting DL ACK\n");
 
 	tbf_dl_request_dl_ack(dl_tbf);
 }
@@ -1042,7 +1042,7 @@
 
 	dl_tbf = ms_dl_tbf(ms);
 	if (dl_tbf && tbf_state((const struct gprs_rlcmac_tbf *)dl_tbf) == TBF_ST_WAIT_RELEASE) {
-		LOGPTBFDL((const struct gprs_rlcmac_tbf *)dl_tbf, LOGL_DEBUG, "in WAIT RELEASE state (T3193), so reuse TBF\n");
+		LOGPTBFDL(dl_tbf, LOGL_DEBUG, "in WAIT RELEASE state (T3193), so reuse TBF\n");
 		tbf_establish_dl_tbf_on_pacch((struct gprs_rlcmac_tbf *)dl_tbf);
 	}
 
diff --git a/src/nacc_fsm.c b/src/nacc_fsm.c
index 2c321c7..25e7cd8 100644
--- a/src/nacc_fsm.c
+++ b/src/nacc_fsm.c
@@ -203,8 +203,9 @@
 	rate_ctr_inc(rate_ctr_group_get_ctr(bts_rate_counters(ms->bts), CTR_PKT_CELL_CHG_CONTINUE));
 	talloc_free(mac_control_block);
 	tbf_set_polling(tbf, *new_poll_fn, data->ts, PDCH_ULC_POLL_CELL_CHG_CONTINUE);
-	LOGPTBFDL(tbf, LOGL_DEBUG, "Scheduled 'Packet Cell Change Continue' polling on PACCH (FN=%d, TS=%d)\n",
-		  *new_poll_fn, data->ts);
+	LOGPTBF(tbf, LOGL_DEBUG,
+	     "Scheduled 'Packet Cell Change Continue' polling on PACCH (FN=%d, TS=%d)\n",
+	     *new_poll_fn, data->ts);
 	return msg;
 
 free_ret:
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 6598067..7094d40 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -535,7 +535,7 @@
 {
 	/* schedule polling */
 	if (pdch_ulc_reserve_tbf_poll(trx->pdch[ts].ulc, new_poll_fn, this, reason) < 0)
-		LOGPTBFDL(this, LOGL_ERROR, "Failed scheduling poll on PACCH (FN=%d, TS=%d)\n",
+		LOGPTBF(this, LOGL_ERROR, "Failed scheduling poll on PACCH (FN=%d, TS=%d)\n",
 			  new_poll_fn, ts);
 }
 
diff --git a/src/tbf_dl.h b/src/tbf_dl.h
index 620cccf..8160cf3 100644
--- a/src/tbf_dl.h
+++ b/src/tbf_dl.h
@@ -141,7 +141,17 @@
 void tbf_dl_trigger_ass(struct gprs_rlcmac_dl_tbf *tbf, struct gprs_rlcmac_tbf *old_tbf);
 void tbf_dl_request_dl_ack(struct gprs_rlcmac_dl_tbf *tbf);
 
-#define LOGPTBFDL(tbf, level, fmt, args...) LOGP(DTBFDL, level, "%s " fmt, tbf_name(tbf), ## args)
+static inline struct gprs_rlcmac_tbf *dl_tbf_as_tbf(struct gprs_rlcmac_dl_tbf *dl_tbf)
+{
+	return (struct gprs_rlcmac_tbf *)dl_tbf;
+}
+
+static inline const struct gprs_rlcmac_tbf *dl_tbf_as_tbf_const(const struct gprs_rlcmac_dl_tbf *dl_tbf)
+{
+	return (const struct gprs_rlcmac_tbf *)dl_tbf;
+}
+
+#define LOGPTBFDL(dl_tbf, level, fmt, args...) LOGP(DTBFDL, level, "%s " fmt, tbf_name(dl_tbf_as_tbf_const(dl_tbf)), ## args)
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/tbf_dl_ass_fsm.c b/src/tbf_dl_ass_fsm.c
index 9ea216c..37c5a1b 100644
--- a/src/tbf_dl_ass_fsm.c
+++ b/src/tbf_dl_ass_fsm.c
@@ -114,7 +114,7 @@
 	bts_do_rate_ctr_inc(ms->bts, CTR_PKT_DL_ASSIGNMENT);
 
 	tbf_set_polling(ctx->tbf, new_poll_fn, d->ts, PDCH_ULC_POLL_DL_ASS);
-	LOGPTBFDL(ctx->tbf, LOGL_INFO, "Scheduled DL Assignment polling on PACCH (FN=%d, TS=%d)\n",
+	LOGPTBF(ctx->tbf, LOGL_INFO, "Scheduled DL Assignment polling on PACCH (FN=%d, TS=%d)\n",
 		  new_poll_fn, d->ts);
 
 	talloc_free(mac_control_block);
diff --git a/src/tbf_ul.h b/src/tbf_ul.h
index 62b9456..d69220d 100644
--- a/src/tbf_ul.h
+++ b/src/tbf_ul.h
@@ -143,7 +143,17 @@
 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);
 
-#define LOGPTBFUL(tbf, level, fmt, args...) LOGP(DTBFUL, level, "%s " fmt, tbf_name(tbf), ## args)
+static inline struct gprs_rlcmac_tbf *ul_tbf_as_tbf(struct gprs_rlcmac_ul_tbf *ul_tbf)
+{
+	return (struct gprs_rlcmac_tbf *)ul_tbf;
+}
+
+static inline const struct gprs_rlcmac_tbf *ul_tbf_as_tbf_const(const struct gprs_rlcmac_ul_tbf *ul_tbf)
+{
+	return (const struct gprs_rlcmac_tbf *)ul_tbf;
+}
+
+#define LOGPTBFUL(ul_tbf, level, fmt, args...) LOGP(DTBFUL, level, "%s " fmt, tbf_name(ul_tbf_as_tbf_const(ul_tbf)), ## args)
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/tbf_ul_ack_fsm.c b/src/tbf_ul_ack_fsm.c
index 2ccc493..0faf21e 100644
--- a/src/tbf_ul_ack_fsm.c
+++ b/src/tbf_ul_ack_fsm.c
@@ -89,9 +89,9 @@
 
 	if (final) {
 		tbf_set_polling(tbf, new_poll_fn, d->ts, PDCH_ULC_POLL_UL_ACK);
-		LOGPTBFUL(tbf, LOGL_DEBUG,
-			  "Scheduled UL Acknowledgement polling on PACCH (FN=%d, TS=%d)\n",
-			  new_poll_fn, d->ts);
+		LOGPTBF(tbf, LOGL_DEBUG,
+			"Scheduled UL Acknowledgement polling on PACCH (FN=%d, TS=%d)\n",
+			new_poll_fn, d->ts);
 	}
 
 	return msg;
@@ -111,7 +111,7 @@
 static void st_sched_ul_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 {
 	struct tbf_ul_ack_fsm_ctx *ctx = (struct tbf_ul_ack_fsm_ctx *)fi->priv;
-	struct gprs_rlcmac_tbf *tbf = (struct gprs_rlcmac_tbf *)ctx->tbf;
+	struct gprs_rlcmac_ul_tbf *tbf = ctx->tbf;
 	struct tbf_ul_ack_ev_create_rlcmac_msg_ctx *data_ctx;
 	bool final;
 
@@ -122,7 +122,7 @@
 		break;
 	case TBF_UL_ACK_EV_CREATE_RLCMAC_MSG:
 		data_ctx = (struct tbf_ul_ack_ev_create_rlcmac_msg_ctx *)data;
-		final = tbf_state(tbf) == TBF_ST_FINISHED;
+		final = tbf_state(ul_tbf_as_tbf(tbf)) == TBF_ST_FINISHED;
 		data_ctx->msg = create_ul_ack_nack(ctx, data_ctx, final);
 		if (!data_ctx->msg)
 			return;
diff --git a/src/tbf_ul_ass_fsm.c b/src/tbf_ul_ass_fsm.c
index b443e4f..ee5f681 100644
--- a/src/tbf_ul_ass_fsm.c
+++ b/src/tbf_ul_ass_fsm.c
@@ -129,7 +129,7 @@
 	bts_do_rate_ctr_inc(ms->bts, CTR_PKT_UL_ASSIGNMENT);
 
 	tbf_set_polling(ctx->tbf, new_poll_fn, d->ts, PDCH_ULC_POLL_UL_ASS);
-	LOGPTBFUL(ctx->tbf, LOGL_INFO, "Scheduled UL Assignment polling on PACCH (FN=%d, TS=%d)\n",
+	LOGPTBF(ctx->tbf, LOGL_INFO, "Scheduled UL Assignment polling on PACCH (FN=%d, TS=%d)\n",
 		  new_poll_fn, d->ts);
 
 	talloc_free(mac_control_block);