codec_filter_set_ms_from_bc: prepare for CSD

In all the places where codec_filter_ functions get called, for CSD we
will need to filter the bearer services. Add a new
transaction_cc.c file for functions that either combine the
codec_filter_ function with logic for CSD and voice calls or just call
the existing codec_filter function and a new csd_filter function.

Start with moving codec_filter_set_ms_from_bc to this new file, it will
be extended with a case for CSD in a future patch.

Related: OS#4394
Change-Id: If225f2a299ce6bc9ae35a17d6f591d889f49155e
diff --git a/src/libmsc/Makefile.am b/src/libmsc/Makefile.am
index bde70c9..9577475 100644
--- a/src/libmsc/Makefile.am
+++ b/src/libmsc/Makefile.am
@@ -68,6 +68,7 @@
 	sms_queue.c \
 	smsc_vty.c \
 	transaction.c \
+	transaction_cc.c \
 	msc_net_init.c \
 	ctrl_commands.c \
 	sgs_iface.c \
diff --git a/src/libmsc/codec_filter.c b/src/libmsc/codec_filter.c
index 674d564..e93ebaf 100644
--- a/src/libmsc/codec_filter.c
+++ b/src/libmsc/codec_filter.c
@@ -81,13 +81,6 @@
 	}
 }
 
-void codec_filter_set_ms_from_bc(struct codec_filter *codec_filter, const struct gsm_mncc_bearer_cap *ms_bearer_cap)
-{
-	codec_filter->ms = (struct sdp_audio_codecs){0};
-	if (ms_bearer_cap)
-		sdp_audio_codecs_from_bearer_cap(&codec_filter->ms, ms_bearer_cap);
-}
-
 void codec_filter_set_bss(struct codec_filter *codec_filter,
 			  const struct gsm0808_speech_codec_list *codec_list_bss_supported)
 {
diff --git a/src/libmsc/gsm_04_08_cc.c b/src/libmsc/gsm_04_08_cc.c
index 083e2d8..9d429a0 100644
--- a/src/libmsc/gsm_04_08_cc.c
+++ b/src/libmsc/gsm_04_08_cc.c
@@ -43,6 +43,7 @@
 #include <osmocom/msc/gsm_09_11.h>
 #include <osmocom/msc/signal.h>
 #include <osmocom/msc/transaction.h>
+#include <osmocom/msc/transaction_cc.h>
 #include <osmocom/msc/silent_call.h>
 #include <osmocom/msc/mncc_int.h>
 #include <osmocom/abis/e1_input.h>
@@ -674,7 +675,7 @@
 	codec_filter_set_ran(&trans->cc.codecs, trans->msc_a->c.ran->type);
 	codec_filter_set_bss(&trans->cc.codecs, &trans->msc_a->cc.compl_l3_codec_list_bss_supported);
 	if (setup.fields & MNCC_F_BEARER_CAP)
-		codec_filter_set_ms_from_bc(&trans->cc.codecs, &trans->bearer_cap);
+		trans_cc_filter_set_ms_from_bc(trans, &trans->bearer_cap);
 	codec_filter_run(&trans->cc.codecs);
 
 	LOG_TRANS(trans, setup.emergency ? LOGL_NOTICE : LOGL_INFO, "%sSETUP to %s\n",
@@ -926,7 +927,7 @@
 
 		/* This is the MT call leg's Call Conf, containing the MS Bearer Capabilities of the MT MS.
 		 * Store in codecs filter. */
-		codec_filter_set_ms_from_bc(&trans->cc.codecs, &call_conf.bearer_cap);
+		trans_cc_filter_set_ms_from_bc(trans, &call_conf.bearer_cap);
 	}
 
 	/* cause */
diff --git a/src/libmsc/transaction_cc.c b/src/libmsc/transaction_cc.c
new file mode 100644
index 0000000..3a0db2c
--- /dev/null
+++ b/src/libmsc/transaction_cc.c
@@ -0,0 +1,43 @@
+/* Filter/overlay codec and CSD bearer service selections for voice calls/CSD,
+ * across MS, RAN and CN limitations
+ *
+ * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Oliver Smith
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <osmocom/msc/transaction_cc.h>
+
+void trans_cc_filter_set_ms_from_bc(struct gsm_trans *trans, const struct gsm_mncc_bearer_cap *bcap)
+{
+	trans->cc.codecs.ms = (struct sdp_audio_codecs){0};
+
+	if (!bcap)
+		return;
+
+	switch (bcap->transfer) {
+	case GSM48_BCAP_ITCAP_SPEECH:
+		sdp_audio_codecs_from_bearer_cap(&trans->cc.codecs.ms, bcap);
+		break;
+	default:
+		LOG_TRANS(trans, LOGL_ERROR, "Handling of information transfer capability %d not implemented\n",
+			  bcap->transfer);
+		break;
+	}
+}